mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:27:36 +00:00
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! :^)
This commit is contained in:
parent
9c9d3f0904
commit
1c406294fc
14 changed files with 196 additions and 1 deletions
12
Base/home/anon/www/dom.html
Normal file
12
Base/home/anon/www/dom.html
Normal file
|
@ -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>
|
|
@ -23,6 +23,7 @@ h1 {
|
||||||
<p>This is a very simple browser built on the LibWeb engine.</p>
|
<p>This is a very simple browser built on the LibWeb engine.</p>
|
||||||
<p>Some small test pages:</p>
|
<p>Some small test pages:</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><a href="dom.html">simple DOM JS test</a></li>
|
||||||
<li><a href="alert.html">alert() test</a></li>
|
<li><a href="alert.html">alert() test</a></li>
|
||||||
<li><a href="small.html">small</a></li>
|
<li><a href="small.html">small</a></li>
|
||||||
<li><a href="first-child.html">:first-child</a></li>
|
<li><a href="first-child.html">:first-child</a></li>
|
||||||
|
|
29
Libraries/LibWeb/Bindings/DocumentWrapper.cpp
Normal file
29
Libraries/LibWeb/Bindings/DocumentWrapper.cpp
Normal file
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
21
Libraries/LibWeb/Bindings/DocumentWrapper.h
Normal file
21
Libraries/LibWeb/Bindings/DocumentWrapper.h
Normal file
|
@ -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"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
20
Libraries/LibWeb/Bindings/NodeWrapper.cpp
Normal file
20
Libraries/LibWeb/Bindings/NodeWrapper.cpp
Normal file
|
@ -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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
23
Libraries/LibWeb/Bindings/NodeWrapper.h
Normal file
23
Libraries/LibWeb/Bindings/NodeWrapper.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
18
Libraries/LibWeb/Bindings/Wrappable.cpp
Normal file
18
Libraries/LibWeb/Bindings/Wrappable.cpp
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
31
Libraries/LibWeb/Bindings/Wrappable.h
Normal file
31
Libraries/LibWeb/Bindings/Wrappable.h
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
Libraries/LibWeb/Bindings/Wrapper.h
Normal file
19
Libraries/LibWeb/Bindings/Wrapper.h
Normal file
|
@ -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() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@
|
||||||
#include <LibGUI/MessageBox.h>
|
#include <LibGUI/MessageBox.h>
|
||||||
#include <LibJS/GlobalObject.h>
|
#include <LibJS/GlobalObject.h>
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
|
#include <LibWeb/Bindings/DocumentWrapper.h>
|
||||||
#include <LibWeb/CSS/StyleResolver.h>
|
#include <LibWeb/CSS/StyleResolver.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/DOM/DocumentType.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);
|
GUI::MessageBox::show(arguments[0].to_string(), "Alert", GUI::MessageBox::Type::Information);
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_interpreter->global_object().put("document", wrap(m_interpreter->heap(), *this));
|
||||||
}
|
}
|
||||||
return *m_interpreter;
|
return *m_interpreter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ class StyleSheet;
|
||||||
|
|
||||||
class Document : public ParentNode {
|
class Document : public ParentNode {
|
||||||
public:
|
public:
|
||||||
|
using WrapperType = Bindings::DocumentWrapper;
|
||||||
|
|
||||||
Document();
|
Document();
|
||||||
virtual ~Document() override;
|
virtual ~Document() override;
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibWeb/Bindings/Wrappable.h>
|
||||||
#include <LibWeb/TreeNode.h>
|
#include <LibWeb/TreeNode.h>
|
||||||
|
|
||||||
namespace Web {
|
namespace Web {
|
||||||
|
@ -53,7 +54,9 @@ class LayoutNode;
|
||||||
class StyleResolver;
|
class StyleResolver;
|
||||||
class StyleProperties;
|
class StyleProperties;
|
||||||
|
|
||||||
class Node : public TreeNode<Node> {
|
class Node
|
||||||
|
: public TreeNode<Node>
|
||||||
|
, public Bindings::Wrappable {
|
||||||
public:
|
public:
|
||||||
virtual ~Node();
|
virtual ~Node();
|
||||||
|
|
||||||
|
|
|
@ -34,4 +34,14 @@ class Frame;
|
||||||
class HtmlView;
|
class HtmlView;
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
|
namespace Bindings {
|
||||||
|
|
||||||
|
class DocumentWrapper;
|
||||||
|
class NodeWrapper;
|
||||||
|
class Wrappable;
|
||||||
|
class Wrapper;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
LIBWEB_OBJS = \
|
LIBWEB_OBJS = \
|
||||||
|
Bindings/Wrappable.o \
|
||||||
|
Bindings/NodeWrapper.o \
|
||||||
|
Bindings/DocumentWrapper.o \
|
||||||
CSS/DefaultStyleSheetSource.o \
|
CSS/DefaultStyleSheetSource.o \
|
||||||
CSS/PropertyID.o \
|
CSS/PropertyID.o \
|
||||||
CSS/Selector.o \
|
CSS/Selector.o \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue