summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-03-14 13:15:11 +0100
committerAndreas Kling <kling@serenityos.org>2020-03-14 13:25:40 +0100
commit1c406294fc426a2d083e7d5f30f7e4e97ef4a794 (patch)
tree9dbd3c6fce454018e1f0af6c9dd2ecad1b779898
parent9c9d3f090429746df8a39232eb75467007463a9e (diff)
downloadserenity-1c406294fc426a2d083e7d5f30f7e4e97ef4a794.zip
LibWeb: Start implementing basic JavaScript DOM bindings
This patch introduces the Wrapper and Wrappable classes. Node now inherits from Wrappable, and can be wrapped in a GC-allocated Bindings::NodeWrapper object. The only property we expose right now is the very simple nodeName property. When a Document's JS::Interpreter is first instantiated, we add a "document" property with a DocumentWrapper object to the global object. This is pretty cool! :^)
-rw-r--r--Base/home/anon/www/dom.html12
-rw-r--r--Base/home/anon/www/welcome.html1
-rw-r--r--Libraries/LibWeb/Bindings/DocumentWrapper.cpp29
-rw-r--r--Libraries/LibWeb/Bindings/DocumentWrapper.h21
-rw-r--r--Libraries/LibWeb/Bindings/NodeWrapper.cpp20
-rw-r--r--Libraries/LibWeb/Bindings/NodeWrapper.h23
-rw-r--r--Libraries/LibWeb/Bindings/Wrappable.cpp18
-rw-r--r--Libraries/LibWeb/Bindings/Wrappable.h31
-rw-r--r--Libraries/LibWeb/Bindings/Wrapper.h19
-rw-r--r--Libraries/LibWeb/DOM/Document.cpp3
-rw-r--r--Libraries/LibWeb/DOM/Document.h2
-rw-r--r--Libraries/LibWeb/DOM/Node.h5
-rw-r--r--Libraries/LibWeb/Forward.h10
-rw-r--r--Libraries/LibWeb/Makefile3
14 files changed, 196 insertions, 1 deletions
diff --git a/Base/home/anon/www/dom.html b/Base/home/anon/www/dom.html
new file mode 100644
index 0000000000..0c6a15dfad
--- /dev/null
+++ b/Base/home/anon/www/dom.html
@@ -0,0 +1,12 @@
+<!DOCTYPE>
+<html>
+ <head></head>
+ <body>
+ <div id="foo"></div>
+ <script>
+ alert(document.nodeName);
+ //var e = document.getElementById("foo");
+ //alert(e.nodeName);
+ </script>
+ </body>
+</html>
diff --git a/Base/home/anon/www/welcome.html b/Base/home/anon/www/welcome.html
index 6f7f3a3a78..4f2d30a013 100644
--- a/Base/home/anon/www/welcome.html
+++ b/Base/home/anon/www/welcome.html
@@ -23,6 +23,7 @@ h1 {
<p>This is a very simple browser built on the LibWeb engine.</p>
<p>Some small test pages:</p>
<ul>
+ <li><a href="dom.html">simple DOM JS test</a></li>
<li><a href="alert.html">alert() test</a></li>
<li><a href="small.html">small</a></li>
<li><a href="first-child.html">:first-child</a></li>
diff --git a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp
new file mode 100644
index 0000000000..91836d7c8e
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp
@@ -0,0 +1,29 @@
+#include <LibJS/PrimitiveString.h>
+#include <LibJS/Value.h>
+#include <LibWeb/Bindings/DocumentWrapper.h>
+#include <LibWeb/DOM/Document.h>
+
+namespace Web {
+namespace Bindings {
+
+DocumentWrapper::DocumentWrapper(Document& document)
+ : NodeWrapper(document)
+{
+}
+
+DocumentWrapper::~DocumentWrapper()
+{
+}
+
+Document& DocumentWrapper::node()
+{
+ return static_cast<Document&>(NodeWrapper::node());
+}
+
+const Document& DocumentWrapper::node() const
+{
+ return static_cast<const Document&>(NodeWrapper::node());
+}
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/DocumentWrapper.h b/Libraries/LibWeb/Bindings/DocumentWrapper.h
new file mode 100644
index 0000000000..931720c696
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/DocumentWrapper.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <LibWeb/Bindings/NodeWrapper.h>
+
+namespace Web {
+namespace Bindings {
+
+class DocumentWrapper : public NodeWrapper {
+public:
+ explicit DocumentWrapper(Document&);
+ virtual ~DocumentWrapper() override;
+
+ Document& node();
+ const Document& node() const;
+
+private:
+ virtual const char* class_name() const override { return "Document"; }
+};
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/NodeWrapper.cpp b/Libraries/LibWeb/Bindings/NodeWrapper.cpp
new file mode 100644
index 0000000000..9aaa9b21a4
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/NodeWrapper.cpp
@@ -0,0 +1,20 @@
+#include <LibJS/PrimitiveString.h>
+#include <LibJS/Value.h>
+#include <LibWeb/Bindings/NodeWrapper.h>
+#include <LibWeb/DOM/Node.h>
+
+namespace Web {
+namespace Bindings {
+
+NodeWrapper::NodeWrapper(Node& node)
+ : m_node(node)
+{
+ put("nodeName", JS::js_string(heap(), node.tag_name()));
+}
+
+NodeWrapper::~NodeWrapper()
+{
+}
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/NodeWrapper.h b/Libraries/LibWeb/Bindings/NodeWrapper.h
new file mode 100644
index 0000000000..b7a24b94b7
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/NodeWrapper.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <LibWeb/Bindings/Wrapper.h>
+
+namespace Web {
+namespace Bindings {
+
+class NodeWrapper : public Wrapper {
+public:
+ explicit NodeWrapper(Node&);
+ virtual ~NodeWrapper() override;
+
+ Node& node() { return *m_node; }
+ const Node& node() const { return *m_node; }
+
+private:
+ virtual const char* class_name() const override { return "Node"; }
+
+ NonnullRefPtr<Node> m_node;
+};
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/Wrappable.cpp b/Libraries/LibWeb/Bindings/Wrappable.cpp
new file mode 100644
index 0000000000..2245e14723
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/Wrappable.cpp
@@ -0,0 +1,18 @@
+#include <LibWeb/Bindings/Wrappable.h>
+#include <LibWeb/Bindings/Wrapper.h>
+
+namespace Web {
+namespace Bindings {
+
+Wrappable::~Wrappable()
+{
+}
+
+void Wrappable::set_wrapper(Wrapper& wrapper)
+{
+ ASSERT(!m_wrapper);
+ m_wrapper = wrapper.make_weak_ptr();
+}
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/Wrappable.h b/Libraries/LibWeb/Bindings/Wrappable.h
new file mode 100644
index 0000000000..4531f63935
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/Wrappable.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <AK/WeakPtr.h>
+#include <LibJS/Heap.h>
+#include <LibWeb/Forward.h>
+
+namespace Web {
+namespace Bindings {
+
+class Wrappable {
+public:
+ virtual ~Wrappable();
+
+ void set_wrapper(Wrapper&);
+ Wrapper* wrapper() { return m_wrapper; }
+ const Wrapper* wrapper() const { return m_wrapper; }
+
+private:
+ WeakPtr<Wrapper> m_wrapper;
+};
+
+template<class NativeObject>
+inline Wrapper* wrap(JS::Heap& heap, NativeObject& native_object)
+{
+ if (!native_object.wrapper())
+ native_object.set_wrapper(*heap.allocate<typename NativeObject::WrapperType>(native_object));
+ return native_object.wrapper();
+}
+
+}
+}
diff --git a/Libraries/LibWeb/Bindings/Wrapper.h b/Libraries/LibWeb/Bindings/Wrapper.h
new file mode 100644
index 0000000000..680200eaab
--- /dev/null
+++ b/Libraries/LibWeb/Bindings/Wrapper.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <AK/NonnullRefPtr.h>
+#include <AK/Weakable.h>
+#include <LibJS/Object.h>
+#include <LibWeb/Forward.h>
+
+namespace Web {
+namespace Bindings {
+
+class Wrapper
+ : public JS::Object
+ , public Weakable<Wrapper> {
+protected:
+ explicit Wrapper() {}
+};
+
+}
+}
diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp
index 8e25cbf64d..669f399047 100644
--- a/Libraries/LibWeb/DOM/Document.cpp
+++ b/Libraries/LibWeb/DOM/Document.cpp
@@ -31,6 +31,7 @@
#include <LibGUI/MessageBox.h>
#include <LibJS/GlobalObject.h>
#include <LibJS/Interpreter.h>
+#include <LibWeb/Bindings/DocumentWrapper.h>
#include <LibWeb/CSS/StyleResolver.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/DocumentType.h>
@@ -346,6 +347,8 @@ JS::Interpreter& Document::interpreter()
GUI::MessageBox::show(arguments[0].to_string(), "Alert", GUI::MessageBox::Type::Information);
return JS::js_undefined();
});
+
+ m_interpreter->global_object().put("document", wrap(m_interpreter->heap(), *this));
}
return *m_interpreter;
}
diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h
index bdfe6e6cb9..b4fef21bb2 100644
--- a/Libraries/LibWeb/DOM/Document.h
+++ b/Libraries/LibWeb/DOM/Document.h
@@ -51,6 +51,8 @@ class StyleSheet;
class Document : public ParentNode {
public:
+ using WrapperType = Bindings::DocumentWrapper;
+
Document();
virtual ~Document() override;
diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h
index 51a48bdffd..3cf67681a3 100644
--- a/Libraries/LibWeb/DOM/Node.h
+++ b/Libraries/LibWeb/DOM/Node.h
@@ -30,6 +30,7 @@
#include <AK/RefPtr.h>
#include <AK/String.h>
#include <AK/Vector.h>
+#include <LibWeb/Bindings/Wrappable.h>
#include <LibWeb/TreeNode.h>
namespace Web {
@@ -53,7 +54,9 @@ class LayoutNode;
class StyleResolver;
class StyleProperties;
-class Node : public TreeNode<Node> {
+class Node
+ : public TreeNode<Node>
+ , public Bindings::Wrappable {
public:
virtual ~Node();
diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h
index d700b317c3..8c87919e5b 100644
--- a/Libraries/LibWeb/Forward.h
+++ b/Libraries/LibWeb/Forward.h
@@ -34,4 +34,14 @@ class Frame;
class HtmlView;
class Node;
+namespace Bindings {
+
+class DocumentWrapper;
+class NodeWrapper;
+class Wrappable;
+class Wrapper;
+
+}
+
+
}
diff --git a/Libraries/LibWeb/Makefile b/Libraries/LibWeb/Makefile
index 96acd12078..2a4601ae0b 100644
--- a/Libraries/LibWeb/Makefile
+++ b/Libraries/LibWeb/Makefile
@@ -1,4 +1,7 @@
LIBWEB_OBJS = \
+ Bindings/Wrappable.o \
+ Bindings/NodeWrapper.o \
+ Bindings/DocumentWrapper.o \
CSS/DefaultStyleSheetSource.o \
CSS/PropertyID.o \
CSS/Selector.o \