diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp
index 9800437210c..a172759bbfe 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.cpp
+++ b/Libraries/LibWeb/HTML/HTMLElement.cpp
@@ -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 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(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(*next).data()));
+
+ // 4. Remove next.
+ next->remove();
+}
+
+// https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute:dom-outertext-2
+WebIDL::ExceptionOr 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(next->previous_sibling()))
+ merge_with_the_next_text_node(static_cast(*next->previous_sibling()));
+
+ // 8. If previous is a Text node, then merge with the next text node given previous.
+ if (is(previous))
+ merge_with_the_next_text_node(static_cast(*previous));
+
+ set_needs_style_update(true);
return {};
}
diff --git a/Libraries/LibWeb/HTML/HTMLElement.h b/Libraries/LibWeb/HTML/HTMLElement.h
index feb47862570..6e29a48b105 100644
--- a/Libraries/LibWeb/HTML/HTMLElement.h
+++ b/Libraries/LibWeb/HTML/HTMLElement.h
@@ -45,7 +45,7 @@ public:
void set_inner_text(StringView);
[[nodiscard]] String outer_text();
- WebIDL::ExceptionOr set_outer_text(String);
+ WebIDL::ExceptionOr set_outer_text(String const&);
int offset_top() const;
int offset_left() const;
diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.txt b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.txt
index 8b63fe2ff8a..ced1f9f078b 100644
--- a/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.txt
+++ b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.txt
@@ -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 s with no text nodes
-Fail Removing a node
-Fail Detached node
-Fail Simplest possible test
-Fail Newlines convert to in non-white-space:pre elements
-Fail Newlines convert to in