LibWeb: Implement HTMLElement.innerText setter

This commit is contained in:
Shannon Booth 2024-11-11 05:33:44 +13:00 committed by Alexander Kalenik
parent a1a740bb3e
commit 653c8f231d
Notes: github-actions[bot] 2024-11-10 20:32:20 +00:00
3 changed files with 91 additions and 47 deletions

View file

@ -153,10 +153,55 @@ void HTMLElement::set_inner_text(StringView text)
set_needs_style_update(true);
}
// https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute:dom-outertext-2
WebIDL::ExceptionOr<void> HTMLElement::set_outer_text(String)
// https://html.spec.whatwg.org/multipage/dom.html#merge-with-the-next-text-node
static void merge_with_the_next_text_node(DOM::Text& node)
{
dbgln("FIXME: Implement HTMLElement::set_outer_text()");
// 1. Let next be node's next sibling.
auto next = node.next_sibling();
// 2. If next is not a Text node, then return.
if (!is<DOM::Text>(next))
return;
// 3. Replace data with node, node's data's length, 0, and next's data.
MUST(node.replace_data(node.length_in_utf16_code_units(), 0, static_cast<DOM::Text const&>(*next).data()));
// 4. Remove next.
next->remove();
}
// https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute:dom-outertext-2
WebIDL::ExceptionOr<void> HTMLElement::set_outer_text(String const& value)
{
// 1. If this's parent is null, then throw a "NoModificationAllowedError" DOMException.
if (!parent())
return WebIDL::NoModificationAllowedError::create(realm(), "setOuterText: parent is null"_string);
// 2. Let next be this's next sibling.
auto* next = next_sibling();
// 3. Let previous be this's previous sibling.
auto* previous = previous_sibling();
// 4. Let fragment be the rendered text fragment for the given value given this's node document.
auto fragment = rendered_text_fragment(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 {})));
// 6. Replace this with fragment within this's parent.
MUST(parent()->replace_child(fragment, *this));
// 7. If next is non-null and next's previous sibling is a Text node, then merge with the next text node given next's previous sibling.
if (next && is<DOM::Text>(next->previous_sibling()))
merge_with_the_next_text_node(static_cast<DOM::Text&>(*next->previous_sibling()));
// 8. If previous is a Text node, then merge with the next text node given previous.
if (is<DOM::Text>(previous))
merge_with_the_next_text_node(static_cast<DOM::Text&>(*previous));
set_needs_style_update(true);
return {};
}

View file

@ -45,7 +45,7 @@ public:
void set_inner_text(StringView);
[[nodiscard]] String outer_text();
WebIDL::ExceptionOr<void> set_outer_text(String);
WebIDL::ExceptionOr<void> set_outer_text(String const&);
int offset_top() const;
int offset_left() const;

View file

@ -6,49 +6,48 @@ Rerun
Found 43 tests
2 Pass
41 Fail
43 Pass
Details
Result Test Name MessageFail Replacing a node and merging with the previous text node
Fail Replacing a node and merging with the following text node
Fail Replacing a node and merging with the previous and following text node
Fail Only merges with the previous and following text nodes, does not completely normalize
Fail Empty string
Fail Empty string with surrounding text nodes
Fail Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes
Fail Removing a node
Fail Detached node
Fail Simplest possible test
Fail Newlines convert to <br> in non-white-space:pre elements
Fail Newlines convert to <br> in <pre> element
Fail Newlines convert to <br> in <textarea> element
Fail Newlines convert to <br> in white-space:pre element
Fail CRs convert to <br> in non-white-space:pre elements
Fail CRs convert to <br> in <pre> element
Fail Newline/CR pair converts to <br> in non-white-space:pre element
Fail Newline/newline pair converts to two <br>s in non-white-space:pre element
Fail CR/CR pair converts to two <br>s in non-white-space:pre element
Fail CRs convert to <br> in white-space:pre element
Fail < preserved
Fail > preserved
Fail & preserved
Fail " preserved
Fail ' preserved
Result Test Name MessagePass Replacing a node and merging with the previous text node
Pass Replacing a node and merging with the following text node
Pass Replacing a node and merging with the previous and following text node
Pass Only merges with the previous and following text nodes, does not completely normalize
Pass Empty string
Pass Empty string with surrounding text nodes
Pass Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes
Pass Removing a node
Pass Detached node
Pass Simplest possible test
Pass Newlines convert to <br> in non-white-space:pre elements
Pass Newlines convert to <br> in <pre> element
Pass Newlines convert to <br> in <textarea> element
Pass Newlines convert to <br> in white-space:pre element
Pass CRs convert to <br> in non-white-space:pre elements
Pass CRs convert to <br> in <pre> element
Pass Newline/CR pair converts to <br> in non-white-space:pre element
Pass Newline/newline pair converts to two <br>s in non-white-space:pre element
Pass CR/CR pair converts to two <br>s in non-white-space:pre element
Pass CRs convert to <br> in white-space:pre element
Pass < preserved
Pass > preserved
Pass & preserved
Pass " preserved
Pass ' preserved
Pass outerText not supported on SVG elements
Pass outerText not supported on MathML elements
Fail Null characters preserved
Fail Tabs preserved
Fail Leading whitespace preserved
Fail Trailing whitespace preserved
Fail Whitespace not compressed
Fail Existing text deleted
Fail Existing <br> deleted
Fail Assigning the empty string
Fail Assigning null
Fail Assigning undefined
Fail Start with CR
Fail Start with LF
Fail Start with CRLF
Fail End with CR
Fail End with LF
Fail End with CRLF
Pass Null characters preserved
Pass Tabs preserved
Pass Leading whitespace preserved
Pass Trailing whitespace preserved
Pass Whitespace not compressed
Pass Existing text deleted
Pass Existing <br> deleted
Pass Assigning the empty string
Pass Assigning null
Pass Assigning undefined
Pass Start with CR
Pass Start with LF
Pass Start with CRLF
Pass End with CR
Pass End with LF
Pass End with CRLF