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.
This commit is contained in:
parent
950c460efd
commit
a1bc2a6223
19 changed files with 82 additions and 67 deletions
|
|
@ -5,6 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibJS/Runtime/ExternalMemory.h>
|
||||
#include <LibUnicode/Segmenter.h>
|
||||
#include <LibWeb/Bindings/CharacterData.h>
|
||||
|
|
@ -89,13 +90,13 @@ WebIDL::ExceptionOr<void> 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.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <AK/JsonObjectSerializer.h>
|
||||
#include <AK/NeverDestroyed.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibGC/DeferGC.h>
|
||||
#include <LibGC/WeakHashMap.h>
|
||||
#include <LibJS/Runtime/ExternalMemory.h>
|
||||
|
|
@ -191,14 +192,14 @@ Optional<String> 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<Text>([&](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<void> 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<Text>([&](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<String> 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<DOM::Text const&>(*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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/NeverDestroyed.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/Range.h>
|
||||
#include <LibWeb/DOM/Comment.h>
|
||||
|
|
@ -569,7 +570,7 @@ WebIDL::ExceptionOr<WebIDL::Short> Range::compare_point(GC::Ref<Node> 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
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibUnicode/CharacterTypes.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/Text.h>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibGfx/Color.h>
|
||||
#include <LibWeb/Bindings/Document.h>
|
||||
#include <LibWeb/CSS/CascadedProperties.h>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/NeverDestroyed.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibURL/Origin.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/Crypto/Crypto.h>
|
||||
|
|
@ -29,10 +29,10 @@ BlobURLStore& blob_url_store()
|
|||
ErrorOr<Utf16String> 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<Utf16String> 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
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <AK/Base64.h>
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibGC/Heap.h>
|
||||
#include <LibJS/Runtime/Promise.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
|
|
@ -139,10 +140,10 @@ WebIDL::ExceptionOr<FileReader::Result> 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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <AK/Checked.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/CanvasCommandList.h>
|
||||
#include <LibGfx/CompositingAndBlendingOperator.h>
|
||||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibUnicode/CharacterTypes.h>
|
||||
#include <LibUnicode/Segmenter.h>
|
||||
#include <LibWeb/CSS/Invalidation/FormControlInvalidator.h>
|
||||
|
|
@ -887,20 +888,20 @@ WebIDL::ExceptionOr<void> 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.
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibJS/Runtime/NativeFunction.h>
|
||||
#include <LibWeb/ARIA/Roles.h>
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = [&]() {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibWeb/ARIA/Roles.h>
|
||||
#include <LibWeb/Bindings/HTMLOptionElement.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
|
|
@ -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<HTMLScriptElement>(node) || is<SVG::SVGScriptElement>(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
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <AK/GenericLexer.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <AK/Utf16View.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibWeb/Infra/CharacterTypes.h>
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibGfx/BoundingBox.h>
|
||||
#include <LibGfx/Font/Font.h>
|
||||
#include <LibGfx/Path.h>
|
||||
|
|
@ -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<DOM::Text>([&](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
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
*/
|
||||
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/UnicodeUtils.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibUnicode/CharacterTypes.h>
|
||||
#include <LibUnicode/Locale.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
|
|
@ -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<StringView> 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;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/CharacterTypes.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Range.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
|
|
@ -43,7 +44,7 @@ Vector<Viewport::TextBlock> const& Viewport::text_blocks()
|
|||
|
||||
void Viewport::update_text_blocks()
|
||||
{
|
||||
StringBuilder builder(StringBuilder::Mode::UTF16);
|
||||
Utf16StringBuilder builder;
|
||||
Vector<TextPosition> text_positions;
|
||||
Vector<TextBlock> 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;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <AK/Array.h>
|
||||
#include <AK/GenericShorthands.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibGfx/Font/Font.h>
|
||||
#include <LibWeb/CSS/ComputedProperties.h>
|
||||
#include <LibWeb/CSS/ComputedValues.h>
|
||||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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<DOM::Text&>(*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));
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Utf16StringBuilder.h>
|
||||
#include <LibWeb/DOM/Comment.h>
|
||||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
|
|
@ -51,7 +52,7 @@ private:
|
|||
GC::Ptr<DOM::Node> 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<NamespaceAndPrefix, 2> namespaces;
|
||||
|
|
|
|||
Loading…
Reference in a new issue