From 3c548adf9c135aa041f16842670ded4593614f60 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 15 Oct 2022 23:10:56 +0200 Subject: [PATCH] LibWeb: Create and hook up a WindowProxy for each BrowsingContext All the machinery for this was already in place, we just never created the actual WindowProxy and installed it. --- Userland/Libraries/LibWeb/DOM/Document.cpp | 7 ++-- .../Libraries/LibWeb/HTML/BrowsingContext.cpp | 37 ++++++++++++++----- .../Libraries/LibWeb/HTML/BrowsingContext.h | 7 +++- .../Libraries/LibWeb/HTML/WindowProxy.cpp | 8 +++- Userland/Libraries/LibWeb/HTML/WindowProxy.h | 9 ++--- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 36d7a6dc9c..443eb28f5c 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -177,9 +178,9 @@ JS::NonnullGCPtr Document::create_and_initialize(Type type, String con window = HTML::Window::create(realm); return window; }, - [](JS::Realm&) -> JS::Object* { - // FIXME: - For the global this binding, use browsingContext's WindowProxy object. - return nullptr; + [&](JS::Realm&) -> JS::Object* { + // - For the global this binding, use browsingContext's WindowProxy object. + return browsing_context->window_proxy(); }); // 6. Let topLevelCreationURL be creationURL. diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 2a7b465a9a..a751f8e521 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -136,13 +137,15 @@ NonnullRefPtr BrowsingContext::create_a_new_browsing_context(Pa auto realm_execution_context = Bindings::create_a_new_javascript_realm( Bindings::main_thread_vm(), [&](JS::Realm& realm) -> JS::Object* { + browsing_context->m_window_proxy = realm.heap().allocate(realm, realm); + // - For the global object, create a new Window object. window = HTML::Window::create(realm); return window.ptr(); }, - [](JS::Realm&) -> JS::Object* { - // FIXME: - For the global this binding, use browsingContext's WindowProxy object. - return nullptr; + [&](JS::Realm&) -> JS::Object* { + // - For the global this binding, use browsingContext's WindowProxy object. + return browsing_context->m_window_proxy; }); // 9. Let topLevelCreationURL be about:blank if embedder is null; otherwise embedder's relevant settings object's top-level creation URL. @@ -299,7 +302,7 @@ void BrowsingContext::set_active_document(JS::NonnullGCPtr docume document->set_visibility_state({}, top_level_browsing_context().system_visibility_state()); // 3. Set browsingContext's active window to window. - m_active_window = window; + m_window_proxy->set_window({}, window); // 4. Set window's associated Document to document. window.set_associated_document(document); @@ -792,26 +795,40 @@ bool BrowsingContext::still_on_its_initial_about_blank_document() const DOM::Document const* BrowsingContext::active_document() const { - if (!m_active_window) + auto* window = active_window(); + if (!window) return nullptr; - return &m_active_window->associated_document(); + return &window->associated_document(); } DOM::Document* BrowsingContext::active_document() { - if (!m_active_window) + auto* window = active_window(); + if (!window) return nullptr; - return &m_active_window->associated_document(); + return &window->associated_document(); } +// https://html.spec.whatwg.org/multipage/browsers.html#active-window HTML::Window* BrowsingContext::active_window() { - return m_active_window; + return m_window_proxy->window(); } +// https://html.spec.whatwg.org/multipage/browsers.html#active-window HTML::Window const* BrowsingContext::active_window() const { - return m_active_window; + return m_window_proxy->window(); +} + +HTML::WindowProxy* BrowsingContext::window_proxy() +{ + return m_window_proxy.ptr(); +} + +HTML::WindowProxy const* BrowsingContext::window_proxy() const +{ + return m_window_proxy.ptr(); } void BrowsingContext::scroll_offset_did_change() diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h index 65910ba39e..34b2d920a8 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.h +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.h @@ -49,6 +49,9 @@ public: void set_active_document(JS::NonnullGCPtr); + HTML::WindowProxy* window_proxy(); + HTML::WindowProxy const* window_proxy() const; + HTML::Window* active_window(); HTML::Window const* active_window() const; @@ -202,10 +205,12 @@ private: Optional m_creator_origin; WeakPtr m_container; - JS::Handle m_active_window; Gfx::IntSize m_size; Gfx::IntPoint m_viewport_scroll_offset; + // https://html.spec.whatwg.org/multipage/browsers.html#browsing-context + JS::Handle m_window_proxy; + DOM::Position m_cursor_position; RefPtr m_cursor_blink_timer; bool m_cursor_blink_state { false }; diff --git a/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp b/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp index 1a0947b555..c87446f10b 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp +++ b/Userland/Libraries/LibWeb/HTML/WindowProxy.cpp @@ -20,9 +20,8 @@ namespace Web::HTML { // 7.4 The WindowProxy exotic object, https://html.spec.whatwg.org/multipage/window-object.html#the-windowproxy-exotic-object -WindowProxy::WindowProxy(JS::Realm& realm, Window& window) +WindowProxy::WindowProxy(JS::Realm& realm) : JS::Object(realm, nullptr) - , m_window(window) { } @@ -256,4 +255,9 @@ void WindowProxy::visit_edges(JS::Cell::Visitor& visitor) visitor.visit(m_window.ptr()); } +void WindowProxy::set_window(Badge, JS::NonnullGCPtr window) +{ + m_window = window; +} + } diff --git a/Userland/Libraries/LibWeb/HTML/WindowProxy.h b/Userland/Libraries/LibWeb/HTML/WindowProxy.h index 75b87c9469..0b1de46879 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowProxy.h +++ b/Userland/Libraries/LibWeb/HTML/WindowProxy.h @@ -31,14 +31,11 @@ public: virtual JS::ThrowCompletionOr internal_delete(JS::PropertyKey const&) override; virtual JS::ThrowCompletionOr> internal_own_property_keys() const override; - Window& window() const { return const_cast(*m_window); } - - // NOTE: Someone will have to replace the wrapped window object as well: - // "When the browsing context is navigated, the Window object wrapped by the browsing context's associated WindowProxy object is changed." - // I haven't found where that actually happens yet. Make sure to use a Badge guarded setter. + JS::GCPtr window() const { return m_window; } + void set_window(Badge, JS::NonnullGCPtr); private: - WindowProxy(JS::Realm&, Window&); + explicit WindowProxy(JS::Realm&); virtual void visit_edges(JS::Cell::Visitor&) override;