From b603e860af86147a3b4809b5d632892804ae188d Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Thu, 7 Sep 2023 21:36:05 +1200 Subject: [PATCH] LibWeb: Port CharacterData from DeprecatedString to String The existing implementation has some pre-existing issues where it is incorrectly assumes that byte offsets are given through the IDL instead of UTF-16 code units. While making these changes, leave some FIXMEs for that. --- .../Libraries/LibWeb/DOM/CharacterData.cpp | 34 +++++++++++-------- Userland/Libraries/LibWeb/DOM/CharacterData.h | 21 ++++++------ .../Libraries/LibWeb/DOM/CharacterData.idl | 2 +- Userland/Libraries/LibWeb/DOM/Comment.cpp | 2 +- Userland/Libraries/LibWeb/DOM/Node.cpp | 21 ++++++------ Userland/Libraries/LibWeb/DOM/Position.cpp | 2 +- .../LibWeb/DOM/ProcessingInstruction.cpp | 2 +- Userland/Libraries/LibWeb/DOM/Range.cpp | 18 +++++----- Userland/Libraries/LibWeb/DOM/Text.cpp | 8 ++--- .../LibWeb/DOMParsing/XMLSerializer.cpp | 8 ++--- .../Libraries/LibWeb/HTML/BrowsingContext.cpp | 6 ++-- .../LibWeb/HTML/HTMLInputElement.cpp | 10 +++--- .../LibWeb/HTML/Parser/HTMLParser.cpp | 2 +- .../LibWeb/Layout/FormattingContext.cpp | 2 +- Userland/Libraries/LibWeb/Layout/TextNode.cpp | 2 +- .../LibWeb/Page/EditEventHandler.cpp | 24 ++++++------- .../Libraries/LibWeb/Page/EventHandler.cpp | 2 +- .../LibWeb/XML/XMLDocumentBuilder.cpp | 2 +- 18 files changed, 87 insertions(+), 81 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/CharacterData.cpp b/Userland/Libraries/LibWeb/DOM/CharacterData.cpp index 7bc88441a0..c2eecce9e4 100644 --- a/Userland/Libraries/LibWeb/DOM/CharacterData.cpp +++ b/Userland/Libraries/LibWeb/DOM/CharacterData.cpp @@ -14,7 +14,7 @@ namespace Web::DOM { -CharacterData::CharacterData(Document& document, NodeType type, DeprecatedString const& data) +CharacterData::CharacterData(Document& document, NodeType type, String const& data) : Node(document, type) , m_data(data) { @@ -27,7 +27,7 @@ void CharacterData::initialize(JS::Realm& realm) } // https://dom.spec.whatwg.org/#dom-characterdata-data -void CharacterData::set_data(DeprecatedString data) +void CharacterData::set_data(String const& data) { // [The data] setter must replace data with node this, offset 0, count this’s length, and data new value. // NOTE: Since the offset is 0, it can never be above data's length, so this can never throw. @@ -37,7 +37,7 @@ void CharacterData::set_data(DeprecatedString data) } // https://dom.spec.whatwg.org/#concept-cd-substring -WebIDL::ExceptionOr CharacterData::substring_data(size_t offset, size_t count) const +WebIDL::ExceptionOr CharacterData::substring_data(size_t offset, size_t count) const { // 1. Let length be node’s length. auto length = this->length(); @@ -46,18 +46,22 @@ WebIDL::ExceptionOr CharacterData::substring_data(size_t offse if (offset > length) return WebIDL::IndexSizeError::create(realm(), "Substring offset out of range."_fly_string); + // FIXME: The offset and count we are given here is in UTF-16 code units, but we are incorrectly assuming it is a byte offset. + // 3. If offset plus count is greater than length, return a string whose value is the code units from the offsetth code unit // to the end of node’s data, and then return. if (offset + count > length) - return m_data.substring(offset); + return MUST(m_data.substring_from_byte_offset(offset)); // 4. Return a string whose value is the code units from the offsetth code unit to the offset+countth code unit in node’s data. - return m_data.substring(offset, count); + return MUST(m_data.substring_from_byte_offset(offset, count)); } // https://dom.spec.whatwg.org/#concept-cd-replace -WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t count, DeprecatedString const& data) +WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t count, String const& data) { + // FIXME: The offset and count we are given here is in UTF-16 code units, but we are incorrectly assuming it is a byte offset. + // 1. Let length be node’s length. auto length = this->length(); @@ -70,16 +74,16 @@ WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t coun count = length - offset; // 4. Queue a mutation record of "characterData" for node with null, null, node’s data, « », « », null, and null. - queue_mutation_record(MutationType::characterData, {}, {}, m_data, {}, {}, nullptr, nullptr); + queue_mutation_record(MutationType::characterData, {}, {}, m_data.to_deprecated_string(), {}, {}, nullptr, nullptr); // 5. Insert data into node’s data after offset code units. // 6. Let delete offset be offset + data’s length. // 7. Starting from delete offset code units, remove count code units from node’s data. StringBuilder builder; - builder.append(this->data().substring_view(0, offset)); + builder.append(this->data().bytes_as_string_view().substring_view(0, offset)); builder.append(data); - builder.append(this->data().substring_view(offset + count)); - m_data = builder.to_deprecated_string(); + builder.append(this->data().bytes_as_string_view().substring_view(offset + count)); + m_data = MUST(builder.to_string()); // 8. For each live range whose start node is node and start offset is greater than offset but less than or equal to offset plus count, set its start offset to offset. for (auto& range : Range::live_ranges()) { @@ -96,13 +100,13 @@ WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t coun // 10. For each live range whose start node is node and start offset is greater than offset plus count, increase its start offset by data’s length and decrease it by count. for (auto& range : Range::live_ranges()) { if (range->start_container() == this && range->start_offset() > (offset + count)) - TRY(range->set_start(*range->start_container(), range->start_offset() + data.length() - count)); + TRY(range->set_start(*range->start_container(), range->start_offset() + data.bytes().size() - count)); } // 11. For each live range whose end node is node and end offset is greater than offset plus count, increase its end offset by data’s length and decrease it by count. for (auto& range : Range::live_ranges()) { if (range->end_container() == this && range->end_offset() > (offset + count)) - TRY(range->set_end(*range->end_container(), range->end_offset() + data.length() - count)); + TRY(range->set_end(*range->end_container(), range->end_offset() + data.bytes().size() - count)); } // 12. If node’s parent is non-null, then run the children changed steps for node’s parent. @@ -121,14 +125,14 @@ WebIDL::ExceptionOr CharacterData::replace_data(size_t offset, size_t coun } // https://dom.spec.whatwg.org/#dom-characterdata-appenddata -WebIDL::ExceptionOr CharacterData::append_data(DeprecatedString const& data) +WebIDL::ExceptionOr CharacterData::append_data(String const& data) { // The appendData(data) method steps are to replace data with node this, offset this’s length, count 0, and data data. return replace_data(this->length(), 0, data); } // https://dom.spec.whatwg.org/#dom-characterdata-insertdata -WebIDL::ExceptionOr CharacterData::insert_data(size_t offset, DeprecatedString const& data) +WebIDL::ExceptionOr CharacterData::insert_data(size_t offset, String const& data) { // The insertData(offset, data) method steps are to replace data with node this, offset offset, count 0, and data data. return replace_data(offset, 0, data); @@ -138,7 +142,7 @@ WebIDL::ExceptionOr CharacterData::insert_data(size_t offset, DeprecatedSt WebIDL::ExceptionOr CharacterData::delete_data(size_t offset, size_t count) { // The deleteData(offset, count) method steps are to replace data with node this, offset offset, count count, and data the empty string. - return replace_data(offset, count, DeprecatedString::empty()); + return replace_data(offset, count, String {}); } } diff --git a/Userland/Libraries/LibWeb/DOM/CharacterData.h b/Userland/Libraries/LibWeb/DOM/CharacterData.h index 328a14a0db..491065e5d0 100644 --- a/Userland/Libraries/LibWeb/DOM/CharacterData.h +++ b/Userland/Libraries/LibWeb/DOM/CharacterData.h @@ -6,7 +6,7 @@ #pragma once -#include +#include #include #include #include @@ -22,24 +22,25 @@ class CharacterData public: virtual ~CharacterData() override = default; - DeprecatedString const& data() const { return m_data; } - void set_data(DeprecatedString); + String const& data() const { return m_data; } + void set_data(String const&); - unsigned length() const { return m_data.length(); } + // FIXME: This should be in UTF-16 code units, not byte size. + unsigned length() const { return m_data.bytes().size(); } - WebIDL::ExceptionOr substring_data(size_t offset, size_t count) const; - WebIDL::ExceptionOr append_data(DeprecatedString const&); - WebIDL::ExceptionOr insert_data(size_t offset, DeprecatedString const&); + WebIDL::ExceptionOr substring_data(size_t offset, size_t count) const; + WebIDL::ExceptionOr append_data(String const&); + WebIDL::ExceptionOr insert_data(size_t offset, String const&); WebIDL::ExceptionOr delete_data(size_t offset, size_t count); - WebIDL::ExceptionOr replace_data(size_t offset, size_t count, DeprecatedString const&); + WebIDL::ExceptionOr replace_data(size_t offset, size_t count, String const&); protected: - CharacterData(Document&, NodeType, DeprecatedString const&); + CharacterData(Document&, NodeType, String const&); virtual void initialize(JS::Realm&) override; private: - DeprecatedString m_data; + String m_data; }; } diff --git a/Userland/Libraries/LibWeb/DOM/CharacterData.idl b/Userland/Libraries/LibWeb/DOM/CharacterData.idl index 9af7903a4c..324a9c7bb0 100644 --- a/Userland/Libraries/LibWeb/DOM/CharacterData.idl +++ b/Userland/Libraries/LibWeb/DOM/CharacterData.idl @@ -3,7 +3,7 @@ #import // https://dom.spec.whatwg.org/#characterdata -[Exposed=Window, UseDeprecatedAKString] +[Exposed=Window] interface CharacterData : Node { [LegacyNullToEmptyString] attribute DOMString data; readonly attribute unsigned long length; diff --git a/Userland/Libraries/LibWeb/DOM/Comment.cpp b/Userland/Libraries/LibWeb/DOM/Comment.cpp index 1cbe7fefeb..a0f36e965b 100644 --- a/Userland/Libraries/LibWeb/DOM/Comment.cpp +++ b/Userland/Libraries/LibWeb/DOM/Comment.cpp @@ -12,7 +12,7 @@ namespace Web::DOM { Comment::Comment(Document& document, String const& data) - : CharacterData(document, NodeType::COMMENT_NODE, data.to_deprecated_string()) + : CharacterData(document, NodeType::COMMENT_NODE, data) { } diff --git a/Userland/Libraries/LibWeb/DOM/Node.cpp b/Userland/Libraries/LibWeb/DOM/Node.cpp index 28a91030de..107a09cffa 100644 --- a/Userland/Libraries/LibWeb/DOM/Node.cpp +++ b/Userland/Libraries/LibWeb/DOM/Node.cpp @@ -162,7 +162,7 @@ Optional Node::text_content() const // If CharacterData, return this’s data. if (is(this)) - return MUST(String::from_deprecated_string(static_cast(*this).data())); + return static_cast(*this).data(); // If Attr node, return this's value. if (is(*this)) @@ -188,7 +188,7 @@ void Node::set_text_content(Optional const& maybe_content) else if (is(this)) { auto* character_data_node = verify_cast(this); - character_data_node->set_data(content); + character_data_node->set_data(MUST(String::from_deprecated_string(content))); // FIXME: CharacterData::set_data is not spec compliant. Make this match the spec when set_data becomes spec compliant. // Do note that this will make this function able to throw an exception. @@ -217,7 +217,7 @@ Optional Node::node_value() const // If CharacterData, return this’s data. if (is(this)) { - return MUST(String::from_deprecated_string(verify_cast(this)->data())); + return verify_cast(this)->data(); } // Otherwise, return null. @@ -236,7 +236,7 @@ void Node::set_node_value(Optional const& maybe_value) verify_cast(this)->set_value(value.to_deprecated_string()); } else if (is(this)) { // If CharacterData, replace data with node this, offset 0, count this’s length, and data the given value. - verify_cast(this)->set_data(value.to_deprecated_string()); + verify_cast(this)->set_data(value); } // Otherwise, do nothing. @@ -854,21 +854,21 @@ JS::NonnullGCPtr Node::clone_node(Document* document, bool clone_children) auto text = verify_cast(this); // Set copy’s data to that of node. - auto text_copy = heap().allocate(realm(), *document, MUST(String::from_deprecated_string(text->data()))); + auto text_copy = heap().allocate(realm(), *document, text->data()); copy = move(text_copy); } else if (is(this)) { // Comment auto comment = verify_cast(this); // Set copy’s data to that of node. - auto comment_copy = heap().allocate(realm(), *document, MUST(String::from_deprecated_string(comment->data()))); + auto comment_copy = heap().allocate(realm(), *document, comment->data()); copy = move(comment_copy); } else if (is(this)) { // ProcessingInstruction auto processing_instruction = verify_cast(this); // Set copy’s target and data to those of node. - auto processing_instruction_copy = heap().allocate(realm(), *document, processing_instruction->data(), processing_instruction->target()); + auto processing_instruction_copy = heap().allocate(realm(), *document, processing_instruction->data().to_deprecated_string(), processing_instruction->target()); copy = processing_instruction_copy; } // Otherwise, Do nothing. @@ -1143,7 +1143,7 @@ bool Node::is_uninteresting_whitespace_node() const { if (!is(*this)) return false; - if (!static_cast(*this).data().is_whitespace()) + if (!static_cast(*this).data().bytes_as_string_view().is_whitespace()) return false; if (!layout_node()) return true; @@ -1491,7 +1491,8 @@ size_t Node::length() const // 2. If node is a CharacterData node, then return node’s data’s length. if (is_character_data()) { auto* character_data_node = verify_cast(this); - return character_data_node->data().length(); + // FIXME: This should be in UTF-16 code units, not byte size. + return character_data_node->data().bytes().size(); } // 3. Return the number of node’s children. @@ -1874,7 +1875,7 @@ ErrorOr Node::name_or_description(NameOrDescription target, Document con // G. Otherwise, if the current node is a Text node, return its textual contents. if (is_text()) { auto const* text_node = static_cast(this); - return String::from_deprecated_string(text_node->data()); + return text_node->data(); } // TODO: H. Otherwise, if the current node is a descendant of an element whose Accessible Name or Accessible Description is being computed, and contains descendants, proceed to 2F.i. diff --git a/Userland/Libraries/LibWeb/DOM/Position.cpp b/Userland/Libraries/LibWeb/DOM/Position.cpp index a82e4ba58c..1136f4ea3e 100644 --- a/Userland/Libraries/LibWeb/DOM/Position.cpp +++ b/Userland/Libraries/LibWeb/DOM/Position.cpp @@ -67,7 +67,7 @@ bool Position::offset_is_at_end_of_node() const auto& node = verify_cast(*m_node); auto text = node.data(); - return m_offset == text.length(); + return m_offset == text.bytes_as_string_view().length(); } } diff --git a/Userland/Libraries/LibWeb/DOM/ProcessingInstruction.cpp b/Userland/Libraries/LibWeb/DOM/ProcessingInstruction.cpp index 791d8eede7..3dd85d68de 100644 --- a/Userland/Libraries/LibWeb/DOM/ProcessingInstruction.cpp +++ b/Userland/Libraries/LibWeb/DOM/ProcessingInstruction.cpp @@ -12,7 +12,7 @@ namespace Web::DOM { ProcessingInstruction::ProcessingInstruction(Document& document, DeprecatedString const& data, DeprecatedString const& target) - : CharacterData(document, NodeType::PROCESSING_INSTRUCTION_NODE, data) + : CharacterData(document, NodeType::PROCESSING_INSTRUCTION_NODE, MUST(String::from_deprecated_string(data))) , m_target(target) { } diff --git a/Userland/Libraries/LibWeb/DOM/Range.cpp b/Userland/Libraries/LibWeb/DOM/Range.cpp index 9393fa7d9a..db771b8dda 100644 --- a/Userland/Libraries/LibWeb/DOM/Range.cpp +++ b/Userland/Libraries/LibWeb/DOM/Range.cpp @@ -559,11 +559,11 @@ String Range::to_string() const // 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. if (start_container() == end_container() && is(*start_container())) - return String::from_deprecated_string(static_cast(*start_container()).data().substring(start_offset(), end_offset() - start_offset())).release_value(); + return MUST(static_cast(*start_container()).data().substring_from_byte_offset(start_offset(), end_offset() - start_offset())); // 3. If this’s start node is a Text node, then append the substring of that node’s data from this’s start offset until the end to s. if (is(*start_container())) - builder.append(static_cast(*start_container()).data().substring_view(start_offset())); + builder.append(static_cast(*start_container()).data().bytes_as_string_view().substring_view(start_offset())); // 4. Append the concatenation of the data of all Text nodes that are contained in this, in tree order, to s. for (Node const* node = start_container(); node != end_container()->next_sibling(); node = node->next_in_pre_order()) { @@ -573,7 +573,7 @@ String Range::to_string() const // 5. If this’s end node is a Text node, then append the substring of that node’s data from its start until this’s end offset to s. if (is(*end_container())) - builder.append(static_cast(*end_container()).data().substring_view(0, end_offset())); + builder.append(static_cast(*end_container()).data().bytes_as_string_view().substring_view(0, end_offset())); // 6. Return s. return MUST(builder.to_string()); @@ -616,7 +616,7 @@ WebIDL::ExceptionOr> Range::extract() TRY(fragment->append_child(clone)); // 4. Replace data with node original start node, offset original start offset, count original end offset minus original start offset, and data the empty string. - TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, "")); + TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, String {})); // 5. Return fragment. return fragment; @@ -706,7 +706,7 @@ WebIDL::ExceptionOr> Range::extract() TRY(fragment->append_child(clone)); // 4. Replace data with node original start node, offset original start offset, count original start node’s length minus original start offset, and data the empty string. - TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, "")); + TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, String {})); } // 16. Otherwise, if first partially contained child is not null: else if (first_partially_contained_child) { @@ -744,7 +744,7 @@ WebIDL::ExceptionOr> Range::extract() TRY(fragment->append_child(clone)); // 4. Replace data with node original end node, offset 0, count original end offset, and data the empty string. - TRY(verify_cast(*original_end_node).replace_data(0, original_end_offset, "")); + TRY(verify_cast(*original_end_node).replace_data(0, original_end_offset, String {})); } // 19. Otherwise, if last partially contained child is not null: else if (last_partially_contained_child) { @@ -1086,7 +1086,7 @@ WebIDL::ExceptionOr Range::delete_contents() // 3. If original start node is original end node and it is a CharacterData node, then replace data with node original start node, offset original start offset, // count original end offset minus original start offset, and data the empty string, and then return. if (original_start_node.ptr() == original_end_node.ptr() && is(*original_start_node)) { - TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, "")); + TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, String {})); return {}; } @@ -1121,7 +1121,7 @@ WebIDL::ExceptionOr Range::delete_contents() // 7. If original start node is a CharacterData node, then replace data with node original start node, offset original start offset, count original start node’s length minus original start offset, data the empty string. if (is(*original_start_node)) - TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, "")); + TRY(static_cast(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, String {})); // 8. For each node in nodes to remove, in tree order, remove node. for (auto& node : nodes_to_remove) @@ -1129,7 +1129,7 @@ WebIDL::ExceptionOr Range::delete_contents() // 9. If original end node is a CharacterData node, then replace data with node original end node, offset 0, count original end offset and data the empty string. if (is(*original_end_node)) - TRY(static_cast(*original_end_node).replace_data(0, original_end_offset, "")); + TRY(static_cast(*original_end_node).replace_data(0, original_end_offset, String {})); // 10. Set start and end to (new node, new offset). TRY(set_start(*new_node, new_offset)); diff --git a/Userland/Libraries/LibWeb/DOM/Text.cpp b/Userland/Libraries/LibWeb/DOM/Text.cpp index 58440dee59..8d5279c8c9 100644 --- a/Userland/Libraries/LibWeb/DOM/Text.cpp +++ b/Userland/Libraries/LibWeb/DOM/Text.cpp @@ -14,12 +14,12 @@ namespace Web::DOM { Text::Text(Document& document, String const& data) - : CharacterData(document, NodeType::TEXT_NODE, data.to_deprecated_string()) + : CharacterData(document, NodeType::TEXT_NODE, data) { } Text::Text(Document& document, NodeType type, String const& data) - : CharacterData(document, type, data.to_deprecated_string()) + : CharacterData(document, type, data) { } @@ -63,7 +63,7 @@ WebIDL::ExceptionOr> Text::split_text(size_t offset) auto new_data = TRY(substring_data(offset, count)); // 5. Let new node be a new Text node, with the same node document as node. Set new node’s data to new data. - auto new_node = heap().allocate(realm(), document(), MUST(String::from_deprecated_string(new_data))); + auto new_node = heap().allocate(realm(), document(), new_data); // 6. Let parent be node’s parent. JS::GCPtr parent = this->parent(); @@ -100,7 +100,7 @@ WebIDL::ExceptionOr> Text::split_text(size_t offset) } // 8. Replace data with node node, offset offset, count count, and data the empty string. - TRY(replace_data(offset, count, "")); + TRY(replace_data(offset, count, String {})); // 9. Return new node. return new_node; diff --git a/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp b/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp index be941556f9..c7b3bd6dbc 100644 --- a/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp +++ b/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp @@ -755,16 +755,16 @@ static WebIDL::ExceptionOr serialize_text(DOM::Text const& tex // then throw an exception; the serialization of this node's data would not be well-formed. // 2. Let markup be the value of node's data. - DeprecatedString markup = text.data(); + auto markup = text.data(); // 3. Replace any occurrences of "&" in markup by "&". - markup = markup.replace("&"sv, "&"sv, ReplaceMode::All); + markup = MUST(markup.replace("&"sv, "&"sv, ReplaceMode::All)); // 4. Replace any occurrences of "<" in markup by "<". - markup = markup.replace("<"sv, "<"sv, ReplaceMode::All); + markup = MUST(markup.replace("<"sv, "<"sv, ReplaceMode::All)); // 5. Replace any occurrences of ">" in markup by ">". - markup = markup.replace(">"sv, ">"sv, ReplaceMode::All); + markup = MUST(markup.replace(">"sv, ">"sv, ReplaceMode::All)); // 6. Return the value of markup. return markup; diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 1dfa836833..3b1d4a5f3b 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -447,11 +447,11 @@ static DeprecatedString visible_text_in_range(DOM::Range const& range) if (range.start_container() == range.end_container() && is(*range.start_container())) { if (!range.start_container()->layout_node()) return ""sv; - return static_cast(*range.start_container()).data().substring(range.start_offset(), range.end_offset() - range.start_offset()); + return MUST(static_cast(*range.start_container()).data().substring_from_byte_offset(range.start_offset(), range.end_offset() - range.start_offset())).to_deprecated_string(); } if (is(*range.start_container()) && range.start_container()->layout_node()) - builder.append(static_cast(*range.start_container()).data().substring_view(range.start_offset())); + builder.append(static_cast(*range.start_container()).data().bytes_as_string_view().substring_view(range.start_offset())); for (DOM::Node const* node = range.start_container(); node != range.end_container()->next_sibling(); node = node->next_in_pre_order()) { if (is(*node) && range.contains_node(*node) && node->layout_node()) @@ -459,7 +459,7 @@ static DeprecatedString visible_text_in_range(DOM::Range const& range) } if (is(*range.end_container()) && range.end_container()->layout_node()) - builder.append(static_cast(*range.end_container()).data().substring_view(0, range.end_offset())); + builder.append(static_cast(*range.end_container()).data().bytes_as_string_view().substring_view(0, range.end_offset())); return builder.to_deprecated_string(); } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 46c2d9b611..b7768845a2 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -287,7 +287,7 @@ WebIDL::ExceptionOr HTMLInputElement::run_input_activation_behavior() void HTMLInputElement::did_edit_text_node(Badge) { // An input element's dirty value flag must be set to true whenever the user interacts with the control in a way that changes the value. - m_value = value_sanitization_algorithm(m_text_node->data()); + m_value = value_sanitization_algorithm(m_text_node->data().to_deprecated_string()); m_dirty_value = true; update_placeholder_visibility(); @@ -363,7 +363,7 @@ WebIDL::ExceptionOr HTMLInputElement::set_value(String const& value) // and the element has a text entry cursor position, move the text entry cursor position to the end of the // text control, unselecting any selected text and resetting the selection direction to "none". if (m_text_node && (m_value != old_value)) { - m_text_node->set_data(m_value); + m_text_node->set_data(MUST(String::from_deprecated_string(m_value))); update_placeholder_visibility(); } @@ -502,7 +502,7 @@ void HTMLInputElement::create_shadow_tree_if_needed() MUST(m_placeholder_element->style_for_bindings()->set_property(CSS::PropertyID::Height, "1lh"sv)); m_placeholder_text_node = heap().allocate(realm(), document(), MUST(String::from_deprecated_string(initial_value))); - m_placeholder_text_node->set_data(deprecated_attribute(HTML::AttributeNames::placeholder)); + m_placeholder_text_node->set_data(attribute(HTML::AttributeNames::placeholder).value_or(String {})); m_placeholder_text_node->set_editable_text_node_owner(Badge {}, *this); MUST(m_placeholder_element->append_child(*m_placeholder_text_node)); MUST(element->append_child(*m_placeholder_element)); @@ -581,7 +581,7 @@ void HTMLInputElement::attribute_changed(DeprecatedFlyString const& name, Deprec } } else if (name == HTML::AttributeNames::placeholder) { if (m_placeholder_text_node) - m_placeholder_text_node->set_data(value); + m_placeholder_text_node->set_data(MUST(String::from_deprecated_string(value))); } else if (name == HTML::AttributeNames::readonly) { handle_readonly_attribute(value); } @@ -909,7 +909,7 @@ void HTMLInputElement::reset_algorithm() // and then invoke the value sanitization algorithm, if the type attribute's current state defines one. m_value = value_sanitization_algorithm(m_value); if (m_text_node) { - m_text_node->set_data(m_value); + m_text_node->set_data(MUST(String::from_deprecated_string(m_value))); update_placeholder_visibility(); } } diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 45308401ba..21366058e1 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -1026,7 +1026,7 @@ void HTMLParser::flush_character_insertions() { if (m_character_insertion_builder.is_empty()) return; - m_character_insertion_node->set_data(m_character_insertion_builder.to_deprecated_string()); + m_character_insertion_node->set_data(MUST(m_character_insertion_builder.to_string())); m_character_insertion_builder.clear(); } diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index 50f38204c4..b287a1973c 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -1654,7 +1654,7 @@ bool FormattingContext::can_skip_is_anonymous_text_run(Box& box) if (box.is_anonymous() && !box.is_generated() && !box.first_child_of_type()) { bool contains_only_white_space = true; box.for_each_in_subtree([&](auto const& node) { - if (!is(node) || !static_cast(node).dom_node().data().is_whitespace()) { + if (!is(node) || !static_cast(node).dom_node().data().bytes_as_string_view().is_whitespace()) { contains_only_white_space = false; return IterationDecision::Break; } diff --git a/Userland/Libraries/LibWeb/Layout/TextNode.cpp b/Userland/Libraries/LibWeb/Layout/TextNode.cpp index 5cbd9ec3c6..dee468d5b3 100644 --- a/Userland/Libraries/LibWeb/Layout/TextNode.cpp +++ b/Userland/Libraries/LibWeb/Layout/TextNode.cpp @@ -328,7 +328,7 @@ void TextNode::compute_text_for_rendering() if (dom_node().is_editable() && !dom_node().is_uninteresting_whitespace_node()) collapse = false; - auto data = apply_text_transform(dom_node().data(), computed_values().text_transform()).release_value_but_fixme_should_propagate_errors(); + auto data = apply_text_transform(dom_node().data().to_deprecated_string(), computed_values().text_transform()).release_value_but_fixme_should_propagate_errors(); if (dom_node().is_password_input()) { m_text_for_rendering = DeprecatedString::repeated('*', data.length()); diff --git a/Userland/Libraries/LibWeb/Page/EditEventHandler.cpp b/Userland/Libraries/LibWeb/Page/EditEventHandler.cpp index e1b88085f3..9740bbec26 100644 --- a/Userland/Libraries/LibWeb/Page/EditEventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EditEventHandler.cpp @@ -29,9 +29,9 @@ void EditEventHandler::handle_delete_character_after(DOM::Position const& cursor } StringBuilder builder; - builder.append(text.substring_view(0, cursor_position.offset())); - builder.append(text.substring_view(*next_grapheme_offset)); - node.set_data(builder.to_deprecated_string()); + builder.append(text.bytes_as_string_view().substring_view(0, cursor_position.offset())); + builder.append(text.bytes_as_string_view().substring_view(*next_grapheme_offset)); + node.set_data(MUST(builder.to_string())); // FIXME: When nodes are removed from the DOM, the associated layout nodes become stale and still // remain in the layout tree. This has to be fixed, this just causes everything to be recomputed @@ -49,10 +49,10 @@ void EditEventHandler::handle_delete(DOM::Range& range) if (start == end) { StringBuilder builder; - builder.append(start->data().substring_view(0, range.start_offset())); - builder.append(end->data().substring_view(range.end_offset())); + builder.append(start->data().bytes_as_string_view().substring_view(0, range.start_offset())); + builder.append(end->data().bytes_as_string_view().substring_view(range.end_offset())); - start->set_data(builder.to_deprecated_string()); + start->set_data(MUST(builder.to_string())); } else { // Remove all the nodes that are fully enclosed in the range. HashTable queued_for_deletion; @@ -87,10 +87,10 @@ void EditEventHandler::handle_delete(DOM::Range& range) // Join the start and end nodes. StringBuilder builder; - builder.append(start->data().substring_view(0, range.start_offset())); - builder.append(end->data().substring_view(range.end_offset())); + builder.append(start->data().bytes_as_string_view().substring_view(0, range.start_offset())); + builder.append(end->data().bytes_as_string_view().substring_view(range.end_offset())); - start->set_data(builder.to_deprecated_string()); + start->set_data(MUST(builder.to_string())); end->remove(); } @@ -108,10 +108,10 @@ void EditEventHandler::handle_insert(DOM::Position position, u32 code_point) auto& node = verify_cast(*position.node()); StringBuilder builder; - builder.append(node.data().substring_view(0, position.offset())); + builder.append(node.data().bytes_as_string_view().substring_view(0, position.offset())); builder.append_code_point(code_point); - builder.append(node.data().substring_view(position.offset())); - node.set_data(builder.to_deprecated_string()); + builder.append(node.data().bytes_as_string_view().substring_view(position.offset())); + node.set_data(MUST(builder.to_string())); node.invalidate_style(); } diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index feb4a916b1..1c16f66aa8 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -772,7 +772,7 @@ bool EventHandler::handle_keydown(KeyCode key, unsigned modifiers, u32 code_poin } if (key == KeyCode::Key_End) { auto& node = *static_cast(const_cast(m_browsing_context->cursor_position().node())); - m_browsing_context->set_cursor_position(DOM::Position { node, (unsigned)node.data().length() }); + m_browsing_context->set_cursor_position(DOM::Position { node, (unsigned)node.data().bytes().size() }); return true; } if (!should_ignore_keydown_event(code_point)) { diff --git a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp index 4dff5726ab..de34dd5fe7 100644 --- a/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp +++ b/Userland/Libraries/LibWeb/XML/XMLDocumentBuilder.cpp @@ -140,7 +140,7 @@ void XMLDocumentBuilder::text(StringView data) auto& text_node = static_cast(*last); text_builder.append(text_node.data()); text_builder.append(data); - text_node.set_data(text_builder.to_deprecated_string()); + text_node.set_data(MUST(text_builder.to_string())); text_builder.clear(); } else { auto string = DeprecatedString::empty();