diff --git a/Tests/LibWeb/Text/expected/HTML/set-innerText.txt b/Tests/LibWeb/Text/expected/HTML/set-innerText.txt
new file mode 100644
index 00000000000..f350d150a30
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/HTML/set-innerText.txt
@@ -0,0 +1,3 @@
+Empty string: ""
+Simple text: "foo"
+Text with newlines: "
foo
bar
baz
foobar
"
diff --git a/Tests/LibWeb/Text/input/HTML/set-innerText.html b/Tests/LibWeb/Text/input/HTML/set-innerText.html
new file mode 100644
index 00000000000..a8b568fb228
--- /dev/null
+++ b/Tests/LibWeb/Text/input/HTML/set-innerText.html
@@ -0,0 +1,12 @@
+
+
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp
index 803796a0a49..1e4dd593e0b 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.cpp
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -32,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -150,10 +152,13 @@ WebIDL::ExceptionOr HTMLElement::set_content_editable(StringView content_e
return WebIDL::SyntaxError::create(realm(), "Invalid contentEditable value, must be 'true', 'false', or 'inherit'"_string);
}
+// https://html.spec.whatwg.org/multipage/dom.html#set-the-inner-text-steps
void HTMLElement::set_inner_text(StringView text)
{
+ // 1. Let fragment be the rendered text fragment for value given element's node document.
+ // 2. Replace all with fragment within element.
remove_all_children();
- MUST(append_child(document().create_text_node(MUST(String::from_utf8(text)))));
+ append_rendered_text_fragment(text);
set_needs_style_update(true);
}
@@ -165,6 +170,45 @@ WebIDL::ExceptionOr HTMLElement::set_outer_text(String)
return {};
}
+// https://html.spec.whatwg.org/multipage/dom.html#rendered-text-fragment
+void HTMLElement::append_rendered_text_fragment(StringView input)
+{
+ // FIXME: 1. Let fragment be a new DocumentFragment whose node document is document.
+ // Instead of creating a DocumentFragment the nodes are appended directly.
+
+ // 2. Let position be a position variable for input, initially pointing at the start of input.
+ // 3. Let text be the empty string.
+ // 4. While position is not past the end of input:
+ while (!input.is_empty()) {
+ // 1. Collect a sequence of code points that are not U+000A LF or U+000D CR from input given position, and set text to the result.
+ auto newline_index = input.find_any_of("\n\r"sv);
+ size_t const sequence_end_index = newline_index.value_or(input.length());
+ StringView const text = input.substring_view(0, sequence_end_index);
+ input = input.substring_view_starting_after_substring(text);
+
+ // 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(append_child(document().create_text_node(MUST(String::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:
+ while (input.starts_with('\n') || input.starts_with('\r')) {
+ // 1. If the code point at position is U+000D CR and the next code point is U+000A LF, then advance position to the next code point in input.
+ if (input.starts_with("\r\n"sv)) {
+ // 2. Advance position to the next code point in input.
+ input = input.substring_view(2);
+ } else {
+ // 2. Advance position to the next code point in input.
+ input = input.substring_view(1);
+ }
+
+ // 3. Append the result of creating an element given document, br, and the HTML namespace to fragment.
+ auto br_element = DOM::create_element(document(), HTML::TagNames::br, Namespace::HTML).release_value();
+ MUST(append_child(br_element));
+ }
+ }
+}
+
// https://html.spec.whatwg.org/multipage/dom.html#get-the-text-steps
String HTMLElement::get_the_text_steps()
{
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.h b/Userland/Libraries/LibWeb/HTML/HTMLElement.h
index f1a305b2de6..ea511b4d115 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.h
@@ -97,6 +97,7 @@ private:
virtual void did_receive_focus() override;
[[nodiscard]] String get_the_text_steps();
+ void append_rendered_text_fragment(StringView input);
JS::GCPtr m_dataset;