summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-08-17 22:06:08 -0400
committerAndreas Kling <kling@serenityos.org>2020-08-18 16:58:46 +0200
commit2460980d2c4cda800d50e8e323f0e510c943a022 (patch)
tree3c197a4ab6b80273cd2e8236ed74972a0e782674 /Libraries
parent2f85af2a20bdc3d994256078fafbf58162ec8d36 (diff)
downloadserenity-2460980d2c4cda800d50e8e323f0e510c943a022.zip
LibWeb: Implement Element.innerText
Reading the property has a few warts (see FIXMEs in the included tests), but with this the timestamps on http://45.33.8.238/ get localized :^) Since the Date() constructor currently ignores all arguments, they don't get localized correctly but are all set to the current time, but hey, it's still progress from a certain point of view.
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibWeb/DOM/Element.cpp34
-rw-r--r--Libraries/LibWeb/DOM/Element.h3
-rw-r--r--Libraries/LibWeb/DOM/Element.idl1
-rw-r--r--Libraries/LibWeb/Tests/DOM/Element.js24
-rw-r--r--Libraries/LibWeb/Tests/DOM/Node.js10
5 files changed, 71 insertions, 1 deletions
diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp
index 19cc1733ad..b5445ab593 100644
--- a/Libraries/LibWeb/DOM/Element.cpp
+++ b/Libraries/LibWeb/DOM/Element.cpp
@@ -41,6 +41,7 @@
#include <LibWeb/Layout/LayoutTableCell.h>
#include <LibWeb/Layout/LayoutTableRow.h>
#include <LibWeb/Layout/LayoutTableRowGroup.h>
+#include <LibWeb/Layout/LayoutText.h>
#include <LibWeb/Layout/LayoutTreeBuilder.h>
namespace Web::DOM {
@@ -295,6 +296,39 @@ String Element::inner_html() const
return builder.to_string();
}
+void Element::set_inner_text(StringView text)
+{
+ remove_all_children();
+ append_child(document().create_text_node(text));
+
+ set_needs_style_update(true);
+ document().schedule_style_update();
+ document().invalidate_layout();
+}
+
+String Element::inner_text()
+{
+ StringBuilder builder;
+
+ // innerText for element being rendered takes visibility into account, so force a layout and then walk the layout tree.
+ document().layout();
+ if (!layout_node())
+ return text_content();
+
+ Function<void(const LayoutNode&)> recurse = [&](auto& node) {
+ for (auto* child = node.first_child(); child; child = child->next_sibling()) {
+ if (child->is_text())
+ builder.append(downcast<LayoutText>(*child).text_for_rendering());
+ if (child->is_break())
+ builder.append('\n');
+ recurse(*child);
+ }
+ };
+ recurse(*layout_node());
+
+ return builder.to_string();
+}
+
bool Element::is_focused() const
{
return document().focused_element() == this;
diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h
index b08ff34e42..253f532aff 100644
--- a/Libraries/LibWeb/DOM/Element.h
+++ b/Libraries/LibWeb/DOM/Element.h
@@ -87,6 +87,9 @@ public:
String inner_html() const;
void set_inner_html(StringView);
+ String inner_text();
+ void set_inner_text(StringView);
+
bool is_focused() const;
virtual bool is_focusable() const { return false; }
diff --git a/Libraries/LibWeb/DOM/Element.idl b/Libraries/LibWeb/DOM/Element.idl
index 082d0a951a..34baef070e 100644
--- a/Libraries/LibWeb/DOM/Element.idl
+++ b/Libraries/LibWeb/DOM/Element.idl
@@ -9,6 +9,7 @@ interface Element : Node {
ArrayFromVector querySelectorAll(DOMString selectors);
attribute DOMString innerHTML;
+ attribute DOMString innerText;
[Reflect] attribute DOMString id;
[Reflect=class] attribute DOMString className;
diff --git a/Libraries/LibWeb/Tests/DOM/Element.js b/Libraries/LibWeb/Tests/DOM/Element.js
new file mode 100644
index 0000000000..0fd40594cc
--- /dev/null
+++ b/Libraries/LibWeb/Tests/DOM/Element.js
@@ -0,0 +1,24 @@
+loadPage("file:///res/html/misc/innertext_textcontent.html");
+
+afterInitialPageLoad(() => {
+ test("Element.innerText", () => {
+ var p = document.getElementsByTagName("p")[0];
+ expect(p.innerText).toBe("This is a very small test page :^)");
+
+ // FIXME: Call this on p once that's supported.
+ var b = document.getElementsByTagName("b")[0];
+ b.innerText = "foo";
+ expect(b.innerText).toBe("foo");
+ expect(p.innerText).toBe("This is a foo test page :^)");
+
+ p.innerText = "bar";
+ expect(p.innerText).toBe("bar");
+
+ var p = document.getElementById("source");
+ // FIXME: The leading and trailing two spaces each are wrong.
+ // FIXME: The text should be affected by the text-transform:uppercase.
+ expect(p.innerText).toBe(` Take a look at
+how this text
+is interpreted below. `);
+ });
+});
diff --git a/Libraries/LibWeb/Tests/DOM/Node.js b/Libraries/LibWeb/Tests/DOM/Node.js
index 2af91d1cbb..5427d143bd 100644
--- a/Libraries/LibWeb/Tests/DOM/Node.js
+++ b/Libraries/LibWeb/Tests/DOM/Node.js
@@ -1,4 +1,4 @@
-loadPage("file:///res/html/misc/small.html");
+loadPage("file:///res/html/misc/innertext_textcontent.html");
afterInitialPageLoad(() => {
test("Node.textContent", () => {
@@ -16,5 +16,13 @@ afterInitialPageLoad(() => {
expect(p.textContent).toBe("bar");
expect(p.firstChild.textContent).toBe("bar");
expect(p.firstChild.firstChild).toBe(null);
+
+ var p = document.getElementById("source");
+ expect(p.textContent).toBe(`
+ #source { color: red; } #text { text-transform: uppercase; }
+ Take a look athow this textis interpreted
+ below.
+ HIDDEN TEXT
+ `);
});
});