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 @@
+
+
+
+
+
+
+
+
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 {
This is a very simple browser built on the LibWeb engine.
Some small test pages:
+ - simple DOM JS test
- alert() test
- small
- :first-child
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
+#include
+#include
+#include
+
+namespace Web {
+namespace Bindings {
+
+DocumentWrapper::DocumentWrapper(Document& document)
+ : NodeWrapper(document)
+{
+}
+
+DocumentWrapper::~DocumentWrapper()
+{
+}
+
+Document& DocumentWrapper::node()
+{
+ return static_cast(NodeWrapper::node());
+}
+
+const Document& DocumentWrapper::node() const
+{
+ return static_cast(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
+
+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
+#include
+#include
+#include
+
+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
+
+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 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
+#include
+
+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
+#include
+#include
+
+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 m_wrapper;
+};
+
+template
+inline Wrapper* wrap(JS::Heap& heap, NativeObject& native_object)
+{
+ if (!native_object.wrapper())
+ native_object.set_wrapper(*heap.allocate(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
+#include
+#include
+#include
+
+namespace Web {
+namespace Bindings {
+
+class Wrapper
+ : public JS::Object
+ , public Weakable {
+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
#include
#include
+#include
#include
#include
#include
@@ -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
#include
#include
+#include
#include
namespace Web {
@@ -53,7 +54,9 @@ class LayoutNode;
class StyleResolver;
class StyleProperties;
-class Node : public TreeNode {
+class Node
+ : public TreeNode
+ , 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 \