From b98a2be96bf03562ec21e80b48d4b3b97ad74cd6 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 10 Mar 2024 08:41:18 +0100 Subject: [PATCH] LibWeb: Ignore window-forwarded document.body.onfoo in detached DOM Normally, assigning to e.g document.body.onload will forward to window.onload. However, in a detached DOM tree, there is no associated window, so we have nowhere to forward to, making this a no-op. The bulk of this change is making Document::window() return a nullable pointer, as documents created by DOMParser or DOMImplementation do not have an associated window object, and so must be able to return null from here. --- .../Window-event-handler-in-detached-DOM.txt | 1 + .../Window-event-handler-in-detached-DOM.html | 10 ++++++++++ .../LibWeb/Animations/DocumentTimeline.cpp | 2 +- .../Libraries/LibWeb/CSS/MediaQueryList.cpp | 6 +++++- .../LibWeb/CSS/Parser/ParsingContext.cpp | 4 +++- Userland/Libraries/LibWeb/DOM/Document.cpp | 20 +++++++++++++------ Userland/Libraries/LibWeb/DOM/Document.h | 4 ++-- Userland/Libraries/LibWeb/DOM/EventTarget.cpp | 6 +++--- Userland/Libraries/LibWeb/HTML/Focus.cpp | 4 ++-- .../LibWeb/HTML/GlobalEventHandlers.cpp | 19 ++++++++++-------- .../LibWeb/HTML/GlobalEventHandlers.h | 2 +- .../Libraries/LibWeb/HTML/HTMLBodyElement.cpp | 4 ++-- .../Libraries/LibWeb/HTML/HTMLBodyElement.h | 4 ++-- Userland/Libraries/LibWeb/HTML/HTMLElement.h | 2 +- .../LibWeb/HTML/HTMLFrameSetElement.cpp | 4 ++-- .../LibWeb/HTML/HTMLFrameSetElement.h | 4 ++-- .../LibWeb/HTML/HTMLImageElement.cpp | 2 +- .../Libraries/LibWeb/HTML/HTMLMetaElement.cpp | 2 +- .../LibWeb/HTML/Parser/HTMLParser.cpp | 6 +++--- Userland/Libraries/LibWeb/HTML/Window.cpp | 2 +- Userland/Libraries/LibWeb/HTML/Window.h | 4 ++-- .../LibWeb/HTML/WindowEventHandlers.cpp | 19 ++++++++++-------- .../LibWeb/HTML/WindowEventHandlers.h | 2 +- .../Libraries/LibWeb/MathML/MathMLElement.h | 2 +- .../ResizeObserver/ResizeObserverSize.cpp | 2 +- .../LibWeb/WebDriver/ExecuteScript.cpp | 8 ++++---- .../Libraries/LibWeb/WebDriver/Screenshot.cpp | 2 +- .../WebContent/ConnectionFromClient.cpp | 6 +++--- 28 files changed, 92 insertions(+), 61 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/HTML/Window-event-handler-in-detached-DOM.txt create mode 100644 Tests/LibWeb/Text/input/HTML/Window-event-handler-in-detached-DOM.html diff --git a/Tests/LibWeb/Text/expected/HTML/Window-event-handler-in-detached-DOM.txt b/Tests/LibWeb/Text/expected/HTML/Window-event-handler-in-detached-DOM.txt new file mode 100644 index 0000000000..aaecaf93c4 --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/Window-event-handler-in-detached-DOM.txt @@ -0,0 +1 @@ +PASS (didn't crash) diff --git a/Tests/LibWeb/Text/input/HTML/Window-event-handler-in-detached-DOM.html b/Tests/LibWeb/Text/input/HTML/Window-event-handler-in-detached-DOM.html new file mode 100644 index 0000000000..ef47c55155 --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/Window-event-handler-in-detached-DOM.html @@ -0,0 +1,10 @@ + + diff --git a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp index 6982cc3512..5f0bb816ee 100644 --- a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp +++ b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp @@ -19,7 +19,7 @@ JS_DEFINE_ALLOCATOR(DocumentTimeline); JS::NonnullGCPtr DocumentTimeline::create(JS::Realm& realm, DOM::Document& document, HighResolutionTime::DOMHighResTimeStamp origin_time) { auto timeline = realm.heap().allocate(realm, realm, document, origin_time); - timeline->set_current_time(document.window().performance()->now()); + timeline->set_current_time(document.window()->performance()->now()); return timeline; } diff --git a/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp b/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp index 0be05008a0..3f891e0142 100644 --- a/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp +++ b/Userland/Libraries/LibWeb/CSS/MediaQueryList.cpp @@ -60,9 +60,13 @@ bool MediaQueryList::matches() const bool MediaQueryList::evaluate() { + auto window = m_document->window(); + if (!window) + return false; + bool now_matches = false; for (auto& media : m_media) { - now_matches = now_matches || media->evaluate(m_document->window()); + now_matches = now_matches || media->evaluate(*window); } return now_matches; diff --git a/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp b/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp index 156523cce1..bd4585250c 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/ParsingContext.cpp @@ -56,7 +56,9 @@ URL ParsingContext::complete_url(StringView relative_url) const HTML::Window const* ParsingContext::window() const { - return m_document && m_document->default_view() ? &m_document->window() : nullptr; + if (!m_document) + return nullptr; + return m_document->window(); } } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 93629248d3..5a0da0a2b9 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -638,7 +638,7 @@ WebIDL::ExceptionOr> Document::open(StringView url, return WebIDL::InvalidAccessError::create(realm(), "Cannot perform open on a document that isn't fully active."_fly_string); // 2. Return the result of running the window open steps with url, name, and features. - return window().open_impl(url, name, features); + return window()->open_impl(url, name, features); } // https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#closing-the-input-stream @@ -2273,7 +2273,7 @@ JS::GCPtr Document::location() if (!is_fully_active()) return nullptr; - return window().location(); + return window()->location(); } // https://html.spec.whatwg.org/multipage/interaction.html#dom-document-hidden @@ -2330,7 +2330,7 @@ void Document::run_the_resize_steps() return; m_last_viewport_size = viewport_size; - window().dispatch_event(DOM::Event::create(realm(), UIEvents::EventNames::resize)); + window()->dispatch_event(DOM::Event::create(realm(), UIEvents::EventNames::resize)); schedule_layout_update(); } @@ -2401,9 +2401,13 @@ void Document::evaluate_media_queries_and_report_changes() void Document::evaluate_media_rules() { + auto window = this->window(); + if (!window) + return; + bool any_media_queries_changed_match_state = false; for (auto& style_sheet : style_sheets().sheets()) { - if (style_sheet->evaluate_media_queries(window())) + if (style_sheet->evaluate_media_queries(*window)) any_media_queries_changed_match_state = true; } @@ -3305,6 +3309,10 @@ void Document::unregister_resize_observer(Badge, // https://www.w3.org/TR/intersection-observer/#queue-an-intersection-observer-task void Document::queue_intersection_observer_task() { + auto window = this->window(); + if (!window) + return; + // 1. If document’s IntersectionObserverTaskQueued flag is set to true, return. if (m_intersection_observer_task_queued) return; @@ -3313,7 +3321,7 @@ void Document::queue_intersection_observer_task() m_intersection_observer_task_queued = true; // 3. Queue a task on the IntersectionObserver task source associated with the document's event loop to notify intersection observers. - HTML::queue_global_task(HTML::Task::Source::IntersectionObserver, window(), [this]() { + HTML::queue_global_task(HTML::Task::Source::IntersectionObserver, *window, [this]() { auto& realm = this->realm(); // https://www.w3.org/TR/intersection-observer/#notify-intersection-observers @@ -4039,7 +4047,7 @@ void Document::ensure_animation_timer() return; } - update_animations_and_send_events(window().performance()->now()); + update_animations_and_send_events(window()->performance()->now()); for (auto& timeline : m_associated_animation_timelines) { for (auto& animation : timeline->associated_animations()) diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index fbae8afca4..378321185f 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -317,7 +317,7 @@ public: HTML::DocumentReadyState readiness() const { return m_readiness; } void update_readiness(HTML::DocumentReadyState); - HTML::Window& window() const { return const_cast(*m_window); } + [[nodiscard]] JS::GCPtr window() const { return m_window; } void set_window(HTML::Window&); @@ -616,7 +616,7 @@ protected: private: // ^HTML::GlobalEventHandlers - virtual EventTarget& global_event_handlers_to_event_target(FlyString const&) final { return *this; } + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const&) final { return *this; } void tear_down_layout_tree(); diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp index 11d709b0d5..1f44b67a48 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp @@ -327,7 +327,7 @@ static EventTarget* determine_target_of_event_handler(EventTarget& event_target, return nullptr; // 4. Return eventTarget's node document's relevant global object. - return &event_target_element.document().window(); + return &verify_cast(HTML::relevant_global_object(event_target_element.document())); } // https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:event-handler-idl-attributes-2 @@ -807,8 +807,8 @@ bool EventTarget::dispatch_event(Event& event) static_cast(this)->set_last_activation_timestamp(current_time); } else if (is(this)) { auto const* element = static_cast(this); - auto& window = element->document().window(); - window.set_last_activation_timestamp(current_time); + if (auto window = element->document().window()) + window->set_last_activation_timestamp(current_time); } } diff --git a/Userland/Libraries/LibWeb/HTML/Focus.cpp b/Userland/Libraries/LibWeb/HTML/Focus.cpp index 7fc25b38d8..b4589ce09e 100644 --- a/Userland/Libraries/LibWeb/HTML/Focus.cpp +++ b/Userland/Libraries/LibWeb/HTML/Focus.cpp @@ -55,7 +55,7 @@ static void run_focus_update_steps(Vector> old_chain, Vect blur_event_target = entry.ptr(); } else if (is(*entry)) { // If entry is a Document object, let blur event target be that Document object's relevant global object. - blur_event_target = &static_cast(*entry).window(); + blur_event_target = static_cast(*entry).window(); } // 3. If entry is the last entry in old chain, and entry is an Element, @@ -105,7 +105,7 @@ static void run_focus_update_steps(Vector> old_chain, Vect focus_event_target = entry.ptr(); } else if (is(*entry)) { // If entry is a Document object, let focus event target be that Document object's relevant global object. - focus_event_target = &static_cast(*entry).window(); + focus_event_target = static_cast(*entry).window(); } // 3. If entry is the last entry in new chain, and entry is an Element, diff --git a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp index 8bef4f4d21..45cdb1e103 100644 --- a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp +++ b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.cpp @@ -12,14 +12,17 @@ namespace Web::HTML { #undef __ENUMERATE -#define __ENUMERATE(attribute_name, event_name) \ - void GlobalEventHandlers::set_##attribute_name(WebIDL::CallbackType* value) \ - { \ - global_event_handlers_to_event_target(event_name).set_event_handler_attribute(event_name, value); \ - } \ - WebIDL::CallbackType* GlobalEventHandlers::attribute_name() \ - { \ - return global_event_handlers_to_event_target(event_name).event_handler_attribute(event_name); \ +#define __ENUMERATE(attribute_name, event_name) \ + void GlobalEventHandlers::set_##attribute_name(WebIDL::CallbackType* value) \ + { \ + if (auto event_target = global_event_handlers_to_event_target(event_name)) \ + event_target->set_event_handler_attribute(event_name, value); \ + } \ + WebIDL::CallbackType* GlobalEventHandlers::attribute_name() \ + { \ + if (auto event_target = global_event_handlers_to_event_target(event_name)) \ + return event_target->event_handler_attribute(event_name); \ + return nullptr; \ } ENUMERATE_GLOBAL_EVENT_HANDLERS(__ENUMERATE) #undef __ENUMERATE diff --git a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h index 79e7d48b8b..7c2a4b2e4f 100644 --- a/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h +++ b/Userland/Libraries/LibWeb/HTML/GlobalEventHandlers.h @@ -94,7 +94,7 @@ public: #undef __ENUMERATE protected: - virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) = 0; + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const& event_name) = 0; }; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.cpp index 23d60d5cd1..77613fe385 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.cpp @@ -94,7 +94,7 @@ void HTMLBodyElement::attribute_changed(FlyString const& name, Optional #undef __ENUMERATE } -DOM::EventTarget& HTMLBodyElement::global_event_handlers_to_event_target(FlyString const& event_name) +JS::GCPtr HTMLBodyElement::global_event_handlers_to_event_target(FlyString const& event_name) { // NOTE: This is a little weird, but IIUC document.body.onload actually refers to window.onload // NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping. @@ -104,7 +104,7 @@ DOM::EventTarget& HTMLBodyElement::global_event_handlers_to_event_target(FlyStri return *this; } -DOM::EventTarget& HTMLBodyElement::window_event_handlers_to_event_target() +JS::GCPtr HTMLBodyElement::window_event_handlers_to_event_target() { // All WindowEventHandlers on HTMLFrameSetElement (e.g. document.body.onrejectionhandled) are mapped to window.on{event}. // NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping. diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.h b/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.h index 870a5aa41c..ba172b2505 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLBodyElement.h @@ -38,10 +38,10 @@ private: virtual void initialize(JS::Realm&) override; // ^HTML::GlobalEventHandlers - virtual EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) override; + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const& event_name) override; // ^HTML::WindowEventHandlers - virtual EventTarget& window_event_handlers_to_event_target() override; + virtual JS::GCPtr window_event_handlers_to_event_target() override; RefPtr m_background_style_value; }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLElement.h b/Userland/Libraries/LibWeb/HTML/HTMLElement.h index dea86d592e..1719c636eb 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLElement.h @@ -82,7 +82,7 @@ private: virtual bool is_html_element() const final { return true; } // ^HTML::GlobalEventHandlers - virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; } + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const&) override { return *this; } virtual void did_receive_focus() override; JS::GCPtr m_dataset; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.cpp index 0f98059f31..bf9fcf04b3 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.cpp @@ -38,7 +38,7 @@ void HTMLFrameSetElement::attribute_changed(FlyString const& name, Optional HTMLFrameSetElement::global_event_handlers_to_event_target(FlyString const& event_name) { // NOTE: This is a little weird, but IIUC document.body.onload actually refers to window.onload // NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping. @@ -48,7 +48,7 @@ DOM::EventTarget& HTMLFrameSetElement::global_event_handlers_to_event_target(Fly return *this; } -DOM::EventTarget& HTMLFrameSetElement::window_event_handlers_to_event_target() +JS::GCPtr HTMLFrameSetElement::window_event_handlers_to_event_target() { // All WindowEventHandlers on HTMLFrameSetElement (e.g. document.body.onrejectionhandled) are mapped to window.on{event}. // NOTE: document.body can return either a HTMLBodyElement or HTMLFrameSetElement, so both these elements must support this mapping. diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.h b/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.h index 2afcf99b62..17d32c8ae7 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLFrameSetElement.h @@ -28,10 +28,10 @@ private: virtual void attribute_changed(FlyString const&, Optional const&) override; // ^HTML::GlobalEventHandlers - virtual EventTarget& global_event_handlers_to_event_target(FlyString const& event_name) override; + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const& event_name) override; // ^HTML::WindowEventHandlers - virtual EventTarget& window_event_handlers_to_event_target() override; + virtual JS::GCPtr window_event_handlers_to_event_target() override; }; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index c6e94eb8cc..280a9f6664 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -941,7 +941,7 @@ static void update_the_source_set(DOM::Element& element) if (child->has_attribute(HTML::AttributeNames::media)) { auto media_query = parse_media_query(CSS::Parser::ParsingContext { element.document() }, child->get_attribute_value(HTML::AttributeNames::media)); - if (!media_query || !media_query->evaluate(element.document().window())) { + if (!media_query || !element.document().window() || !media_query->evaluate(*element.document().window())) { continue; } } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMetaElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLMetaElement.cpp index 29ee5755e0..2bf21c45e5 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMetaElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLMetaElement.cpp @@ -64,7 +64,7 @@ void HTMLMetaElement::inserted() auto media = attribute(AttributeNames::media); if (media.has_value()) { auto query = parse_media_query(context, media.value()); - if (!query->evaluate(document().window())) + if (document().window() && !query->evaluate(*document().window())) return; } diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 5932da8005..527562be1e 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -328,7 +328,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr document, JS::GCPtr window = document->window(); + auto& window = verify_cast(relevant_global_object(*document)); // 4. Set the Document's load timing info's load event start time to the current high resolution time given window. document->load_timing_info().load_event_start_time = HighResolutionTime::unsafe_shared_current_time(); @@ -336,7 +336,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr document, JS::GCPtrdispatch_event(DOM::Event::create(document->realm(), HTML::EventNames::load)); + window.dispatch_event(DOM::Event::create(document->realm(), HTML::EventNames::load)); // FIXME: 6. Invoke WebDriver BiDi load complete with the Document's browsing context, and a new WebDriver BiDi navigation status whose id is the Document object's navigation id, status is "complete", and url is the Document object's URL. @@ -352,7 +352,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr document, JS::GCPtrset_page_showing(true); // 11. Fire a page transition event named pageshow at window with false. - window->fire_a_page_transition_event(HTML::EventNames::pageshow, false); + window.fire_a_page_transition_event(HTML::EventNames::pageshow, false); // 12. Completely finish loading the Document. document->completely_finish_loading(); diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index 2c2a36456e..657aa7fccf 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -79,7 +79,7 @@ JS_DEFINE_ALLOCATOR(Window); void run_animation_frame_callbacks(DOM::Document& document, double now) { // FIXME: Bring this closer to the spec. - document.window().animation_frame_callback_driver().run(now); + document.window()->animation_frame_callback_driver().run(now); } class IdleCallback : public RefCounted { diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h index bf6ac081dd..9fae9fb118 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.h +++ b/Userland/Libraries/LibWeb/HTML/Window.h @@ -218,10 +218,10 @@ private: virtual void finalize() override; // ^HTML::GlobalEventHandlers - virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; } + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const&) override { return *this; } // ^HTML::WindowEventHandlers - virtual DOM::EventTarget& window_event_handlers_to_event_target() override { return *this; } + virtual JS::GCPtr window_event_handlers_to_event_target() override { return *this; } void invoke_idle_callbacks(); diff --git a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp index c80c4847c3..4061caea78 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp +++ b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.cpp @@ -11,14 +11,17 @@ namespace Web::HTML { #undef __ENUMERATE -#define __ENUMERATE(attribute_name, event_name) \ - void WindowEventHandlers::set_##attribute_name(WebIDL::CallbackType* value) \ - { \ - window_event_handlers_to_event_target().set_event_handler_attribute(event_name, value); \ - } \ - WebIDL::CallbackType* WindowEventHandlers::attribute_name() \ - { \ - return window_event_handlers_to_event_target().event_handler_attribute(event_name); \ +#define __ENUMERATE(attribute_name, event_name) \ + void WindowEventHandlers::set_##attribute_name(WebIDL::CallbackType* value) \ + { \ + if (auto event_target = window_event_handlers_to_event_target()) \ + event_target->set_event_handler_attribute(event_name, value); \ + } \ + WebIDL::CallbackType* WindowEventHandlers::attribute_name() \ + { \ + if (auto event_target = window_event_handlers_to_event_target()) \ + return event_target->event_handler_attribute(event_name); \ + return nullptr; \ } ENUMERATE_WINDOW_EVENT_HANDLERS(__ENUMERATE) #undef __ENUMERATE diff --git a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h index e5e8ce5f75..226c7d8794 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h +++ b/Userland/Libraries/LibWeb/HTML/WindowEventHandlers.h @@ -41,7 +41,7 @@ public: #undef __ENUMERATE protected: - virtual DOM::EventTarget& window_event_handlers_to_event_target() = 0; + virtual JS::GCPtr window_event_handlers_to_event_target() = 0; }; } diff --git a/Userland/Libraries/LibWeb/MathML/MathMLElement.h b/Userland/Libraries/LibWeb/MathML/MathMLElement.h index 613bce5d46..d59a0bc0a2 100644 --- a/Userland/Libraries/LibWeb/MathML/MathMLElement.h +++ b/Userland/Libraries/LibWeb/MathML/MathMLElement.h @@ -29,7 +29,7 @@ public: void blur(); protected: - virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; } + virtual JS::GCPtr global_event_handlers_to_event_target(FlyString const&) override { return *this; } private: MathMLElement(DOM::Document&, DOM::QualifiedName); diff --git a/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserverSize.cpp b/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserverSize.cpp index 85d3533575..64cbe591d6 100644 --- a/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserverSize.cpp +++ b/Userland/Libraries/LibWeb/ResizeObserver/ResizeObserverSize.cpp @@ -44,7 +44,7 @@ JS::NonnullGCPtr ResizeObserverSize::calculate_box_size(JS:: computed_size->set_block_size(paintable_box.content_height().to_double()); break; case Bindings::ResizeObserverBoxOptions::DevicePixelContentBox: { - auto device_pixel_ratio = target.document().window().device_pixel_ratio(); + auto device_pixel_ratio = target.document().window()->device_pixel_ratio(); // 1. Set computedSize’s inlineSize attribute to target’s content area inline length, in integral device pixels. computed_size->set_inline_size(paintable_box.border_box_width().to_double() * device_pixel_ratio); // 2. Set computedSize’s blockSize attribute to target’s content area block length, in integral device pixels. diff --git a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index d346c1a788..a3561a818b 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -227,15 +227,15 @@ static JS::ThrowCompletionOr execute_a_function_body(Web::Page& page, // 1. Let window be the associated window of the current browsing context’s active document. // FIXME: This will need adjusting when WebDriver supports frames. - auto& window = page.top_level_browsing_context().active_document()->window(); + auto window = page.top_level_browsing_context().active_document()->window(); // 2. Let environment settings be the environment settings object for window. - auto& environment_settings = Web::HTML::relevant_settings_object(window); + auto& environment_settings = Web::HTML::relevant_settings_object(*window); // 3. Let global scope be environment settings realm’s global environment. auto& global_scope = environment_settings.realm().global_environment(); - auto& realm = window.realm(); + auto& realm = window->realm(); bool contains_direct_call_to_eval = false; auto source_text = ByteString::formatted("function() {{ {} }}", body); @@ -271,7 +271,7 @@ static JS::ThrowCompletionOr execute_a_function_body(Web::Page& page, // 9. Let completion be Function.[[Call]](window, parameters) with function as the this value. // NOTE: This is not entirely clear, but I don't think they mean actually passing `function` as // the this value argument, but using it as the object [[Call]] is executed on. - auto completion = function->internal_call(&window, move(parameters)); + auto completion = function->internal_call(window, move(parameters)); // 10. Clean up after running a callback with environment settings. environment_settings.clean_up_after_running_callback(); diff --git a/Userland/Libraries/LibWeb/WebDriver/Screenshot.cpp b/Userland/Libraries/LibWeb/WebDriver/Screenshot.cpp index 4edbeea8a8..597f610207 100644 --- a/Userland/Libraries/LibWeb/WebDriver/Screenshot.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/Screenshot.cpp @@ -54,7 +54,7 @@ Response capture_element_screenshot(Painter const& painter, Page& page, DOM::Ele { Optional encoded_string_or_error; - element.document().window().animation_frame_callback_driver().add([&](auto) { + element.document().window()->animation_frame_callback_driver().add([&](auto) { auto viewport_rect = page.top_level_traversable()->viewport_rect(); rect.intersect(page.enclosing_device_rect(viewport_rect).to_type()); diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index cdc8eb5424..e93e08707e 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -436,7 +436,7 @@ void ConnectionFromClient::debug_request(u64 page_id, ByteString const& request, if (request == "dump-local-storage") { if (auto* document = page.page().top_level_browsing_context().active_document()) - document->window().local_storage().release_value_but_fixme_should_propagate_errors()->dump(); + document->window()->local_storage().release_value_but_fixme_should_propagate_errors()->dump(); return; } @@ -1086,7 +1086,7 @@ Messages::WebContentServer::GetLocalStorageEntriesResponse ConnectionFromClient: auto& page = maybe_page.release_value(); auto* document = page.page().top_level_browsing_context().active_document(); - auto local_storage = document->window().local_storage().release_value_but_fixme_should_propagate_errors(); + auto local_storage = document->window()->local_storage().release_value_but_fixme_should_propagate_errors(); return local_storage->map(); } @@ -1100,7 +1100,7 @@ Messages::WebContentServer::GetSessionStorageEntriesResponse ConnectionFromClien auto& page = maybe_page.release_value(); auto* document = page.page().top_level_browsing_context().active_document(); - auto session_storage = document->window().session_storage().release_value_but_fixme_should_propagate_errors(); + auto session_storage = document->window()->session_storage().release_value_but_fixme_should_propagate_errors(); return session_storage->map(); }