From 9c04c1050d0706c0af335e8856db4ed481035ee2 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 26 Oct 2024 21:02:28 +1300 Subject: [PATCH 1/5] LibWeb: Rename Bindings::HostDefined to Bindings::PrincipalHostDefined With the introduction of shadow realms, there will be two different possible host defined objects. For clarity, rename the existing host defined object to PrincipalHostDefined. --- .../Libraries/LibWeb/Bindings/HostDefined.h | 46 ------------------- .../Libraries/LibWeb/Bindings/Intrinsics.h | 4 +- ...stDefined.cpp => PrincipalHostDefined.cpp} | 4 +- .../LibWeb/Bindings/PrincipalHostDefined.h | 46 +++++++++++++++++++ Userland/Libraries/LibWeb/CMakeLists.txt | 2 +- .../Libraries/LibWeb/Clipboard/Clipboard.cpp | 1 - Userland/Libraries/LibWeb/DOM/Document.cpp | 6 +-- Userland/Libraries/LibWeb/DOM/EventTarget.cpp | 2 +- Userland/Libraries/LibWeb/Fetch/Body.cpp | 1 - .../Libraries/LibWeb/Fetch/FetchMethod.cpp | 1 - .../Fetch/Fetching/FetchedDataReceiver.cpp | 1 - .../LibWeb/Fetch/Fetching/Fetching.cpp | 4 +- .../IncrementalReadLoopReadRequest.cpp | 1 - Userland/Libraries/LibWeb/FileAPI/Blob.cpp | 2 +- .../Libraries/LibWeb/HTML/BrowsingContext.cpp | 2 +- .../LibWeb/HTML/HTMLDialogElement.cpp | 4 +- .../LibWeb/HTML/HTMLInputElement.cpp | 18 ++++---- .../LibWeb/HTML/Scripting/Environments.cpp | 10 ++-- .../LibWeb/HTML/Scripting/ImportMap.cpp | 1 - .../WindowEnvironmentSettingsObject.cpp | 4 +- .../WorkerEnvironmentSettingsObject.cpp | 2 +- .../LibWeb/HTML/SharedResourceRequest.cpp | 2 +- .../Libraries/LibWeb/HTML/WorkerAgent.cpp | 4 +- .../LibWeb/WebIDL/AbstractOperations.h | 1 - Userland/Libraries/LibWeb/WebIDL/Promise.cpp | 1 - 25 files changed, 81 insertions(+), 89 deletions(-) delete mode 100644 Userland/Libraries/LibWeb/Bindings/HostDefined.h rename Userland/Libraries/LibWeb/Bindings/{HostDefined.cpp => PrincipalHostDefined.cpp} (80%) create mode 100644 Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.h diff --git a/Userland/Libraries/LibWeb/Bindings/HostDefined.h b/Userland/Libraries/LibWeb/Bindings/HostDefined.h deleted file mode 100644 index 911df1b09c48..000000000000 --- a/Userland/Libraries/LibWeb/Bindings/HostDefined.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2022, Andrew Kaster - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include -#include - -namespace Web::Bindings { - -struct HostDefined : public JS::Realm::HostDefined { - HostDefined(JS::NonnullGCPtr eso, JS::NonnullGCPtr intrinsics, JS::NonnullGCPtr page) - : environment_settings_object(eso) - , intrinsics(intrinsics) - , page(page) - { - } - virtual ~HostDefined() override = default; - virtual void visit_edges(JS::Cell::Visitor& visitor) override; - - JS::NonnullGCPtr environment_settings_object; - JS::NonnullGCPtr intrinsics; - JS::NonnullGCPtr page; -}; - -[[nodiscard]] inline HTML::EnvironmentSettingsObject& host_defined_environment_settings_object(JS::Realm& realm) -{ - return *verify_cast(realm.host_defined())->environment_settings_object; -} - -[[nodiscard]] inline HTML::EnvironmentSettingsObject const& host_defined_environment_settings_object(JS::Realm const& realm) -{ - return *verify_cast(realm.host_defined())->environment_settings_object; -} - -[[nodiscard]] inline Page& host_defined_page(JS::Realm& realm) -{ - return *verify_cast(realm.host_defined())->page; -} - -} diff --git a/Userland/Libraries/LibWeb/Bindings/Intrinsics.h b/Userland/Libraries/LibWeb/Bindings/Intrinsics.h index 8dfd13bd786b..23ecb5b505e0 100644 --- a/Userland/Libraries/LibWeb/Bindings/Intrinsics.h +++ b/Userland/Libraries/LibWeb/Bindings/Intrinsics.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #define WEB_SET_PROTOTYPE_FOR_INTERFACE_WITH_CUSTOM_NAME(interface_class, interface_name) \ do { \ @@ -84,7 +84,7 @@ class Intrinsics final : public JS::Cell { [[nodiscard]] inline Intrinsics& host_defined_intrinsics(JS::Realm& realm) { - return *verify_cast(realm.host_defined())->intrinsics; + return *verify_cast(realm.host_defined())->intrinsics; } template diff --git a/Userland/Libraries/LibWeb/Bindings/HostDefined.cpp b/Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.cpp similarity index 80% rename from Userland/Libraries/LibWeb/Bindings/HostDefined.cpp rename to Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.cpp index 4dd279eecf76..a5c2c60a51df 100644 --- a/Userland/Libraries/LibWeb/Bindings/HostDefined.cpp +++ b/Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.cpp @@ -6,14 +6,14 @@ #include #include -#include #include +#include #include #include namespace Web::Bindings { -void HostDefined::visit_edges(JS::Cell::Visitor& visitor) +void PrincipalHostDefined::visit_edges(JS::Cell::Visitor& visitor) { JS::Realm::HostDefined::visit_edges(visitor); visitor.visit(environment_settings_object); diff --git a/Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.h b/Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.h new file mode 100644 index 000000000000..d0d465a0aba7 --- /dev/null +++ b/Userland/Libraries/LibWeb/Bindings/PrincipalHostDefined.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022, Andrew Kaster + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Web::Bindings { + +struct PrincipalHostDefined : public JS::Realm::HostDefined { + PrincipalHostDefined(JS::NonnullGCPtr eso, JS::NonnullGCPtr intrinsics, JS::NonnullGCPtr page) + : environment_settings_object(eso) + , intrinsics(intrinsics) + , page(page) + { + } + virtual ~PrincipalHostDefined() override = default; + virtual void visit_edges(JS::Cell::Visitor& visitor) override; + + JS::NonnullGCPtr environment_settings_object; + JS::NonnullGCPtr intrinsics; + JS::NonnullGCPtr page; +}; + +[[nodiscard]] inline HTML::EnvironmentSettingsObject& principal_host_defined_environment_settings_object(JS::Realm& realm) +{ + return *verify_cast(realm.host_defined())->environment_settings_object; +} + +[[nodiscard]] inline HTML::EnvironmentSettingsObject const& principal_host_defined_environment_settings_object(JS::Realm const& realm) +{ + return *verify_cast(realm.host_defined())->environment_settings_object; +} + +[[nodiscard]] inline Page& principal_host_defined_page(JS::Realm& realm) +{ + return *verify_cast(realm.host_defined())->page; +} + +} diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index b022eb040a4a..0812e4ed72a7 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -16,13 +16,13 @@ set(SOURCES ARIA/RoleType.cpp ARIA/StateAndProperties.cpp Bindings/AudioConstructor.cpp - Bindings/HostDefined.cpp Bindings/ImageConstructor.cpp Bindings/Intrinsics.cpp Bindings/LocationConstructor.cpp Bindings/MainThreadVM.cpp Bindings/OptionConstructor.cpp Bindings/PlatformObject.cpp + Bindings/PrincipalHostDefined.cpp Clipboard/Clipboard.cpp Clipboard/ClipboardEvent.cpp Crypto/Crypto.cpp diff --git a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp index 06f9d8d2426f..f2e224e1621e 100644 --- a/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp +++ b/Userland/Libraries/LibWeb/Clipboard/Clipboard.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index f1b61e2d7760..f22d272868de 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -383,7 +383,7 @@ JS::NonnullGCPtr Document::create_for_fragment_parsing(JS::Realm& real Document::Document(JS::Realm& realm, const URL::URL& url, TemporaryDocumentForFragmentParsing temporary_document_for_fragment_parsing) : ParentNode(realm, *this, NodeType::DOCUMENT_NODE) - , m_page(Bindings::host_defined_page(realm)) + , m_page(Bindings::principal_host_defined_page(realm)) , m_style_computer(make(*this)) , m_url(url) , m_temporary_document_for_fragment_parsing(temporary_document_for_fragment_parsing) @@ -1649,7 +1649,7 @@ Color Document::visited_link_color() const HTML::EnvironmentSettingsObject& Document::relevant_settings_object() const { // Then, the relevant settings object for a platform object o is the environment settings object of the relevant Realm for o. - return Bindings::host_defined_environment_settings_object(realm()); + return Bindings::principal_host_defined_environment_settings_object(realm()); } // https://dom.spec.whatwg.org/#dom-document-createelement @@ -4171,7 +4171,7 @@ void Document::start_intersection_observing_a_lazy_loading_element(Element& elem // Spec Note: This allows for fetching the image during scrolling, when it does not yet — but is about to — intersect the viewport. auto options = IntersectionObserver::IntersectionObserverInit {}; - auto wrapped_callback = realm.heap().allocate_without_realm(callback, Bindings::host_defined_environment_settings_object(realm)); + auto wrapped_callback = realm.heap().allocate_without_realm(callback, Bindings::principal_host_defined_environment_settings_object(realm)); m_lazy_load_intersection_observer = IntersectionObserver::IntersectionObserver::construct_impl(realm, wrapped_callback, options).release_value_but_fixme_should_propagate_errors(); } diff --git a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp index 00180f63ad92..63440573e2fe 100644 --- a/Userland/Libraries/LibWeb/DOM/EventTarget.cpp +++ b/Userland/Libraries/LibWeb/DOM/EventTarget.cpp @@ -590,7 +590,7 @@ void EventTarget::activate_event_handler(FlyString const& name, HTML::EventHandl 0, "", &realm); // NOTE: As per the spec, the callback context is arbitrary. - auto callback = realm.heap().allocate_without_realm(*callback_function, Bindings::host_defined_environment_settings_object(realm)); + auto callback = realm.heap().allocate_without_realm(*callback_function, Bindings::principal_host_defined_environment_settings_object(realm)); // 5. Let listener be a new event listener whose type is the event handler event type corresponding to eventHandler and callback is callback. auto listener = realm.heap().allocate_without_realm(); diff --git a/Userland/Libraries/LibWeb/Fetch/Body.cpp b/Userland/Libraries/LibWeb/Fetch/Body.cpp index 69abea24488d..76bd196e2e96 100644 --- a/Userland/Libraries/LibWeb/Fetch/Body.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Body.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp b/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp index 42679f5e0bf9..05067f95d35e 100644 --- a/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp +++ b/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.cpp index 8540cb1a4e92..c8b98d4c2528 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/FetchedDataReceiver.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index ae4fc1884180..94ad38f4e879 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -1833,7 +1833,7 @@ WebIDL::ExceptionOr> http_network_or_cache_fet // with the user agent’s cookie store and httpRequest’s current URL. auto cookies = ([&] { // FIXME: Getting to the page client reliably is way too complicated, and going via the document won't work in workers. - auto document = Bindings::host_defined_environment_settings_object(realm).responsible_document(); + auto document = Bindings::principal_host_defined_environment_settings_object(realm).responsible_document(); if (!document) return String {}; return document->page().client().page_did_request_cookie(http_request->current_url(), Cookie::Source::Http); @@ -2193,7 +2193,7 @@ WebIDL::ExceptionOr> nonstandard_resource_load auto request = fetch_params.request(); - auto& page = Bindings::host_defined_page(realm); + auto& page = Bindings::principal_host_defined_page(realm); // NOTE: Using LoadRequest::create_for_url_on_page here will unconditionally add cookies as long as there's a page available. // However, it is up to http_network_or_cache_fetch to determine if cookies should be added to the request. diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/IncrementalReadLoopReadRequest.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/IncrementalReadLoopReadRequest.cpp index 932aaf480400..0ec13989c9c9 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/IncrementalReadLoopReadRequest.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/IncrementalReadLoopReadRequest.cpp @@ -5,7 +5,6 @@ */ #include -#include #include #include diff --git a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp index aa9880c74108..a5c54ed7fc3c 100644 --- a/Userland/Libraries/LibWeb/FileAPI/Blob.cpp +++ b/Userland/Libraries/LibWeb/FileAPI/Blob.cpp @@ -341,7 +341,7 @@ JS::NonnullGCPtr Blob::get_stream() // onto the realm's VM, and we need an incumbent realm which is pushed onto the incumbent realm stack // by HTML::prepare_to_run_callback(). auto& realm = stream->realm(); - auto& environment_settings = Bindings::host_defined_environment_settings_object(realm); + auto& environment_settings = Bindings::principal_host_defined_environment_settings_object(realm); realm.vm().push_execution_context(environment_settings.realm_execution_context()); HTML::prepare_to_run_callback(realm); ScopeGuard const guard = [&realm] { diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index 13b143f7213b..f38aac0aa00e 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -210,7 +210,7 @@ WebIDL::ExceptionOr BrowsingContext auto load_timing_info = DOM::DocumentLoadTimingInfo(); load_timing_info.navigation_start_time = HighResolutionTime::coarsen_time( unsafe_context_creation_time, - verify_cast(Bindings::host_defined_environment_settings_object(window->realm())).cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::Yes); + verify_cast(Bindings::principal_host_defined_environment_settings_object(window->realm())).cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::Yes); // 15. Let document be a new Document, with: auto document = HTML::HTMLDocument::create(window->realm()); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.cpp index 444b84167c9e..d619365dcfc7 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLDialogElement.cpp @@ -124,7 +124,7 @@ WebIDL::ExceptionOr HTMLDialogElement::show_modal() return JS::js_undefined(); }, 0, "", &realm()); - auto cancel_callback = realm().heap().allocate_without_realm(*cancel_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto cancel_callback = realm().heap().allocate_without_realm(*cancel_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); m_close_watcher->add_event_listener_without_options(HTML::EventNames::cancel, DOM::IDLEventListener::create(realm(), cancel_callback)); // - closeAction being to close the dialog given this and null. auto close_callback_function = JS::NativeFunction::create( @@ -134,7 +134,7 @@ WebIDL::ExceptionOr HTMLDialogElement::show_modal() return JS::js_undefined(); }, 0, "", &realm()); - auto close_callback = realm().heap().allocate_without_realm(*close_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto close_callback = realm().heap().allocate_without_realm(*close_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); m_close_watcher->add_event_listener_without_options(HTML::EventNames::close, DOM::IDLEventListener::create(realm(), close_callback)); // FIXME: 11. Set this's previously focused element to the focused element. diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index d14771f58450..b6a299a05943 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -894,7 +894,7 @@ void HTMLInputElement::create_text_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto mouseup_callback = realm().heap().allocate_without_realm(*mouseup_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto mouseup_callback = realm().heap().allocate_without_realm(*mouseup_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); DOM::AddEventListenerOptions mouseup_listener_options; mouseup_listener_options.once = true; @@ -907,7 +907,7 @@ void HTMLInputElement::create_text_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto step_up_callback = realm().heap().allocate_without_realm(*up_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto step_up_callback = realm().heap().allocate_without_realm(*up_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); up_button->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_up_callback)); up_button->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback)); @@ -929,7 +929,7 @@ void HTMLInputElement::create_text_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto step_down_callback = realm().heap().allocate_without_realm(*down_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto step_down_callback = realm().heap().allocate_without_realm(*down_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); down_button->add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), step_down_callback)); down_button->add_event_listener_without_options(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback)); } @@ -988,7 +988,7 @@ void HTMLInputElement::create_file_input_shadow_tree() }; auto on_button_click_function = JS::NativeFunction::create(realm, move(on_button_click), 0, "", &realm); - auto on_button_click_callback = realm.heap().allocate_without_realm(on_button_click_function, Bindings::host_defined_environment_settings_object(realm)); + auto on_button_click_callback = realm.heap().allocate_without_realm(on_button_click_function, Bindings::principal_host_defined_environment_settings_object(realm)); m_file_button->add_event_listener_without_options(UIEvents::EventNames::click, DOM::IDLEventListener::create(realm, on_button_click_callback)); update_file_input_shadow_tree(); @@ -1060,7 +1060,7 @@ void HTMLInputElement::create_range_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto keydown_callback = realm().heap().allocate_without_realm(*keydown_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto keydown_callback = realm().heap().allocate_without_realm(*keydown_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); add_event_listener_without_options(UIEvents::EventNames::keydown, DOM::IDLEventListener::create(realm(), keydown_callback)); auto wheel_callback_function = JS::NativeFunction::create( @@ -1075,7 +1075,7 @@ void HTMLInputElement::create_range_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto wheel_callback = realm().heap().allocate_without_realm(*wheel_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto wheel_callback = realm().heap().allocate_without_realm(*wheel_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); add_event_listener_without_options(UIEvents::EventNames::wheel, DOM::IDLEventListener::create(realm(), wheel_callback)); auto update_slider_by_mouse = [this](JS::VM& vm) { @@ -1098,7 +1098,7 @@ void HTMLInputElement::create_range_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto mousemove_callback = realm().heap().allocate_without_realm(*mousemove_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto mousemove_callback = realm().heap().allocate_without_realm(*mousemove_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); auto mousemove_listener = DOM::IDLEventListener::create(realm(), mousemove_callback); auto& window = static_cast(relevant_global_object(*this)); window.add_event_listener_without_options(UIEvents::EventNames::mousemove, mousemove_listener); @@ -1110,7 +1110,7 @@ void HTMLInputElement::create_range_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto mouseup_callback = realm().heap().allocate_without_realm(*mouseup_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto mouseup_callback = realm().heap().allocate_without_realm(*mouseup_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); DOM::AddEventListenerOptions mouseup_listener_options; mouseup_listener_options.once = true; window.add_event_listener(UIEvents::EventNames::mouseup, DOM::IDLEventListener::create(realm(), mouseup_callback), mouseup_listener_options); @@ -1118,7 +1118,7 @@ void HTMLInputElement::create_range_input_shadow_tree() return JS::js_undefined(); }, 0, "", &realm()); - auto mousedown_callback = realm().heap().allocate_without_realm(*mousedown_callback_function, Bindings::host_defined_environment_settings_object(realm())); + auto mousedown_callback = realm().heap().allocate_without_realm(*mousedown_callback_function, Bindings::principal_host_defined_environment_settings_object(realm())); add_event_listener_without_options(UIEvents::EventNames::mousedown, DOM::IDLEventListener::create(realm(), mousedown_callback)); } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 1ced21521fd7..897df65a5481 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -140,7 +140,7 @@ JS::ExecutionContext const& execution_context_of_realm(JS::Realm const& realm) // FIXME: 1. If realm is a principal realm, then return the realm execution context of the environment settings object of realm. // FIXME: 2. Assert: realm is a synthetic realm. // FIXME: 3. Return the execution context of the synthetic realm settings object of realm. - return Bindings::host_defined_environment_settings_object(realm).realm_execution_context(); + return Bindings::principal_host_defined_environment_settings_object(realm).realm_execution_context(); } // https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script @@ -327,7 +327,7 @@ JS::Realm& incumbent_realm() EnvironmentSettingsObject& incumbent_settings_object() { // FIXME: Then, the incumbent settings object is the incumbent realm's principal realm settings object. - return Bindings::host_defined_environment_settings_object(incumbent_realm()); + return Bindings::principal_host_defined_environment_settings_object(incumbent_realm()); } // https://html.spec.whatwg.org/multipage/webappapis.html#concept-incumbent-global @@ -362,7 +362,7 @@ JS::Realm& principal_realm(JS::Realm& realm) EnvironmentSettingsObject& principal_realm_settings_object(JS::Realm& realm) { // A principal realm has a [[HostDefined]] field, which contains the principal realm's settings object. - return Bindings::host_defined_environment_settings_object(realm); + return Bindings::principal_host_defined_environment_settings_object(realm); } // https://html.spec.whatwg.org/multipage/webappapis.html#current-settings-object @@ -392,7 +392,7 @@ JS::Realm& relevant_realm(JS::Object const& object) EnvironmentSettingsObject& relevant_settings_object(JS::Object const& object) { // Then, the relevant settings object for a platform object o is the environment settings object of the relevant Realm for o. - return Bindings::host_defined_environment_settings_object(relevant_realm(object)); + return Bindings::principal_host_defined_environment_settings_object(relevant_realm(object)); } EnvironmentSettingsObject& relevant_settings_object(DOM::Node const& node) @@ -424,7 +424,7 @@ JS::Realm& entry_realm() EnvironmentSettingsObject& entry_settings_object() { // Then, the entry settings object is the environment settings object of the entry realm. - return Bindings::host_defined_environment_settings_object(entry_realm()); + return Bindings::principal_host_defined_environment_settings_object(entry_realm()); } // https://html.spec.whatwg.org/multipage/webappapis.html#entry-global-object diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp index b4bca211cf3a..a25c963f76c6 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ImportMap.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp index 14aed00a9363..a83289eed3d0 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp @@ -4,8 +4,8 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include +#include #include #include #include @@ -74,7 +74,7 @@ void WindowEnvironmentSettingsObject::setup(Page& page, URL::URL const& creation // 7. Set realm's [[HostDefined]] field to settings object. // Non-Standard: We store the ESO next to the web intrinsics in a custom HostDefined object auto intrinsics = realm->heap().allocate(*realm, *realm); - auto host_defined = make(settings_object, intrinsics, page); + auto host_defined = make(settings_object, intrinsics, page); realm->set_host_defined(move(host_defined)); // Non-Standard: We cannot fully initialize window object until *after* the we set up diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.cpp index 3177d7c1cc02..de97d78c6fca 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.cpp @@ -44,7 +44,7 @@ JS::NonnullGCPtr WorkerEnvironmentSettingsObjec // 8. Set realm's [[HostDefined]] field to settings object. auto intrinsics = realm->heap().allocate(*realm, *realm); - auto host_defined = make(settings_object, intrinsics, page); + auto host_defined = make(settings_object, intrinsics, page); realm->set_host_defined(move(host_defined)); // Non-Standard: We cannot fully initialize worker object until *after* the we set up diff --git a/Userland/Libraries/LibWeb/HTML/SharedResourceRequest.cpp b/Userland/Libraries/LibWeb/HTML/SharedResourceRequest.cpp index 7d891a2785ca..462ce34ddddc 100644 --- a/Userland/Libraries/LibWeb/HTML/SharedResourceRequest.cpp +++ b/Userland/Libraries/LibWeb/HTML/SharedResourceRequest.cpp @@ -24,7 +24,7 @@ JS_DEFINE_ALLOCATOR(SharedResourceRequest); JS::NonnullGCPtr SharedResourceRequest::get_or_create(JS::Realm& realm, JS::NonnullGCPtr page, URL::URL const& url) { - auto document = Bindings::host_defined_environment_settings_object(realm).responsible_document(); + auto document = Bindings::principal_host_defined_environment_settings_object(realm).responsible_document(); VERIFY(document); auto& shared_resource_requests = document->shared_resource_requests(); if (auto it = shared_resource_requests.find(url); it != shared_resource_requests.end()) diff --git a/Userland/Libraries/LibWeb/HTML/WorkerAgent.cpp b/Userland/Libraries/LibWeb/HTML/WorkerAgent.cpp index bbb37555323a..7fd9870f17a6 100644 --- a/Userland/Libraries/LibWeb/HTML/WorkerAgent.cpp +++ b/Userland/Libraries/LibWeb/HTML/WorkerAgent.cpp @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include #include #include @@ -34,7 +34,7 @@ void WorkerAgent::initialize(JS::Realm& realm) // NOTE: This blocking IPC call may launch another process. // If spinning the event loop for this can cause other javascript to execute, we're in trouble. - auto worker_socket_file = Bindings::host_defined_page(realm).client().request_worker_agent(); + auto worker_socket_file = Bindings::principal_host_defined_page(realm).client().request_worker_agent(); auto worker_socket = MUST(Core::LocalSocket::adopt_fd(worker_socket_file.take_fd())); MUST(worker_socket->set_blocking(true)); diff --git a/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.h b/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.h index 28d7529d3813..2f3ad156a7af 100644 --- a/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.h +++ b/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/Userland/Libraries/LibWeb/WebIDL/Promise.cpp b/Userland/Libraries/LibWeb/WebIDL/Promise.cpp index 25de081d2053..0d7a58a6e0ba 100644 --- a/Userland/Libraries/LibWeb/WebIDL/Promise.cpp +++ b/Userland/Libraries/LibWeb/WebIDL/Promise.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include From dd6c60ebdb9f7b920bab06c1f1b84648a21a52b2 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 26 Oct 2024 19:46:13 +1300 Subject: [PATCH 2/5] LibWeb: Introduce a SyntheticHostDefined class This class is the host defined field of a synthetic realm created as part of a shadow realm. --- .../LibWeb/Bindings/SyntheticHostDefined.cpp | 20 ++++++++++ .../LibWeb/Bindings/SyntheticHostDefined.h | 27 ++++++++++++++ Userland/Libraries/LibWeb/CMakeLists.txt | 2 + Userland/Libraries/LibWeb/Forward.h | 2 + .../HTML/Scripting/SyntheticRealmSettings.cpp | 20 ++++++++++ .../HTML/Scripting/SyntheticRealmSettings.h | 37 +++++++++++++++++++ 6 files changed, 108 insertions(+) create mode 100644 Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.cpp create mode 100644 Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.h create mode 100644 Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.cpp create mode 100644 Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.h diff --git a/Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.cpp b/Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.cpp new file mode 100644 index 000000000000..0aa7e24f3e78 --- /dev/null +++ b/Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::Bindings { + +void SyntheticHostDefined::visit_edges(JS::Cell::Visitor& visitor) +{ + JS::Realm::HostDefined::visit_edges(visitor); + synthetic_realm_settings.visit_edges(visitor); +} + +} diff --git a/Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.h b/Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.h new file mode 100644 index 000000000000..f404dacb0fbf --- /dev/null +++ b/Userland/Libraries/LibWeb/Bindings/SyntheticHostDefined.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::Bindings { + +struct SyntheticHostDefined : public JS::Realm::HostDefined { + SyntheticHostDefined(HTML::SyntheticRealmSettings synthetic_realm_settings) + : synthetic_realm_settings(move(synthetic_realm_settings)) + { + } + + virtual ~SyntheticHostDefined() override = default; + virtual void visit_edges(JS::Cell::Visitor& visitor) override; + + HTML::SyntheticRealmSettings synthetic_realm_settings; +}; + +} diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 0812e4ed72a7..f9e4cfc80596 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -23,6 +23,7 @@ set(SOURCES Bindings/OptionConstructor.cpp Bindings/PlatformObject.cpp Bindings/PrincipalHostDefined.cpp + Bindings/SyntheticHostDefined.cpp Clipboard/Clipboard.cpp Clipboard/ClipboardEvent.cpp Crypto/Crypto.cpp @@ -449,6 +450,7 @@ set(SOURCES HTML/Scripting/ModuleMap.cpp HTML/Scripting/ModuleScript.cpp HTML/Scripting/Script.cpp + HTML/Scripting/SyntheticRealmSettings.cpp HTML/Scripting/TemporaryExecutionContext.cpp HTML/Scripting/WindowEnvironmentSettingsObject.cpp HTML/Scripting/WorkerEnvironmentSettingsObject.cpp diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index b6c3f7fca373..2060fdba1168 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -491,6 +491,7 @@ class MessageEvent; class MessagePort; class MimeType; class MimeTypeArray; +class ModuleMap; class Navigable; class NavigableContainer; class NavigateEvent; @@ -555,6 +556,7 @@ struct ScrollOptions; struct ScrollToOptions; struct SerializedFormData; struct StructuredSerializeOptions; +struct SyntheticRealmSettings; struct ToggleTaskTracker; struct TransferDataHolder; } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.cpp new file mode 100644 index 000000000000..d1cbf9d0d557 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.cpp @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::HTML { + +void SyntheticRealmSettings::visit_edges(JS::Cell::Visitor& visitor) +{ + execution_context->visit_edges(visitor); + visitor.visit(principal_realm); + visitor.visit(underlying_realm); + visitor.visit(module_map); +} + +} diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.h b/Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.h new file mode 100644 index 000000000000..eb59931f0326 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/Scripting/SyntheticRealmSettings.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::HTML { + +// https://whatpr.org/html/9893/webappapis.html#synthetic-realm-settings-objects +// Each synthetic realm has an associated synthetic realm settings object with the following fields: +struct SyntheticRealmSettings { + // An execution context + // The JavaScript execution context for the scripts within this realm. + NonnullOwnPtr execution_context; + + // A principal realm + // The principal realm which this synthetic realm exists within. + JS::NonnullGCPtr principal_realm; + + // An underlying realm + // The synthetic realm which this settings object represents. + JS::NonnullGCPtr underlying_realm; + + // A module map + // A module map that is used when importing JavaScript modules. + JS::NonnullGCPtr module_map; + + void visit_edges(JS::Cell::Visitor&); +}; + +} From 4622249d75c0a9c02149a59805cda66c95b59b72 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 26 Oct 2024 21:35:21 +1300 Subject: [PATCH 3/5] LibWeb: Introduce the 'ShadowRealmGlobalScope' interface This object represents the global object for a shadow realm. The IDL generator will need to be adjusted to the '[Global]' extended attribute and no '[Exposed]' field (the change in the test is not correct, as I understand it), but this should be enough to get us started on shadow realms. --- .../Text/expected/all-window-properties.txt | 1 + Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../LibWeb/HTML/ShadowRealmGlobalScope.cpp | 38 +++++++++++++++++++ .../LibWeb/HTML/ShadowRealmGlobalScope.h | 38 +++++++++++++++++++ .../LibWeb/HTML/ShadowRealmGlobalScope.idl | 6 +++ Userland/Libraries/LibWeb/idl_files.cmake | 1 + 6 files changed, 85 insertions(+) create mode 100644 Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.cpp create mode 100644 Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.h create mode 100644 Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.idl diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 565e69e1a36d..8e3b83a0bc61 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -338,6 +338,7 @@ ServiceWorkerContainer ServiceWorkerRegistration Set ShadowRealm +ShadowRealmGlobalScope ShadowRoot SharedArrayBuffer SourceBuffer diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index f9e4cfc80596..24ec7c346782 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -462,6 +462,7 @@ set(SOURCES HTML/ServiceWorkerRegistration.cpp HTML/SessionHistoryEntry.cpp HTML/SessionHistoryTraversalQueue.cpp + HTML/ShadowRealmGlobalScope.cpp HTML/SharedResourceRequest.cpp HTML/SourceSet.cpp HTML/Storage.cpp diff --git a/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.cpp new file mode 100644 index 000000000000..8083d4298cde --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::HTML { + +JS_DEFINE_ALLOCATOR(ShadowRealmGlobalScope); + +ShadowRealmGlobalScope::ShadowRealmGlobalScope(JS::Realm& realm) + : DOM::EventTarget(realm) +{ +} + +ShadowRealmGlobalScope::~ShadowRealmGlobalScope() = default; + +JS::NonnullGCPtr ShadowRealmGlobalScope::create(JS::Realm& realm) +{ + return realm.heap().allocate(realm, realm); +} + +void ShadowRealmGlobalScope::initialize(JS::Realm&) +{ + // FIXME: This does not work as we do not have any intrinsics in the [HostDefined] of a shadow realm. Figure out how this _should_ work. + // Base::initialize(realm); + // WEB_SET_PROTOTYPE_FOR_INTERFACE(ShadowRealmGlobalScope); +} + +void ShadowRealmGlobalScope::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); +} + +} diff --git a/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.h b/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.h new file mode 100644 index 000000000000..931764f8803a --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::HTML { + +// https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope +class ShadowRealmGlobalScope : public DOM::EventTarget { + WEB_PLATFORM_OBJECT(ShadowRealmGlobalScope, DOM::EventTarget); + JS_DECLARE_ALLOCATOR(ShadowRealmGlobalScope); + +public: + virtual ~ShadowRealmGlobalScope() override; + + static JS::NonnullGCPtr create(JS::Realm&); + + // https://whatpr.org/html/9893/webappapis.html#dom-shadowrealmglobalscope-self + JS::NonnullGCPtr self() + { + // The self getter steps are to return this. + return *this; + } + +protected: + explicit ShadowRealmGlobalScope(JS::Realm&); + + virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Cell::Visitor&) override; +}; + +} diff --git a/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.idl b/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.idl new file mode 100644 index 000000000000..043b16981c5a --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.idl @@ -0,0 +1,6 @@ +// https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope +// FIXME: This is not correct! We should not have Exposed=Window here. +[Global, Exposed=Window] +interface ShadowRealmGlobalScope : EventTarget { + readonly attribute ShadowRealmGlobalScope self; +}; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 3b5eb8cc6892..2e5436e40267 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -222,6 +222,7 @@ libweb_js_bindings(HTML/RadioNodeList) libweb_js_bindings(HTML/ServiceWorker) libweb_js_bindings(HTML/ServiceWorkerContainer) libweb_js_bindings(HTML/ServiceWorkerRegistration) +libweb_js_bindings(HTML/ShadowRealmGlobalScope) libweb_js_bindings(HTML/Storage) libweb_js_bindings(HTML/SubmitEvent) libweb_js_bindings(HTML/TextMetrics) From 320b478270a87256c1cb6503f2a5fdd2cca83dd8 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 26 Oct 2024 22:18:22 +1300 Subject: [PATCH 4/5] LibWeb: Wire up synthetic realm to settings object and execution context --- .../LibWeb/HTML/Scripting/Environments.cpp | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 897df65a5481..fc5651110b58 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -137,10 +138,15 @@ void prepare_to_run_script(JS::Realm& realm) // https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#concept-realm-execution-context JS::ExecutionContext const& execution_context_of_realm(JS::Realm const& realm) { - // FIXME: 1. If realm is a principal realm, then return the realm execution context of the environment settings object of realm. - // FIXME: 2. Assert: realm is a synthetic realm. - // FIXME: 3. Return the execution context of the synthetic realm settings object of realm. - return Bindings::principal_host_defined_environment_settings_object(realm).realm_execution_context(); + VERIFY(realm.host_defined()); + + // 1. If realm is a principal realm, then return the realm execution context of the environment settings object of realm. + if (is(*realm.host_defined())) + return static_cast(*realm.host_defined()).environment_settings_object->realm_execution_context(); + + // 2. Assert: realm is a synthetic realm. + // 3. Return the execution context of the synthetic realm settings object of realm. + return *verify_cast(*realm.host_defined()).synthetic_realm_settings.execution_context; } // https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script @@ -291,10 +297,15 @@ void disallow_further_import_maps(JS::Realm& realm) // https://whatpr.org/html/9893/webappapis.html#concept-realm-module-map ModuleMap& module_map_of_realm(JS::Realm& realm) { - // FIXME: 1. If realm is a principal realm, then return the module map of the environment settings object of realm. - // FIXME: 2. Assert: realm is a synthetic realm. - // FIXME: 3. Return the module map of the synthetic realm settings object of realm. - return principal_realm_settings_object(realm).module_map(); + VERIFY(realm.host_defined()); + + // 1. If realm is a principal realm, then return the module map of the environment settings object of realm. + if (is(*realm.host_defined())) + return static_cast(*realm.host_defined()).environment_settings_object->module_map(); + + // 2. Assert: realm is a synthetic realm. + // 3. Return the module map of the synthetic realm settings object of realm. + return *verify_cast(*realm.host_defined()).synthetic_realm_settings.module_map; } // https://html.spec.whatwg.org/multipage/webappapis.html#concept-incumbent-realm @@ -326,8 +337,8 @@ JS::Realm& incumbent_realm() // https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#incumbent-settings-object EnvironmentSettingsObject& incumbent_settings_object() { - // FIXME: Then, the incumbent settings object is the incumbent realm's principal realm settings object. - return Bindings::principal_host_defined_environment_settings_object(incumbent_realm()); + // Then, the incumbent settings object is the incumbent realm's principal realm settings object. + return principal_realm_settings_object(principal_realm(incumbent_realm())); } // https://html.spec.whatwg.org/multipage/webappapis.html#concept-incumbent-global @@ -350,10 +361,18 @@ JS::Realm& current_principal_realm() // https://whatpr.org/html/9893/webappapis.html#concept-principal-realm-of-realm JS::Realm& principal_realm(JS::Realm& realm) { - // FIXME: 1. If realm.[[HostDefined]] is a synthetic realm settings object, then: - // FIXME: 1.1. Assert: realm is a synthetic realm. - // FIXME: 1.2. Set realm to the principal realm of realm.[[HostDefined]]. - // FIXME: 2. Assert: realm.[[HostDefined]] is an environment settings object and realm is a principal realm. + VERIFY(realm.host_defined()); + + // 1. If realm.[[HostDefined]] is a synthetic realm settings object, then: + if (is(*realm.host_defined())) { + // 1. Assert: realm is a synthetic realm. + // 2. Set realm to the principal realm of realm.[[HostDefined]]. + return static_cast(*realm.host_defined()).synthetic_realm_settings.principal_realm; + } + + // 2. Assert: realm.[[HostDefined]] is an environment settings object and realm is a principal realm. + VERIFY(is(*realm.host_defined())); + // 3. Return realm. return realm; } @@ -409,15 +428,16 @@ JS::Object& relevant_global_object(JS::Object const& object) } // https://html.spec.whatwg.org/multipage/webappapis.html#concept-entry-realm +// https://whatpr.org/html/9893/webappapis.html#concept-entry-realm JS::Realm& entry_realm() { auto& event_loop = HTML::main_thread_event_loop(); auto& vm = event_loop.vm(); // With this in hand, we define the entry execution context to be the most recently pushed item in the JavaScript execution context stack that is a realm execution context. - // The entry realm is the entry execution context's Realm component. + // The entry realm is the principal realm of the entry execution context's Realm component. // NOTE: Currently all execution contexts in LibJS are realm execution contexts - return *vm.running_execution_context().realm; + return principal_realm(*vm.running_execution_context().realm); } // https://html.spec.whatwg.org/multipage/webappapis.html#entry-settings-object From 69aa1f4b07551753742cd749ea2e91fdb6d73061 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Sat, 26 Oct 2024 22:07:09 +1300 Subject: [PATCH 5/5] LibWeb: Hook up the HostInitializeShadowRealm callback This is enough for a basic shadow realm to work :^) There is more that we still need to implement here such as module loading and fixing up the global object, but this is enough to get some basic usage working. --- .../HTML/shadow-realm-async-evaluate.txt | 1 + .../HTML/shadow-realm-sync-evaluate.txt | 1 + .../HTML/shadow-realm-async-evaluate.html | 13 ++++++ .../HTML/shadow-realm-sync-evaluate.html | 8 ++++ Userland/Libraries/LibJS/Runtime/Realm.h | 3 ++ .../LibWeb/Bindings/MainThreadVM.cpp | 44 +++++++++++++++++++ 6 files changed, 70 insertions(+) create mode 100644 Tests/LibWeb/Text/expected/HTML/shadow-realm-async-evaluate.txt create mode 100644 Tests/LibWeb/Text/expected/HTML/shadow-realm-sync-evaluate.txt create mode 100644 Tests/LibWeb/Text/input/HTML/shadow-realm-async-evaluate.html create mode 100644 Tests/LibWeb/Text/input/HTML/shadow-realm-sync-evaluate.html diff --git a/Tests/LibWeb/Text/expected/HTML/shadow-realm-async-evaluate.txt b/Tests/LibWeb/Text/expected/HTML/shadow-realm-async-evaluate.txt new file mode 100644 index 000000000000..495cc9e1719c --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/shadow-realm-async-evaluate.txt @@ -0,0 +1 @@ +PASS: Exception thrown 'TypeError: Wrapped value must be primitive or a function object, got [object Promise]' diff --git a/Tests/LibWeb/Text/expected/HTML/shadow-realm-sync-evaluate.txt b/Tests/LibWeb/Text/expected/HTML/shadow-realm-sync-evaluate.txt new file mode 100644 index 000000000000..3b0b39fe9bd7 --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/shadow-realm-sync-evaluate.txt @@ -0,0 +1 @@ +Shadow realm evaluation returned: 2 diff --git a/Tests/LibWeb/Text/input/HTML/shadow-realm-async-evaluate.html b/Tests/LibWeb/Text/input/HTML/shadow-realm-async-evaluate.html new file mode 100644 index 000000000000..46e92a937c4b --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/shadow-realm-async-evaluate.html @@ -0,0 +1,13 @@ + + diff --git a/Tests/LibWeb/Text/input/HTML/shadow-realm-sync-evaluate.html b/Tests/LibWeb/Text/input/HTML/shadow-realm-sync-evaluate.html new file mode 100644 index 000000000000..a1cf3f1fa3dd --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/shadow-realm-sync-evaluate.html @@ -0,0 +1,8 @@ + + diff --git a/Userland/Libraries/LibJS/Runtime/Realm.h b/Userland/Libraries/LibJS/Runtime/Realm.h index a47eff87519a..d09c5cfc30b7 100644 --- a/Userland/Libraries/LibJS/Runtime/Realm.h +++ b/Userland/Libraries/LibJS/Runtime/Realm.h @@ -34,7 +34,10 @@ class Realm final : public Cell { static ThrowCompletionOr> initialize_host_defined_realm(VM&, Function create_global_object, Function create_global_this_value); [[nodiscard]] Object& global_object() const { return *m_global_object; } + void set_global_object(NonnullGCPtr global) { m_global_object = global; } + [[nodiscard]] GlobalEnvironment& global_environment() const { return *m_global_environment; } + void set_global_environment(NonnullGCPtr environment) { m_global_environment = environment; } [[nodiscard]] Intrinsics const& intrinsics() const { return *m_intrinsics; } [[nodiscard]] Intrinsics& intrinsics() { return *m_intrinsics; } diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index d561e1f66dbd..5d3a54d7e418 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -13,13 +13,16 @@ #include #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -35,7 +38,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -560,6 +565,45 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) HTML::fetch_single_imported_module_script(*module_map_realm, url.release_value(), *fetch_client, destination, fetch_options, *module_map_realm, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete); }; + // https://whatpr.org/html/9893/webappapis.html#hostinitializeshadowrealm(realm,-context,-o) + // 8.1.6.8 HostInitializeShadowRealm(realm, context, O) + s_main_thread_vm->host_initialize_shadow_realm = [](JS::Realm& realm, NonnullOwnPtr context, JS::ShadowRealm& object) -> JS::ThrowCompletionOr { + // FIXME: 1. Set realm's is global prototype chain mutable to true. + + // 2. Let globalObject be a new ShadowRealmGlobalScope object with realm. + auto global_object = HTML::ShadowRealmGlobalScope::create(realm); + + // 3. Let settings be a new synthetic realm settings object that this algorithm will subsequently initialize. + auto settings = HTML::SyntheticRealmSettings { + // 4. Set settings's execution context to context. + .execution_context = move(context), + + // 5. Set settings's principal realm to O's associated realm + .principal_realm = object.shape().realm(), + + // 6. Set settings's underlying realm to realm. + .underlying_realm = realm, + + // 7. Set settings's module map to a new module map, initially empty. + .module_map = realm.heap().allocate(realm), + }; + + // 8. Set realm.[[HostDefined]] to settings. + realm.set_host_defined(make(move(settings))); + + // 9. Set realm.[[GlobalObject]] to globalObject. + realm.set_global_object(global_object); + + // 10. Set realm.[[GlobalEnv]] to NewGlobalEnvironment(globalObject, globalObject). + realm.set_global_environment(realm.vm().heap().allocate_without_realm(global_object, global_object)); + + // 11. Perform ? SetDefaultGlobalBindings(realm). + set_default_global_bindings(realm); + + // 12. Return NormalCompletion(unused). + return {}; + }; + s_main_thread_vm->host_unrecognized_date_string = [](StringView date) { dbgln("Unable to parse date string: \"{}\"", date); };