From a1bc2a6223adc5d183f7be84a0ea79c8cbed8e78 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 22 Jun 2026 13:30:00 +0200 Subject: [PATCH] LibWeb: Use Utf16StringBuilder for UTF-16 text assembly Replace the remaining UTF-16-mode StringBuilder instances in LibWeb with Utf16StringBuilder when they assemble Utf16String values or UTF-16 text views. This keeps those paths in UTF-16 throughout and uses explicit ASCII append helpers for ASCII-only pieces. Keep StringBuilder in place for JSON, markup, CSS serialization, and other byte-oriented string construction paths. --- Libraries/LibWeb/DOM/CharacterData.cpp | 5 +++-- Libraries/LibWeb/DOM/Node.cpp | 17 +++++++++-------- Libraries/LibWeb/DOM/Range.cpp | 5 +++-- Libraries/LibWeb/DOM/Text.cpp | 5 +++-- .../LibWeb/Editing/Internal/Algorithms.cpp | 15 +++++++++------ Libraries/LibWeb/FileAPI/BlobURLStore.cpp | 14 +++++++------- Libraries/LibWeb/FileAPI/FileReader.cpp | 5 +++-- .../LibWeb/HTML/CanvasRenderingContext2D.cpp | 5 +++-- Libraries/LibWeb/HTML/FormAssociatedElement.cpp | 9 +++++---- Libraries/LibWeb/HTML/HTMLElement.cpp | 8 ++++---- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 4 ++-- Libraries/LibWeb/HTML/HTMLOptionElement.cpp | 8 ++++---- Libraries/LibWeb/Infra/Strings.cpp | 15 ++++++++------- .../LibWeb/Layout/SVGFormattingContext.cpp | 5 +++-- Libraries/LibWeb/Layout/TextNode.cpp | 10 +++++----- Libraries/LibWeb/Layout/Viewport.cpp | 5 +++-- Libraries/LibWeb/Painting/PaintableBox.cpp | 7 ++++--- Libraries/LibWeb/XML/XMLDocumentBuilder.cpp | 4 ++-- Libraries/LibWeb/XML/XMLDocumentBuilder.h | 3 ++- 19 files changed, 82 insertions(+), 67 deletions(-) diff --git a/Libraries/LibWeb/DOM/CharacterData.cpp b/Libraries/LibWeb/DOM/CharacterData.cpp index 9dd79bd0ce..1e43a29d73 100644 --- a/Libraries/LibWeb/DOM/CharacterData.cpp +++ b/Libraries/LibWeb/DOM/CharacterData.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -89,13 +90,13 @@ WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t coun auto before_data = m_data.substring_view(0, offset); auto after_data = m_data.substring_view(offset + count); - StringBuilder full_data(StringBuilder::Mode::UTF16, before_data.length_in_code_units() + data.length_in_code_units() + after_data.length_in_code_units()); + Utf16StringBuilder full_data(before_data.length_in_code_units() + data.length_in_code_units() + after_data.length_in_code_units()); full_data.append(before_data); full_data.append(data); full_data.append(after_data); auto old_data = m_data; - m_data = full_data.to_utf16_string(); + m_data = full_data.to_string(); // 4. Queue a mutation record of "characterData" for node with null, null, node’s data, « », « », null, and null. // NOTE: We do this later so that the mutation observer may notify UI clients of this node's new value. diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp index 3c6a322635..8c77265edb 100644 --- a/Libraries/LibWeb/DOM/Node.cpp +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -191,14 +192,14 @@ Optional Node::alternative_text() const // https://dom.spec.whatwg.org/#concept-descendant-text-content Utf16String Node::descendant_text_content() const { - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; for_each_in_subtree_of_type([&](auto& text_node) { builder.append(text_node.data()); return TraversalDecision::Continue; }); - return builder.to_utf16_string(); + return builder.to_string(); } // https://dom.spec.whatwg.org/#dom-node-textcontent @@ -310,12 +311,12 @@ WebIDL::ExceptionOr Node::normalize() } // 3. Let data be the concatenation of the data of node’s contiguous exclusive Text nodes (excluding itself), in tree order. - StringBuilder data(StringBuilder::Mode::UTF16); + Utf16StringBuilder data; for (auto const& text_node : contiguous_exclusive_text_nodes_excluding_self(node)) data.append(text_node->data()); // 4. Replace data with node node, offset length, count 0, and data data. - TRY(character_data.replace_data(length, 0, data.to_utf16_string())); + TRY(character_data.replace_data(length, 0, data.to_string())); // 5. Let currentNode be node’s next sibling. auto* current_node = node.next_sibling(); @@ -471,7 +472,7 @@ Utf16String Node::child_text_content() const if (!parent_node) return {}; - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; parent_node->for_each_child_of_type([&](auto const& child) { if (auto content = child.text_content(); content.has_value()) @@ -479,7 +480,7 @@ Utf16String Node::child_text_content() const return IterationDecision::Continue; }); - return builder.to_utf16_string(); + return builder.to_string(); } // https://dom.spec.whatwg.org/#concept-shadow-including-root @@ -3362,13 +3363,13 @@ ErrorOr Node::name_or_description(NameOrDescription target, Document con // aria-labelledby or aria-describedby and/or un-hidden. See the comment for substep A above. if (is_text() && (!parent_element() || (parent_element()->is_referenced() || !parent_element()->is_hidden() || !parent_element()->has_hidden_ancestor() || parent_element()->has_referenced_and_hidden_ancestor()))) { if (layout_node()) { - StringBuilder builder { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder builder; Layout::TextOffsetMapping mapping { static_cast(*this) }; mapping.for_each_fragment([&](Layout::TextNode const& slice) { builder.append(slice.text_for_rendering()); }); if (!builder.is_empty()) - return builder.to_utf16_string().to_utf8_but_should_be_ported_to_utf16(); + return builder.to_string().to_utf8_but_should_be_ported_to_utf16(); } return text_content()->to_utf8_but_should_be_ported_to_utf16(); } diff --git a/Libraries/LibWeb/DOM/Range.cpp b/Libraries/LibWeb/DOM/Range.cpp index 914ec81c41..aee98df391 100644 --- a/Libraries/LibWeb/DOM/Range.cpp +++ b/Libraries/LibWeb/DOM/Range.cpp @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -569,7 +570,7 @@ WebIDL::ExceptionOr Range::compare_point(GC::Ref node, WebI Utf16String Range::to_string() const { // 1. Let s be the empty string. - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; // 2. If this’s start node is this’s end node and it is a Text node, // then return the substring of that Text node’s data beginning at this’s start offset and ending at this’s end offset. @@ -593,7 +594,7 @@ Utf16String Range::to_string() const builder.append(MUST(end_text->substring_data(0, end_offset()))); // 6. Return s. - return builder.to_utf16_string(); + return builder.to_string(); } // https://dom.spec.whatwg.org/#dom-range-extractcontents diff --git a/Libraries/LibWeb/DOM/Text.cpp b/Libraries/LibWeb/DOM/Text.cpp index f7b735010b..83464aad7e 100644 --- a/Libraries/LibWeb/DOM/Text.cpp +++ b/Libraries/LibWeb/DOM/Text.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -141,11 +142,11 @@ Utf16String Text::whole_text() current_node = current_node->next_sibling(); } - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; for (auto const& text_node : nodes) builder.append(text_node->data()); - return builder.to_utf16_string(); + return builder.to_string(); } // https://html.spec.whatwg.org/multipage/dom.html#text-node-directionality diff --git a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp index 8a22ce452b..e7e0eb6a99 100644 --- a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -286,16 +287,18 @@ Utf16String canonical_space_sequence(size_t length, bool non_breaking_start, boo return "\u00A0"_utf16; // 4. Let buffer be the empty string. - StringBuilder buffer { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder buffer; // 5. If non-breaking start is true, let repeated pair be U+00A0 U+0020. Otherwise, let it be // U+0020 U+00A0. - auto repeated_pair = non_breaking_start ? "\u00A0 "sv : " \u00A0"sv; + auto first_repeated_code_unit = non_breaking_start ? u'\u00A0' : u' '; + auto second_repeated_code_unit = non_breaking_start ? u' ' : u'\u00A0'; // 6. While n is greater than three, append repeated pair to buffer and subtract two from n. // AD-HOC: Other browsers seem to fit in as many repeated pairs until the remaining length is <= 2. while (n > 2) { - buffer.append(repeated_pair); + buffer.append_code_unit(first_repeated_code_unit); + buffer.append_code_unit(second_repeated_code_unit); n -= 2; } @@ -330,16 +333,16 @@ Utf16String canonical_space_sequence(size_t length, bool non_breaking_start, boo // AD-HOC: Other browsers seem to ignore the above and deal differently with padding the remainder; the first // remaining position is filled with the first character from repeated pair. if (n > 0) { - buffer.append(repeated_pair.substring_view(0, 1) == " "sv ? " "sv : "\u00A0"sv); + buffer.append_code_unit(first_repeated_code_unit); --n; } // AD-HOC: Then, the final position is set depending on the value of non-breaking end. if (n > 0) - buffer.append(non_breaking_end ? "\u00A0"sv : " "sv); + buffer.append_code_unit(non_breaking_end ? u'\u00A0' : u' '); // 9. Return buffer. - return buffer.to_utf16_string(); + return buffer.to_string(); } // https://w3c.github.io/editing/docs/execCommand/#canonicalize-whitespace diff --git a/Libraries/LibWeb/FileAPI/BlobURLStore.cpp b/Libraries/LibWeb/FileAPI/BlobURLStore.cpp index b3c2f05a63..0bd89afe24 100644 --- a/Libraries/LibWeb/FileAPI/BlobURLStore.cpp +++ b/Libraries/LibWeb/FileAPI/BlobURLStore.cpp @@ -7,7 +7,7 @@ */ #include -#include +#include #include #include #include @@ -29,10 +29,10 @@ BlobURLStore& blob_url_store() ErrorOr generate_new_blob_url() { // 1. Let result be the empty string. - StringBuilder result { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder result; // 2. Append the string "blob:" to result. - TRY(result.try_append("blob:"sv)); + result.append_ascii("blob:"sv); // 3. Let settings be the current settings object auto& settings = HTML::current_settings_object(); @@ -48,17 +48,17 @@ ErrorOr generate_new_blob_url() serialized = "ladybird"_string; // 7. Append serialized to result. - TRY(result.try_append(serialized)); + result.append_ascii(serialized.bytes_as_string_view()); // 8. Append U+0024 SOLIDUS (/) to result. - TRY(result.try_append('/')); + result.append_ascii('/'); // 9. Generate a UUID [RFC4122] as a string and append it to result. auto uuid = Crypto::generate_random_uuid(); - TRY(result.try_append(uuid)); + result.append_ascii(uuid.bytes_as_string_view()); // 10. Return result. - return result.to_utf16_string(); + return result.to_string(); } // https://w3c.github.io/FileAPI/#add-an-entry diff --git a/Libraries/LibWeb/FileAPI/FileReader.cpp b/Libraries/LibWeb/FileAPI/FileReader.cpp index c3452f94df..8788518857 100644 --- a/Libraries/LibWeb/FileAPI/FileReader.cpp +++ b/Libraries/LibWeb/FileAPI/FileReader.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -139,10 +140,10 @@ WebIDL::ExceptionOr FileReader::blob_package_data(JS::Realm& return JS::ArrayBuffer::create(realm, move(bytes)); case Type::BinaryString: // Return bytes as a binary string, in which every byte is represented by a code unit of equal value [0..255]. - StringBuilder builder(StringBuilder::Mode::UTF16, bytes.size()); + Utf16StringBuilder builder(bytes.size()); for (auto byte : bytes.bytes()) builder.append_code_unit(byte); - return MUST(builder.utf16_string_view().to_utf8()); + return MUST(builder.view().to_utf8()); } VERIFY_NOT_REACHED(); } diff --git a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 7ae8e723fb..4dd1e86741 100644 --- a/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -981,11 +982,11 @@ CanvasRenderingContext2D::PreparedText CanvasRenderingContext2D::prepare_text(Ut } // 2. Replace all ASCII whitespace in text with U+0020 SPACE characters. - StringBuilder builder { StringBuilder::Mode::UTF16, text.length_in_code_units() }; + Utf16StringBuilder builder { text.length_in_code_units() }; for (auto c : text) { builder.append_code_point(Infra::is_ascii_whitespace(c) ? ' ' : c); } - auto replaced_text = builder.to_utf16_string(); + auto replaced_text = builder.to_string(); // 3. Let font be the current font of target, as given by that object's font attribute. auto glyph_runs = Gfx::shape_text({ 0, 0 }, replaced_text.utf16_view(), *font_cascade_list(), resolved_letter_spacing()); diff --git a/Libraries/LibWeb/HTML/FormAssociatedElement.cpp b/Libraries/LibWeb/HTML/FormAssociatedElement.cpp index fa543f7bc7..ea947202b6 100644 --- a/Libraries/LibWeb/HTML/FormAssociatedElement.cpp +++ b/Libraries/LibWeb/HTML/FormAssociatedElement.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -887,20 +888,20 @@ WebIDL::ExceptionOr FormAssociatedTextControlElement::set_range_text(Utf16 // 9. If start is less than end, delete the sequence of code units within the element's relevant value starting with // the code unit at the startth position and ending with the code unit at the (end-1)th position. if (start < end) { - StringBuilder builder(StringBuilder::Mode::UTF16, the_relevant_value.length_in_code_units() - (end - start)); + Utf16StringBuilder builder(the_relevant_value.length_in_code_units() - (end - start)); builder.append(the_relevant_value.substring_view(0, start)); builder.append(the_relevant_value.substring_view(end)); - the_relevant_value = builder.to_utf16_string(); + the_relevant_value = builder.to_string(); } // 10. Insert the value of the first argument into the text of the relevant value of the text control, immediately before the startth code unit. - StringBuilder builder(StringBuilder::Mode::UTF16, the_relevant_value.length_in_code_units() + replacement.length_in_code_units()); + Utf16StringBuilder builder(the_relevant_value.length_in_code_units() + replacement.length_in_code_units()); builder.append(the_relevant_value.substring_view(0, start)); builder.append(replacement); builder.append(the_relevant_value.substring_view(start)); - the_relevant_value = builder.to_utf16_string(); + the_relevant_value = builder.to_string(); TRY(set_relevant_value(the_relevant_value)); // 11. Let new length be the length of the value of the first argument. diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp index 03f6076020..e637d9be01 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -5,7 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include #include @@ -418,7 +418,7 @@ Utf16String HTMLElement::get_the_text_steps() // 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); + Utf16StringBuilder builder; for (size_t i = 0; i < results.size(); ++i) { results[i].visit( [&](Utf16String const& string) { @@ -435,12 +435,12 @@ Utf16String HTMLElement::get_the_text_steps() // Skip over the run of required line break counts. i = j - 1; - builder.append_repeated('\n', max_line_breaks); + builder.append_repeated_ascii('\n', max_line_breaks); }); } // 7. Return the concatenation of the string items in results. - return builder.to_utf16_string(); + return builder.to_string(); } // https://html.spec.whatwg.org/multipage/dom.html#dom-innertext diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index fb7c550613..4285bc0a62 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1843,7 +1843,7 @@ Utf16String HTMLInputElement::value_sanitization_algorithm(Utf16String const& va if (!value.contains('\r') && !value.contains('\n')) return value; - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; for (size_t i = 0; i < value.length_in_code_units(); ++i) { auto code_unit = value.code_unit_at(i); @@ -1851,7 +1851,7 @@ Utf16String HTMLInputElement::value_sanitization_algorithm(Utf16String const& va builder.append_code_unit(code_unit); } - return builder.to_utf16_string(); + return builder.to_string(); }; auto strip_newlines_and_trim = [&]() { diff --git a/Libraries/LibWeb/HTML/HTMLOptionElement.cpp b/Libraries/LibWeb/HTML/HTMLOptionElement.cpp index f05acc8e0b..3473a90354 100644 --- a/Libraries/LibWeb/HTML/HTMLOptionElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLOptionElement.cpp @@ -5,7 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include #include @@ -119,7 +119,7 @@ void HTMLOptionElement::set_value(Utf16String const& value) set_attribute_value(HTML::AttributeNames::value, value.to_utf8_but_should_be_ported_to_utf16()); } -static void concatenate_descendants_text_content(DOM::Node const* node, StringBuilder& builder) +static void concatenate_descendants_text_content(DOM::Node const* node, Utf16StringBuilder& builder) { if (is(node) || is(node)) return; @@ -151,7 +151,7 @@ void HTMLOptionElement::set_label(String const& label) // https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-text Utf16String HTMLOptionElement::text() const { - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; // Concatenation of data of all the Text node descendants of the option element, in tree order, // excluding any that are descendants of descendants of the option element that are themselves @@ -162,7 +162,7 @@ Utf16String HTMLOptionElement::text() const }); // Return the result of stripping and collapsing ASCII whitespace from the above concatenation. - return Infra::strip_and_collapse_whitespace(builder.to_utf16_string()); + return Infra::strip_and_collapse_whitespace(builder.to_string()); } // https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-text diff --git a/Libraries/LibWeb/Infra/Strings.cpp b/Libraries/LibWeb/Infra/Strings.cpp index 24609efd7f..0f5aa939a4 100644 --- a/Libraries/LibWeb/Infra/Strings.cpp +++ b/Libraries/LibWeb/Infra/Strings.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -52,19 +53,19 @@ Utf16String normalize_newlines(Utf16String const& string) return string; // FIXME: Implement a UTF-16 GenericLexer. - StringBuilder builder(StringBuilder::Mode::UTF16, string.length_in_code_units()); + Utf16StringBuilder builder(string.length_in_code_units()); for (size_t i = 0; i < string.length_in_code_units(); ++i) { if (auto code_unit = string.code_unit_at(i); code_unit == '\r') { if (i + 1 < string.length_in_code_units() && string.code_unit_at(i + 1) == '\n') ++i; - builder.append('\n'); + builder.append_ascii('\n'); } else { builder.append_code_unit(code_unit); } } - return builder.to_utf16_string(); + return builder.to_string(); } // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace @@ -92,12 +93,12 @@ Utf16String strip_and_collapse_whitespace(Utf16String const& string) if (!string.contains_any_of(Infra::ASCII_WHITESPACE_CODE_POINTS)) return string; - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; for (auto code_point : string) { if (Infra::is_ascii_whitespace(code_point)) { - if (!builder.utf16_string_view().ends_with(' ')) - builder.append(' '); + if (!builder.view().ends_with(' ')) + builder.append_ascii(' '); continue; } @@ -105,7 +106,7 @@ Utf16String strip_and_collapse_whitespace(Utf16String const& string) } // ...and then remove any leading and trailing ASCII whitespace from that string. - return builder.to_utf16_string().trim(Infra::ASCII_WHITESPACE); + return builder.to_string().trim(Infra::ASCII_WHITESPACE); } // https://infra.spec.whatwg.org/#code-unit-prefix diff --git a/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Libraries/LibWeb/Layout/SVGFormattingContext.cpp index 3b7c7f7faf..a93a8ba6f1 100644 --- a/Libraries/LibWeb/Layout/SVGFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/SVGFormattingContext.cpp @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -439,7 +440,7 @@ Gfx::Path SVGFormattingContext::compute_path_for_text(SVGTextBox const& text_box static Utf16String rendered_text_contents(SVG::SVGTextContentElement const& element) { - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; element.for_each_in_subtree_of_type([&](auto const& text_node) { if (text_node.parent() && text_node.parent()->unsafe_layout_node()) { if (auto content = text_node.text_content(); content.has_value()) @@ -447,7 +448,7 @@ static Utf16String rendered_text_contents(SVG::SVGTextContentElement const& elem } return TraversalDecision::Continue; }); - return builder.to_utf16_string().trim_ascii_whitespace(); + return builder.to_string().trim_ascii_whitespace(); } Gfx::Path SVGFormattingContext::compute_path_for_text_path(SVGTextPathBox const& text_path_box) const diff --git a/Libraries/LibWeb/Layout/TextNode.cpp b/Libraries/LibWeb/Layout/TextNode.cpp index 5959ab8baf..ffc48b2202 100644 --- a/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Libraries/LibWeb/Layout/TextNode.cpp @@ -8,8 +8,8 @@ */ #include -#include #include +#include #include #include #include @@ -307,12 +307,12 @@ static Utf16String apply_math_auto_text_transform(Utf16String const& string) } }; - StringBuilder builder { StringBuilder::Mode::UTF16, string.length_in_code_units() }; + Utf16StringBuilder builder { string.length_in_code_units() }; for (auto code_point : string) builder.append_code_point(map_code_point_to_italic(code_point)); - return builder.to_utf16_string(); + return builder.to_string(); } static Utf16String apply_text_transform(Utf16String const& string, CSS::TextTransform text_transform, Optional const& locale) @@ -457,13 +457,13 @@ Utf16String TextNode::compute_text_for_rendering(TextForRenderingCacheKey const& // 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() }; + Utf16StringBuilder text_builder { 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(); + text = text_builder.to_string(); } return text; diff --git a/Libraries/LibWeb/Layout/Viewport.cpp b/Libraries/LibWeb/Layout/Viewport.cpp index cbb6f4f0ea..bec9cb39ae 100644 --- a/Libraries/LibWeb/Layout/Viewport.cpp +++ b/Libraries/LibWeb/Layout/Viewport.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -43,7 +44,7 @@ Vector const& Viewport::text_blocks() void Viewport::update_text_blocks() { - StringBuilder builder(StringBuilder::Mode::UTF16); + Utf16StringBuilder builder; Vector text_positions; Vector text_blocks; @@ -55,7 +56,7 @@ void Viewport::update_text_blocks() auto flush_block = [&] { if (!builder.is_empty()) - text_blocks.append({ builder.to_utf16_string(), text_positions }); + text_blocks.append({ builder.to_string(), text_positions }); text_positions.clear_with_capacity(); builder.clear(); builder_length_in_code_units = 0; diff --git a/Libraries/LibWeb/Painting/PaintableBox.cpp b/Libraries/LibWeb/Painting/PaintableBox.cpp index 5e78cd1da5..37fdc4e9f3 100644 --- a/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1371,10 +1372,10 @@ void PaintableBox::paint_inspector_overlay_internal(DisplayListRecordingContext& auto font = Platform::FontPlugin::the().default_font(12); - StringBuilder builder(StringBuilder::Mode::UTF16); - builder.append(debug_description()); + Utf16StringBuilder builder; + builder.appendff("{}", debug_description()); builder.appendff(" {}x{} @ {},{}", border_rect.width(), border_rect.height(), border_rect.x(), border_rect.y()); - auto size_text = builder.to_utf16_string(); + auto size_text = builder.to_string(); auto size_text_rect = border_rect; size_text_rect.set_y(border_rect.y() + border_rect.height()); size_text_rect.set_top(size_text_rect.top()); diff --git a/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp b/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp index aea83f53ac..76a2cb15d4 100644 --- a/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp +++ b/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp @@ -254,8 +254,8 @@ void XMLDocumentBuilder::text(StringView data) if (auto* last = m_current_node->last_child(); last && last->is_text()) { auto& text_node = static_cast(*last); m_text_builder.append(text_node.data()); - m_text_builder.append(data); - text_node.set_data(m_text_builder.to_utf16_string()); + m_text_builder.append(Utf16String::from_utf8(data)); + text_node.set_data(m_text_builder.to_string()); m_text_builder.clear(); } else if (!data.is_empty()) { auto node = m_document->create_text_node(Utf16String::from_utf8(data)); diff --git a/Libraries/LibWeb/XML/XMLDocumentBuilder.h b/Libraries/LibWeb/XML/XMLDocumentBuilder.h index 3f4428b6b7..c13d4cbcf0 100644 --- a/Libraries/LibWeb/XML/XMLDocumentBuilder.h +++ b/Libraries/LibWeb/XML/XMLDocumentBuilder.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -51,7 +52,7 @@ private: GC::Ptr m_current_node; XMLScriptingSupport m_scripting_support { XMLScriptingSupport::Enabled }; bool m_has_error { false }; - StringBuilder m_text_builder { StringBuilder::Mode::UTF16 }; + Utf16StringBuilder m_text_builder; struct NamespaceStackEntry { Vector namespaces;