summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/DOM/Document.h
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-08-28 13:42:07 +0200
committerAndreas Kling <kling@serenityos.org>2022-09-06 00:27:09 +0200
commit6f433c86564c24d47d520cb5bdcc2209d724ac96 (patch)
tree886a2f727782e466e99c61c628637872c1b7403f /Userland/Libraries/LibWeb/DOM/Document.h
parentbb547ce1c4251e3689287eac845593398a379ca5 (diff)
downloadserenity-6f433c86564c24d47d520cb5bdcc2209d724ac96.zip
LibWeb+LibJS: Make the EventTarget hierarchy (incl. DOM) GC-allocated
This is a monster patch that turns all EventTargets into GC-allocated PlatformObjects. Their C++ wrapper classes are removed, and the LibJS garbage collector is now responsible for their lifetimes. There's a fair amount of hacks and band-aids in this patch, and we'll have a lot of cleanup to do after this.
Diffstat (limited to 'Userland/Libraries/LibWeb/DOM/Document.h')
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.h151
1 files changed, 58 insertions, 93 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h
index ccd0cd411f..d0d90e87e7 100644
--- a/Userland/Libraries/LibWeb/DOM/Document.h
+++ b/Userland/Libraries/LibWeb/DOM/Document.h
@@ -17,7 +17,6 @@
#include <AK/WeakPtr.h>
#include <LibCore/Forward.h>
#include <LibJS/Forward.h>
-#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/CSS/CSSStyleSheet.h>
#include <LibWeb/CSS/StyleComputer.h>
#include <LibWeb/CSS/StyleSheetList.h>
@@ -31,6 +30,7 @@
#include <LibWeb/HTML/History.h>
#include <LibWeb/HTML/Origin.h>
#include <LibWeb/HTML/Scripting/Environments.h>
+#include <LibWeb/HTML/Window.h>
namespace Web::DOM {
@@ -44,25 +44,20 @@ class Document
: public ParentNode
, public NonElementParentNode<Document>
, public HTML::GlobalEventHandlers {
-public:
- using WrapperType = Bindings::DocumentWrapper;
+ WEB_PLATFORM_OBJECT(Document, ParentNode);
+public:
enum class Type {
XML,
HTML
};
- static NonnullRefPtr<Document> create_and_initialize(Type, String content_type, HTML::NavigationParams);
+ static JS::NonnullGCPtr<Document> create_and_initialize(Type, String content_type, HTML::NavigationParams);
- static NonnullRefPtr<Document> create(AK::URL const& url = "about:blank"sv);
- static NonnullRefPtr<Document> create_with_global_object(Bindings::WindowObject&);
+ static JS::NonnullGCPtr<Document> create(HTML::Window&, AK::URL const& url = "about:blank"sv);
+ static JS::NonnullGCPtr<Document> create_with_global_object(HTML::Window&);
virtual ~Document() override;
- // NOTE: This returns the web-facing window object if there is one,
- // otherwise it returns the internal window object.
- // FIXME: Remove this when Document is a JS::Object.
- Bindings::WindowObject& preferred_window_object() const;
-
size_t next_layout_node_serial_id(Badge<Layout::Node>) { return m_next_layout_node_serial_id++; }
size_t layout_node_count() const { return m_next_layout_node_serial_id; }
@@ -80,7 +75,7 @@ public:
AK::URL fallback_base_url() const;
AK::URL base_url() const;
- RefPtr<HTML::HTMLBaseElement> first_base_element_with_href_in_tree_order() const;
+ JS::GCPtr<HTML::HTMLBaseElement> first_base_element_with_href_in_tree_order() const;
String url_string() const { return m_url.to_string(); }
String document_uri() const { return m_url.to_string(); }
@@ -96,20 +91,20 @@ public:
CSS::StyleComputer& style_computer() { return *m_style_computer; }
const CSS::StyleComputer& style_computer() const { return *m_style_computer; }
- CSS::StyleSheetList& style_sheets() { return *m_style_sheets; }
- const CSS::StyleSheetList& style_sheets() const { return *m_style_sheets; }
+ CSS::StyleSheetList& style_sheets();
+ CSS::StyleSheetList const& style_sheets() const;
- CSS::StyleSheetList* style_sheets_for_bindings() { return m_style_sheets.cell(); }
+ CSS::StyleSheetList* style_sheets_for_bindings() { return &style_sheets(); }
virtual FlyString node_name() const override { return "#document"; }
void set_hovered_node(Node*);
- Node* hovered_node() { return m_hovered_node; }
- Node const* hovered_node() const { return m_hovered_node; }
+ Node* hovered_node() { return m_hovered_node.ptr(); }
+ Node const* hovered_node() const { return m_hovered_node.ptr(); }
void set_inspected_node(Node*);
- Node* inspected_node() { return m_inspected_node; }
- Node const* inspected_node() const { return m_inspected_node; }
+ Node* inspected_node() { return m_inspected_node.ptr(); }
+ Node const* inspected_node() const { return m_inspected_node.ptr(); }
Element* document_element();
Element const* document_element() const;
@@ -193,30 +188,29 @@ public:
void set_source(String const& source) { m_source = source; }
HTML::EnvironmentSettingsObject& relevant_settings_object();
- JS::Realm& realm();
JS::Interpreter& interpreter();
JS::Value run_javascript(StringView source, StringView filename = "(unknown)"sv);
- ExceptionOr<NonnullRefPtr<Element>> create_element(String const& tag_name);
- ExceptionOr<NonnullRefPtr<Element>> create_element_ns(String const& namespace_, String const& qualified_name);
- NonnullRefPtr<DocumentFragment> create_document_fragment();
- NonnullRefPtr<Text> create_text_node(String const& data);
- NonnullRefPtr<Comment> create_comment(String const& data);
+ ExceptionOr<JS::NonnullGCPtr<Element>> create_element(String const& tag_name);
+ ExceptionOr<JS::NonnullGCPtr<Element>> create_element_ns(String const& namespace_, String const& qualified_name);
+ JS::NonnullGCPtr<DocumentFragment> create_document_fragment();
+ JS::NonnullGCPtr<Text> create_text_node(String const& data);
+ JS::NonnullGCPtr<Comment> create_comment(String const& data);
ExceptionOr<JS::NonnullGCPtr<Event>> create_event(String const& interface);
JS::NonnullGCPtr<Range> create_range();
void set_pending_parsing_blocking_script(Badge<HTML::HTMLScriptElement>, HTML::HTMLScriptElement*);
- HTML::HTMLScriptElement* pending_parsing_blocking_script() { return m_pending_parsing_blocking_script; }
- NonnullRefPtr<HTML::HTMLScriptElement> take_pending_parsing_blocking_script(Badge<HTML::HTMLParser>);
+ HTML::HTMLScriptElement* pending_parsing_blocking_script() { return m_pending_parsing_blocking_script.ptr(); }
+ JS::NonnullGCPtr<HTML::HTMLScriptElement> take_pending_parsing_blocking_script(Badge<HTML::HTMLParser>);
void add_script_to_execute_when_parsing_has_finished(Badge<HTML::HTMLScriptElement>, HTML::HTMLScriptElement&);
- NonnullRefPtrVector<HTML::HTMLScriptElement> take_scripts_to_execute_when_parsing_has_finished(Badge<HTML::HTMLParser>);
- NonnullRefPtrVector<HTML::HTMLScriptElement>& scripts_to_execute_when_parsing_has_finished() { return m_scripts_to_execute_when_parsing_has_finished; }
+ Vector<JS::Handle<HTML::HTMLScriptElement>> take_scripts_to_execute_when_parsing_has_finished(Badge<HTML::HTMLParser>);
+ Vector<JS::Handle<HTML::HTMLScriptElement>>& scripts_to_execute_when_parsing_has_finished() { return m_scripts_to_execute_when_parsing_has_finished; }
void add_script_to_execute_as_soon_as_possible(Badge<HTML::HTMLScriptElement>, HTML::HTMLScriptElement&);
- NonnullRefPtrVector<HTML::HTMLScriptElement> take_scripts_to_execute_as_soon_as_possible(Badge<HTML::HTMLParser>);
- NonnullRefPtrVector<HTML::HTMLScriptElement>& scripts_to_execute_as_soon_as_possible() { return m_scripts_to_execute_as_soon_as_possible; }
+ Vector<JS::Handle<HTML::HTMLScriptElement>> take_scripts_to_execute_as_soon_as_possible(Badge<HTML::HTMLParser>);
+ Vector<JS::Handle<HTML::HTMLScriptElement>>& scripts_to_execute_as_soon_as_possible() { return m_scripts_to_execute_as_soon_as_possible; }
QuirksMode mode() const { return m_quirks_mode; }
bool in_quirks_mode() const { return m_quirks_mode == QuirksMode::Yes; }
@@ -228,9 +222,9 @@ public:
// https://dom.spec.whatwg.org/#xml-document
bool is_xml_document() const { return m_type == Type::XML; }
- ExceptionOr<NonnullRefPtr<Node>> import_node(NonnullRefPtr<Node> node, bool deep);
+ ExceptionOr<JS::NonnullGCPtr<Node>> import_node(JS::NonnullGCPtr<Node> node, bool deep);
void adopt_node(Node&);
- ExceptionOr<NonnullRefPtr<Node>> adopt_node_binding(NonnullRefPtr<Node>);
+ ExceptionOr<JS::NonnullGCPtr<Node>> adopt_node_binding(JS::NonnullGCPtr<Node>);
DocumentType const* doctype() const;
String const& compat_mode() const;
@@ -238,39 +232,26 @@ public:
void set_editable(bool editable) { m_editable = editable; }
virtual bool is_editable() const final;
- Element* focused_element() { return m_focused_element; }
- Element const* focused_element() const { return m_focused_element; }
+ Element* focused_element() { return m_focused_element.ptr(); }
+ Element const* focused_element() const { return m_focused_element.ptr(); }
void set_focused_element(Element*);
- Element const* active_element() const { return m_active_element; }
+ Element const* active_element() const { return m_active_element.ptr(); }
void set_active_element(Element*);
bool created_for_appropriate_template_contents() const { return m_created_for_appropriate_template_contents; }
void set_created_for_appropriate_template_contents(bool value) { m_created_for_appropriate_template_contents = value; }
- Document* associated_inert_template_document() { return m_associated_inert_template_document; }
- Document const* associated_inert_template_document() const { return m_associated_inert_template_document; }
- void set_associated_inert_template_document(Document& document) { m_associated_inert_template_document = document; }
+ Document* associated_inert_template_document() { return m_associated_inert_template_document.ptr(); }
+ Document const* associated_inert_template_document() const { return m_associated_inert_template_document.ptr(); }
+ void set_associated_inert_template_document(Document& document) { m_associated_inert_template_document = &document; }
String ready_state() const;
void update_readiness(HTML::DocumentReadyState);
- void ref_from_node(Badge<Node>)
- {
- increment_referencing_node_count();
- }
-
- void unref_from_node(Badge<Node>)
- {
- decrement_referencing_node_count();
- }
-
- void removed_last_ref();
-
- HTML::Window& window() { return *m_window; }
- HTML::Window const& window() const { return *m_window; }
+ HTML::Window& window() const { return const_cast<HTML::Window&>(*m_window); }
void set_window(Badge<HTML::BrowsingContext>, HTML::Window&);
@@ -280,7 +261,7 @@ public:
ExceptionOr<Document*> open(String const& = "", String const& = "");
ExceptionOr<void> close();
- HTML::Window* default_view() { return m_window; }
+ HTML::Window* default_view() { return m_window.ptr(); }
String const& content_type() const { return m_content_type; }
void set_content_type(String const& content_type) { m_content_type = content_type; }
@@ -302,8 +283,8 @@ public:
DOMImplementation* implementation();
- RefPtr<HTML::HTMLScriptElement> current_script() const { return m_current_script; }
- void set_current_script(Badge<HTML::HTMLScriptElement>, RefPtr<HTML::HTMLScriptElement> script) { m_current_script = move(script); }
+ JS::GCPtr<HTML::HTMLScriptElement> current_script() const { return m_current_script.ptr(); }
+ void set_current_script(Badge<HTML::HTMLScriptElement>, JS::GCPtr<HTML::HTMLScriptElement> script) { m_current_script = move(script); }
u32 ignore_destructive_writes_counter() const { return m_ignore_destructive_writes_counter; }
void increment_ignore_destructive_writes_counter() { m_ignore_destructive_writes_counter++; }
@@ -335,7 +316,7 @@ public:
void run_the_resize_steps();
void evaluate_media_queries_and_report_changes();
- void add_media_query_list(NonnullRefPtr<CSS::MediaQueryList>&);
+ void add_media_query_list(JS::NonnullGCPtr<CSS::MediaQueryList>);
bool has_focus() const;
@@ -359,15 +340,13 @@ public:
template<typename Callback>
void for_each_node_iterator(Callback callback)
{
- for (auto* node_iterator : m_node_iterators)
+ for (auto& node_iterator : m_node_iterators)
callback(*node_iterator);
}
bool needs_full_style_update() const { return m_needs_full_style_update; }
void set_needs_full_style_update(bool b) { m_needs_full_style_update = b; }
- bool in_removed_last_ref() const { return m_in_removed_last_ref; }
-
bool has_active_favicon() const { return m_active_favicon; }
void check_favicon_after_loading_link_resource();
@@ -375,8 +354,11 @@ public:
bool is_initial_about_blank() const { return m_is_initial_about_blank; }
void set_is_initial_about_blank(bool b) { m_is_initial_about_blank = b; }
+protected:
+ virtual void visit_edges(Cell::Visitor&) override;
+
private:
- explicit Document(const AK::URL&);
+ Document(HTML::Window&, AK::URL const&);
// ^HTML::GlobalEventHandlers
virtual EventTarget& global_event_handlers_to_event_target(FlyString const&) final { return *this; }
@@ -387,36 +369,17 @@ private:
ExceptionOr<void> run_the_document_write_steps(String);
- void increment_referencing_node_count()
- {
- VERIFY(!m_deletion_has_begun);
- ++m_referencing_node_count;
- }
-
- void decrement_referencing_node_count()
- {
- VERIFY(!m_deletion_has_begun);
- VERIFY(m_referencing_node_count);
- --m_referencing_node_count;
- if (!m_referencing_node_count && !ref_count()) {
- m_deletion_has_begun = true;
- delete this;
- }
- }
-
- unsigned m_referencing_node_count { 0 };
-
size_t m_next_layout_node_serial_id { 0 };
OwnPtr<CSS::StyleComputer> m_style_computer;
- JS::Handle<CSS::StyleSheetList> m_style_sheets;
- RefPtr<Node> m_hovered_node;
- RefPtr<Node> m_inspected_node;
- RefPtr<Node> m_active_favicon;
+ JS::GCPtr<CSS::StyleSheetList> m_style_sheets;
+ JS::GCPtr<Node> m_hovered_node;
+ JS::GCPtr<Node> m_inspected_node;
+ JS::GCPtr<Node> m_active_favicon;
WeakPtr<HTML::BrowsingContext> m_browsing_context;
AK::URL m_url;
- RefPtr<HTML::Window> m_window;
+ JS::GCPtr<HTML::Window> m_window;
RefPtr<Layout::InitialContainingBlock> m_layout_root;
@@ -434,9 +397,9 @@ private:
OwnPtr<JS::Interpreter> m_interpreter;
- RefPtr<HTML::HTMLScriptElement> m_pending_parsing_blocking_script;
- NonnullRefPtrVector<HTML::HTMLScriptElement> m_scripts_to_execute_when_parsing_has_finished;
- NonnullRefPtrVector<HTML::HTMLScriptElement> m_scripts_to_execute_as_soon_as_possible;
+ JS::GCPtr<HTML::HTMLScriptElement> m_pending_parsing_blocking_script;
+ Vector<JS::Handle<HTML::HTMLScriptElement>> m_scripts_to_execute_when_parsing_has_finished;
+ Vector<JS::Handle<HTML::HTMLScriptElement>> m_scripts_to_execute_as_soon_as_possible;
QuirksMode m_quirks_mode { QuirksMode::No };
@@ -445,11 +408,11 @@ private:
bool m_editable { false };
- WeakPtr<Element> m_focused_element;
- WeakPtr<Element> m_active_element;
+ JS::GCPtr<Element> m_focused_element;
+ JS::GCPtr<Element> m_active_element;
bool m_created_for_appropriate_template_contents { false };
- RefPtr<Document> m_associated_inert_template_document;
+ JS::GCPtr<Document> m_associated_inert_template_document;
HTML::DocumentReadyState m_readiness { HTML::DocumentReadyState::Loading };
String m_content_type { "application/xml" };
@@ -457,8 +420,8 @@ private:
bool m_ready_for_post_load_tasks { false };
- JS::Handle<DOMImplementation> m_implementation;
- RefPtr<HTML::HTMLScriptElement> m_current_script;
+ JS::GCPtr<DOMImplementation> m_implementation;
+ JS::GCPtr<HTML::HTMLScriptElement> m_current_script;
bool m_should_invalidate_styles_on_attribute_changes { true };
@@ -506,3 +469,5 @@ private:
};
}
+
+WRAPPER_HACK(Document, Web::DOM)