diff --git a/Libraries/LibWeb/Dump.cpp b/Libraries/LibWeb/Dump.cpp index 49a4fa0380c..e39678de7bd 100644 --- a/Libraries/LibWeb/Dump.cpp +++ b/Libraries/LibWeb/Dump.cpp @@ -389,20 +389,17 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho fragment.length_in_code_units(), fragment.absolute_rect(), fragment.baseline()); - if (is(fragment.layout_node())) { + if (fragment.length_in_code_units() > 0) { builder.append_repeated(" "sv, indent); - auto const& layout_text = static_cast(fragment.layout_node()); - auto fragment_text = layout_text.text_for_rendering().substring_view(fragment.start_offset(), fragment.length_in_code_units()); - builder.appendff(" \"{}\"\n", fragment_text); + builder.appendff(" \"{}\"\n", fragment.text()); } }; - if (is(layout_node) && static_cast(layout_node).children_are_inline()) { - auto& block = static_cast(layout_node); - for (size_t fragment_index = 0; block.paintable_with_lines() && fragment_index < block.paintable_with_lines()->fragments().size(); ++fragment_index) { - auto const& fragment = block.paintable_with_lines()->fragments()[fragment_index]; - dump_fragment(fragment, fragment_index); - } + if (auto const* block_container = as_if(layout_node); + block_container && block_container->children_are_inline() && block_container->paintable_with_lines()) { + size_t fragment_index = 0; + for (auto const& fragment : block_container->paintable_with_lines()->fragments()) + dump_fragment(fragment, fragment_index++); } if (is(layout_node) && layout_node.first_paintable()) { diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp index 499b4468a6a..086d0cd348d 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -318,7 +318,8 @@ struct RequiredLineBreakCount { // https://html.spec.whatwg.org/multipage/dom.html#rendered-text-collection-steps static Vector> rendered_text_collection_steps(DOM::Node const& node) { - // 1. Let items be the result of running the rendered text collection steps with each child node of node in tree order, and then concatenating the results to a single list. + // 1. Let items be the result of running the rendered text collection steps with each child node of node in tree + // order, and then concatenating the results to a single list. Vector> items; node.for_each_child([&](auto const& child) { auto child_items = rendered_text_collection_steps(child); @@ -348,18 +349,22 @@ static Vector> rendered_text_collec if (computed_values.content_visibility() == CSS::ContentVisibility::Hidden) return items; - // 4. If node is a Text node, then for each CSS text box produced by node, in content order, - // compute the text of the box after application of the CSS 'white-space' processing rules - // and 'text-transform' rules, set items to the list of the resulting strings, and return items. + // 4. If node is a Text node, then for each CSS text box produced by node, in content order, compute the text of the + // box after application of the CSS 'white-space' processing rules and 'text-transform' rules, set items to the + // list of the resulting strings, and return items. - // FIXME: The CSS 'white-space' processing rules are slightly modified: - // collapsible spaces at the end of lines are always collapsed, - // but they are only removed if the line is the last line of the block, - // or it ends with a br element. Soft hyphens should be preserved. [CSSTEXT] + // FIXME: The CSS 'white-space' processing rules are slightly modified: collapsible spaces at the end of lines are + // always collapsed, but they are only removed if the line is the last line of the block, or it ends with a br + // element. Soft hyphens should be preserved. [CSSTEXT] - if (is(node)) { - auto const* layout_text_node = as(layout_node); - items.append(layout_text_node->text_for_rendering()); + if (auto const* layout_text_node = as_if(layout_node)) { + Layout::TextNode::ChunkIterator iterator { *layout_text_node, false, false }; + while (true) { + auto chunk = iterator.next(); + if (!chunk.has_value()) + break; + items.append(Utf16String::from_utf16(chunk.release_value().view)); + } return items; } @@ -430,9 +435,8 @@ Utf16String HTMLElement::get_the_text_steps() while (!results.is_empty() && results.last().has()) results.take_last(); - // 6. Replace each remaining run of consecutive required line break count items - // with a string consisting of as many U+000A LF code points as the maximum of the values - // in the required line break count items. + // 6. Replace each remaining run of consecutive required line break count items with a string consisting of as many + // U+000A LF code points as the maximum of the values in the required line break count items. StringBuilder builder(StringBuilder::Mode::UTF16); for (size_t i = 0; i < results.size(); ++i) { results[i].visit( diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index dcd68f7576b..4a19c3cebe2 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -341,8 +341,7 @@ void InlineFormattingContext::generate_line_boxes() next_width = iterator.next_non_whitespace_sequence_width(); } - // If whitespace caused us to break, we swallow the whitespace instead of - // putting it on the next line. + // If whitespace caused us to break, we swallow the whitespace instead of putting it on the next line. if (is_whitespace && next_width > 0 && line_builder.break_if_needed(item.border_box_width() + next_width)) break; } else if (text_node.computed_values().text_overflow() == CSS::TextOverflow::Ellipsis diff --git a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp index dafd8edf929..6f577f53a7c 100644 --- a/Libraries/LibWeb/Layout/InlineLevelIterator.cpp +++ b/Libraries/LibWeb/Layout/InlineLevelIterator.cpp @@ -490,11 +490,9 @@ Optional InlineLevelIterator::next_without_lookahead( if (!m_current_node) return {}; - if (is(*m_current_node)) { - auto& text_node = static_cast(*m_current_node); - + if (auto* text_node = as_if(*m_current_node)) { if (!m_text_node_context.has_value()) - enter_text_node(text_node); + enter_text_node(*text_node); auto chunk_opt = m_text_node_context->chunk_iterator.next(); if (!chunk_opt.has_value()) { @@ -511,7 +509,8 @@ Optional InlineLevelIterator::next_without_lookahead( if (text_type == Gfx::GlyphRun::TextType::Ltr || text_type == Gfx::GlyphRun::TextType::Rtl) m_text_node_context->last_known_direction = text_type; - if (m_text_node_context->do_respect_linebreaks && chunk.has_breaking_newline) { + auto do_respect_linebreak = m_text_node_context->chunk_iterator.should_respect_linebreaks(); + if (do_respect_linebreak && chunk.has_breaking_newline) { m_text_node_context->is_last_chunk = true; if (chunk.is_all_whitespace) text_type = Gfx::GlyphRun::TextType::EndPadding; @@ -520,15 +519,12 @@ Optional InlineLevelIterator::next_without_lookahead( if (text_type == Gfx::GlyphRun::TextType::ContextDependent) text_type = resolve_text_direction_from_context(); - if (m_text_node_context->do_respect_linebreaks && chunk.has_breaking_newline) { - return Item { - .type = Item::Type::ForcedBreak, - }; - } + if (do_respect_linebreak && chunk.has_breaking_newline) + return Item { .type = Item::Type::ForcedBreak }; - auto letter_spacing = text_node.computed_values().letter_spacing(); + auto letter_spacing = text_node->computed_values().letter_spacing(); // FIXME: We should apply word spacing to all word-separator characters not just breaking tabs - auto word_spacing = text_node.computed_values().word_spacing(); + auto word_spacing = text_node->computed_values().word_spacing(); auto x = 0.0f; if (chunk.has_breaking_tab) { @@ -541,13 +537,13 @@ Optional InlineLevelIterator::next_without_lookahead( } // https://drafts.csswg.org/css-text/#tab-size-property - CSS::CalculationResolutionContext calculation_context { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(text_node) }; - auto tab_size = text_node.computed_values().tab_size(); + CSS::CalculationResolutionContext calculation_context { .length_resolution_context = CSS::Length::ResolutionContext::for_layout_node(*text_node) }; + auto tab_size = text_node->computed_values().tab_size(); CSSPixels tab_width; tab_width = tab_size.visit( [&](CSS::LengthOrCalculated const& t) -> CSSPixels { return t.resolved(calculation_context) - .map([&](auto& it) { return it.to_px(text_node); }) + .map([&](auto& it) { return it.to_px(*text_node); }) .value_or(0); }, [&](CSS::NumberOrCalculated const& n) -> CSSPixels { @@ -585,16 +581,17 @@ Optional InlineLevelIterator::next_without_lookahead( CSSPixels chunk_width = CSSPixels::nearest_value_for(glyph_run->width() + x); // NOTE: We never consider `content: ""` to be collapsible whitespace. - bool is_generated_empty_string = text_node.is_generated() && chunk.length == 0; + bool is_generated_empty_string = text_node->is_generated() && chunk.length == 0; + auto collapse_whitespace = m_text_node_context->chunk_iterator.should_collapse_whitespace(); Item item { .type = Item::Type::Text, - .node = &text_node, + .node = text_node, .glyph_run = move(glyph_run), .offset_in_node = chunk.start, .length_in_node = chunk.length, .width = chunk_width, - .is_collapsible_whitespace = m_text_node_context->do_collapse && chunk.is_all_whitespace && !is_generated_empty_string, + .is_collapsible_whitespace = collapse_whitespace && chunk.is_all_whitespace && !is_generated_empty_string, }; add_extra_box_model_metrics_to_item(item, m_text_node_context->is_first_chunk, m_text_node_context->is_last_chunk); @@ -671,17 +668,11 @@ void InlineLevelIterator::enter_text_node(Layout::TextNode const& text_node) auto white_space_collapse = text_node.computed_values().white_space_collapse(); auto text_wrap_mode = text_node.computed_values().text_wrap_mode(); - bool do_collapse = white_space_collapse == CSS::WhiteSpaceCollapse::Collapse || white_space_collapse == CSS::WhiteSpaceCollapse::PreserveBreaks; + // https://drafts.csswg.org/css-text-4/#collapse 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; + bool do_respect_linebreaks = first_is_one_of(white_space_collapse, CSS::WhiteSpaceCollapse::Preserve, CSS::WhiteSpaceCollapse::PreserveBreaks, CSS::WhiteSpaceCollapse::BreakSpaces); m_text_node_context = TextNodeContext { - .do_collapse = do_collapse, - .do_wrap_lines = do_wrap_lines, - .do_respect_linebreaks = do_respect_linebreaks, .is_first_chunk = true, .is_last_chunk = false, .chunk_iterator = TextNode::ChunkIterator { text_node, do_wrap_lines, do_respect_linebreaks }, diff --git a/Libraries/LibWeb/Layout/InlineLevelIterator.h b/Libraries/LibWeb/Layout/InlineLevelIterator.h index e6d5b79d29c..a0c9c9ba174 100644 --- a/Libraries/LibWeb/Layout/InlineLevelIterator.h +++ b/Libraries/LibWeb/Layout/InlineLevelIterator.h @@ -81,9 +81,6 @@ private: LayoutMode const m_layout_mode; struct TextNodeContext { - bool do_collapse {}; - bool do_wrap_lines {}; - bool do_respect_linebreaks {}; bool is_first_chunk {}; bool is_last_chunk {}; TextNode::ChunkIterator chunk_iterator; diff --git a/Libraries/LibWeb/Layout/LayoutState.cpp b/Libraries/LibWeb/Layout/LayoutState.cpp index 55c4a90c474..30f32199a22 100644 --- a/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Libraries/LibWeb/Layout/LayoutState.cpp @@ -289,7 +289,7 @@ void LayoutState::commit(Box& root) if (auto* paintable_with_lines = as_if(*paintable_box)) { for (size_t line_index = 0; line_index < used_values.line_boxes.size(); ++line_index) { auto& line_box = used_values.line_boxes[line_index]; - for (auto& fragment : line_box.fragments()) { + for (auto const& fragment : line_box.fragments()) { if (auto const* text_node = as_if(fragment.layout_node())) text_nodes.set(const_cast(text_node)); auto did_relocate_fragment = try_to_relocate_fragment_in_inline_node(fragment, line_index); diff --git a/Libraries/LibWeb/Layout/LineBox.cpp b/Libraries/LibWeb/Layout/LineBox.cpp index f1011fcd9ff..ca42ac582c1 100644 --- a/Libraries/LibWeb/Layout/LineBox.cpp +++ b/Libraries/LibWeb/Layout/LineBox.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ @@ -35,18 +36,24 @@ CSSPixels LineBox::bottom() const return m_bottom; } -void LineBox::add_fragment(Node const& layout_node, size_t start, size_t length, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, CSSPixels content_height, CSSPixels border_box_top, CSSPixels border_box_bottom, RefPtr glyph_run) +void LineBox::add_fragment(Node const& layout_node, size_t start, size_t length, CSSPixels leading_size, + CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, + CSSPixels content_height, CSSPixels border_box_top, CSSPixels border_box_bottom, RefPtr glyph_run) { bool text_align_is_justify = layout_node.computed_values().text_align() == CSS::TextAlign::Justify; - if (glyph_run && !text_align_is_justify && !m_fragments.is_empty() && &m_fragments.last().layout_node() == &layout_node && &m_fragments.last().m_glyph_run->font() == &glyph_run->font()) { + if (glyph_run && !text_align_is_justify && !m_fragments.is_empty() + && &m_fragments.last().layout_node() == &layout_node + && &m_fragments.last().m_glyph_run->font() == &glyph_run->font() + && m_fragments.last().start() + m_fragments.last().length_in_code_units() == start) { // The fragment we're adding is from the last Layout::Node on the line. // Expand the last fragment instead of adding a new one with the same Layout::Node. - m_fragments.last().m_length = (start - m_fragments.last().m_start) + length; + m_fragments.last().m_length_in_code_units += length; m_fragments.last().append_glyph_run(glyph_run, content_width); } else { CSSPixels inline_offset = leading_margin + leading_size + m_inline_length; CSSPixels block_offset = 0; - m_fragments.append(LineBoxFragment { layout_node, start, length, inline_offset, block_offset, content_width, content_height, border_box_top, m_direction, m_writing_mode, move(glyph_run) }); + m_fragments.append(LineBoxFragment { layout_node, start, length, inline_offset, block_offset, content_width, + content_height, border_box_top, m_direction, m_writing_mode, move(glyph_run) }); } m_inline_length += leading_margin + leading_size + content_width + trailing_size + trailing_margin; m_block_length = max(m_block_length, content_height + border_box_top + border_box_bottom); @@ -68,8 +75,7 @@ CSSPixels LineBox::calculate_or_trim_trailing_whitespace(RemoveTrailingWhitespac return whitespace_width; last_fragment = &m_fragments[--fragment_index]; - auto const* dom_node = last_fragment->layout_node().dom_node(); - if (dom_node) { + if (auto const* dom_node = last_fragment->layout_node().dom_node()) { auto cursor_position = dom_node->document().cursor_position(); if (cursor_position && cursor_position->node() == dom_node) return whitespace_width; @@ -90,9 +96,9 @@ CSSPixels LineBox::calculate_or_trim_trailing_whitespace(RemoveTrailingWhitespac if (last_text.is_null()) return whitespace_width; - size_t last_fragment_length = last_fragment->length(); - while (last_fragment_length) { - auto last_character = last_text.code_unit_at(--last_fragment_length); + size_t last_text_length = last_text.length_in_code_units(); + while (last_text_length) { + auto last_character = last_text.code_unit_at(--last_text_length); if (!is_ascii_space(last_character)) break; @@ -100,7 +106,7 @@ CSSPixels LineBox::calculate_or_trim_trailing_whitespace(RemoveTrailingWhitespac int last_character_width = font.glyph_width(last_character); whitespace_width += last_character_width; if (should_remove == RemoveTrailingWhitespace::Yes) { - last_fragment->m_length -= 1; + --last_fragment->m_length_in_code_units; last_fragment->set_inline_length(last_fragment->inline_length() - last_character_width); m_inline_length -= last_character_width; } diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.cpp b/Libraries/LibWeb/Layout/LineBoxFragment.cpp index 5b4e39cfe71..f04716ed284 100644 --- a/Libraries/LibWeb/Layout/LineBoxFragment.cpp +++ b/Libraries/LibWeb/Layout/LineBoxFragment.cpp @@ -12,10 +12,12 @@ namespace Web::Layout { -LineBoxFragment::LineBoxFragment(Node const& layout_node, size_t start, size_t length, CSSPixels inline_offset, CSSPixels block_offset, CSSPixels inline_length, CSSPixels block_length, CSSPixels border_box_top, CSS::Direction direction, CSS::WritingMode writing_mode, RefPtr glyph_run) +LineBoxFragment::LineBoxFragment(Node const& layout_node, size_t start, size_t length_in_code_units, + CSSPixels inline_offset, CSSPixels block_offset, CSSPixels inline_length, CSSPixels block_length, + CSSPixels border_box_top, CSS::Direction direction, CSS::WritingMode writing_mode, RefPtr glyph_run) : m_layout_node(layout_node) , m_start(start) - , m_length(length) + , m_length_in_code_units(length_in_code_units) , m_inline_offset(inline_offset) , m_block_offset(block_offset) , m_inline_length(inline_length) @@ -48,10 +50,9 @@ CSSPixelSize LineBoxFragment::size() const bool LineBoxFragment::ends_in_whitespace() const { - auto text = this->text(); - if (text.is_empty()) + if (m_length_in_code_units == 0) return false; - return is_ascii_space(text.code_unit_at(text.length_in_code_units() - 1)); + return is_ascii_space(text().code_unit_at(m_length_in_code_units - 1)); } bool LineBoxFragment::is_justifiable_whitespace() const @@ -62,7 +63,7 @@ bool LineBoxFragment::is_justifiable_whitespace() const Utf16View LineBoxFragment::text() const { if (auto* text_node = as_if(layout_node())) - return text_node->text_for_rendering().substring_view(m_start, m_length); + return text_node->text_for_rendering().substring_view(m_start, m_length_in_code_units); return {}; } diff --git a/Libraries/LibWeb/Layout/LineBoxFragment.h b/Libraries/LibWeb/Layout/LineBoxFragment.h index 96719d10cbf..06fe2cae87f 100644 --- a/Libraries/LibWeb/Layout/LineBoxFragment.h +++ b/Libraries/LibWeb/Layout/LineBoxFragment.h @@ -22,7 +22,7 @@ public: Node const& layout_node() const { return m_layout_node; } size_t start() const { return m_start; } - size_t length() const { return m_length; } + size_t length_in_code_units() const { return m_length_in_code_units; } CSSPixelPoint offset() const; CSSPixels inline_offset() const { return m_inline_offset; } @@ -61,7 +61,7 @@ private: GC::Ref m_layout_node; size_t m_start { 0 }; - size_t m_length { 0 }; + size_t m_length_in_code_units { 0 }; CSSPixels m_inline_offset; CSSPixels m_block_offset; CSSPixels m_inline_length; diff --git a/Libraries/LibWeb/Layout/LineBuilder.cpp b/Libraries/LibWeb/Layout/LineBuilder.cpp index dd6effa3f57..bd9202d5c9c 100644 --- a/Libraries/LibWeb/Layout/LineBuilder.cpp +++ b/Libraries/LibWeb/Layout/LineBuilder.cpp @@ -86,7 +86,8 @@ void LineBuilder::append_box(Box const& box, CSSPixels leading_size, CSSPixels t { auto& box_state = m_layout_state.get_mutable(box); auto& line_box = ensure_last_line_box(); - line_box.add_fragment(box, 0, 0, leading_size, trailing_size, leading_margin, trailing_margin, box_state.content_width(), box_state.content_height(), box_state.border_box_top(), box_state.border_box_bottom()); + line_box.add_fragment(box, 0, 0, leading_size, trailing_size, leading_margin, trailing_margin, + box_state.content_width(), box_state.content_height(), box_state.border_box_top(), box_state.border_box_bottom()); m_max_height_on_current_line = max(m_max_height_on_current_line, box_state.margin_box_height()); box_state.containing_line_box_fragment = LineBoxFragmentCoordinate { @@ -98,7 +99,8 @@ void LineBuilder::append_box(Box const& box, CSSPixels leading_size, CSSPixels t void LineBuilder::append_text_chunk(TextNode const& text_node, size_t offset_in_node, size_t length_in_node, CSSPixels leading_size, CSSPixels trailing_size, CSSPixels leading_margin, CSSPixels trailing_margin, CSSPixels content_width, CSSPixels content_height, RefPtr glyph_run) { auto& line_box = ensure_last_line_box(); - line_box.add_fragment(text_node, offset_in_node, length_in_node, leading_size, trailing_size, leading_margin, trailing_margin, content_width, content_height, 0, 0, move(glyph_run)); + line_box.add_fragment(text_node, offset_in_node, length_in_node, leading_size, trailing_size, leading_margin, + trailing_margin, content_width, content_height, 0, 0, move(glyph_run)); m_max_height_on_current_line = max(m_max_height_on_current_line, line_box.block_length()); } @@ -300,9 +302,7 @@ void LineBuilder::update_last_line() CSSPixels uppermost_box_top = strut_top; CSSPixels lowermost_box_bottom = strut_bottom; - for (size_t i = 0; i < line_box.fragments().size(); ++i) { - auto& fragment = line_box.fragments()[i]; - + for (auto& fragment : line_box.fragments()) { CSSPixels new_fragment_inline_offset = inline_offset + fragment.inline_offset(); CSSPixels new_fragment_block_offset = 0; diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp index f896e420602..271c8cfdf79 100644 --- a/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Libraries/LibWeb/Layout/TextNode.cpp @@ -282,10 +282,9 @@ static Utf16String apply_text_transform(Utf16String const& string, CSS::TextTran return apply_math_auto_text_transform(string); case CSS::TextTransform::Capitalize: return string.to_titlecase(locale, TrailingCodePointTransformation::PreserveExisting); - case CSS::TextTransform::FullSizeKana: { + case CSS::TextTransform::FullSizeKana: dbgln("FIXME: Implement text-transform full-size-kana"); return string; - } case CSS::TextTransform::FullWidth: return string.to_fullwidth(); } @@ -306,7 +305,6 @@ Utf16String const& TextNode::text_for_rendering() const return *m_text_for_rendering; } -// NOTE: This collapses whitespace into a single ASCII space if the CSS white-space property tells us to. void TextNode::compute_text_for_rendering() { if (dom_node().is_password_input()) { @@ -314,53 +312,85 @@ void TextNode::compute_text_for_rendering() return; } - bool collapse = first_is_one_of(computed_values().white_space_collapse(), CSS::WhiteSpaceCollapse::Collapse, CSS::WhiteSpaceCollapse::PreserveBreaks); - + // Apply text-transform + // FIXME: This can generate more code points than there were before; we need to find a better way to map the + // resulting paintable fragments' offsets into the original text node data. + // See: https://github.com/LadybirdBrowser/ladybird/issues/6177 auto parent_element = dom_node().parent_element(); auto const maybe_lang = parent_element ? parent_element->lang() : Optional {}; auto const lang = maybe_lang.has_value() ? maybe_lang.value() : Optional {}; + auto text = apply_text_transform(dom_node().data(), computed_values().text_transform(), lang); - auto data = apply_text_transform(dom_node().data(), computed_values().text_transform(), lang); - - // NOTE: A couple fast returns to avoid unnecessarily allocating a StringBuilder. - if (!collapse || data.is_empty()) { - m_text_for_rendering = move(data); + // The logic below deals with converting whitespace characters. If we don't have them, return early. + if (text.is_empty() || !any_of(text, is_ascii_space)) { + m_text_for_rendering = move(text); return; } - if (data.length_in_code_units() == 1) { - if (data.is_ascii_whitespace()) - m_text_for_rendering = " "_utf16; - else - m_text_for_rendering = move(data); - return; - } + // https://drafts.csswg.org/css-text-4/#white-space-phase-1 + bool convert_newlines = false; + bool convert_tabs = false; - if (!any_of(data, is_ascii_space)) { - m_text_for_rendering = move(data); - return; - } + // If white-space-collapse is set to collapse or preserve-breaks, white space characters are considered collapsible + // and are processed by performing the following steps: + auto white_space_collapse = computed_values().white_space_collapse(); + if (first_is_one_of(white_space_collapse, CSS::WhiteSpaceCollapse::Collapse, CSS::WhiteSpaceCollapse::PreserveBreaks)) { + // 1. FIXME: Any sequence of collapsible spaces and tabs immediately preceding or following a segment break is removed. - StringBuilder builder { StringBuilder::Mode::UTF16, data.length_in_code_units() }; - size_t index = 0; + // 2. Collapsible segment breaks are transformed for rendering according to the segment break transformation + // rules. + { + // https://drafts.csswg.org/css-text-4/#line-break-transform + // FIXME: When white-space-collapse is not collapse, segment breaks are not collapsible. For values other than + // collapse or preserve-spaces (which transforms them into spaces), segment breaks are instead transformed + // into a preserved line feed (U+000A). - auto skip_over_whitespace = [&] { - while (index < data.length_in_code_units() && is_ascii_space(data.code_unit_at(index))) - ++index; - }; + // When white-space-collapse is collapse, segment breaks are collapsible, and are collapsed as follows: + if (white_space_collapse == CSS::WhiteSpaceCollapse::Collapse) { + // 1. FIXME: First, any collapsible segment break immediately following another collapsible segment break is + // removed. - while (index < data.length_in_code_units()) { - if (is_ascii_space(data.code_unit_at(index))) { - builder.append(' '); - ++index; - skip_over_whitespace(); - } else { - builder.append_code_unit(data.code_unit_at(index)); - ++index; + // 2. FIXME: Then any remaining segment break is either transformed into a space (U+0020) or removed depending + // on the context before and after the break. The rules for this operation are UA-defined in this + // level. + convert_newlines = true; + } } + + // 3. Every collapsible tab is converted to a collapsible space (U+0020). + convert_tabs = true; + + // 4. Any collapsible space immediately following another collapsible space—even one outside the boundary of the + // inline containing that space, provided both spaces are within the same inline formatting context—is + // collapsed to have zero advance width. (It is invisible, but retains its soft wrap opportunity, if any.) + // AD-HOC: This is handled by TextNode::ChunkIterator by removing the space. } - m_text_for_rendering = builder.to_utf16_string(); + // If white-space-collapse is set to preserve-spaces, each tab and segment break is converted to a space. + if (white_space_collapse == CSS::WhiteSpaceCollapse::PreserveSpaces) { + convert_tabs = true; + convert_newlines = true; + } + + // AD-HOC: Prevent allocating a StringBuilder for a single space/newline/tab. + if (text == " "sv || (convert_tabs && text == "\t"sv) || (convert_newlines && text == "\n"sv)) { + m_text_for_rendering = " "_utf16; + return; + } + + // AD-HOC: It's important to not change the amount of code units in the resulting transformed text, so ChunkIterator + // can pass views to this string with associated code unit offsets that still match the original text. + if (convert_newlines || convert_tabs) { + StringBuilder text_builder { StringBuilder::Mode::UTF16, text.length_in_code_units() }; + for (auto code_point : text) { + if ((convert_newlines && code_point == '\n') || (convert_tabs && code_point == '\t')) + code_point = ' '; + text_builder.append_code_point(code_point); + } + text = text_builder.to_utf16_string(); + } + + m_text_for_rendering = move(text); } Unicode::Segmenter& TextNode::grapheme_segmenter() const @@ -373,22 +403,20 @@ Unicode::Segmenter& TextNode::grapheme_segmenter() const return *m_grapheme_segmenter; } -TextNode::ChunkIterator::ChunkIterator(TextNode const& text_node, bool wrap_lines, bool respect_linebreaks) - : m_wrap_lines(wrap_lines) - , m_respect_linebreaks(respect_linebreaks) - , m_view(text_node.text_for_rendering()) - , m_font_cascade_list(text_node.computed_values().font_list()) - , m_grapheme_segmenter(text_node.grapheme_segmenter()) +TextNode::ChunkIterator::ChunkIterator(TextNode const& text_node, bool should_wrap_lines, bool should_respect_linebreaks) + : ChunkIterator(text_node, text_node.text_for_rendering(), text_node.grapheme_segmenter(), should_wrap_lines, should_respect_linebreaks) { } -TextNode::ChunkIterator::ChunkIterator(TextNode const& text_node, Utf16View const& text, Unicode::Segmenter& grapheme_segmenter, bool wrap_lines, bool respect_linebreaks) - : m_wrap_lines(wrap_lines) - , m_respect_linebreaks(respect_linebreaks) +TextNode::ChunkIterator::ChunkIterator(TextNode const& text_node, Utf16View const& text, + Unicode::Segmenter& grapheme_segmenter, bool should_wrap_lines, bool should_respect_linebreaks) + : m_should_wrap_lines(should_wrap_lines) + , m_should_respect_linebreaks(should_respect_linebreaks) , m_view(text) , m_font_cascade_list(text_node.computed_values().font_list()) , m_grapheme_segmenter(grapheme_segmenter) { + m_should_collapse_whitespace = first_is_one_of(text_node.computed_values().white_space_collapse(), CSS::WhiteSpaceCollapse::Collapse, CSS::WhiteSpaceCollapse::PreserveBreaks); } static Gfx::GlyphRun::TextType text_type_for_code_point(u32 code_point) @@ -456,13 +484,18 @@ Optional TextNode::ChunkIterator::next_without_peek() if (m_current_index >= m_view.length_in_code_units()) return {}; - auto current_code_point = [this]() { + auto current_code_point = [this] { return m_view.code_point_at(m_current_index); }; - auto next_grapheme_boundary = [this]() { + auto next_grapheme_boundary = [this] { return m_grapheme_segmenter.next_boundary(m_current_index).value_or(m_view.length_in_code_units()); }; + // https://drafts.csswg.org/css-text-4/#collapsible-white-space + auto is_collapsible = [this](u32 code_point) { + return m_should_collapse_whitespace && is_ascii_space(code_point); + }; + auto code_point = current_code_point(); auto start_of_chunk = m_current_index; @@ -489,7 +522,7 @@ Optional TextNode::ChunkIterator::next_without_peek() return result.release_value(); } - if (m_respect_linebreaks && code_point == '\n') { + if (m_should_respect_linebreaks && code_point == '\n') { // Newline encountered, and we're supposed to preserve them. // If we have accumulated some code points in the current chunk, commit them now and continue with the newline next time. if (auto result = try_commit_chunk(start_of_chunk, m_current_index, false, broken_on_tab, font, text_type); result.has_value()) @@ -502,7 +535,19 @@ Optional TextNode::ChunkIterator::next_without_peek() return result.release_value(); } - if (m_wrap_lines) { + // If both this code point and the previous code point are collapsible, skip code points until we're at a non- + // collapsible code point. + if (is_collapsible(code_point) && m_current_index > 0 && is_collapsible(m_view.code_point_at(m_current_index - 1))) { + auto result = try_commit_chunk(start_of_chunk, m_current_index, false, broken_on_tab, font, text_type); + + while (m_current_index < m_view.length_in_code_units() && is_collapsible(current_code_point())) + m_current_index = next_grapheme_boundary(); + + if (result.has_value()) + return result.release_value(); + } + + if (m_should_wrap_lines) { if (text_type != text_type_for_code_point(code_point)) { if (auto result = try_commit_chunk(start_of_chunk, m_current_index, false, broken_on_tab, font, text_type); result.has_value()) return result.release_value(); diff --git a/Libraries/LibWeb/Layout/TextNode.h b/Libraries/LibWeb/Layout/TextNode.h index 4d651b65953..cb03cad1c15 100644 --- a/Libraries/LibWeb/Layout/TextNode.h +++ b/Libraries/LibWeb/Layout/TextNode.h @@ -42,8 +42,12 @@ public: class ChunkIterator { public: - ChunkIterator(TextNode const&, bool wrap_lines, bool respect_linebreaks); - ChunkIterator(TextNode const&, Utf16View const&, Unicode::Segmenter&, bool wrap_lines, bool respect_linebreaks); + ChunkIterator(TextNode const&, bool should_wrap_lines, bool should_respect_linebreaks); + ChunkIterator(TextNode const&, Utf16View const&, Unicode::Segmenter&, bool should_wrap_lines, bool should_respect_linebreaks); + + bool should_wrap_lines() const { return m_should_wrap_lines; } + bool should_respect_linebreaks() const { return m_should_respect_linebreaks; } + bool should_collapse_whitespace() const { return m_should_collapse_whitespace; } Optional next(); Optional peek(size_t); @@ -52,8 +56,9 @@ public: Optional next_without_peek(); Optional try_commit_chunk(size_t start, size_t end, bool has_breaking_newline, bool has_breaking_tab, Gfx::Font const&, Gfx::GlyphRun::TextType) const; - bool const m_wrap_lines; - bool const m_respect_linebreaks; + bool const m_should_wrap_lines; + bool const m_should_respect_linebreaks; + bool m_should_collapse_whitespace; Utf16View m_view; Gfx::FontCascadeList const& m_font_cascade_list; diff --git a/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Libraries/LibWeb/Layout/TreeBuilder.cpp index e1d264f52e0..712dd3982e7 100644 --- a/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -490,10 +490,10 @@ void TreeBuilder::restructure_block_node_in_inline_parent(NodeWithStyleAndBoxMod static bool is_ignorable_whitespace(Layout::Node const& node) { - if (node.is_text_node() && static_cast(node).text_for_rendering().is_ascii_whitespace()) + if (auto* text_node = as_if(node); text_node && text_node->text_for_rendering().is_ascii_whitespace()) return true; - if (node.is_anonymous() && node.is_block_container() && static_cast(node).children_are_inline()) { + if (node.is_anonymous() && node.is_block_container() && node.children_are_inline()) { bool contains_only_white_space = true; node.for_each_in_inclusive_subtree([&contains_only_white_space](auto& descendant) { if (auto* text_node = as_if(descendant)) { diff --git a/Libraries/LibWeb/Painting/PaintableBox.h b/Libraries/LibWeb/Painting/PaintableBox.h index deffeed5ece..aab276344a8 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.h +++ b/Libraries/LibWeb/Painting/PaintableBox.h @@ -369,8 +369,6 @@ public: m_fragments.append(PaintableFragment { fragment }); } - void set_fragments(Vector&& fragments) { m_fragments = move(fragments); } - template void for_each_fragment(Callback callback) const { diff --git a/Libraries/LibWeb/Painting/PaintableFragment.cpp b/Libraries/LibWeb/Painting/PaintableFragment.cpp index 643d19f3ca5..e6d57494cb8 100644 --- a/Libraries/LibWeb/Painting/PaintableFragment.cpp +++ b/Libraries/LibWeb/Painting/PaintableFragment.cpp @@ -21,7 +21,7 @@ PaintableFragment::PaintableFragment(Layout::LineBoxFragment const& fragment) , m_size(fragment.size()) , m_baseline(fragment.baseline()) , m_start_offset(fragment.start()) - , m_length_in_code_units(fragment.length()) + , m_length_in_code_units(fragment.length_in_code_units()) , m_glyph_run(fragment.glyph_run()) , m_writing_mode(fragment.writing_mode()) { diff --git a/Tests/LibWeb/Layout/expected/acid1.txt b/Tests/LibWeb/Layout/expected/acid1.txt index 59fea336699..612518d3043 100644 --- a/Tests/LibWeb/Layout/expected/acid1.txt +++ b/Tests/LibWeb/Layout/expected/acid1.txt @@ -35,7 +35,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- TextNode <#text> (not painted) BlockContainer <(anonymous)> at [235,65] [0+0+0 139.96875 0+0+0] [0+0+0 19 0+0+0] children: not-inline continuation BlockContainer

at [235,65] [0+0+0 139.96875 0+0+0] [0+0+0 19 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 5, rect: [235,65 27.5x19] baseline: 12.5 + frag 0 from TextNode start: 33, length: 5, rect: [235,65 27.5x19] baseline: 12.5 "bang " frag 1 from RadioButton start: 0, length: 0, rect: [262.5,65 12x12] baseline: 12 TextNode <#text> (not painted) @@ -46,7 +46,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- TextNode <#text> (not painted) BlockContainer <(anonymous)> at [235,84] [0+0+0 139.96875 0+0+0] [0+0+0 19 0+0+0] children: not-inline continuation BlockContainer

at [235,84] [0+0+0 139.96875 0+0+0] [0+0+0 19 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 8, rect: [235,84 45.171875x19] baseline: 12.5 + frag 0 from TextNode start: 33, length: 8, rect: [235,84 45.171875x19] baseline: 12.5 "whimper " frag 1 from RadioButton start: 0, length: 0, rect: [280.171875,84 12x12] baseline: 12 TextNode <#text> (not painted) @@ -94,19 +94,27 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer <(anonymous)> at [20,30] [0+0+0 480 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer

at [20,335] [0+0+0 480 0+0+0] [0+0+0 65 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 90, rect: [20,335 473.6875x13] baseline: 9.5 - "This is a nonsensical document, but syntactically valid HTML 4.0. All 100%-conformant CSS1" - frag 1 from TextNode start: 92, length: 74, rect: [20,348 396.96875x13] baseline: 9.5 + frag 0 from TextNode start: 13, length: 86, rect: [20,335 448.296875x13] baseline: 9.5 + "This is a nonsensical document, but syntactically valid HTML 4.0. All 100%-conformant " + frag 1 from TextNode start: 111, length: 4, rect: [468.296875,335 25.390625x13] baseline: 9.5 + "CSS1" + frag 2 from TextNode start: 116, length: 74, rect: [20,348 396.96875x13] baseline: 9.5 "agents should be able to render the document elements above this paragraph" - frag 2 from TextNode start: 167, length: 43, rect: [20,361 207.9375x13] baseline: 9.5 + frag 3 from TextNode start: 203, length: 43, rect: [20,361 207.9375x13] baseline: 9.5 "indistinguishably (to the pixel) from this " - frag 3 from TextNode start: 0, length: 31, rect: [330.96875,361 159.671875x13] baseline: 9.5 - " (except font rasterization and" - frag 4 from TextNode start: 32, length: 89, rect: [20,374 465.09375x13] baseline: 9.5 - "form widgets). All discrepancies should be traceable to CSS1 implementation shortcomings." - frag 5 from TextNode start: 122, length: 67, rect: [20,387 345.59375x13] baseline: 9.5 - "Once you have finished evaluating this test, you can return to the " - frag 6 from TextNode start: 0, length: 1, rect: [425.5,387 2.71875x13] baseline: 9.5 + frag 4 from TextNode start: 0, length: 1, rect: [330.96875,361 5x13] baseline: 9.5 + " " + frag 5 from TextNode start: 13, length: 30, rect: [335.96875,361 154.671875x13] baseline: 9.5 + "(except font rasterization and" + frag 6 from TextNode start: 44, length: 56, rect: [20,374 286.6875x13] baseline: 9.5 + "form widgets). All discrepancies should be traceable to " + frag 7 from TextNode start: 112, length: 33, rect: [306.6875,374 178.40625x13] baseline: 9.5 + "CSS1 implementation shortcomings." + frag 8 from TextNode start: 146, length: 53, rect: [20,387 271.421875x13] baseline: 9.5 + "Once you have finished evaluating this test, you can " + frag 9 from TextNode start: 211, length: 14, rect: [291.421875,387 74.171875x13] baseline: 9.5 + "return to the " + frag 10 from TextNode start: 0, length: 1, rect: [425.5,387 2.71875x13] baseline: 9.5 "." TextNode <#text> (not painted) InlineNode at [227.9375,361] [0+0+0 103.03125 0+0+0] [0+0+0 13 0+0+0] diff --git a/Tests/LibWeb/Layout/expected/bfc-fit-content-width-with-margin.txt b/Tests/LibWeb/Layout/expected/bfc-fit-content-width-with-margin.txt index f15758e6654..be69ca523ac 100644 --- a/Tests/LibWeb/Layout/expected/bfc-fit-content-width-with-margin.txt +++ b/Tests/LibWeb/Layout/expected/bfc-fit-content-width-with-margin.txt @@ -2,23 +2,23 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [0,0] [0+0+0 800 0+0+0] [0+0+0 304 0+0+0] [BFC] children: not-inline BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 288 0+0+8] children: not-inline BlockContainer at [243.1875,8] [235.1875+0+0 548.8125 0+0+0] [0+0+0 162 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 62, rect: [243.1875,8 515.390625x18] baseline: 13.796875 + frag 0 from TextNode start: 2, length: 62, rect: [243.1875,8 515.390625x18] baseline: 13.796875 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce" - frag 1 from TextNode start: 64, length: 68, rect: [243.1875,26 543.484375x18] baseline: 13.796875 + frag 1 from TextNode start: 65, length: 68, rect: [243.1875,26 543.484375x18] baseline: 13.796875 "cursus est eget nisl porta, id vulputate velit imperdiet. Vestibulum" - frag 2 from TextNode start: 133, length: 69, rect: [243.1875,44 533.765625x18] baseline: 13.796875 + frag 2 from TextNode start: 134, length: 69, rect: [243.1875,44 533.765625x18] baseline: 13.796875 "mollis ligula sit amet ligula aliquam, vitae vulputate magna iaculis." - frag 3 from TextNode start: 203, length: 68, rect: [243.1875,62 533.015625x18] baseline: 13.796875 + frag 3 from TextNode start: 204, length: 68, rect: [243.1875,62 533.015625x18] baseline: 13.796875 "Nulla et augue fringilla, molestie nulla blandit, condimentum risus." - frag 4 from TextNode start: 272, length: 58, rect: [243.1875,80 488.140625x18] baseline: 13.796875 + frag 4 from TextNode start: 273, length: 58, rect: [243.1875,80 488.140625x18] baseline: 13.796875 "Suspendisse lectus augue, sodales vitae metus ac, interdum" - frag 5 from TextNode start: 331, length: 63, rect: [243.1875,98 526.546875x18] baseline: 13.796875 + frag 5 from TextNode start: 332, length: 63, rect: [243.1875,98 526.546875x18] baseline: 13.796875 "volutpat arcu. Aenean eu placerat risus, at dictum lectus. Nunc" - frag 6 from TextNode start: 395, length: 64, rect: [243.1875,116 524.5x18] baseline: 13.796875 + frag 6 from TextNode start: 396, length: 64, rect: [243.1875,116 524.5x18] baseline: 13.796875 "maximus est eu risus porta tincidunt. Cras nec felis tellus. Sed" - frag 7 from TextNode start: 460, length: 66, rect: [243.1875,134 523.078125x18] baseline: 13.796875 + frag 7 from TextNode start: 461, length: 66, rect: [243.1875,134 523.078125x18] baseline: 13.796875 "euismod ultricies ipsum, eget ultricies nisl dignissim nec. Mauris" - frag 8 from TextNode start: 527, length: 21, rect: [243.1875,152 178.53125x18] baseline: 13.796875 + frag 8 from TextNode start: 528, length: 21, rect: [243.1875,152 178.53125x18] baseline: 13.796875 "aliquet rhoncus urna." TextNode <#text> (not painted) BlockContainer <(anonymous)> at [8,170] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt b/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt index a8996bc1eeb..1252eac45b7 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/bfc-consider-all-currently-stacked-floats.txt @@ -4,7 +4,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- TextNode <#text> (not painted) BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 36 0+0+8] children: not-inline BlockContainer <(anonymous)> at [8,8] [0+0+0 784 0+0+0] [0+0+0 18 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [137.109375,8 27.640625x18] baseline: 13.796875 + frag 0 from TextNode start: 3, length: 3, rect: [137.109375,8 27.640625x18] baseline: 13.796875 "bar" BlockContainer at [8,8] floating [0+0+0 100 0+0+0] [0+0+0 100 0+0+0] [BFC] children: not-inline TextNode <#text> (not painted) @@ -14,7 +14,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- TextNode <#text> (not painted) TextNode <#text> (not painted) BlockContainer

at [8,26] [0+0+0 784 0+0+0] [0+0+0 18 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [129.515625,26 27.203125x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 3, rect: [129.515625,26 27.203125x18] baseline: 13.796875 "baz" TextNode <#text> (not painted) BlockContainer at [108,26] floating [0+0+0 21.515625 0+0+0] [0+0+0 18 0+0+0] [BFC] children: inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/button-should-have-vertically-aligned-content.txt b/Tests/LibWeb/Layout/expected/block-and-inline/button-should-have-vertically-aligned-content.txt index c9e5725e2a1..4046e168d34 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/button-should-have-vertically-aligned-content.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/button-should-have-vertically-aligned-content.txt @@ -9,13 +9,13 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer <(anonymous)> at [22,29] [0+0+0 48.6875 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer at [32,39] [0+10+0 28.6875 0+10+0] [0+10+0 18 0+10+0] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [32,39 28.6875x18] baseline: 13.796875 + frag 0 from TextNode start: 13, length: 3, rect: [32,39 28.6875x18] baseline: 13.796875 "one" TextNode <#text> (not painted) BlockContainer <(anonymous)> at [22,67] [0+0+0 48.6875 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer at [32,77] [0+10+0 28.6875 0+10+0] [0+10+0 100 0+10+0] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [32.125,77 28.4375x18] baseline: 13.796875 + frag 0 from TextNode start: 13, length: 3, rect: [32.125,77 28.4375x18] baseline: 13.796875 "two" TextNode <#text> (not painted) BlockContainer <(anonymous)> at [22,187] [0+0+0 48.6875 0+0+0] [0+0+0 0 0+0+0] children: inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-1.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-1.txt index 4798a4a3269..f1200fc3cd5 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-1.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-1.txt @@ -46,43 +46,51 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer <(anonymous)> at [8,8] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer
at [8,8] [0+0+0 784 0+0+0] [0+0+0 342 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 47, rect: [228,8 414.5625x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 47, rect: [228,8 414.5625x18] baseline: 13.796875 "lorem ipsum lorem ipsum lorem ipsum lorem ipsum" - frag 1 from TextNode start: 49, length: 47, rect: [228,26 414.5625x18] baseline: 13.796875 + frag 1 from TextNode start: 53, length: 47, rect: [228,26 414.5625x18] baseline: 13.796875 "lorem ipsum lorem ipsum lorem ipsum lorem ipsum" - frag 2 from TextNode start: 97, length: 53, rect: [228,44 466.90625x18] baseline: 13.796875 + frag 2 from TextNode start: 101, length: 53, rect: [228,44 466.90625x18] baseline: 13.796875 "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 3 from TextNode start: 151, length: 65, rect: [188,62 573.5x18] baseline: 13.796875 + frag 3 from TextNode start: 155, length: 65, rect: [188,62 573.5x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum" - frag 4 from TextNode start: 217, length: 65, rect: [188,80 572.546875x18] baseline: 13.796875 - "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 5 from TextNode start: 283, length: 77, rect: [108,98 679.140625x18] baseline: 13.796875 + frag 4 from TextNode start: 221, length: 60, rect: [188,80 528.203125x18] baseline: 13.796875 + "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum " + frag 5 from TextNode start: 285, length: 5, rect: [716.203125,80 44.34375x18] baseline: 13.796875 + "lorem" + frag 6 from TextNode start: 291, length: 77, rect: [108,98 679.140625x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum" - frag 6 from TextNode start: 361, length: 89, rect: [8,116 783.828125x18] baseline: 13.796875 + frag 7 from TextNode start: 369, length: 89, rect: [8,116 783.828125x18] baseline: 13.796875 "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 7 from TextNode start: 451, length: 83, rect: [8,134 731.484375x18] baseline: 13.796875 + frag 8 from TextNode start: 459, length: 83, rect: [8,134 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 8 from TextNode start: 535, length: 83, rect: [8,152 731.484375x18] baseline: 13.796875 + frag 9 from TextNode start: 543, length: 18, rect: [8,152 158.9375x18] baseline: 13.796875 + "ipsum lorem ipsum " + frag 10 from TextNode start: 565, length: 65, rect: [166.9375,152 572.546875x18] baseline: 13.796875 + "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" + frag 11 from TextNode start: 631, length: 83, rect: [8,170 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 9 from TextNode start: 619, length: 83, rect: [8,170 731.484375x18] baseline: 13.796875 + frag 12 from TextNode start: 715, length: 83, rect: [8,188 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 10 from TextNode start: 703, length: 83, rect: [8,188 731.484375x18] baseline: 13.796875 + frag 13 from TextNode start: 799, length: 42, rect: [8,206 370.21875x18] baseline: 13.796875 + "ipsum lorem ipsum lorem ipsum lorem ipsum " + frag 14 from TextNode start: 845, length: 41, rect: [378.21875,206 361.265625x18] baseline: 13.796875 + "lorem ipsum lorem ipsum lorem ipsum lorem" + frag 15 from TextNode start: 887, length: 83, rect: [8,224 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 11 from TextNode start: 787, length: 83, rect: [8,206 731.484375x18] baseline: 13.796875 + frag 16 from TextNode start: 971, length: 83, rect: [8,242 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 12 from TextNode start: 871, length: 83, rect: [8,224 731.484375x18] baseline: 13.796875 + frag 17 from TextNode start: 1055, length: 66, rect: [8,260 581.5x18] baseline: 13.796875 + "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum " + frag 18 from TextNode start: 1125, length: 17, rect: [589.5,260 149.984375x18] baseline: 13.796875 + "lorem ipsum lorem" + frag 19 from TextNode start: 1143, length: 83, rect: [8,278 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 13 from TextNode start: 955, length: 83, rect: [8,242 731.484375x18] baseline: 13.796875 + frag 20 from TextNode start: 1227, length: 83, rect: [8,296 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 14 from TextNode start: 1039, length: 83, rect: [8,260 731.484375x18] baseline: 13.796875 + frag 21 from TextNode start: 1311, length: 83, rect: [8,314 731.484375x18] baseline: 13.796875 "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 15 from TextNode start: 1123, length: 83, rect: [8,278 731.484375x18] baseline: 13.796875 - "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 16 from TextNode start: 1207, length: 83, rect: [8,296 731.484375x18] baseline: 13.796875 - "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 17 from TextNode start: 1291, length: 83, rect: [8,314 731.484375x18] baseline: 13.796875 - "ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem" - frag 18 from TextNode start: 1375, length: 5, rect: [8,332 45.296875x18] baseline: 13.796875 + frag 22 from TextNode start: 1395, length: 5, rect: [8,332 45.296875x18] baseline: 13.796875 "ipsum" TextNode <#text> (not painted) BlockContainer <(anonymous)> at [8,350] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt index e2f4ee2b8d2..1cb5e79931d 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-at-end-of-block.txt @@ -2,7 +2,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [0,0] [0+0+0 800 0+0+0] [0+0+0 416 0+0+0] [BFC] children: not-inline BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 400 0+0+8] children: not-inline BlockContainer at [8,8] [0+0+0 784 0+0+0] [0+0+0 200 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [8,8 27.15625x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 3, rect: [8,8 27.15625x18] baseline: 13.796875 "foo" TextNode <#text> (not painted) BlockContainer at [292,8] floating [0+0+0 500 0+0+0] [0+0+0 200 0+0+0] [BFC] children: not-inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-initial-available-space-vs-height.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-initial-available-space-vs-height.txt index ee5215380d6..edcab404dd0 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-initial-available-space-vs-height.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-initial-available-space-vs-height.txt @@ -2,7 +2,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [0,0] [0+0+0 800 0+0+0] [0+0+0 414 0+0+0] [BFC] children: not-inline BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 6 0+0+8] children: not-inline BlockContainer at [8,8] [0+0+0 100 0+0+684] [0+0+0 6 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 1, rect: [8,8 4.328125x6] baseline: 4.5 + frag 0 from TextNode start: 5, length: 1, rect: [8,8 4.328125x6] baseline: 4.5 "H" TextNode <#text> (not painted) BlockContainer at [8,14] floating [0+0+0 100 0+0+0] [0+0+0 100 0+0+0] [BFC] children: not-inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-1.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-1.txt index 358121a1a53..dfa33e70f82 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-1.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-1.txt @@ -4,40 +4,54 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer <(anonymous)> at [8,8] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer at [9,9] [0+1+0 300 0+1+482] [0+1+0 250 0+1+0] children: inline - frag 0 from TextNode start: 1, length: 24, rect: [61,9 212x16] baseline: 12.796875 + frag 0 from TextNode start: 9, length: 24, rect: [61,9 212x16] baseline: 12.796875 "foo bar baz foo bar baz " - frag 1 from TextNode start: 1, length: 3, rect: [273,9 27.15625x16] baseline: 12.796875 + frag 1 from TextNode start: 9, length: 3, rect: [273,9 27.15625x16] baseline: 12.796875 "foo" - frag 2 from TextNode start: 5, length: 3, rect: [263,25 27.640625x16] baseline: 12.796875 + frag 2 from TextNode start: 13, length: 3, rect: [263,25 27.640625x16] baseline: 12.796875 "bar" - frag 3 from TextNode start: 9, length: 3, rect: [263,41 27.203125x16] baseline: 12.796875 + frag 3 from TextNode start: 17, length: 3, rect: [263,41 27.203125x16] baseline: 12.796875 "baz" - frag 4 from TextNode start: 13, length: 3, rect: [263,57 27.15625x16] baseline: 12.796875 + frag 4 from TextNode start: 21, length: 3, rect: [263,57 27.15625x16] baseline: 12.796875 "foo" - frag 5 from TextNode start: 17, length: 11, rect: [9,77 98x16] baseline: 12.796875 + frag 5 from TextNode start: 25, length: 8, rect: [9,77 70.84375x16] baseline: 12.796875 + "bar baz " + frag 6 from TextNode start: 41, length: 3, rect: [79.84375,77 27.15625x16] baseline: 12.796875 + "foo" + frag 7 from TextNode start: 45, length: 11, rect: [9,93 98x16] baseline: 12.796875 "bar baz foo" - frag 6 from TextNode start: 29, length: 11, rect: [9,93 98x16] baseline: 12.796875 - "bar baz foo" - frag 7 from TextNode start: 41, length: 7, rect: [9,109 62.84375x16] baseline: 12.796875 + frag 8 from TextNode start: 57, length: 7, rect: [9,109 62.84375x16] baseline: 12.796875 "bar baz" - frag 8 from TextNode start: 1, length: 7, rect: [9,125 62.796875x16] baseline: 12.796875 + frag 9 from TextNode start: 9, length: 7, rect: [9,125 62.796875x16] baseline: 12.796875 "foo bar" - frag 9 from TextNode start: 9, length: 31, rect: [9,141 274.359375x16] baseline: 12.796875 - "baz foo bar baz foo bar baz foo" - frag 10 from TextNode start: 41, length: 31, rect: [9,157 274.84375x16] baseline: 12.796875 - "bar baz foo bar baz foo bar baz" - frag 11 from TextNode start: 1, length: 23, rect: [61,173 204x16] baseline: 12.796875 + frag 10 from TextNode start: 17, length: 16, rect: [9,141 141.203125x16] baseline: 12.796875 + "baz foo bar baz " + frag 11 from TextNode start: 41, length: 15, rect: [150.203125,141 133.15625x16] baseline: 12.796875 + "foo bar baz foo" + frag 12 from TextNode start: 57, length: 8, rect: [9,157 70.84375x16] baseline: 12.796875 + "bar baz " + frag 13 from TextNode start: 73, length: 23, rect: [79.84375,157 204x16] baseline: 12.796875 "foo bar baz foo bar baz" - frag 12 from TextNode start: 1, length: 23, rect: [61,189 204x16] baseline: 12.796875 + frag 14 from TextNode start: 9, length: 23, rect: [61,173 204x16] baseline: 12.796875 + "foo bar baz foo bar baz" + frag 15 from TextNode start: 9, length: 23, rect: [61,189 204x16] baseline: 12.796875 + "foo bar baz foo bar baz" + frag 16 from TextNode start: 41, length: 24, rect: [61,205 212x16] baseline: 12.796875 + "foo bar baz foo bar baz " + frag 17 from TextNode start: 73, length: 3, rect: [273,205 27.15625x16] baseline: 12.796875 + "foo" + frag 18 from TextNode start: 77, length: 20, rect: [61,221 176.84375x16] baseline: 12.796875 + "bar baz foo bar baz " + frag 19 from TextNode start: 105, length: 7, rect: [237.84375,221 62.796875x16] baseline: 12.796875 + "foo bar" + frag 20 from TextNode start: 113, length: 16, rect: [9,237 141.203125x16] baseline: 12.796875 + "baz foo bar baz " + frag 21 from TextNode start: 137, length: 15, rect: [150.203125,237 133.15625x16] baseline: 12.796875 + "foo bar baz foo" + frag 22 from TextNode start: 153, length: 8, rect: [9,253 70.84375x16] baseline: 12.796875 + "bar baz " + frag 23 from TextNode start: 169, length: 23, rect: [79.84375,253 204x16] baseline: 12.796875 "foo bar baz foo bar baz" - frag 13 from TextNode start: 25, length: 27, rect: [61,205 239.15625x16] baseline: 12.796875 - "foo bar baz foo bar baz foo" - frag 14 from TextNode start: 53, length: 27, rect: [61,221 239.640625x16] baseline: 12.796875 - "bar baz foo bar baz foo bar" - frag 15 from TextNode start: 81, length: 31, rect: [9,237 274.359375x16] baseline: 12.796875 - "baz foo bar baz foo bar baz foo" - frag 16 from TextNode start: 113, length: 31, rect: [9,253 274.84375x16] baseline: 12.796875 - "bar baz foo bar baz foo bar baz" TextNode <#text> (not painted) BlockContainer at [10,10] floating [0+1+0 50 0+1+0] [0+1+0 50 0+1+0] [BFC] children: not-inline TextNode <#text> (not painted) diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-3.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-3.txt index 641d8d68abf..5a91b1ab737 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-3.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-stress-3.txt @@ -4,7 +4,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer <(anonymous)> at [8,8] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer at [9,9] [0+1+0 300 0+1+482] [0+1+0 250 0+1+0] children: inline - frag 0 from TextNode start: 1, length: 23, rect: [61,9 204x16] baseline: 12.796875 + frag 0 from TextNode start: 9, length: 23, rect: [61,9 204x16] baseline: 12.796875 "foo bar baz foo bar baz" TextNode <#text> (not painted) BlockContainer at [10,10] floating [0+1+0 50 0+1+0] [0+1+0 50 0+1+0] [BFC] children: not-inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-under-if-would-fit.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-under-if-would-fit.txt index 6c5df6d30ab..ced0ebf9166 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-under-if-would-fit.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-under-if-would-fit.txt @@ -6,9 +6,9 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer <(anonymous)> at [8,8] [0+0+0 784 0+0+0] [0+0+0 0 0+0+0] children: inline TextNode <#text> (not painted) BlockContainer at [9,9] [0+1+0 100 0+1+682] [0+1+0 150 0+1+0] children: inline - frag 0 from TextNode start: 1, length: 11, rect: [9,9 99.109375x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 11, rect: [9,9 99.109375x18] baseline: 13.796875 "abc abc abc" - frag 1 from TextNode start: 13, length: 11, rect: [9,27 99.109375x18] baseline: 13.796875 + frag 1 from TextNode start: 21, length: 11, rect: [9,27 99.109375x18] baseline: 13.796875 "abc abc abc" TextNode <#text> (not painted) BlockContainer at [9,45] floating [0+0+0 80 0+0+0] [0+0+0 50 0+0+0] [BFC] children: not-inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-vertical-clearance-for-text-after-break.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-vertical-clearance-for-text-after-break.txt index cb5ef68b228..1511f165978 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/float-vertical-clearance-for-text-after-break.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-vertical-clearance-for-text-after-break.txt @@ -2,9 +2,9 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [0,0] [0+0+0 800 0+0+0] [0+0+0 102 0+0+0] [BFC] children: not-inline BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 86 0+0+8] children: not-inline BlockContainer at [8,8] [0+0+0 50 0+0+734] [0+0+0 86 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [8,58 27.15625x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 3, rect: [8,58 27.15625x18] baseline: 13.796875 "foo" - frag 1 from TextNode start: 1, length: 3, rect: [8,76 27.640625x18] baseline: 13.796875 + frag 1 from TextNode start: 5, length: 3, rect: [8,76 27.640625x18] baseline: 13.796875 "bar" TextNode <#text> (not painted) BlockContainer at [8,8] floating [0+0+0 50 0+0+0] [0+0+0 50 0+0+0] [BFC] children: not-inline diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/floats-and-negative-margins.txt b/Tests/LibWeb/Layout/expected/block-and-inline/floats-and-negative-margins.txt index 7d485345e49..7c5339fb1c2 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/floats-and-negative-margins.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/floats-and-negative-margins.txt @@ -3,12 +3,12 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [100,8] [100+0+0 200 0+0+500] [8+0+0 200 0+0+8] children: not-inline BlockContainer at [50,8] [-50+0+0 250 0+0+0] [0+0+0 200 0+0+0] children: inline BlockContainer at [50,8] floating [0+0+0 125 0+0+0] [0+0+0 18 0+0+0] [BFC] children: inline - frag 0 from TextNode start: 1, length: 1, rect: [50,8 9.34375x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 1, rect: [50,8 9.34375x18] baseline: 13.796875 "a" TextNode <#text> (not painted) TextNode <#text> (not painted) BlockContainer at [175,8] floating [0+0+0 125 0+0+0] [0+0+0 18 0+0+0] [BFC] children: inline - frag 0 from TextNode start: 1, length: 1, rect: [175,8 9.46875x18] baseline: 13.796875 + frag 0 from TextNode start: 5, length: 1, rect: [175,8 9.46875x18] baseline: 13.796875 "b" TextNode <#text> (not painted) TextNode <#text> (not painted) diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/narrow-bfc-width-to-avoid-overlap-with-floats.txt b/Tests/LibWeb/Layout/expected/block-and-inline/narrow-bfc-width-to-avoid-overlap-with-floats.txt index 0f673e6ea91..d638bfd0e79 100644 --- a/Tests/LibWeb/Layout/expected/block-and-inline/narrow-bfc-width-to-avoid-overlap-with-floats.txt +++ b/Tests/LibWeb/Layout/expected/block-and-inline/narrow-bfc-width-to-avoid-overlap-with-floats.txt @@ -6,14 +6,22 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [18,18] [0+10+0 564 0+10+0] [0+10+0 90 0+10+0] [BFC] children: inline frag 0 from TextNode start: 0, length: 56, rect: [18,18 458.125x18] baseline: 13.796875 "Lorem ipsum dolor sit amet, consectetur adipiscing elit." - frag 1 from TextNode start: 57, length: 60, rect: [18,36 511.796875x18] baseline: 13.796875 - "Pellentesque vitae neque nunc. Nam fermentum libero a lectus" - frag 2 from TextNode start: 118, length: 67, rect: [18,54 537.078125x18] baseline: 13.796875 - "vulputate eleifend. Nam sagittis tristique augue, id sodales mauris" - frag 3 from TextNode start: 186, length: 65, rect: [18,72 537.34375x18] baseline: 13.796875 - "suscipit at. Vivamus eget placerat ex. Suspendisse potenti. Morbi" - frag 4 from TextNode start: 252, length: 57, rect: [18,90 455.375x18] baseline: 13.796875 - "pulvinar ipsum eget nulla dapibus, ac varius mi eleifend." + frag 1 from TextNode start: 57, length: 19, rect: [18,36 155.203125x18] baseline: 13.796875 + "Pellentesque vitae " + frag 2 from TextNode start: 80, length: 41, rect: [173.203125,36 356.59375x18] baseline: 13.796875 + "neque nunc. Nam fermentum libero a lectus" + frag 3 from TextNode start: 122, length: 33, rect: [18,54 258.640625x18] baseline: 13.796875 + "vulputate eleifend. Nam sagittis " + frag 4 from TextNode start: 159, length: 34, rect: [276.640625,54 278.4375x18] baseline: 13.796875 + "tristique augue, id sodales mauris" + frag 5 from TextNode start: 194, length: 39, rect: [18,72 316.96875x18] baseline: 13.796875 + "suscipit at. Vivamus eget placerat ex. " + frag 6 from TextNode start: 237, length: 26, rect: [334.96875,72 220.375x18] baseline: 13.796875 + "Suspendisse potenti. Morbi" + frag 7 from TextNode start: 264, length: 48, rect: [18,90 392.171875x18] baseline: 13.796875 + "pulvinar ipsum eget nulla dapibus, ac varius mi " + frag 8 from TextNode start: 316, length: 9, rect: [410.171875,90 63.203125x18] baseline: 13.796875 + "eleifend." TextNode <#text> (not painted) ViewportPaintable (Viewport<#document>) [0,0 800x600] overflow: [0,0 800x1008] diff --git a/Tests/LibWeb/Layout/expected/display-contents-blockification-of-flex-items.txt b/Tests/LibWeb/Layout/expected/display-contents-blockification-of-flex-items.txt index b135ee13e87..be2d54e63e8 100644 --- a/Tests/LibWeb/Layout/expected/display-contents-blockification-of-flex-items.txt +++ b/Tests/LibWeb/Layout/expected/display-contents-blockification-of-flex-items.txt @@ -3,14 +3,14 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer at [8,8] [8+0+0 784 0+0+8] [8+0+0 28 0+0+8] children: not-inline Box at [8,8] flex-container(row) [0+0+0 784 0+0+0] [0+0+0 28 0+0+0] [FFC] children: not-inline BlockContainer <(anonymous)> at [8,8] flex-item [0+0+0 24.171875 0+0+0] [0+0+0 28 0+0+0] [BFC] children: inline - frag 0 from TextNode start: 1, length: 3, rect: [8,8 24.171875x18] baseline: 13.796875 + frag 0 from TextNode start: 3, length: 3, rect: [8,8 24.171875x18] baseline: 13.796875 "163" TextNode <#text> (not painted) TextNode <#text> (not painted) BlockContainer at [32.171875,8] flex-item [0+0+0 58.15625 0+0+0] [0+0+0 28 0+0+0] [BFC] children: not-inline Box at [37.171875,13] flex-container(row) [0+5+0 48.15625 0+5+0] [0+5+0 18 0+5+0] [FFC] children: not-inline BlockContainer <(anonymous)> at [37.171875,13] flex-item [0+0+0 48.15625 0+0+0] [0+0+0 18 0+0+0] [BFC] children: inline - frag 0 from TextNode start: 1, length: 5, rect: [37.171875,13 48.15625x18] baseline: 13.796875 + frag 0 from TextNode start: 9, length: 5, rect: [37.171875,13 48.15625x18] baseline: 13.796875 "Share" TextNode <#text> (not painted) TextNode <#text> (not painted) diff --git a/Tests/LibWeb/Layout/expected/div_align_nested.txt b/Tests/LibWeb/Layout/expected/div_align_nested.txt index 679ed108245..610eee995af 100644 --- a/Tests/LibWeb/Layout/expected/div_align_nested.txt +++ b/Tests/LibWeb/Layout/expected/div_align_nested.txt @@ -11,9 +11,9 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- TextNode <#text> (not painted) BlockContainer
at [8,126] [0+0+0 784 0+0+0] [0+0+0 136 0+0+0] children: not-inline BlockContainer <(anonymous)> at [8,126] [0+0+0 784 0+0+0] [0+0+0 36 0+0+0] children: inline - frag 0 from TextNode start: 1, length: 87, rect: [8,126 711.4375x18] baseline: 13.796875 + frag 0 from TextNode start: 9, length: 87, rect: [8,126 711.4375x18] baseline: 13.796875 "This text and the green square are both left aligned despite being nested in a div with" - frag 1 from TextNode start: 89, length: 14, rect: [8,144 94.296875x18] baseline: 13.796875 + frag 1 from TextNode start: 97, length: 14, rect: [8,144 94.296875x18] baseline: 13.796875 "align="right":" TextNode <#text> (not painted) BlockContainer at [8,162] [0+0+0 100 0+0+684] [0+0+0 100 0+0+0] children: inline diff --git a/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt b/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt index 6aa7d272bb1..ba0722ab66c 100644 --- a/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt +++ b/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt @@ -7,7 +7,7 @@ Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not- BlockContainer