mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 23:17:46 +00:00
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.
This commit is contained in:
parent
bb547ce1c4
commit
6f433c8656
445 changed files with 4797 additions and 4268 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue