diff --git a/Base/home/anon/www/innerHTML.html b/Base/home/anon/www/innerHTML.html
new file mode 100644
index 0000000000..9bd382d497
--- /dev/null
+++ b/Base/home/anon/www/innerHTML.html
@@ -0,0 +1,17 @@
+
+
+
+
+
+Click me
+This has some HTML inside it!
+
+
+
diff --git a/Base/home/anon/www/welcome.html b/Base/home/anon/www/welcome.html
index 719d910ff4..af8dd8381d 100644
--- a/Base/home/anon/www/welcome.html
+++ b/Base/home/anon/www/welcome.html
@@ -23,6 +23,7 @@ h1 {
This is a very simple browser built on the LibWeb engine.
Some small test pages:
+ - innerHTML property test
- position: absolute; for top and left
- fun demo
- requestAnimationFrame test
diff --git a/Libraries/LibWeb/Bindings/ElementWrapper.cpp b/Libraries/LibWeb/Bindings/ElementWrapper.cpp
new file mode 100644
index 0000000000..d392853973
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/ElementWrapper.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2020, Andreas Kling
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Web {
+namespace Bindings {
+
+ElementWrapper::ElementWrapper(Element& element)
+ : NodeWrapper(element)
+{
+ put_native_property(
+ "innerHTML",
+ [this](JS::Object*) {
+ return JS::js_string(heap(), node().inner_html());
+ },
+ [this](JS::Object*, JS::Value value) {
+ node().set_inner_html(value.to_string());
+ });
+}
+
+ElementWrapper::~ElementWrapper()
+{
+}
+
+Element& ElementWrapper::node()
+{
+ return static_cast(NodeWrapper::node());
+}
+
+const Element& ElementWrapper::node() const
+{
+ return static_cast(NodeWrapper::node());
+}
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/ElementWrapper.h b/Libraries/LibWeb/Bindings/ElementWrapper.h
new file mode 100644
index 0000000000..d91c94ccf0
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/ElementWrapper.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2020, Andreas Kling
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include
+
+namespace Web {
+namespace Bindings {
+
+class ElementWrapper : public NodeWrapper {
+public:
+ explicit ElementWrapper(Element&);
+ virtual ~ElementWrapper() override;
+
+ Element& node();
+ const Element& node() const;
+
+private:
+ virtual const char* class_name() const override { return "ElementWrapper"; }
+};
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp
index 9c3895b0f0..99b8f9df10 100644
--- a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp
+++ b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp
@@ -37,7 +37,7 @@ namespace Web {
namespace Bindings {
HTMLCanvasElementWrapper::HTMLCanvasElementWrapper(HTMLCanvasElement& element)
- : NodeWrapper(element)
+ : ElementWrapper(element)
{
put_native_function("getContext", [this](JS::Object*, const Vector& arguments) -> JS::Value {
if (arguments.size() >= 1) {
diff --git a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h
index ae46fa8914..d82342c668 100644
--- a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h
+++ b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.h
@@ -26,12 +26,12 @@
#pragma once
-#include
+#include
namespace Web {
namespace Bindings {
-class HTMLCanvasElementWrapper : public NodeWrapper {
+class HTMLCanvasElementWrapper : public ElementWrapper {
public:
explicit HTMLCanvasElementWrapper(HTMLCanvasElement&);
virtual ~HTMLCanvasElementWrapper() override;
diff --git a/Libraries/LibWeb/Bindings/NodeWrapper.cpp b/Libraries/LibWeb/Bindings/NodeWrapper.cpp
index badf650cc0..289a5c69f2 100644
--- a/Libraries/LibWeb/Bindings/NodeWrapper.cpp
+++ b/Libraries/LibWeb/Bindings/NodeWrapper.cpp
@@ -43,6 +43,8 @@ NodeWrapper* wrap(JS::Heap& heap, Node& node)
return static_cast(wrap_impl(heap, to(node)));
if (is(node))
return static_cast(wrap_impl(heap, to(node)));
+ if (is(node))
+ return static_cast(wrap_impl(heap, to(node)));
return static_cast(wrap_impl(heap, node));
}
diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp
index b7ebb004b1..3f5e93be41 100644
--- a/Libraries/LibWeb/DOM/Element.cpp
+++ b/Libraries/LibWeb/DOM/Element.cpp
@@ -24,11 +24,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include
-#include
+#include
#include
+#include
+#include
#include
+#include
#include
+#include
+#include
#include
#include
#include
@@ -36,6 +40,7 @@
#include
#include
#include
+#include
namespace Web {
@@ -218,4 +223,47 @@ NonnullRefPtr Element::computed_style()
return properties;
}
+void Element::set_inner_html(StringView markup)
+{
+ auto fragment = parse_html_fragment(document(), markup);
+ remove_all_children();
+ if (!fragment)
+ return;
+ while (RefPtr child = fragment->first_child()) {
+ fragment->remove_child(*child);
+ append_child(*child);
+ }
+
+ set_needs_style_update(true);
+ document().schedule_style_update();
+ document().invalidate_layout();
+}
+
+String Element::inner_html() const
+{
+ StringBuilder builder;
+
+ Function recurse = [&](auto& node) {
+ for (auto* child = node.first_child(); child; child = child->next_sibling()) {
+ if (child->is_element()) {
+ builder.append('<');
+ builder.append(to(*child).tag_name());
+ builder.append('>');
+
+ recurse(*child);
+
+ builder.append("");
+ builder.append(to(*child).tag_name());
+ builder.append('>');
+ }
+ if (child->is_text()) {
+ builder.append(to(*child).data());
+ }
+ }
+ };
+ recurse(*this);
+
+ return builder.to_string();
+}
+
}
diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h
index b23ac2c454..f1602d4b07 100644
--- a/Libraries/LibWeb/DOM/Element.h
+++ b/Libraries/LibWeb/DOM/Element.h
@@ -55,6 +55,8 @@ private:
class Element : public ParentNode {
public:
+ using WrapperType = Bindings::ElementWrapper;
+
Element(Document&, const FlyString& tag_name);
virtual ~Element() override;
@@ -88,6 +90,9 @@ public:
const StyleProperties* resolved_style() const { return m_resolved_style.ptr(); }
NonnullRefPtr computed_style();
+ String inner_html() const;
+ void set_inner_html(StringView);
+
private:
RefPtr create_layout_node(const StyleProperties* parent_style) const override;
diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h
index 623511e311..c94ddd4400 100644
--- a/Libraries/LibWeb/Forward.h
+++ b/Libraries/LibWeb/Forward.h
@@ -45,6 +45,7 @@ namespace Bindings {
class CanvasRenderingContext2DWrapper;
class DocumentWrapper;
+class ElementWrapper;
class EventWrapper;
class EventListenerWrapper;
class EventTargetWrapper;
diff --git a/Libraries/LibWeb/Makefile b/Libraries/LibWeb/Makefile
index bc36ffeda1..5de6b61cd2 100644
--- a/Libraries/LibWeb/Makefile
+++ b/Libraries/LibWeb/Makefile
@@ -1,6 +1,7 @@
LIBWEB_OBJS = \
Bindings/CanvasRenderingContext2DWrapper.o \
Bindings/DocumentWrapper.o \
+ Bindings/ElementWrapper.o \
Bindings/EventWrapper.o \
Bindings/EventListenerWrapper.o \
Bindings/EventTargetWrapper.o \