diff options
author | Andreas Kling <kling@serenityos.org> | 2022-08-28 13:42:07 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-09-06 00:27:09 +0200 |
commit | 6f433c86564c24d47d520cb5bdcc2209d724ac96 (patch) | |
tree | 886a2f727782e466e99c61c628637872c1b7403f /Userland/Libraries/LibWeb/DOM/Document.h | |
parent | bb547ce1c4251e3689287eac845593398a379ca5 (diff) | |
download | serenity-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.h | 151 |
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) |