mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-19 15:58:56 +00:00
LibWeb+LibUnicode+WebContent: Port DOM:CharacterData to UTF-16
This replaces the underlying storage of CharacterData with Utf16String and deals with the fallout.
This commit is contained in:
parent
cb85eac3d8
commit
8b6e3cb735
Notes:
github-actions[bot]
2025-07-24 17:01:33 +00:00
Author: https://github.com/trflynn89
Commit: 8b6e3cb735
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5592
Reviewed-by: https://github.com/gmta ✅
56 changed files with 233 additions and 245 deletions
|
@ -247,7 +247,7 @@ NonnullOwnPtr<Segmenter> Segmenter::create(StringView locale, SegmenterGranulari
|
|||
return make<SegmenterImpl>(segmenter.release_nonnull(), segmenter_granularity);
|
||||
}
|
||||
|
||||
bool Segmenter::should_continue_beyond_word(Utf8View const& word)
|
||||
bool Segmenter::should_continue_beyond_word(Utf16View const& word)
|
||||
{
|
||||
for (auto code_point : word) {
|
||||
if (!code_point_has_punctuation_general_category(code_point) && !code_point_has_separator_general_category(code_point))
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
static NonnullOwnPtr<Segmenter> create(StringView locale, SegmenterGranularity segmenter_granularity);
|
||||
virtual ~Segmenter() = default;
|
||||
|
||||
static bool should_continue_beyond_word(Utf8View const&);
|
||||
static bool should_continue_beyond_word(Utf16View const&);
|
||||
|
||||
SegmenterGranularity segmenter_granularity() const { return m_segmenter_granularity; }
|
||||
|
||||
|
|
|
@ -60,9 +60,9 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> OptionConstructor::construct(Function
|
|||
GC::Ref<HTML::HTMLOptionElement> option_element = as<HTML::HTMLOptionElement>(*element);
|
||||
|
||||
// 3. If text is not the empty string, then append to option a new Text node whose data is text.
|
||||
auto text = TRY(text_value.to_string(vm));
|
||||
auto text = TRY(text_value.to_utf16_string(vm));
|
||||
if (!text.is_empty()) {
|
||||
auto new_text_node = realm.create<DOM::Text>(document, text);
|
||||
auto new_text_node = realm.create<DOM::Text>(document, move(text));
|
||||
MUST(option_element->append_child(*new_text_node));
|
||||
}
|
||||
|
||||
|
|
|
@ -51,12 +51,11 @@ void AccessibilityTreeNode::serialize_tree_as_json(JsonObjectSerializer<StringBu
|
|||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
} else if (value()->is_text()) {
|
||||
MUST(object.add("type"sv, "text"sv));
|
||||
|
||||
auto const* text_node = static_cast<DOM::Text const*>(value().ptr());
|
||||
MUST(object.add("text"sv, text_node->data()));
|
||||
MUST(object.add("text"sv, text_node->data().to_utf8()));
|
||||
}
|
||||
|
||||
if (value()->has_child_nodes()) {
|
||||
|
|
|
@ -12,8 +12,8 @@ namespace Web::DOM {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(CDATASection);
|
||||
|
||||
CDATASection::CDATASection(Document& document, String const& data)
|
||||
: Text(document, NodeType::CDATA_SECTION_NODE, data)
|
||||
CDATASection::CDATASection(Document& document, Utf16String data)
|
||||
: Text(document, NodeType::CDATA_SECTION_NODE, move(data))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
virtual FlyString node_name() const override { return "#cdata-section"_fly_string; }
|
||||
|
||||
private:
|
||||
CDATASection(Document&, String const&);
|
||||
CDATASection(Document&, Utf16String);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
};
|
||||
|
|
|
@ -17,9 +17,9 @@ namespace Web::DOM {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(CharacterData);
|
||||
|
||||
CharacterData::CharacterData(Document& document, NodeType type, String const& data)
|
||||
CharacterData::CharacterData(Document& document, NodeType type, Utf16String data)
|
||||
: Node(document, type)
|
||||
, m_data(data)
|
||||
, m_data(move(data))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ void CharacterData::initialize(JS::Realm& realm)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-data
|
||||
void CharacterData::set_data(String const& data)
|
||||
void CharacterData::set_data(Utf16String 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.
|
||||
|
@ -42,12 +42,10 @@ void CharacterData::set_data(String const& data)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-cd-substring
|
||||
WebIDL::ExceptionOr<String> CharacterData::substring_data(size_t offset, size_t count) const
|
||||
WebIDL::ExceptionOr<Utf16String> CharacterData::substring_data(size_t offset, size_t count) const
|
||||
{
|
||||
// 1. Let length be node’s length.
|
||||
// FIXME: This is very inefficient!
|
||||
auto utf16_string = Utf16String::from_utf8(m_data);
|
||||
auto length = utf16_string.length_in_code_units();
|
||||
auto length = m_data.length_in_code_units();
|
||||
|
||||
// 2. If offset is greater than length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > length)
|
||||
|
@ -56,19 +54,17 @@ WebIDL::ExceptionOr<String> CharacterData::substring_data(size_t offset, size_t
|
|||
// 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 MUST(utf16_string.substring_view(offset).to_utf8());
|
||||
return Utf16String::from_utf16_without_validation(m_data.substring_view(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 MUST(utf16_string.substring_view(offset, count).to_utf8());
|
||||
return Utf16String::from_utf16_without_validation(m_data.substring_view(offset, count));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-cd-replace
|
||||
WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t count, String const& data)
|
||||
WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t count, Utf16View const& data)
|
||||
{
|
||||
// 1. Let length be node’s length.
|
||||
// FIXME: This is very inefficient!
|
||||
auto utf16_string = Utf16String::from_utf8(m_data);
|
||||
auto length = utf16_string.length_in_code_units();
|
||||
auto length = m_data.length_in_code_units();
|
||||
|
||||
// 2. If offset is greater than length, then throw an "IndexSizeError" DOMException.
|
||||
if (offset > length)
|
||||
|
@ -81,27 +77,20 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
|
|||
// 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.
|
||||
auto before_data = utf16_string.substring_view(0, offset);
|
||||
auto inserted_data = Utf16String::from_utf8(data);
|
||||
auto after_data = utf16_string.substring_view(offset + count);
|
||||
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() + inserted_data.length_in_code_units() + after_data.length_in_code_units());
|
||||
StringBuilder full_data(StringBuilder::Mode::UTF16, 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(inserted_data);
|
||||
full_data.append(data);
|
||||
full_data.append(after_data);
|
||||
|
||||
auto full_view = full_data.utf16_string_view();
|
||||
bool characters_are_the_same = utf16_string == full_view;
|
||||
auto old_data = m_data;
|
||||
|
||||
// OPTIMIZATION: Skip UTF-8 encoding if the characters are the same.
|
||||
if (!characters_are_the_same) {
|
||||
m_data = MUST(full_view.to_utf8());
|
||||
}
|
||||
m_data = full_data.to_utf16_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.
|
||||
queue_mutation_record(MutationType::characterData, {}, {}, old_data, {}, {}, nullptr, nullptr);
|
||||
queue_mutation_record(MutationType::characterData, {}, {}, old_data.to_utf8_but_should_be_ported_to_utf16(), {}, {}, nullptr, nullptr);
|
||||
|
||||
// 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.
|
||||
|
@ -121,14 +110,14 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
|
|||
// 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))
|
||||
range->set_start_offset(range->start_offset() + inserted_data.length_in_code_units() - count);
|
||||
range->set_start_offset(range->start_offset() + data.length_in_code_units() - 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))
|
||||
range->set_end_offset(range->end_offset() + inserted_data.length_in_code_units() - count);
|
||||
range->set_end_offset(range->end_offset() + data.length_in_code_units() - count);
|
||||
}
|
||||
|
||||
// 12. If node’s parent is non-null, then run the children changed steps for node’s parent.
|
||||
|
@ -136,7 +125,7 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
|
|||
parent()->children_changed(nullptr);
|
||||
|
||||
// OPTIMIZATION: If the characters are the same, we can skip the remainder of this function.
|
||||
if (characters_are_the_same)
|
||||
if (m_data == old_data)
|
||||
return {};
|
||||
|
||||
if (auto* layout_node = this->layout_node(); layout_node && layout_node->is_text_node()) {
|
||||
|
@ -160,14 +149,14 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-appenddata
|
||||
WebIDL::ExceptionOr<void> CharacterData::append_data(String const& data)
|
||||
WebIDL::ExceptionOr<void> CharacterData::append_data(Utf16View 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_in_utf16_code_units(), 0, data);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-characterdata-insertdata
|
||||
WebIDL::ExceptionOr<void> CharacterData::insert_data(size_t offset, String const& data)
|
||||
WebIDL::ExceptionOr<void> CharacterData::insert_data(size_t offset, Utf16View 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);
|
||||
|
@ -177,7 +166,7 @@ WebIDL::ExceptionOr<void> CharacterData::insert_data(size_t offset, String const
|
|||
WebIDL::ExceptionOr<void> 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, String {});
|
||||
return replace_data(offset, count, {});
|
||||
}
|
||||
|
||||
Unicode::Segmenter& CharacterData::grapheme_segmenter() const
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <AK/Utf16View.h>
|
||||
#include <LibUnicode/Forward.h>
|
||||
#include <LibWeb/DOM/ChildNode.h>
|
||||
|
@ -26,30 +26,27 @@ class CharacterData
|
|||
public:
|
||||
virtual ~CharacterData() override;
|
||||
|
||||
String const& data() const { return m_data; }
|
||||
void set_data(String const&);
|
||||
Utf16String const& data() const { return m_data; }
|
||||
void set_data(Utf16String const&);
|
||||
|
||||
unsigned length_in_utf16_code_units() const
|
||||
{
|
||||
return AK::utf16_code_unit_length_from_utf8(m_data);
|
||||
}
|
||||
unsigned length_in_utf16_code_units() const { return m_data.length_in_code_units(); }
|
||||
|
||||
WebIDL::ExceptionOr<String> substring_data(size_t offset_in_utf16_code_units, size_t count_in_utf16_code_units) const;
|
||||
WebIDL::ExceptionOr<void> append_data(String const&);
|
||||
WebIDL::ExceptionOr<void> insert_data(size_t offset_in_utf16_code_units, String const&);
|
||||
WebIDL::ExceptionOr<Utf16String> substring_data(size_t offset_in_utf16_code_units, size_t count_in_utf16_code_units) const;
|
||||
WebIDL::ExceptionOr<void> append_data(Utf16View const&);
|
||||
WebIDL::ExceptionOr<void> insert_data(size_t offset_in_utf16_code_units, Utf16View const&);
|
||||
WebIDL::ExceptionOr<void> delete_data(size_t offset_in_utf16_code_units, size_t count_in_utf16_code_units);
|
||||
WebIDL::ExceptionOr<void> replace_data(size_t offset_in_utf16_code_units, size_t count_in_utf16_code_units, String const&);
|
||||
WebIDL::ExceptionOr<void> replace_data(size_t offset_in_utf16_code_units, size_t count_in_utf16_code_units, Utf16View const&);
|
||||
|
||||
Unicode::Segmenter& grapheme_segmenter() const;
|
||||
Unicode::Segmenter& word_segmenter() const;
|
||||
|
||||
protected:
|
||||
CharacterData(Document&, NodeType, String const&);
|
||||
CharacterData(Document&, NodeType, Utf16String);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
private:
|
||||
String m_data;
|
||||
Utf16String m_data;
|
||||
|
||||
mutable OwnPtr<Unicode::Segmenter> m_grapheme_segmenter;
|
||||
mutable OwnPtr<Unicode::Segmenter> m_word_segmenter;
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
// https://dom.spec.whatwg.org/#characterdata
|
||||
[Exposed=Window]
|
||||
interface CharacterData : Node {
|
||||
[LegacyNullToEmptyString] attribute DOMString data;
|
||||
[LegacyNullToEmptyString] attribute Utf16DOMString data;
|
||||
[ImplementedAs=length_in_utf16_code_units] readonly attribute unsigned long length;
|
||||
|
||||
DOMString substringData(unsigned long offset, unsigned long count);
|
||||
undefined appendData(DOMString data);
|
||||
undefined insertData(unsigned long offset, DOMString data);
|
||||
Utf16DOMString substringData(unsigned long offset, unsigned long count);
|
||||
undefined appendData(Utf16DOMString data);
|
||||
undefined insertData(unsigned long offset, Utf16DOMString data);
|
||||
undefined deleteData(unsigned long offset, unsigned long count);
|
||||
undefined replaceData(unsigned long offset, unsigned long count, DOMString data);
|
||||
undefined replaceData(unsigned long offset, unsigned long count, Utf16DOMString data);
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-nondocumenttypechildnode
|
||||
readonly attribute Element? previousElementSibling;
|
||||
|
|
|
@ -16,7 +16,7 @@ template<typename NodeType>
|
|||
class ChildNode {
|
||||
public:
|
||||
// https://dom.spec.whatwg.org/#dom-childnode-before
|
||||
WebIDL::ExceptionOr<void> before(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
WebIDL::ExceptionOr<void> before(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
auto* node = static_cast<NodeType*>(this);
|
||||
|
||||
|
@ -46,7 +46,7 @@ public:
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-childnode-after
|
||||
WebIDL::ExceptionOr<void> after(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
WebIDL::ExceptionOr<void> after(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
auto* node = static_cast<NodeType*>(this);
|
||||
|
||||
|
@ -70,7 +70,7 @@ public:
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-childnode-replacewith
|
||||
WebIDL::ExceptionOr<void> replace_with(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
WebIDL::ExceptionOr<void> replace_with(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
auto* node = static_cast<NodeType*>(this);
|
||||
|
||||
|
@ -117,7 +117,7 @@ protected:
|
|||
ChildNode() = default;
|
||||
|
||||
private:
|
||||
GC::Ptr<Node> viable_previous_sibling_for_insertion(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
GC::Ptr<Node> viable_previous_sibling_for_insertion(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
auto* node = static_cast<NodeType*>(this);
|
||||
|
||||
|
@ -142,7 +142,7 @@ private:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
GC::Ptr<Node> viable_next_sibling_for_insertion(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
GC::Ptr<Node> viable_next_sibling_for_insertion(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
auto* node = static_cast<NodeType*>(this);
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
// https://dom.spec.whatwg.org/#childnode
|
||||
interface mixin ChildNode {
|
||||
[CEReactions, Unscopable] undefined before((Node or DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined after((Node or DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined replaceWith((Node or DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined before((Node or Utf16DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined after((Node or Utf16DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined replaceWith((Node or Utf16DOMString)... nodes);
|
||||
[CEReactions, Unscopable, ImplementedAs=remove_binding] undefined remove();
|
||||
};
|
||||
|
|
|
@ -13,16 +13,16 @@ namespace Web::DOM {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(Comment);
|
||||
|
||||
Comment::Comment(Document& document, String const& data)
|
||||
: CharacterData(document, NodeType::COMMENT_NODE, data)
|
||||
Comment::Comment(Document& document, Utf16String data)
|
||||
: CharacterData(document, NodeType::COMMENT_NODE, move(data))
|
||||
{
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-comment-comment
|
||||
WebIDL::ExceptionOr<GC::Ref<Comment>> Comment::construct_impl(JS::Realm& realm, String const& data)
|
||||
WebIDL::ExceptionOr<GC::Ref<Comment>> Comment::construct_impl(JS::Realm& realm, Utf16String data)
|
||||
{
|
||||
auto& window = as<HTML::Window>(realm.global_object());
|
||||
return realm.create<Comment>(window.associated_document(), data);
|
||||
return realm.create<Comment>(window.associated_document(), move(data));
|
||||
}
|
||||
|
||||
void Comment::initialize(JS::Realm& realm)
|
||||
|
|
|
@ -15,13 +15,13 @@ class Comment final : public CharacterData {
|
|||
GC_DECLARE_ALLOCATOR(Comment);
|
||||
|
||||
public:
|
||||
static WebIDL::ExceptionOr<GC::Ref<Comment>> construct_impl(JS::Realm&, String const& data);
|
||||
static WebIDL::ExceptionOr<GC::Ref<Comment>> construct_impl(JS::Realm&, Utf16String data);
|
||||
virtual ~Comment() override = default;
|
||||
|
||||
virtual FlyString node_name() const override { return "#comment"_fly_string; }
|
||||
|
||||
private:
|
||||
Comment(Document&, String const&);
|
||||
Comment(Document&, Utf16String);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
};
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
// https://dom.spec.whatwg.org/#comment
|
||||
[Exposed=Window]
|
||||
interface Comment : CharacterData {
|
||||
constructor(optional DOMString data = "");
|
||||
constructor(optional Utf16DOMString data = "");
|
||||
};
|
||||
|
|
|
@ -90,7 +90,7 @@ WebIDL::ExceptionOr<GC::Ref<XMLDocument>> DOMImplementation::create_document(Opt
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
||||
GC::Ref<Document> DOMImplementation::create_html_document(Optional<String> const& title) const
|
||||
GC::Ref<Document> DOMImplementation::create_html_document(Optional<Utf16String> const& title) const
|
||||
{
|
||||
// 1. Let doc be a new document that is an HTML document.
|
||||
auto html_document = HTML::HTMLDocument::create(realm());
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
virtual ~DOMImplementation();
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XMLDocument>> create_document(Optional<FlyString> const&, String const&, GC::Ptr<DocumentType>) const;
|
||||
GC::Ref<Document> create_html_document(Optional<String> const& title) const;
|
||||
GC::Ref<Document> create_html_document(Optional<Utf16String> const& title) const;
|
||||
WebIDL::ExceptionOr<GC::Ref<DocumentType>> create_document_type(String const& name, String const& public_id, String const& system_id);
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
interface DOMImplementation {
|
||||
[NewObject] DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
|
||||
[NewObject] XMLDocument createDocument([FlyString] DOMString? namespace, [LegacyNullToEmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
|
||||
[NewObject] Document createHTMLDocument(optional DOMString title);
|
||||
[NewObject] Document createHTMLDocument(optional Utf16DOMString title);
|
||||
|
||||
boolean hasFeature(); // useless; always returns true
|
||||
};
|
||||
|
|
|
@ -2122,13 +2122,13 @@ GC::Ref<DocumentFragment> Document::create_document_fragment()
|
|||
return realm().create<DocumentFragment>(*this);
|
||||
}
|
||||
|
||||
GC::Ref<Text> Document::create_text_node(String const& data)
|
||||
GC::Ref<Text> Document::create_text_node(Utf16String data)
|
||||
{
|
||||
return realm().create<Text>(*this, data);
|
||||
return realm().create<Text>(*this, move(data));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-document-createcdatasection
|
||||
WebIDL::ExceptionOr<GC::Ref<CDATASection>> Document::create_cdata_section(String const& data)
|
||||
WebIDL::ExceptionOr<GC::Ref<CDATASection>> Document::create_cdata_section(Utf16String data)
|
||||
{
|
||||
// 1. If this is an HTML document, then throw a "NotSupportedError" DOMException.
|
||||
if (is_html_document())
|
||||
|
@ -2139,16 +2139,16 @@ WebIDL::ExceptionOr<GC::Ref<CDATASection>> Document::create_cdata_section(String
|
|||
return WebIDL::InvalidCharacterError::create(realm(), "String may not contain ']]>'"_string);
|
||||
|
||||
// 3. Return a new CDATASection node with its data set to data and node document set to this.
|
||||
return realm().create<CDATASection>(*this, data);
|
||||
return realm().create<CDATASection>(*this, move(data));
|
||||
}
|
||||
|
||||
GC::Ref<Comment> Document::create_comment(String const& data)
|
||||
GC::Ref<Comment> Document::create_comment(Utf16String data)
|
||||
{
|
||||
return realm().create<Comment>(*this, data);
|
||||
return realm().create<Comment>(*this, move(data));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
|
||||
WebIDL::ExceptionOr<GC::Ref<ProcessingInstruction>> Document::create_processing_instruction(String const& target, String const& data)
|
||||
WebIDL::ExceptionOr<GC::Ref<ProcessingInstruction>> Document::create_processing_instruction(String const& target, Utf16String data)
|
||||
{
|
||||
// 1. If target does not match the Name production, then throw an "InvalidCharacterError" DOMException.
|
||||
if (!is_valid_name(target))
|
||||
|
@ -2159,7 +2159,7 @@ WebIDL::ExceptionOr<GC::Ref<ProcessingInstruction>> Document::create_processing_
|
|||
return WebIDL::InvalidCharacterError::create(realm(), "String may not contain '?>'"_string);
|
||||
|
||||
// 3. Return a new ProcessingInstruction node, with target set to target, data set to data, and node document set to this.
|
||||
return realm().create<ProcessingInstruction>(*this, data, target);
|
||||
return realm().create<ProcessingInstruction>(*this, move(data), target);
|
||||
}
|
||||
|
||||
GC::Ref<Range> Document::create_range()
|
||||
|
|
|
@ -377,10 +377,10 @@ public:
|
|||
WebIDL::ExceptionOr<GC::Ref<Element>> create_element(String const& local_name, Variant<String, ElementCreationOptions> const& options);
|
||||
WebIDL::ExceptionOr<GC::Ref<Element>> create_element_ns(Optional<FlyString> const& namespace_, String const& qualified_name, Variant<String, ElementCreationOptions> const& options);
|
||||
GC::Ref<DocumentFragment> create_document_fragment();
|
||||
GC::Ref<Text> create_text_node(String const& data);
|
||||
WebIDL::ExceptionOr<GC::Ref<CDATASection>> create_cdata_section(String const& data);
|
||||
GC::Ref<Comment> create_comment(String const& data);
|
||||
WebIDL::ExceptionOr<GC::Ref<ProcessingInstruction>> create_processing_instruction(String const& target, String const& data);
|
||||
GC::Ref<Text> create_text_node(Utf16String data);
|
||||
WebIDL::ExceptionOr<GC::Ref<CDATASection>> create_cdata_section(Utf16String data);
|
||||
GC::Ref<Comment> create_comment(Utf16String data);
|
||||
WebIDL::ExceptionOr<GC::Ref<ProcessingInstruction>> create_processing_instruction(String const& target, Utf16String data);
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<Attr>> create_attribute(String const& local_name);
|
||||
WebIDL::ExceptionOr<GC::Ref<Attr>> create_attribute_ns(Optional<FlyString> const& namespace_, String const& qualified_name);
|
||||
|
|
|
@ -98,10 +98,10 @@ interface Document : Node {
|
|||
[CEReactions, NewObject] Element createElement(DOMString tagName, optional (DOMString or ElementCreationOptions) options = {});
|
||||
[CEReactions, NewObject] Element createElementNS([FlyString] DOMString? namespace, DOMString qualifiedName, optional (DOMString or ElementCreationOptions) options = {});
|
||||
DocumentFragment createDocumentFragment();
|
||||
Text createTextNode(DOMString data);
|
||||
[NewObject] CDATASection createCDATASection(DOMString data);
|
||||
Comment createComment(DOMString data);
|
||||
[NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
|
||||
Text createTextNode(Utf16DOMString data);
|
||||
[NewObject] CDATASection createCDATASection(Utf16DOMString data);
|
||||
Comment createComment(Utf16DOMString data);
|
||||
[NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, Utf16DOMString data);
|
||||
|
||||
[NewObject] Attr createAttribute(DOMString localName);
|
||||
[NewObject] Attr createAttributeNS([FlyString] DOMString? namespace, DOMString qualifiedName);
|
||||
|
|
|
@ -26,12 +26,12 @@
|
|||
namespace Web {
|
||||
|
||||
// Replaces a document's content with a simple error message.
|
||||
static void convert_to_xml_error_document(DOM::Document& document, String error_string)
|
||||
static void convert_to_xml_error_document(DOM::Document& document, Utf16String error_string)
|
||||
{
|
||||
auto html_element = MUST(DOM::create_element(document, HTML::TagNames::html, Namespace::HTML));
|
||||
auto body_element = MUST(DOM::create_element(document, HTML::TagNames::body, Namespace::HTML));
|
||||
MUST(html_element->append_child(body_element));
|
||||
MUST(body_element->append_child(document.realm().create<DOM::Text>(document, error_string)));
|
||||
MUST(body_element->append_child(document.realm().create<DOM::Text>(document, move(error_string))));
|
||||
document.remove_all_children();
|
||||
MUST(document.append_child(html_element));
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ bool build_xml_document(DOM::Document& document, ByteBuffer const& data, Optiona
|
|||
VERIFY(decoder.has_value());
|
||||
// Well-formed XML documents contain only properly encoded characters
|
||||
if (!decoder->validate(data)) {
|
||||
convert_to_xml_error_document(document, "XML Document contains improperly-encoded characters"_string);
|
||||
convert_to_xml_error_document(document, "XML Document contains improperly-encoded characters"_utf16);
|
||||
return false;
|
||||
}
|
||||
auto source = decoder->to_utf8(data).release_value_but_fixme_should_propagate_errors();
|
||||
|
@ -162,7 +162,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_xml_document(HTML::Navig
|
|||
if (!decoder->validate(data)) {
|
||||
// FIXME: Insert error message into the document.
|
||||
dbgln("XML Document contains improperly-encoded characters");
|
||||
convert_to_xml_error_document(document, "XML Document contains improperly-encoded characters"_string);
|
||||
convert_to_xml_error_document(document, "XML Document contains improperly-encoded characters"_utf16);
|
||||
|
||||
// NOTE: This ensures that the `load` event gets fired for the frame loading this document.
|
||||
document->completely_finish_loading();
|
||||
|
@ -172,7 +172,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_xml_document(HTML::Navig
|
|||
if (source.is_error()) {
|
||||
// FIXME: Insert error message into the document.
|
||||
dbgln("Failed to decode XML document: {}", source.error());
|
||||
convert_to_xml_error_document(document, MUST(String::formatted("Failed to decode XML document: {}", source.error())));
|
||||
convert_to_xml_error_document(document, Utf16String::formatted("Failed to decode XML document: {}", source.error()));
|
||||
|
||||
// NOTE: This ensures that the `load` event gets fired for the frame loading this document.
|
||||
document->completely_finish_loading();
|
||||
|
@ -184,7 +184,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_xml_document(HTML::Navig
|
|||
if (result.is_error()) {
|
||||
// FIXME: Insert error message into the document.
|
||||
dbgln("Failed to parse XML document: {}", result.error());
|
||||
convert_to_xml_error_document(document, MUST(String::formatted("Failed to parse XML document: {}", result.error())));
|
||||
convert_to_xml_error_document(document, Utf16String::formatted("Failed to parse XML document: {}", result.error()));
|
||||
|
||||
// NOTE: XMLDocumentBuilder ensures that the `load` event gets fired. We don't need to do anything else here.
|
||||
}
|
||||
|
@ -246,10 +246,10 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_text_document(HTML::Navi
|
|||
|
||||
// 5. User agents may add content to the head element of document, e.g., linking to a style sheet, providing
|
||||
// script, or giving the document a title.
|
||||
auto title = MUST(String::from_byte_string(LexicalPath::basename(url.to_byte_string())));
|
||||
auto title = Utf16String::from_utf8_with_replacement_character(LexicalPath::basename(url.to_byte_string()));
|
||||
auto title_element = MUST(DOM::create_element(document, HTML::TagNames::title, Namespace::HTML));
|
||||
MUST(document->head()->append_child(title_element));
|
||||
auto title_text = document->realm().create<DOM::Text>(document, title);
|
||||
auto title_text = document->realm().create<DOM::Text>(document, move(title));
|
||||
MUST(title_element->append_child(*title_text));
|
||||
});
|
||||
|
||||
|
@ -283,11 +283,13 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
|
|||
// video, or audio resource.
|
||||
// 6. User agents may add content to the head element of document, or attributes to host element, e.g., to link
|
||||
// to a style sheet, to provide a script, to give the document a title, or to make the media autoplay.
|
||||
auto insert_title = [](auto& document, auto title) -> WebIDL::ExceptionOr<void> {
|
||||
auto insert_title = [](auto& document, auto const& document_url) -> WebIDL::ExceptionOr<void> {
|
||||
auto title = Utf16String::from_utf8_with_replacement_character(LexicalPath::basename(document_url.to_byte_string()));
|
||||
|
||||
auto title_element = TRY(DOM::create_element(document, HTML::TagNames::title, Namespace::HTML));
|
||||
TRY(document->head()->append_child(title_element));
|
||||
|
||||
auto title_text = document->realm().template create<DOM::Text>(document, title);
|
||||
auto title_text = document->realm().template create<DOM::Text>(document, move(title));
|
||||
TRY(title_element->append_child(*title_text));
|
||||
return {};
|
||||
};
|
||||
|
@ -315,7 +317,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
|
|||
auto img_element = TRY(DOM::create_element(document, HTML::TagNames::img, Namespace::HTML));
|
||||
TRY(img_element->set_attribute(HTML::AttributeNames::src, url_string));
|
||||
TRY(document->body()->append_child(img_element));
|
||||
TRY(insert_title(document, MUST(String::from_byte_string(LexicalPath::basename(url_string.to_byte_string())))));
|
||||
TRY(insert_title(document, url_string));
|
||||
|
||||
} else if (type.type() == "video"sv) {
|
||||
auto video_element = TRY(DOM::create_element(document, HTML::TagNames::video, Namespace::HTML));
|
||||
|
@ -323,7 +325,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
|
|||
TRY(video_element->set_attribute(HTML::AttributeNames::autoplay, String {}));
|
||||
TRY(video_element->set_attribute(HTML::AttributeNames::controls, String {}));
|
||||
TRY(document->body()->append_child(video_element));
|
||||
TRY(insert_title(document, MUST(String::from_byte_string(LexicalPath::basename(url_string.to_byte_string())))));
|
||||
TRY(insert_title(document, url_string));
|
||||
|
||||
} else if (type.type() == "audio"sv) {
|
||||
auto audio_element = TRY(DOM::create_element(document, HTML::TagNames::audio, Namespace::HTML));
|
||||
|
@ -331,7 +333,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
|
|||
TRY(audio_element->set_attribute(HTML::AttributeNames::autoplay, String {}));
|
||||
TRY(audio_element->set_attribute(HTML::AttributeNames::controls, String {}));
|
||||
TRY(document->body()->append_child(audio_element));
|
||||
TRY(insert_title(document, MUST(String::from_byte_string(LexicalPath::basename(url_string.to_byte_string())))));
|
||||
TRY(insert_title(document, url_string));
|
||||
|
||||
} else {
|
||||
// FIXME: According to https://mimesniff.spec.whatwg.org/#audio-or-video-mime-type we might have to deal with
|
||||
|
|
|
@ -2200,7 +2200,7 @@ WebIDL::ExceptionOr<GC::Ptr<Element>> Element::insert_adjacent_element(String co
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-element-insertadjacenttext
|
||||
WebIDL::ExceptionOr<void> Element::insert_adjacent_text(String const& where, String const& data)
|
||||
WebIDL::ExceptionOr<void> Element::insert_adjacent_text(String const& where, Utf16String const& data)
|
||||
{
|
||||
// 1. Let text be a new Text node whose data is data and node document is this’s node document.
|
||||
auto text = realm().create<DOM::Text>(document(), data);
|
||||
|
|
|
@ -306,7 +306,7 @@ public:
|
|||
bool is_actually_disabled() const;
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ptr<Element>> insert_adjacent_element(String const& where, GC::Ref<Element> element);
|
||||
WebIDL::ExceptionOr<void> insert_adjacent_text(String const& where, String const& data);
|
||||
WebIDL::ExceptionOr<void> insert_adjacent_text(String const& where, Utf16String const& data);
|
||||
|
||||
// https://w3c.github.io/csswg-drafts/cssom-view-1/#dom-element-scrollintoview
|
||||
ErrorOr<void> scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> = {});
|
||||
|
|
|
@ -77,7 +77,7 @@ interface Element : Node {
|
|||
HTMLCollection getElementsByClassName(DOMString className);
|
||||
|
||||
[CEReactions] Element? insertAdjacentElement(DOMString where, Element element); // legacy
|
||||
undefined insertAdjacentText(DOMString where, DOMString data); // legacy
|
||||
undefined insertAdjacentText(DOMString where, Utf16DOMString data); // legacy
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-nondocumenttypechildnode
|
||||
readonly attribute Element? nextElementSibling;
|
||||
|
|
|
@ -186,7 +186,7 @@ Optional<String> Node::text_content() const
|
|||
|
||||
// If CharacterData, return this’s data.
|
||||
if (is<CharacterData>(this))
|
||||
return static_cast<CharacterData const&>(*this).data();
|
||||
return static_cast<CharacterData const&>(*this).data().to_utf8_but_should_be_ported_to_utf16();
|
||||
|
||||
// If Attr node, return this's value.
|
||||
if (is<Attr>(*this))
|
||||
|
@ -214,9 +214,8 @@ void Node::set_text_content(Optional<String> const& maybe_content)
|
|||
|
||||
// If CharacterData, replace data with node this, offset 0, count this’s length, and data the given value.
|
||||
else if (is<CharacterData>(this)) {
|
||||
|
||||
auto* character_data_node = as<CharacterData>(this);
|
||||
character_data_node->set_data(content);
|
||||
character_data_node->set_data(Utf16String::from_utf8(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.
|
||||
|
@ -288,12 +287,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 data(StringBuilder::Mode::UTF16);
|
||||
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, MUST(data.to_string())));
|
||||
TRY(character_data.replace_data(length, 0, data.to_utf16_string()));
|
||||
|
||||
// 5. Let currentNode be node’s next sibling.
|
||||
auto* current_node = node.next_sibling();
|
||||
|
@ -363,7 +362,7 @@ Optional<String> Node::node_value() const
|
|||
|
||||
// If CharacterData, return this’s data.
|
||||
if (is<CharacterData>(this)) {
|
||||
return as<CharacterData>(this)->data();
|
||||
return as<CharacterData>(this)->data().to_utf8_but_should_be_ported_to_utf16();
|
||||
}
|
||||
|
||||
// Otherwise, return null.
|
||||
|
@ -382,7 +381,7 @@ void Node::set_node_value(Optional<String> const& maybe_value)
|
|||
as<Attr>(this)->set_value(move(value));
|
||||
} else if (is<CharacterData>(this)) {
|
||||
// If CharacterData, replace data with node this, offset 0, count this’s length, and data the given value.
|
||||
as<CharacterData>(this)->set_data(value);
|
||||
as<CharacterData>(this)->set_data(Utf16String::from_utf8(value));
|
||||
}
|
||||
|
||||
// Otherwise, do nothing.
|
||||
|
@ -1870,7 +1869,7 @@ bool Node::is_uninteresting_whitespace_node() const
|
|||
{
|
||||
if (!is<Text>(*this))
|
||||
return false;
|
||||
if (!static_cast<Text const&>(*this).data().bytes_as_string_view().is_whitespace())
|
||||
if (!static_cast<Text const&>(*this).data().is_ascii_whitespace())
|
||||
return false;
|
||||
if (!layout_node())
|
||||
return true;
|
||||
|
@ -1936,10 +1935,10 @@ void Node::serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object) c
|
|||
MUST(object.add("type"sv, "text"));
|
||||
|
||||
auto text_node = static_cast<DOM::Text const*>(this);
|
||||
MUST(object.add("text"sv, text_node->data()));
|
||||
MUST(object.add("text"sv, text_node->data().to_utf8()));
|
||||
} else if (is_comment()) {
|
||||
MUST(object.add("type"sv, "comment"sv));
|
||||
MUST(object.add("data"sv, static_cast<DOM::Comment const&>(*this).data()));
|
||||
MUST(object.add("data"sv, static_cast<DOM::Comment const&>(*this).data().to_utf8()));
|
||||
} else if (is_shadow_root()) {
|
||||
MUST(object.add("type"sv, "shadow-root"));
|
||||
MUST(object.add("mode"sv, static_cast<DOM::ShadowRoot const&>(*this).mode() == Bindings::ShadowRootMode::Open ? "open"sv : "closed"sv));
|
||||
|
@ -2053,7 +2052,7 @@ void Node::string_replace_all(String const& string)
|
|||
|
||||
// 2. If string is not the empty string, then set node to a new Text node whose data is string and node document is parent’s node document.
|
||||
if (!string.is_empty())
|
||||
node = realm().create<Text>(document(), string);
|
||||
node = realm().create<Text>(document(), Utf16String::from_utf8(string));
|
||||
|
||||
// 3. Replace all with node within parent.
|
||||
replace_all(node);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/ByteString.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/DocumentFragment.h>
|
||||
|
@ -15,7 +15,7 @@
|
|||
namespace Web::DOM {
|
||||
|
||||
// https://dom.spec.whatwg.org/#converting-nodes-into-a-node
|
||||
WebIDL::ExceptionOr<GC::Ref<Node>> convert_nodes_to_single_node(Vector<Variant<GC::Root<Node>, String>> const& nodes, DOM::Document& document)
|
||||
WebIDL::ExceptionOr<GC::Ref<Node>> convert_nodes_to_single_node(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes, DOM::Document& document)
|
||||
{
|
||||
// 1. Let node be null.
|
||||
// 2. Replace each string in nodes with a new Text node whose data is the string and node document is document.
|
||||
|
@ -23,11 +23,11 @@ WebIDL::ExceptionOr<GC::Ref<Node>> convert_nodes_to_single_node(Vector<Variant<G
|
|||
// 4. Otherwise, set node to a new DocumentFragment node whose node document is document, and then append each node in nodes, if any, to it.
|
||||
// 5. Return node.
|
||||
|
||||
auto potentially_convert_string_to_text_node = [&document](Variant<GC::Root<Node>, String> const& node) -> GC::Ref<Node> {
|
||||
auto potentially_convert_string_to_text_node = [&document](Variant<GC::Root<Node>, Utf16String> const& node) -> GC::Ref<Node> {
|
||||
if (node.has<GC::Root<Node>>())
|
||||
return *node.get<GC::Root<Node>>();
|
||||
|
||||
return document.realm().create<DOM::Text>(document, node.get<String>());
|
||||
return document.realm().create<DOM::Text>(document, node.get<Utf16String>());
|
||||
};
|
||||
|
||||
if (nodes.size() == 1)
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
|
||||
namespace Web::DOM {
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<Node>> convert_nodes_to_single_node(Vector<Variant<GC::Root<Node>, String>> const& nodes, DOM::Document& document);
|
||||
WebIDL::ExceptionOr<GC::Ref<Node>> convert_nodes_to_single_node(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes, DOM::Document& document);
|
||||
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ GC::Ref<HTMLCollection> ParentNode::get_elements_by_tag_name_ns(Optional<FlyStri
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-parentnode-prepend
|
||||
WebIDL::ExceptionOr<void> ParentNode::prepend(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
WebIDL::ExceptionOr<void> ParentNode::prepend(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
// 1. Let node be the result of converting nodes into a node given nodes and this’s node document.
|
||||
auto node = TRY(convert_nodes_to_single_node(nodes, document()));
|
||||
|
@ -220,7 +220,7 @@ WebIDL::ExceptionOr<void> ParentNode::prepend(Vector<Variant<GC::Root<Node>, Str
|
|||
return {};
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> ParentNode::append(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
WebIDL::ExceptionOr<void> ParentNode::append(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
// 1. Let node be the result of converting nodes into a node given nodes and this’s node document.
|
||||
auto node = TRY(convert_nodes_to_single_node(nodes, document()));
|
||||
|
@ -231,7 +231,7 @@ WebIDL::ExceptionOr<void> ParentNode::append(Vector<Variant<GC::Root<Node>, Stri
|
|||
return {};
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<void> ParentNode::replace_children(Vector<Variant<GC::Root<Node>, String>> const& nodes)
|
||||
WebIDL::ExceptionOr<void> ParentNode::replace_children(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes)
|
||||
{
|
||||
// 1. Let node be the result of converting nodes into a node given nodes and this’s node document.
|
||||
auto node = TRY(convert_nodes_to_single_node(nodes, document()));
|
||||
|
|
|
@ -32,9 +32,9 @@ public:
|
|||
GC::Ref<HTMLCollection> get_elements_by_tag_name(FlyString const&);
|
||||
GC::Ref<HTMLCollection> get_elements_by_tag_name_ns(Optional<FlyString>, FlyString const&);
|
||||
|
||||
WebIDL::ExceptionOr<void> prepend(Vector<Variant<GC::Root<Node>, String>> const& nodes);
|
||||
WebIDL::ExceptionOr<void> append(Vector<Variant<GC::Root<Node>, String>> const& nodes);
|
||||
WebIDL::ExceptionOr<void> replace_children(Vector<Variant<GC::Root<Node>, String>> const& nodes);
|
||||
WebIDL::ExceptionOr<void> prepend(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes);
|
||||
WebIDL::ExceptionOr<void> append(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes);
|
||||
WebIDL::ExceptionOr<void> replace_children(Vector<Variant<GC::Root<Node>, Utf16String>> const& nodes);
|
||||
WebIDL::ExceptionOr<void> move_before(GC::Ref<Node> node, GC::Ptr<Node> child);
|
||||
|
||||
GC::Ref<HTMLCollection> get_elements_by_class_name(StringView);
|
||||
|
|
|
@ -8,9 +8,9 @@ interface mixin ParentNode {
|
|||
readonly attribute Element? lastElementChild;
|
||||
readonly attribute unsigned long childElementCount;
|
||||
|
||||
[CEReactions, Unscopable] undefined prepend((Node or DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined append((Node or DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined replaceChildren((Node or DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined prepend((Node or Utf16DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined append((Node or Utf16DOMString)... nodes);
|
||||
[CEReactions, Unscopable] undefined replaceChildren((Node or Utf16DOMString)... nodes);
|
||||
|
||||
[CEReactions] undefined moveBefore(Node node, Node? child);
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ namespace Web::DOM {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(ProcessingInstruction);
|
||||
|
||||
ProcessingInstruction::ProcessingInstruction(Document& document, String const& data, String const& target)
|
||||
: CharacterData(document, NodeType::PROCESSING_INSTRUCTION_NODE, data)
|
||||
ProcessingInstruction::ProcessingInstruction(Document& document, Utf16String data, String const& target)
|
||||
: CharacterData(document, NodeType::PROCESSING_INSTRUCTION_NODE, move(data))
|
||||
, m_target(target)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
String const& target() const { return m_target; }
|
||||
|
||||
private:
|
||||
ProcessingInstruction(Document&, String const& data, String const& target);
|
||||
ProcessingInstruction(Document&, Utf16String data, String const& target);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ String Range::to_string() const
|
|||
// 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<Text>(*start_container())) {
|
||||
auto const& text = static_cast<Text const&>(*start_container());
|
||||
return MUST(text.substring_data(start_offset(), end_offset() - start_offset()));
|
||||
return MUST(text.substring_data(start_offset(), end_offset() - start_offset())).to_utf8_but_should_be_ported_to_utf16();
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -621,7 +621,7 @@ WebIDL::ExceptionOr<GC::Ref<DocumentFragment>> 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<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, String {}));
|
||||
TRY(static_cast<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, {}));
|
||||
|
||||
// 5. Return fragment.
|
||||
return fragment;
|
||||
|
@ -711,7 +711,7 @@ WebIDL::ExceptionOr<GC::Ref<DocumentFragment>> 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<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, String {}));
|
||||
TRY(static_cast<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, {}));
|
||||
}
|
||||
// 16. Otherwise, if first partially contained child is not null:
|
||||
else if (first_partially_contained_child) {
|
||||
|
@ -749,7 +749,7 @@ WebIDL::ExceptionOr<GC::Ref<DocumentFragment>> 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(as<CharacterData>(*original_end_node).replace_data(0, original_end_offset, String {}));
|
||||
TRY(as<CharacterData>(*original_end_node).replace_data(0, original_end_offset, {}));
|
||||
}
|
||||
// 19. Otherwise, if last partially contained child is not null:
|
||||
else if (last_partially_contained_child) {
|
||||
|
@ -1088,7 +1088,7 @@ WebIDL::ExceptionOr<void> 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<CharacterData>(*original_start_node)) {
|
||||
TRY(static_cast<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, String {}));
|
||||
TRY(static_cast<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_end_offset - original_start_offset, {}));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -1123,7 +1123,7 @@ WebIDL::ExceptionOr<void> 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<CharacterData>(*original_start_node))
|
||||
TRY(static_cast<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, String {}));
|
||||
TRY(static_cast<CharacterData&>(*original_start_node).replace_data(original_start_offset, original_start_node->length() - original_start_offset, {}));
|
||||
|
||||
// 8. For each node in nodes to remove, in tree order, remove node.
|
||||
for (auto& node : nodes_to_remove)
|
||||
|
@ -1131,7 +1131,7 @@ WebIDL::ExceptionOr<void> 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<CharacterData>(*original_end_node))
|
||||
TRY(static_cast<CharacterData&>(*original_end_node).replace_data(0, original_end_offset, String {}));
|
||||
TRY(static_cast<CharacterData&>(*original_end_node).replace_data(0, original_end_offset, {}));
|
||||
|
||||
// 10. Set start and end to (new node, new offset).
|
||||
TRY(set_start(*new_node, new_offset));
|
||||
|
|
|
@ -18,13 +18,13 @@ namespace Web::DOM {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(Text);
|
||||
|
||||
Text::Text(Document& document, String const& data)
|
||||
: CharacterData(document, NodeType::TEXT_NODE, data)
|
||||
Text::Text(Document& document, Utf16String data)
|
||||
: CharacterData(document, NodeType::TEXT_NODE, move(data))
|
||||
{
|
||||
}
|
||||
|
||||
Text::Text(Document& document, NodeType type, String const& data)
|
||||
: CharacterData(document, type, data)
|
||||
Text::Text(Document& document, NodeType type, Utf16String data)
|
||||
: CharacterData(document, type, move(data))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,11 +41,11 @@ void Text::visit_edges(Cell::Visitor& visitor)
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-text-text
|
||||
WebIDL::ExceptionOr<GC::Ref<Text>> Text::construct_impl(JS::Realm& realm, String const& data)
|
||||
WebIDL::ExceptionOr<GC::Ref<Text>> Text::construct_impl(JS::Realm& realm, Utf16String data)
|
||||
{
|
||||
// The new Text(data) constructor steps are to set this’s data to data and this’s node document to current global object’s associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
return realm.create<Text>(window.associated_document(), data);
|
||||
return realm.create<Text>(window.associated_document(), move(data));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-text-splittext
|
||||
|
@ -110,14 +110,14 @@ WebIDL::ExceptionOr<GC::Ref<Text>> 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, String {}));
|
||||
TRY(replace_data(offset, count, {}));
|
||||
|
||||
// 9. Return new node.
|
||||
return new_node;
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-text-wholetext
|
||||
String Text::whole_text()
|
||||
Utf16String Text::whole_text()
|
||||
{
|
||||
// https://dom.spec.whatwg.org/#contiguous-text-nodes
|
||||
// The contiguous Text nodes of a node node are node, node’s previous sibling Text node, if any, and its contiguous
|
||||
|
@ -141,11 +141,11 @@ String Text::whole_text()
|
|||
current_node = current_node->next_sibling();
|
||||
}
|
||||
|
||||
StringBuilder builder;
|
||||
StringBuilder builder(StringBuilder::Mode::UTF16);
|
||||
for (auto const& text_node : nodes)
|
||||
builder.append(text_node->data());
|
||||
|
||||
return MUST(builder.to_string());
|
||||
return builder.to_utf16_string();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#text-node-directionality
|
||||
|
@ -154,7 +154,7 @@ Optional<Element::Directionality> Text::directionality() const
|
|||
// 1. If text's data does not contain a code point whose bidirectional character type is L, AL, or R, then return null.
|
||||
// 2. Let codePoint be the first code point in text's data whose bidirectional character type is L, AL, or R.
|
||||
Optional<Unicode::BidiClass> found_character_bidi_class;
|
||||
for (auto code_point : Utf8View(data())) {
|
||||
for (auto code_point : data()) {
|
||||
auto bidi_class = Unicode::bidirectional_class(code_point);
|
||||
if (first_is_one_of(bidi_class, Unicode::BidiClass::LeftToRight, Unicode::BidiClass::RightToLeftArabic, Unicode::BidiClass::RightToLeft)) {
|
||||
found_character_bidi_class = bidi_class;
|
||||
|
|
|
@ -22,7 +22,7 @@ class Text
|
|||
public:
|
||||
virtual ~Text() override = default;
|
||||
|
||||
static WebIDL::ExceptionOr<GC::Ref<Text>> construct_impl(JS::Realm& realm, String const& data);
|
||||
static WebIDL::ExceptionOr<GC::Ref<Text>> construct_impl(JS::Realm& realm, Utf16String data);
|
||||
|
||||
// ^Node
|
||||
virtual FlyString node_name() const override { return "#text"_fly_string; }
|
||||
|
@ -31,7 +31,7 @@ public:
|
|||
void set_max_length(Optional<size_t> max_length) { m_max_length = move(max_length); }
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<Text>> split_text(size_t offset);
|
||||
String whole_text();
|
||||
Utf16String whole_text();
|
||||
|
||||
bool is_password_input() const { return m_is_password_input; }
|
||||
void set_is_password_input(Badge<HTML::HTMLInputElement>, bool b) { m_is_password_input = b; }
|
||||
|
@ -39,8 +39,8 @@ public:
|
|||
Optional<Element::Directionality> directionality() const;
|
||||
|
||||
protected:
|
||||
Text(Document&, String const&);
|
||||
Text(Document&, NodeType, String const&);
|
||||
Text(Document&, Utf16String);
|
||||
Text(Document&, NodeType, Utf16String);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
// https://dom.spec.whatwg.org/#text
|
||||
[Exposed=Window]
|
||||
interface Text : CharacterData {
|
||||
constructor(optional DOMString data = "");
|
||||
constructor(optional Utf16DOMString data = "");
|
||||
|
||||
[NewObject] Text splitText(unsigned long offset);
|
||||
readonly attribute DOMString wholeText;
|
||||
readonly attribute Utf16DOMString wholeText;
|
||||
};
|
||||
|
||||
Text includes Slottable;
|
||||
|
|
|
@ -1367,10 +1367,10 @@ bool command_insert_linebreak_action(DOM::Document& document, Utf16View const&)
|
|||
if (auto* text_node = as_if<DOM::Text>(*start_node); text_node) {
|
||||
auto resolved_white_space_collapse = resolved_keyword(*start_node, CSS::PropertyID::WhiteSpaceCollapse);
|
||||
if (resolved_white_space_collapse.has_value() && first_is_one_of(resolved_white_space_collapse.value(), CSS::Keyword::Preserve, CSS::Keyword::PreserveBreaks)) {
|
||||
MUST(text_node->insert_data(active_range.start_offset(), "\n"_string));
|
||||
MUST(text_node->insert_data(active_range.start_offset(), "\n"_utf16));
|
||||
MUST(selection.collapse(start_node, active_range.start_offset() + 1));
|
||||
if (selection.range()->start_offset() == start_node->length())
|
||||
MUST(text_node->insert_data(active_range.start_offset(), "\n"_string));
|
||||
MUST(text_node->insert_data(active_range.start_offset(), "\n"_utf16));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1796,7 +1796,7 @@ bool command_insert_text_action(DOM::Document& document, Utf16View const& value)
|
|||
// 13. If node is a Text node:
|
||||
if (is<DOM::Text>(*node)) {
|
||||
// 1. Call insertData(offset, value) on node.
|
||||
MUST(static_cast<DOM::Text&>(*node).insert_data(offset, value.to_utf8_but_should_be_ported_to_utf16()));
|
||||
MUST(static_cast<DOM::Text&>(*node).insert_data(offset, value));
|
||||
|
||||
// 2. Call collapse(node, offset) on the context object's selection.
|
||||
MUST(selection.collapse(node, offset));
|
||||
|
@ -1812,7 +1812,7 @@ bool command_insert_text_action(DOM::Document& document, Utf16View const& value)
|
|||
node->first_child()->remove();
|
||||
|
||||
// 2. Let text be the result of calling createTextNode(value) on the context object.
|
||||
auto text = document.create_text_node(value.to_utf8_but_should_be_ported_to_utf16());
|
||||
auto text = document.create_text_node(Utf16String::from_utf16_without_validation(value));
|
||||
|
||||
// 3. Call insertNode(text) on the active range.
|
||||
MUST(active_range(document)->insert_node(text));
|
||||
|
|
|
@ -566,7 +566,7 @@ void canonicalize_whitespace(DOM::BoundaryPoint boundary, bool fix_collapsed_spa
|
|||
if (element != start_node_code_point) {
|
||||
// 1. Call insertData(start offset, element) on start node.
|
||||
auto& start_node_character_data = static_cast<DOM::CharacterData&>(*start_node);
|
||||
MUST(start_node_character_data.insert_data(start_offset, String::from_code_point(element)));
|
||||
MUST(start_node_character_data.insert_data(start_offset, Utf16String::from_code_point(element)));
|
||||
|
||||
// 2. Call deleteData(start offset + 1, 1) on start node.
|
||||
MUST(start_node_character_data.delete_data(start_offset + 1, 1));
|
||||
|
@ -2615,8 +2615,7 @@ bool is_whitespace_node(GC::Ref<DOM::Node> node)
|
|||
auto is_tab_lf_cr_or_space = [](u32 codepoint) {
|
||||
return codepoint == '\t' || codepoint == '\n' || codepoint == '\r' || codepoint == ' ';
|
||||
};
|
||||
auto code_points = character_data.data().code_points();
|
||||
if (all_of(code_points, is_tab_lf_cr_or_space) && (white_space_collapse == CSS::Keyword::Collapse))
|
||||
if (all_of(character_data.data(), is_tab_lf_cr_or_space) && (white_space_collapse == CSS::Keyword::Collapse))
|
||||
return true;
|
||||
|
||||
// or a Text node whose data consists only of one or more tabs (0x0009), carriage returns
|
||||
|
@ -2626,7 +2625,7 @@ bool is_whitespace_node(GC::Ref<DOM::Node> node)
|
|||
auto is_tab_cr_or_space = [](u32 codepoint) {
|
||||
return codepoint == '\t' || codepoint == '\r' || codepoint == ' ';
|
||||
};
|
||||
if (all_of(code_points, is_tab_cr_or_space) && white_space_collapse == CSS::Keyword::PreserveBreaks)
|
||||
if (all_of(character_data.data(), is_tab_cr_or_space) && white_space_collapse == CSS::Keyword::PreserveBreaks)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -806,7 +806,7 @@ void FormAssociatedTextControlElement::handle_insert(String const& data)
|
|||
String data_for_insertion = data;
|
||||
// FIXME: Cut by UTF-16 code units instead of raw bytes
|
||||
if (auto max_length = text_node->max_length(); max_length.has_value()) {
|
||||
auto remaining_length = *max_length - text_node->data().code_points().length();
|
||||
auto remaining_length = *max_length - text_node->data().length_in_code_points();
|
||||
if (remaining_length < data.code_points().length()) {
|
||||
data_for_insertion = MUST(data.substring_from_byte_offset(0, remaining_length));
|
||||
}
|
||||
|
@ -832,7 +832,7 @@ void FormAssociatedTextControlElement::handle_delete(DeleteDirection direction)
|
|||
MUST(set_range_text(String {}, selection_start - 1, selection_end, Bindings::SelectionMode::End));
|
||||
}
|
||||
} else {
|
||||
if (selection_start < text_node->data().code_points().length()) {
|
||||
if (selection_start < text_node->data().length_in_code_points()) {
|
||||
MUST(set_range_text(String {}, selection_start, selection_end + 1, Bindings::SelectionMode::End));
|
||||
}
|
||||
}
|
||||
|
@ -982,7 +982,7 @@ void FormAssociatedTextControlElement::increment_cursor_position_to_next_word(Co
|
|||
|
||||
while (true) {
|
||||
if (auto offset = text_node->word_segmenter().next_boundary(m_selection_end); offset.has_value()) {
|
||||
auto word = text_node->data().code_points().substring_view(m_selection_end, *offset - m_selection_end);
|
||||
auto word = text_node->data().substring_view(m_selection_end, *offset - m_selection_end);
|
||||
if (collapse == CollapseSelection::Yes) {
|
||||
collapse_selection_to_offset(*offset);
|
||||
} else {
|
||||
|
@ -1005,7 +1005,7 @@ void FormAssociatedTextControlElement::decrement_cursor_position_to_previous_wor
|
|||
|
||||
while (true) {
|
||||
if (auto offset = text_node->word_segmenter().previous_boundary(m_selection_end); offset.has_value()) {
|
||||
auto word = text_node->data().code_points().substring_view(*offset, m_selection_end - *offset);
|
||||
auto word = text_node->data().substring_view(*offset, m_selection_end - *offset);
|
||||
if (collapse == CollapseSelection::Yes) {
|
||||
collapse_selection_to_offset(*offset);
|
||||
} else {
|
||||
|
|
|
@ -240,7 +240,7 @@ WebIDL::ExceptionOr<void> HTMLElement::set_outer_text(String const& value)
|
|||
|
||||
// 5. If fragment has no children, then append a new Text node whose data is the empty string and node document is this's node document to fragment.
|
||||
if (!fragment->has_children())
|
||||
MUST(fragment->append_child(document().create_text_node(String {})));
|
||||
MUST(fragment->append_child(document().create_text_node({})));
|
||||
|
||||
// 6. Replace this with fragment within this's parent.
|
||||
MUST(parent()->replace_child(fragment, *this));
|
||||
|
@ -276,7 +276,7 @@ GC::Ref<DOM::DocumentFragment> HTMLElement::rendered_text_fragment(StringView in
|
|||
|
||||
// 2. If text is not the empty string, then append a new Text node whose data is text and node document is document to fragment.
|
||||
if (!text.is_empty()) {
|
||||
MUST(fragment->append_child(document().create_text_node(MUST(String::from_utf8(text)))));
|
||||
MUST(fragment->append_child(document().create_text_node(Utf16String::from_utf8(text))));
|
||||
}
|
||||
|
||||
// 3. While position is not past the end of input, and the code point at position is either U+000A LF or U+000D CR:
|
||||
|
|
|
@ -530,7 +530,7 @@ void HTMLInputElement::did_edit_text_node()
|
|||
{
|
||||
// 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.
|
||||
auto old_value = move(m_value);
|
||||
m_value = value_sanitization_algorithm(m_text_node->data());
|
||||
m_value = value_sanitization_algorithm(m_text_node->data().to_utf8_but_should_be_ported_to_utf16());
|
||||
m_dirty_value = true;
|
||||
|
||||
m_has_uncommitted_changes = true;
|
||||
|
@ -700,7 +700,7 @@ WebIDL::ExceptionOr<void> HTMLInputElement::set_value(String const& value)
|
|||
relevant_value_was_changed();
|
||||
|
||||
if (m_text_node) {
|
||||
m_text_node->set_data(m_value);
|
||||
m_text_node->set_data(Utf16String::from_utf8(m_value));
|
||||
update_placeholder_visibility();
|
||||
|
||||
set_the_selection_range(m_text_node->length(), m_text_node->length());
|
||||
|
@ -819,7 +819,7 @@ void HTMLInputElement::update_button_input_shadow_tree()
|
|||
}
|
||||
}
|
||||
|
||||
m_text_node->set_data(label.value());
|
||||
m_text_node->set_data(Utf16String::from_utf8(label.value()));
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
}
|
||||
|
@ -827,7 +827,7 @@ void HTMLInputElement::update_button_input_shadow_tree()
|
|||
void HTMLInputElement::update_text_input_shadow_tree()
|
||||
{
|
||||
if (m_text_node) {
|
||||
m_text_node->set_data(m_value);
|
||||
m_text_node->set_data(Utf16String::from_utf8(m_value));
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
}
|
||||
|
@ -1018,7 +1018,7 @@ void HTMLInputElement::create_button_input_shadow_tree()
|
|||
label = value();
|
||||
}
|
||||
}
|
||||
m_text_node = realm().create<DOM::Text>(document(), label.value());
|
||||
m_text_node = realm().create<DOM::Text>(document(), Utf16String::from_utf8(label.value()));
|
||||
MUST(text_container->append_child(*m_text_node));
|
||||
MUST(shadow_root->append_child(*text_container));
|
||||
}
|
||||
|
@ -1053,8 +1053,7 @@ void HTMLInputElement::create_text_input_shadow_tree()
|
|||
|
||||
MUST(element->append_child(*m_placeholder_element));
|
||||
|
||||
m_placeholder_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
m_placeholder_text_node->set_data(placeholder());
|
||||
m_placeholder_text_node = realm().create<DOM::Text>(document(), Utf16String::from_utf8(placeholder()));
|
||||
MUST(m_placeholder_element->append_child(*m_placeholder_text_node));
|
||||
|
||||
// https://www.w3.org/TR/css-ui-4/#input-rules
|
||||
|
@ -1075,7 +1074,7 @@ void HTMLInputElement::create_text_input_shadow_tree()
|
|||
}
|
||||
MUST(element->append_child(*m_inner_text_element));
|
||||
|
||||
m_text_node = realm().create<DOM::Text>(document(), move(initial_value));
|
||||
m_text_node = realm().create<DOM::Text>(document(), Utf16String::from_utf8(initial_value));
|
||||
handle_readonly_attribute(attribute(HTML::AttributeNames::readonly));
|
||||
if (type_state() == TypeAttributeState::Password)
|
||||
m_text_node->set_is_password_input({}, true);
|
||||
|
@ -1421,7 +1420,7 @@ void HTMLInputElement::form_associated_element_attribute_changed(FlyString const
|
|||
}
|
||||
} else if (name == HTML::AttributeNames::placeholder) {
|
||||
if (m_placeholder_text_node) {
|
||||
m_placeholder_text_node->set_data(placeholder());
|
||||
m_placeholder_text_node->set_data(Utf16String::from_utf8(placeholder()));
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
} else if (name == HTML::AttributeNames::readonly) {
|
||||
|
@ -1771,7 +1770,7 @@ void HTMLInputElement::reset_algorithm()
|
|||
relevant_value_was_changed();
|
||||
|
||||
if (m_text_node) {
|
||||
m_text_node->set_data(m_value);
|
||||
m_text_node->set_data(Utf16String::from_utf8(m_value));
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
|
@ -1807,7 +1806,7 @@ void HTMLInputElement::clear_algorithm()
|
|||
relevant_value_was_changed();
|
||||
|
||||
if (m_text_node) {
|
||||
m_text_node->set_data(m_value);
|
||||
m_text_node->set_data(Utf16String::from_utf8(m_value));
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ void HTMLTextAreaElement::set_value(String const& value)
|
|||
// the text control, unselecting any selected text and resetting the selection direction to "none".
|
||||
if (api_value() != old_api_value) {
|
||||
if (m_text_node) {
|
||||
m_text_node->set_data(m_raw_value);
|
||||
m_text_node->set_data(Utf16String::from_utf8(m_raw_value));
|
||||
update_placeholder_visibility();
|
||||
|
||||
set_the_selection_range(m_text_node->length(), m_text_node->length());
|
||||
|
@ -369,14 +369,13 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed()
|
|||
m_placeholder_element->set_use_pseudo_element(CSS::PseudoElement::Placeholder);
|
||||
MUST(element->append_child(*m_placeholder_element));
|
||||
|
||||
m_placeholder_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
m_placeholder_text_node->set_data(get_attribute_value(HTML::AttributeNames::placeholder));
|
||||
m_placeholder_text_node = realm().create<DOM::Text>(document(), Utf16String::from_utf8(get_attribute_value(HTML::AttributeNames::placeholder)));
|
||||
MUST(m_placeholder_element->append_child(*m_placeholder_text_node));
|
||||
|
||||
m_inner_text_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
||||
MUST(element->append_child(*m_inner_text_element));
|
||||
|
||||
m_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
m_text_node = realm().create<DOM::Text>(document(), Utf16String {});
|
||||
handle_readonly_attribute(attribute(HTML::AttributeNames::readonly));
|
||||
// NOTE: If `children_changed()` was called before now, `m_raw_value` will hold the text content.
|
||||
// Otherwise, it will get filled in whenever that does get called.
|
||||
|
@ -442,7 +441,7 @@ void HTMLTextAreaElement::form_associated_element_attribute_changed(FlyString co
|
|||
{
|
||||
if (name == HTML::AttributeNames::placeholder) {
|
||||
if (m_placeholder_text_node)
|
||||
m_placeholder_text_node->set_data(value.value_or(String {}));
|
||||
m_placeholder_text_node->set_data(Utf16String::from_utf8(value.value_or(String {})));
|
||||
} else if (name == HTML::AttributeNames::readonly) {
|
||||
handle_readonly_attribute(value);
|
||||
} else if (name == HTML::AttributeNames::maxlength) {
|
||||
|
@ -453,7 +452,7 @@ void HTMLTextAreaElement::form_associated_element_attribute_changed(FlyString co
|
|||
void HTMLTextAreaElement::did_edit_text_node()
|
||||
{
|
||||
VERIFY(m_text_node);
|
||||
set_raw_value(m_text_node->data());
|
||||
set_raw_value(m_text_node->data().to_utf8_but_should_be_ported_to_utf16());
|
||||
|
||||
// Any time the user causes the element's raw value to change, the user agent must queue an element task on the user
|
||||
// interaction task source given the textarea element to fire an event named input at the textarea element, with the
|
||||
|
|
|
@ -2483,11 +2483,11 @@ static String visible_text_in_range(DOM::Range const& range)
|
|||
if (range.start_container() == range.end_container() && is<DOM::Text>(*range.start_container())) {
|
||||
if (!range.start_container()->layout_node())
|
||||
return String {};
|
||||
return MUST(static_cast<DOM::Text const&>(*range.start_container()).data().substring_from_byte_offset(range.start_offset(), range.end_offset() - range.start_offset()));
|
||||
return static_cast<DOM::Text const&>(*range.start_container()).data().substring_view(range.start_offset(), range.end_offset() - range.start_offset()).to_utf8_but_should_be_ported_to_utf16();
|
||||
}
|
||||
|
||||
if (is<DOM::Text>(*range.start_container()) && range.start_container()->layout_node())
|
||||
builder.append(static_cast<DOM::Text const&>(*range.start_container()).data().bytes_as_string_view().substring_view(range.start_offset()));
|
||||
builder.append(static_cast<DOM::Text const&>(*range.start_container()).data().substring_view(range.start_offset()));
|
||||
|
||||
range.for_each_contained([&](GC::Ref<DOM::Node> node) {
|
||||
if (is<DOM::Text>(*node) && node->layout_node())
|
||||
|
@ -2496,7 +2496,7 @@ static String visible_text_in_range(DOM::Range const& range)
|
|||
});
|
||||
|
||||
if (is<DOM::Text>(*range.end_container()) && range.end_container()->layout_node())
|
||||
builder.append(static_cast<DOM::Text const&>(*range.end_container()).data().bytes_as_string_view().substring_view(0, range.end_offset()));
|
||||
builder.append(static_cast<DOM::Text const&>(*range.end_container()).data().substring_view(0, range.end_offset()));
|
||||
|
||||
return MUST(builder.to_string());
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ void HTMLParser::handle_initial(HTMLToken& token)
|
|||
// -> A comment token
|
||||
if (token.is_comment()) {
|
||||
// Insert a comment as the last child of the Document object.
|
||||
auto comment = realm().create<DOM::Comment>(document(), token.comment());
|
||||
auto comment = realm().create<DOM::Comment>(document(), Utf16String::from_utf8(token.comment()));
|
||||
MUST(document().append_child(*comment));
|
||||
return;
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ void HTMLParser::handle_before_html(HTMLToken& token)
|
|||
// -> A comment token
|
||||
if (token.is_comment()) {
|
||||
// Insert a comment as the last child of the Document object.
|
||||
auto comment = realm().create<DOM::Comment>(document(), token.comment());
|
||||
auto comment = realm().create<DOM::Comment>(document(), Utf16String::from_utf8(token.comment()));
|
||||
MUST(document().append_child(*comment));
|
||||
return;
|
||||
}
|
||||
|
@ -985,7 +985,7 @@ void HTMLParser::handle_before_head(HTMLToken& token)
|
|||
void HTMLParser::insert_comment(HTMLToken& token)
|
||||
{
|
||||
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();
|
||||
adjusted_insertion_location.parent->insert_before(realm().create<DOM::Comment>(document(), token.comment()), adjusted_insertion_location.insert_before_sibling);
|
||||
adjusted_insertion_location.parent->insert_before(realm().create<DOM::Comment>(document(), Utf16String::from_utf8(token.comment())), adjusted_insertion_location.insert_before_sibling);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inhead
|
||||
|
@ -1392,7 +1392,7 @@ DOM::Text* HTMLParser::find_character_insertion_node()
|
|||
if (adjusted_insertion_location.insert_before_sibling) {
|
||||
if (is_text_node(adjusted_insertion_location.insert_before_sibling->previous_sibling()))
|
||||
return static_cast<DOM::Text*>(adjusted_insertion_location.insert_before_sibling->previous_sibling());
|
||||
auto new_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
auto new_text_node = realm().create<DOM::Text>(document(), Utf16String {});
|
||||
adjusted_insertion_location.parent->insert_before(*new_text_node, *adjusted_insertion_location.insert_before_sibling);
|
||||
return new_text_node;
|
||||
}
|
||||
|
@ -1400,7 +1400,7 @@ DOM::Text* HTMLParser::find_character_insertion_node()
|
|||
return nullptr;
|
||||
if (is_text_node(adjusted_insertion_location.parent->last_child()))
|
||||
return static_cast<DOM::Text*>(adjusted_insertion_location.parent->last_child());
|
||||
auto new_text_node = realm().create<DOM::Text>(document(), String {});
|
||||
auto new_text_node = realm().create<DOM::Text>(document(), Utf16String {});
|
||||
MUST(adjusted_insertion_location.parent->append_child(*new_text_node));
|
||||
return new_text_node;
|
||||
}
|
||||
|
@ -1410,9 +1410,9 @@ void HTMLParser::flush_character_insertions()
|
|||
if (m_character_insertion_builder.is_empty())
|
||||
return;
|
||||
if (m_character_insertion_node->data().is_empty())
|
||||
m_character_insertion_node->set_data(MUST(m_character_insertion_builder.to_string()));
|
||||
m_character_insertion_node->set_data(m_character_insertion_builder.to_utf16_string());
|
||||
else
|
||||
(void)m_character_insertion_node->append_data(MUST(m_character_insertion_builder.to_string()));
|
||||
(void)m_character_insertion_node->append_data(m_character_insertion_builder.to_utf16_string());
|
||||
m_character_insertion_builder.clear();
|
||||
}
|
||||
|
||||
|
@ -1579,7 +1579,7 @@ void HTMLParser::handle_after_body(HTMLToken& token)
|
|||
if (token.is_comment()) {
|
||||
// Insert a comment as the last child of the first element in the stack of open elements (the html element).
|
||||
auto& insertion_location = m_stack_of_open_elements.first();
|
||||
MUST(insertion_location.append_child(realm().create<DOM::Comment>(document(), token.comment())));
|
||||
MUST(insertion_location.append_child(realm().create<DOM::Comment>(document(), Utf16String::from_utf8(token.comment()))));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1631,7 +1631,7 @@ void HTMLParser::handle_after_after_body(HTMLToken& token)
|
|||
// -> A comment token
|
||||
if (token.is_comment()) {
|
||||
// Insert a comment as the last child of the Document object.
|
||||
auto comment = realm().create<DOM::Comment>(document(), token.comment());
|
||||
auto comment = realm().create<DOM::Comment>(document(), Utf16String::from_utf8(token.comment()));
|
||||
MUST(document().append_child(*comment));
|
||||
return;
|
||||
}
|
||||
|
@ -4626,7 +4626,7 @@ void HTMLParser::handle_after_after_frameset(HTMLToken& token)
|
|||
// -> A comment token
|
||||
if (token.is_comment()) {
|
||||
// Insert a comment as the last child of the Document object.
|
||||
auto comment = document().realm().create<DOM::Comment>(document(), token.comment());
|
||||
auto comment = document().realm().create<DOM::Comment>(document(), Utf16String::from_utf8(token.comment()));
|
||||
MUST(document().append_child(comment));
|
||||
return;
|
||||
}
|
||||
|
@ -5123,11 +5123,12 @@ enum class AttributeMode {
|
|||
Yes,
|
||||
};
|
||||
|
||||
static String escape_string(StringView string, AttributeMode attribute_mode)
|
||||
template<OneOf<Utf8View, Utf16View> ViewType>
|
||||
static String escape_string(ViewType const& string, AttributeMode attribute_mode)
|
||||
{
|
||||
// https://html.spec.whatwg.org/multipage/parsing.html#escapingString
|
||||
StringBuilder builder;
|
||||
for (auto code_point : Utf8View { string }) {
|
||||
for (auto code_point : string) {
|
||||
// 1. Replace any occurrence of the "&" character by the string "&".
|
||||
if (code_point == '&')
|
||||
builder.append("&"sv);
|
||||
|
@ -5179,7 +5180,7 @@ String HTMLParser::serialize_html_fragment(DOM::Node const& node, SerializableSh
|
|||
// followed by a U+0022 QUOTATION MARK character (").
|
||||
if (element.is_value().has_value() && !element.has_attribute(AttributeNames::is)) {
|
||||
builder.append(" is=\""sv);
|
||||
builder.append(escape_string(element.is_value().value(), AttributeMode::Yes));
|
||||
builder.append(escape_string(element.is_value().value().code_points(), AttributeMode::Yes));
|
||||
builder.append('"');
|
||||
}
|
||||
|
||||
|
@ -5212,7 +5213,7 @@ String HTMLParser::serialize_html_fragment(DOM::Node const& node, SerializableSh
|
|||
builder.append(attribute.name());
|
||||
|
||||
builder.append("=\""sv);
|
||||
builder.append(escape_string(attribute.value(), AttributeMode::Yes));
|
||||
builder.append(escape_string(attribute.value().code_points(), AttributeMode::Yes));
|
||||
builder.append('"');
|
||||
});
|
||||
|
||||
|
@ -5335,7 +5336,7 @@ String HTMLParser::serialize_html_fragment(DOM::Node const& node, SerializableSh
|
|||
}
|
||||
|
||||
// Otherwise, append the value of current node's data IDL attribute, escaped as described below.
|
||||
builder.append(escape_string(text_node.data(), AttributeMode::No));
|
||||
builder.append(escape_string(text_node.data().utf16_view(), AttributeMode::No));
|
||||
}
|
||||
|
||||
if (is<DOM::Comment>(current_node)) {
|
||||
|
|
|
@ -228,7 +228,7 @@ private:
|
|||
Vector<HTMLToken> m_pending_table_character_tokens;
|
||||
|
||||
GC::Ptr<DOM::Text> m_character_insertion_node;
|
||||
StringBuilder m_character_insertion_builder;
|
||||
StringBuilder m_character_insertion_builder { StringBuilder::Mode::UTF16 };
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
|
||||
RefPtr<CSS::CSSStyleValue const> parse_dimension_value(StringView);
|
||||
|
|
|
@ -754,7 +754,7 @@ static WebIDL::ExceptionOr<String> serialize_comment(DOM::Comment const& comment
|
|||
if (comment.data().contains("--"sv))
|
||||
return WebIDL::InvalidStateError::create(comment.realm(), "Comment data contains two adjacent hyphens"_string);
|
||||
|
||||
if (comment.data().ends_with('-'))
|
||||
if (comment.data().ends_with("-"sv))
|
||||
return WebIDL::InvalidStateError::create(comment.realm(), "Comment data ends with a hyphen"_string);
|
||||
}
|
||||
|
||||
|
@ -776,7 +776,7 @@ static WebIDL::ExceptionOr<String> serialize_text(DOM::Text const& text, Require
|
|||
// 1. If the require well-formed flag is set (its value is true), and node's data contains characters that are not matched by the XML Char production,
|
||||
// then throw an exception; the serialization of this node's data would not be well-formed.
|
||||
if (require_well_formed == RequireWellFormed::Yes) {
|
||||
for (u32 code_point : text.data().code_points()) {
|
||||
for (u32 code_point : text.data()) {
|
||||
if (!is_valid_xml_char(code_point))
|
||||
return WebIDL::InvalidStateError::create(text.realm(), "Text contains characters not allowed in XML"_string);
|
||||
}
|
||||
|
@ -786,16 +786,16 @@ static WebIDL::ExceptionOr<String> serialize_text(DOM::Text const& text, Require
|
|||
auto markup = text.data();
|
||||
|
||||
// 3. Replace any occurrences of "&" in markup by "&".
|
||||
markup = MUST(markup.replace("&"sv, "&"sv, ReplaceMode::All));
|
||||
markup = markup.replace("&"sv, "&"sv, ReplaceMode::All);
|
||||
|
||||
// 4. Replace any occurrences of "<" in markup by "<".
|
||||
markup = MUST(markup.replace("<"sv, "<"sv, ReplaceMode::All));
|
||||
markup = markup.replace("<"sv, "<"sv, ReplaceMode::All);
|
||||
|
||||
// 5. Replace any occurrences of ">" in markup by ">".
|
||||
markup = MUST(markup.replace(">"sv, ">"sv, ReplaceMode::All));
|
||||
markup = markup.replace(">"sv, ">"sv, ReplaceMode::All);
|
||||
|
||||
// 6. Return the value of markup.
|
||||
return markup;
|
||||
return markup.to_utf8_but_should_be_ported_to_utf16();
|
||||
}
|
||||
|
||||
// https://w3c.github.io/DOM-Parsing/#xml-serializing-a-documentfragment-node
|
||||
|
|
|
@ -1756,7 +1756,7 @@ bool FormattingContext::can_skip_is_anonymous_text_run(Box& box)
|
|||
if (box.is_anonymous() && !box.is_generated() && !box.first_child_of_type<BlockContainer>()) {
|
||||
bool contains_only_white_space = true;
|
||||
box.for_each_in_subtree([&](auto const& node) {
|
||||
if (!is<TextNode>(node) || !static_cast<TextNode const&>(node).dom_node().data().bytes_as_string_view().is_whitespace()) {
|
||||
if (!is<TextNode>(node) || !static_cast<TextNode const&>(node).dom_node().data().is_ascii_whitespace()) {
|
||||
contains_only_white_space = false;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
|
|
|
@ -322,7 +322,7 @@ String const& TextNode::text_for_rendering() const
|
|||
void TextNode::compute_text_for_rendering()
|
||||
{
|
||||
if (dom_node().is_password_input()) {
|
||||
m_text_for_rendering = MUST(String::repeated('*', dom_node().data().code_points().length()));
|
||||
m_text_for_rendering = MUST(String::repeated('*', dom_node().data().length_in_code_points()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -332,7 +332,7 @@ void TextNode::compute_text_for_rendering()
|
|||
auto const maybe_lang = parent_element ? parent_element->lang() : Optional<String> {};
|
||||
auto const lang = maybe_lang.has_value() ? maybe_lang.value() : Optional<StringView> {};
|
||||
|
||||
auto data = apply_text_transform(dom_node().data(), computed_values().text_transform(), lang).release_value_but_fixme_should_propagate_errors();
|
||||
auto data = apply_text_transform(dom_node().data().to_utf8_but_should_be_ported_to_utf16(), computed_values().text_transform(), lang).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
auto data_view = data.bytes_as_string_view();
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ void TreeBuilder::create_pseudo_element_if_needed(DOM::Element& element, CSS::Ps
|
|||
|
||||
// FIXME: Handle images, and multiple values
|
||||
if (new_content.type == CSS::ContentData::Type::String) {
|
||||
auto text = document.realm().create<DOM::Text>(document, new_content.data);
|
||||
auto text = document.realm().create<DOM::Text>(document, Utf16String::from_utf8(new_content.data));
|
||||
auto text_node = document.heap().allocate<TextNode>(document, *text);
|
||||
text_node->set_generated_for(pseudo_element, element);
|
||||
|
||||
|
|
|
@ -599,12 +599,12 @@ void Selection::move_offset_to_next_word(bool collapse_selection)
|
|||
auto& text_node = static_cast<DOM::Text&>(*anchor_node);
|
||||
while (true) {
|
||||
auto focus_offset = this->focus_offset();
|
||||
if (focus_offset == text_node.data().bytes_as_string_view().length()) {
|
||||
if (focus_offset == text_node.data().length_in_code_units()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto offset = text_node.word_segmenter().next_boundary(focus_offset); offset.has_value()) {
|
||||
auto word = text_node.data().code_points().substring_view(focus_offset, *offset - focus_offset);
|
||||
auto word = text_node.data().substring_view(focus_offset, *offset - focus_offset);
|
||||
if (collapse_selection) {
|
||||
MUST(collapse(anchor_node, *offset));
|
||||
m_document->reset_cursor_blink_cycle();
|
||||
|
@ -629,7 +629,7 @@ void Selection::move_offset_to_previous_word(bool collapse_selection)
|
|||
while (true) {
|
||||
auto focus_offset = this->focus_offset();
|
||||
if (auto offset = text_node.word_segmenter().previous_boundary(focus_offset); offset.has_value()) {
|
||||
auto word = text_node.data().code_points().unicode_substring_view(*offset, focus_offset - *offset);
|
||||
auto word = text_node.data().substring_view(*offset, focus_offset - *offset);
|
||||
if (collapse_selection) {
|
||||
MUST(collapse(anchor_node, *offset));
|
||||
m_document->reset_cursor_blink_cycle();
|
||||
|
|
|
@ -234,6 +234,11 @@ JS::ThrowCompletionOr<String> to_string(JS::VM& vm, JS::Value value)
|
|||
return value.to_string(vm);
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<Utf16String> to_utf16_string(JS::VM& vm, JS::Value value)
|
||||
{
|
||||
return value.to_utf16_string(vm);
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<String> to_usv_string(JS::VM& vm, JS::Value value)
|
||||
{
|
||||
return value.to_well_formed_string(vm);
|
||||
|
|
|
@ -23,6 +23,7 @@ ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source);
|
|||
JS::Completion call_user_object_operation(CallbackType& callback, String const& operation_name, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args);
|
||||
|
||||
JS::ThrowCompletionOr<String> to_string(JS::VM&, JS::Value);
|
||||
JS::ThrowCompletionOr<Utf16String> to_utf16_string(JS::VM&, JS::Value);
|
||||
JS::ThrowCompletionOr<String> to_usv_string(JS::VM&, JS::Value);
|
||||
JS::ThrowCompletionOr<String> to_byte_string(JS::VM&, JS::Value);
|
||||
|
||||
|
|
|
@ -245,18 +245,16 @@ void XMLDocumentBuilder::text(StringView data)
|
|||
{
|
||||
if (m_has_error)
|
||||
return;
|
||||
auto last = m_current_node->last_child();
|
||||
if (last && last->is_text()) {
|
||||
|
||||
if (auto* last = m_current_node->last_child(); last && last->is_text()) {
|
||||
auto& text_node = static_cast<DOM::Text&>(*last);
|
||||
text_builder.append(text_node.data());
|
||||
text_builder.append(data);
|
||||
text_node.set_data(MUST(text_builder.to_string()));
|
||||
text_builder.clear();
|
||||
} else {
|
||||
if (!data.is_empty()) {
|
||||
auto node = m_document->create_text_node(MUST(String::from_utf8(data)));
|
||||
MUST(m_current_node->append_child(node));
|
||||
}
|
||||
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.clear();
|
||||
} else if (!data.is_empty()) {
|
||||
auto node = m_document->create_text_node(Utf16String::from_utf8(data));
|
||||
MUST(m_current_node->append_child(node));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,7 +263,7 @@ void XMLDocumentBuilder::comment(StringView data)
|
|||
if (m_has_error || !m_current_node)
|
||||
return;
|
||||
|
||||
MUST(m_current_node->append_child(m_document->create_comment(MUST(String::from_utf8(data)))));
|
||||
MUST(m_current_node->append_child(m_document->create_comment(Utf16String::from_utf8(data))));
|
||||
}
|
||||
|
||||
void XMLDocumentBuilder::cdata_section(StringView data)
|
||||
|
@ -273,7 +271,7 @@ void XMLDocumentBuilder::cdata_section(StringView data)
|
|||
if (m_has_error || !m_current_node)
|
||||
return;
|
||||
|
||||
auto section = MUST(m_document->create_cdata_section(MUST(String::from_utf8(data))));
|
||||
auto section = MUST(m_document->create_cdata_section(Utf16String::from_utf8(data)));
|
||||
MUST(m_current_node->append_child(section));
|
||||
}
|
||||
|
||||
|
@ -282,7 +280,7 @@ void XMLDocumentBuilder::processing_instruction(StringView target, StringView da
|
|||
if (m_has_error || !m_current_node)
|
||||
return;
|
||||
|
||||
auto processing_instruction = MUST(m_document->create_processing_instruction(MUST(String::from_utf8(target)), MUST(String::from_utf8(data))));
|
||||
auto processing_instruction = MUST(m_document->create_processing_instruction(MUST(String::from_utf8(target)), Utf16String::from_utf8(data)));
|
||||
MUST(m_current_node->append_child(processing_instruction));
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ private:
|
|||
GC::Ptr<DOM::Node> m_current_node;
|
||||
XMLScriptingSupport m_scripting_support { XMLScriptingSupport::Enabled };
|
||||
bool m_has_error { false };
|
||||
StringBuilder text_builder;
|
||||
StringBuilder m_text_builder { StringBuilder::Mode::UTF16 };
|
||||
|
||||
struct NamespaceAndPrefix {
|
||||
FlyString ns;
|
||||
|
|
|
@ -650,7 +650,7 @@ void ConnectionFromClient::get_dom_node_inner_html(u64 page_id, Web::UniqueNodeI
|
|||
html = element.inner_html().release_value_but_fixme_should_propagate_errors();
|
||||
} else if (dom_node->is_text() || dom_node->is_comment()) {
|
||||
auto const& character_data = static_cast<Web::DOM::CharacterData const&>(*dom_node);
|
||||
html = character_data.data();
|
||||
html = character_data.data().to_utf8_but_should_be_ported_to_utf16();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -671,7 +671,7 @@ void ConnectionFromClient::get_dom_node_outer_html(u64 page_id, Web::UniqueNodeI
|
|||
html = element.outer_html().release_value_but_fixme_should_propagate_errors();
|
||||
} else if (dom_node->is_text() || dom_node->is_comment()) {
|
||||
auto const& character_data = static_cast<Web::DOM::CharacterData const&>(*dom_node);
|
||||
html = character_data.data();
|
||||
html = character_data.data().to_utf8_but_should_be_ported_to_utf16();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ void ConnectionFromClient::set_dom_node_outer_html(u64 page_id, Web::UniqueNodeI
|
|||
element.set_outer_html(html).release_value_but_fixme_should_propagate_errors();
|
||||
} else if (dom_node->is_text() || dom_node->is_comment()) {
|
||||
auto& character_data = static_cast<Web::DOM::CharacterData&>(*dom_node);
|
||||
character_data.set_data(html);
|
||||
character_data.set_data(Utf16String::from_utf8(html));
|
||||
} else {
|
||||
async_did_finish_editing_dom_node(page_id, {});
|
||||
return;
|
||||
|
@ -710,7 +710,7 @@ void ConnectionFromClient::set_dom_node_text(u64 page_id, Web::UniqueNodeID node
|
|||
}
|
||||
|
||||
auto& character_data = static_cast<Web::DOM::CharacterData&>(*dom_node);
|
||||
character_data.set_data(text);
|
||||
character_data.set_data(Utf16String::from_utf8(text));
|
||||
|
||||
async_did_finish_editing_dom_node(page_id, character_data.unique_id());
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ void ConnectionFromClient::create_child_text_node(u64 page_id, Web::UniqueNodeID
|
|||
return;
|
||||
}
|
||||
|
||||
auto text_node = dom_node->realm().create<Web::DOM::Text>(dom_node->document(), "text"_string);
|
||||
auto text_node = dom_node->realm().create<Web::DOM::Text>(dom_node->document(), "text"_utf16);
|
||||
dom_node->append_child(text_node).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
async_did_finish_editing_dom_node(page_id, text_node->unique_id());
|
||||
|
|
|
@ -667,7 +667,7 @@ void PageClient::page_did_mutate_dom(FlyString const& type, Web::DOM::Node const
|
|||
mutation = WebView::AttributeMutation { *attribute_name, element.attribute(*attribute_name) };
|
||||
} else if (type == Web::DOM::MutationType::characterData) {
|
||||
auto const& character_data = as<Web::DOM::CharacterData>(target);
|
||||
mutation = WebView::CharacterDataMutation { character_data.data() };
|
||||
mutation = WebView::CharacterDataMutation { character_data.data().to_utf8_but_should_be_ported_to_utf16() };
|
||||
} else if (type == Web::DOM::MutationType::childList) {
|
||||
Vector<Web::UniqueNodeID> added;
|
||||
added.ensure_capacity(added_nodes.length());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue