diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 78add97ac46..432ad4d445c 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -281,7 +281,6 @@ Document::Document(HTML::Window& window, const AK::URL& url) , m_style_computer(make(*this)) , m_url(url) , m_window(window) - , m_history(HTML::History::create(*this)) { set_prototype(&window.ensure_web_prototype("Document")); @@ -315,6 +314,7 @@ void Document::visit_edges(Cell::Visitor& visitor) visitor.visit(m_current_script.ptr()); visitor.visit(m_associated_inert_template_document.ptr()); visitor.visit(m_pending_parsing_blocking_script.ptr()); + visitor.visit(m_history.ptr()); for (auto& script : m_scripts_to_execute_when_parsing_has_finished) visitor.visit(script.ptr()); @@ -1812,4 +1812,11 @@ CSS::StyleSheetList const& Document::style_sheets() const return const_cast(this)->style_sheets(); } +JS::NonnullGCPtr Document::history() +{ + if (!m_history) + m_history = HTML::History::create(window(), *this); + return *m_history; +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 36efd422ca7..6f86126f151 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -298,7 +298,7 @@ public: bool is_fully_active() const; bool is_active() const; - NonnullRefPtr history() const { return m_history; } + JS::NonnullGCPtr history(); Bindings::LocationObject* location(); @@ -433,7 +433,7 @@ private: // https://html.spec.whatwg.org/multipage/semantics.html#script-blocking-style-sheet-counter u32 m_script_blocking_style_sheet_counter { 0 }; - NonnullRefPtr m_history; + JS::GCPtr m_history; size_t m_number_of_things_delaying_the_load_event { 0 }; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 7b7e4f930a0..aa85a14291b 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -462,7 +462,6 @@ class DOMRectWrapper; class FileWrapper; class HeadersWrapper; class HeadersIteratorWrapper; -class HistoryWrapper; class IdleDeadlineWrapper; class ImageDataWrapper; class IntersectionObserverWrapper; diff --git a/Userland/Libraries/LibWeb/HTML/History.cpp b/Userland/Libraries/LibWeb/HTML/History.cpp index 379fddf37f6..52f4d0908b6 100644 --- a/Userland/Libraries/LibWeb/HTML/History.cpp +++ b/Userland/Libraries/LibWeb/HTML/History.cpp @@ -4,18 +4,32 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include namespace Web::HTML { -History::History(DOM::Document& document) - : m_associated_document(document) +JS::NonnullGCPtr History::create(HTML::Window& window, DOM::Document& document) { + return *window.heap().allocate(window.realm(), window, document); +} + +History::History(HTML::Window& window, DOM::Document& document) + : PlatformObject(window.realm()) + , m_associated_document(document) +{ + set_prototype(&window.ensure_web_prototype("History")); } History::~History() = default; +void History::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_associated_document.ptr()); +} + // https://html.spec.whatwg.org/multipage/history.html#dom-history-pushstate DOM::ExceptionOr History::push_state(JS::Value data, String const&, String const& url) { @@ -36,7 +50,7 @@ DOM::ExceptionOr History::shared_history_push_replace_state(JS::Value, Str // 1. Let document be history's associated Document. (NOTE: Not necessary) // 2. If document is not fully active, then throw a "SecurityError" DOMException. - if (!m_associated_document.is_fully_active()) + if (!m_associated_document->is_fully_active()) return DOM::SecurityError::create("Cannot perform pushState or replaceState on a document that isn't fully active."); // 3. Optionally, return. (For example, the user agent might disallow calls to these methods that are invoked on a timer, diff --git a/Userland/Libraries/LibWeb/HTML/History.h b/Userland/Libraries/LibWeb/HTML/History.h index 5e78cc6bd99..1a2b0691524 100644 --- a/Userland/Libraries/LibWeb/HTML/History.h +++ b/Userland/Libraries/LibWeb/HTML/History.h @@ -1,31 +1,23 @@ /* * Copyright (c) 2021, Luke Wilde + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once -#include -#include #include -#include +#include #include -#include namespace Web::HTML { -class History final - : public RefCounted - , public Weakable - , public Bindings::Wrappable { -public: - using WrapperType = Bindings::HistoryWrapper; +class History final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(History, Bindings::PlatformObject); - static NonnullRefPtr create(DOM::Document& document) - { - return adopt_ref(*new History(document)); - } +public: + static JS::NonnullGCPtr create(HTML::Window&, DOM::Document&); virtual ~History() override; @@ -33,7 +25,9 @@ public: DOM::ExceptionOr replace_state(JS::Value data, String const& unused, String const& url); private: - explicit History(DOM::Document&); + explicit History(HTML::Window&, DOM::Document&); + + virtual void visit_edges(Cell::Visitor&) override; enum class IsPush { No, @@ -41,7 +35,9 @@ private: }; DOM::ExceptionOr shared_history_push_replace_state(JS::Value data, String const& url, IsPush is_push); - DOM::Document& m_associated_document; + JS::NonnullGCPtr m_associated_document; }; } + +WRAPPER_HACK(History, Web::HTML) diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index b03ae4d6a1d..035d19eeae4 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 8112c87d184..b7472ef6ec7 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -67,7 +67,7 @@ libweb_js_wrapper(HTML/CloseEvent NO_INSTANCE) libweb_js_wrapper(HTML/DOMParser NO_INSTANCE) libweb_js_wrapper(HTML/DOMStringMap NO_INSTANCE) libweb_js_wrapper(HTML/ErrorEvent NO_INSTANCE) -libweb_js_wrapper(HTML/History) +libweb_js_wrapper(HTML/History NO_INSTANCE) libweb_js_wrapper(HTML/HTMLAnchorElement NO_INSTANCE) libweb_js_wrapper(HTML/HTMLAreaElement NO_INSTANCE) libweb_js_wrapper(HTML/HTMLAudioElement NO_INSTANCE)