diff options
author | Andreas Kling <kling@serenityos.org> | 2022-08-04 21:30:33 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-08-05 12:46:40 +0200 |
commit | 602f927982dc7a1a824c8b85ba7075482a4d170e (patch) | |
tree | 9d5210ea51d64e5deab7bba69e6405e364c28ad2 /Userland/Libraries | |
parent | 0781bdb23e43412a3e591a9574bdee5c17364aa4 (diff) | |
download | serenity-602f927982dc7a1a824c8b85ba7075482a4d170e.zip |
LibWeb: Start implementing "create and initialize a Document" from HTML
The way we've been creating DOM::Document has been pretty far from what
the spec tells us to do, and this is a first big step towards getting us
closer to spec.
The new Document::create_and_initialize() is called by FrameLoader after
loading a "text/html" resource.
We create the JS Realm and the Window object when creating the Document
(previously, we'd do it on first access to Document::interpreter().)
The realm execution context is owned by the Environment Settings Object.
Diffstat (limited to 'Userland/Libraries')
13 files changed, 318 insertions, 81 deletions
diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 57cbd7501e..27e24424d2 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -366,4 +366,28 @@ void queue_mutation_observer_microtask(DOM::Document& document) }); } +// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-new-javascript-realm +NonnullOwnPtr<JS::ExecutionContext> create_a_new_javascript_realm(JS::VM& vm, Function<JS::Value(JS::Realm&)> create_global_object, Function<JS::Value(JS::Realm&)> create_global_this_value) +{ + // 1. Perform InitializeHostDefinedRealm() with the provided customizations for creating the global object and the global this binding. + // 2. Let realm execution context be the running JavaScript execution context. + auto realm_execution_context = MUST(JS::Realm::initialize_host_defined_realm(vm, move(create_global_object), move(create_global_this_value))); + + // 3. Remove realm execution context from the JavaScript execution context stack. + vm.execution_context_stack().remove_first_matching([&realm_execution_context](auto* execution_context) { + return execution_context == realm_execution_context.ptr(); + }); + + // NO-OP: 4. Let realm be realm execution context's Realm component. + // NO-OP: 5. Set realm's agent to agent. + + // FIXME: 6. If agent's agent cluster's cross-origin isolation mode is "none", then: + // 1. Let global be realm's global object. + // 2. Let status be ! global.[[Delete]]("SharedArrayBuffer"). + // 3. Assert: status is true. + + // 7. Return realm execution context. + return realm_execution_context; +} + } diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h index 686ce3ccb1..cea1de14ee 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h @@ -49,5 +49,6 @@ struct WebEngineCustomJobCallbackData final : public JS::JobCallback::CustomData HTML::ClassicScript* active_script(); JS::VM& main_thread_vm(); void queue_mutation_observer_microtask(DOM::Document&); +NonnullOwnPtr<JS::ExecutionContext> create_a_new_javascript_realm(JS::VM&, Function<JS::Value(JS::Realm&)> create_global_object, Function<JS::Value(JS::Realm&)> create_global_this_value); } diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index cd638ac93f..454a3945e2 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -56,6 +56,7 @@ #include <LibWeb/HTML/HTMLScriptElement.h> #include <LibWeb/HTML/HTMLTitleElement.h> #include <LibWeb/HTML/MessageEvent.h> +#include <LibWeb/HTML/NavigationParams.h> #include <LibWeb/HTML/Origin.h> #include <LibWeb/HTML/Parser/HTMLParser.h> #include <LibWeb/HTML/Scripting/ExceptionReporter.h> @@ -74,6 +75,196 @@ namespace Web::DOM { +// https://html.spec.whatwg.org/multipage/origin.html#obtain-browsing-context-navigation +static NonnullRefPtr<HTML::BrowsingContext> obtain_a_browsing_context_to_use_for_a_navigation_response( + HTML::BrowsingContext& browsing_context, + HTML::SandboxingFlagSet sandbox_flags, + HTML::CrossOriginOpenerPolicy navigation_coop, + HTML::CrossOriginOpenerPolicyEnforcementResult coop_enforcement_result) +{ + // 1. If browsingContext is not a top-level browsing context, return browsingContext. + if (!browsing_context.is_top_level()) + return browsing_context; + + // 2. If coopEnforcementResult's needs a browsing context group switch is false, then: + if (!coop_enforcement_result.needs_a_browsing_context_group_switch) { + // 1. If coopEnforcementResult's would need a browsing context group switch due to report-only is true, + if (coop_enforcement_result.would_need_a_browsing_context_group_switch_due_to_report_only) { + // FIXME: set browsing context's virtual browsing context group ID to a new unique identifier. + } + // 2. Return browsingContext. + return browsing_context; + } + + // 3. Let newBrowsingContext be the result of creating a new top-level browsing context. + VERIFY(browsing_context.page()); + auto new_browsing_context = HTML::BrowsingContext::create_a_new_browsing_context(*browsing_context.page(), nullptr, nullptr); + + // FIXME: 4. If navigationCOOP's value is "same-origin-plus-COEP", then set newBrowsingContext's group's + // cross-origin isolation mode to either "logical" or "concrete". The choice of which is implementation-defined. + + // 5. If sandboxFlags is not empty, then: + if (!sandbox_flags.is_empty()) { + // 1. Assert navigationCOOP's value is "unsafe-none". + VERIFY(navigation_coop.value == HTML::CrossOriginOpenerPolicyValue::UnsafeNone); + + // 2. Assert: newBrowsingContext's popup sandboxing flag set is empty. + + // 3. Set newBrowsingContext's popup sandboxing flag set to a clone of sandboxFlags. + } + + // FIXME: 6. Discard browsingContext. + + // 7. Return newBrowsingContext. + return new_browsing_context; +} + +// https://html.spec.whatwg.org/multipage/browsing-the-web.html#initialise-the-document-object +NonnullRefPtr<Document> Document::create_and_initialize(Type type, String content_type, HTML::NavigationParams navigation_params) +{ + // 1. Let browsingContext be the result of the obtaining a browsing context to use for a navigation response + // given navigationParams's browsing context, navigationParams's final sandboxing flag set, + // navigationParams's cross-origin opener policy, and navigationParams's COOP enforcement result. + auto browsing_context = obtain_a_browsing_context_to_use_for_a_navigation_response( + navigation_params.browsing_context, + navigation_params.final_sandboxing_flag_set, + navigation_params.cross_origin_opener_policy, + navigation_params.coop_enforcement_result); + + // FIXME: 2. Let permissionsPolicy be the result of creating a permissions policy from a response + // given browsingContext, navigationParams's origin, and navigationParams's response. + + // 3. Let creationURL be navigationParams's response's URL. + auto creation_url = navigation_params.response->url(); + + // 4. If navigationParams's request is non-null, then set creationURL to navigationParams's request's current URL. + if (navigation_params.request) { + creation_url = navigation_params.request->current_url(); + } + + RefPtr<HTML::Window> window; + + // 5. If browsingContext is still on its initial about:blank Document, + // and navigationParams's history handling is "replace", + // and browsingContext's active document's origin is same origin-domain with navigationParams's origin, + // then do nothing. + if (browsing_context->still_on_its_initial_about_blank_document() + && navigation_params.history_handling == HTML::HistoryHandlingBehavior::Replace + && (browsing_context->active_document() && browsing_context->active_document()->origin().is_same_origin(navigation_params.origin))) { + // Do nothing. + } + + // 6. Otherwise: + else { + // FIXME: 1. Let oacHeader be the result of getting a structured field value given `Origin-Agent-Cluster` and "item" from response's header list. + + // FIXME: 2. Let requestsOAC be true if oacHeader is not null and oacHeader[0] is the boolean true; otherwise false. + [[maybe_unused]] auto requests_oac = false; + + // FIXME: 3. If navigationParams's reserved environment is a non-secure context, then set requestsOAC to false. + + // FIXME: 4. Let agent be the result of obtaining a similar-origin window agent given navigationParams's origin, browsingContext's group, and requestsOAC. + + // 5. Let realm execution context be the result of creating a new JavaScript realm given agent and the following customizations: + auto realm_execution_context = Bindings::create_a_new_javascript_realm( + Bindings::main_thread_vm(), + [&](JS::Realm& realm) -> JS::Value { + // - For the global object, create a new Window object. + window = HTML::Window::create(); + auto* global_object = realm.heap().allocate_without_global_object<Bindings::WindowObject>(realm, *window); + VERIFY(window->wrapper() == global_object); + return global_object; + }, + [](JS::Realm&) -> JS::Value { + // FIXME: - For the global this binding, use browsingContext's WindowProxy object. + return JS::js_undefined(); + }); + + // 6. Let topLevelCreationURL be creationURL. + auto top_level_creation_url = creation_url; + + // 7. Let topLevelOrigin be navigationParams's origin. + auto top_level_origin = navigation_params.origin; + + // 8. If browsingContext is not a top-level browsing context, then: + if (!browsing_context->is_top_level()) { + // 1. Let parentEnvironment be browsingContext's container's relevant settings object. + auto& parent_environment = browsing_context->container()->document().relevant_settings_object(); + + // 2. Set topLevelCreationURL to parentEnvironment's top-level creation URL. + top_level_creation_url = parent_environment.top_level_creation_url; + + // 3. Set topLevelOrigin to parentEnvironment's top-level origin. + top_level_origin = parent_environment.top_level_origin; + } + + // 9. Set up a window environment settings object with creationURL, realm execution context, + // navigationParams's reserved environment, topLevelCreationURL, and topLevelOrigin. + + // FIXME: Why do we assume `creation_url` is non-empty here? Is this a spec bug? + // FIXME: Why do we assume `top_level_creation_url` is non-empty here? Is this a spec bug? + HTML::WindowEnvironmentSettingsObject::setup( + creation_url.value(), + move(realm_execution_context), + navigation_params.reserved_environment, + top_level_creation_url.value(), + top_level_origin); + } + + // FIXME: 7. Let loadTimingInfo be a new document load timing info with its navigation start time set to response's timing info's start time. + + // 8. Let document be a new Document, + // whose type is type, + // content type is contentType, + // FIXME: origin is navigationParams's origin, + // FIXME: policy container is navigationParams's policy container, + // FIXME: permissions policy is permissionsPolicy, + // FIXME: active sandboxing flag set is navigationParams's final sandboxing flag set, + // FIXME: and cross-origin opener policy is navigationParams's cross-origin opener policy, + // FIXME: load timing info is loadTimingInfo, + // FIXME: and navigation id is navigationParams's id. + auto document = Document::create(); + document->m_type = type; + document->m_content_type = content_type; + + document->m_window = window; + window->set_associated_document(*document); + + // 9. Set document's URL to creationURL. + document->m_url = creation_url.value(); + + // 10. Set document's current document readiness to "loading". + document->m_readiness = HTML::DocumentReadyState::Loading; + + // FIXME: 11. Run CSP initialization for a Document given document. + + // 12. If navigationParams's request is non-null, then: + if (navigation_params.request) { + // FIXME: 1. Set document's referrer to the empty string. + // FIXME: 2. Let referrer be navigationParams's request's referrer. + // FIXME: 3. If referrer is a URL record, then set document's referrer to the serialization of referrer. + } + + // FIXME: 13. Let historyHandling be navigationParams's history handling. + + // FIXME: 14: Let navigationTimingType be the result of switching on navigationParams's history handling... + + // FIXME: 15. Let redirectCount be 0 if navigationParams's has cross-origin redirects is true; + // otherwise navigationParams's request's redirect count. + + // FIXME: 16. Create the navigation timing entry for document, with navigationParams's response's timing info, + // redirectCount, navigationTimingType, and navigationParams's response's service worker timing info. + + // FIXME: 17. If navigationParams's response has a `Refresh` header, then... + + // FIXME: 18. If navigationParams's commit early hints is not null, then call navigationParams's commit early hints with document. + + // FIXME: 19. Process link headers given document, navigationParams's response, and "pre-media". + + // 20. Return document. + return document; +} + NonnullRefPtr<Document> Document::create_with_global_object(Bindings::WindowObject&) { return Document::create(); @@ -891,52 +1082,16 @@ HTML::EnvironmentSettingsObject& Document::relevant_settings_object() JS::Realm& Document::realm() { - return interpreter().realm(); + VERIFY(m_window); + VERIFY(m_window->wrapper()); + VERIFY(m_window->wrapper()->associated_realm()); + return *m_window->wrapper()->associated_realm(); } JS::Interpreter& Document::interpreter() { if (!m_interpreter) { - // FIXME: This is all ad-hoc. It loosely follows steps 6.4 to 6.9 of https://html.spec.whatwg.org/#initialise-the-document-object - auto& vm = Bindings::main_thread_vm(); - - // https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-new-javascript-realm - // FIXME: Put all this into it's own function that can be used outside of Document. - - // 1. Perform InitializeHostDefinedRealm() with the provided customizations for creating the global object and the global this binding. - // FIXME: Use WindowProxy as the global this value. - m_interpreter = JS::Interpreter::create<Bindings::WindowObject>(vm, *m_window); - - // 2. Let realm execution context be the running JavaScript execution context. - auto& realm_execution_context = vm.running_execution_context(); - - // 3. Remove realm execution context from the JavaScript execution context stack. - vm.execution_context_stack().remove_first_matching([&realm_execution_context](auto* execution_context) { - return execution_context == &realm_execution_context; - }); - - // FIXME: 4. Let realm be realm execution context's Realm component. - // FIXME: 5. Set realm's agent to agent. - - // FIXME: 6. If agent's agent cluster's cross-origin isolation mode is "none", then: - // 1. Let global be realm's global object. - // 2. Let status be ! global.[[Delete]]("SharedArrayBuffer"). - // 3. Assert: status is true. - - // FIXME: 7. Return realm execution context. (Requires being in it's own function as mentioned above) - - // == End of "create a JavaScript realm" == - - // FIXME: 6. Let topLevelCreationURL be creationURL. - // FIXME: 7. Let topLevelOrigin be navigationParams's origin. - // FIXME: 8. If browsingContext is not a top-level browsing context, then: - // 1. Let parentEnvironment be browsingContext's container's relevant settings object. - // 2. Set topLevelCreationURL to parentEnvironment's top-level creation URL. - // 3. Set topLevelOrigin to parentEnvironment's top-level origin. - - // FIXME: 9. Set up a window environment settings object with creationURL, realm execution context, navigationParams's reserved environment, topLevelCreationURL, and topLevelOrigin. - // (This is missing reserved environment, topLevelCreationURL and topLevelOrigin. It also assumes creationURL is the document's URL, when it's really "navigationParams's response's URL.") - HTML::WindowEnvironmentSettingsObject::setup(m_url, realm_execution_context); + m_interpreter = JS::Interpreter::create_with_existing_realm(realm()); } return *m_interpreter; } diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 51409d8dab..f71b88e13a 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -51,6 +51,8 @@ public: HTML }; + static NonnullRefPtr<Document> create_and_initialize(Type, String content_type, HTML::NavigationParams); + static NonnullRefPtr<Document> create(AK::URL const& url = "about:blank"sv); static NonnullRefPtr<Document> create_with_global_object(Bindings::WindowObject&); virtual ~Document() override; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 6836e00911..0db319a442 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -202,6 +202,8 @@ class BrowsingContextContainer; class CanvasRenderingContext2D; class ClassicScript; class CloseEvent; +struct CrossOriginOpenerPolicy; +struct CrossOriginOpenerPolicyEnforcementResult; class DOMParser; class DOMStringMap; struct Environment; @@ -287,11 +289,13 @@ class ImageData; class MessageChannel; class MessageEvent; class MessagePort; +struct NavigationParams; class Origin; class PageTransitionEvent; struct PolicyContainer; class PromiseRejectionEvent; class WorkerDebugConsoleClient; +struct SandboxingFlagSet; class Storage; class SubmitEvent; class TextMetrics; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index da1945f979..4cbeb56f75 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -16,8 +16,8 @@ namespace Web::HTML { -EnvironmentSettingsObject::EnvironmentSettingsObject(JS::ExecutionContext& realm_execution_context) - : m_realm_execution_context(realm_execution_context) +EnvironmentSettingsObject::EnvironmentSettingsObject(NonnullOwnPtr<JS::ExecutionContext> realm_execution_context) + : m_realm_execution_context(move(realm_execution_context)) { // Register with the responsible event loop so we can perform step 4 of "perform a microtask checkpoint". responsible_event_loop().register_environment_settings_object({}, *this); @@ -31,7 +31,7 @@ EnvironmentSettingsObject::~EnvironmentSettingsObject() JS::ExecutionContext& EnvironmentSettingsObject::realm_execution_context() { // NOTE: All environment settings objects are created with a realm execution context, so it's stored and returned here in the base class. - return m_realm_execution_context; + return *m_realm_execution_context; } // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object%27s-realm diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h index e884af750a..314a3297d5 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h @@ -105,10 +105,10 @@ struct EnvironmentSettingsObject bool is_scripting_disabled() const; protected: - explicit EnvironmentSettingsObject(JS::ExecutionContext& realm_execution_context); + explicit EnvironmentSettingsObject(NonnullOwnPtr<JS::ExecutionContext>); private: - JS::ExecutionContext& m_realm_execution_context; + NonnullOwnPtr<JS::ExecutionContext> m_realm_execution_context; EventLoop* m_responsible_event_loop { nullptr }; // https://html.spec.whatwg.org/multipage/webappapis.html#outstanding-rejected-promises-weak-set diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp index bc5183fce2..e5b6c8e636 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.cpp @@ -10,17 +10,17 @@ namespace Web::HTML { -WindowEnvironmentSettingsObject::WindowEnvironmentSettingsObject(Window& window, JS::ExecutionContext& execution_context) - : EnvironmentSettingsObject(execution_context) +WindowEnvironmentSettingsObject::WindowEnvironmentSettingsObject(Window& window, NonnullOwnPtr<JS::ExecutionContext> execution_context) + : EnvironmentSettingsObject(move(execution_context)) , m_window(window) { } // https://html.spec.whatwg.org/multipage/window-object.html#set-up-a-window-environment-settings-object -void WindowEnvironmentSettingsObject::setup(AK::URL& creation_url, JS::ExecutionContext& execution_context) +void WindowEnvironmentSettingsObject::setup(AK::URL const& creation_url, NonnullOwnPtr<JS::ExecutionContext> execution_context, Optional<Environment> reserved_environment, AK::URL top_level_creation_url, Origin top_level_origin) { // 1. Let realm be the value of execution context's Realm component. - auto* realm = execution_context.realm; + auto* realm = execution_context->realm; VERIFY(realm); // 2. Let window be realm's global object. @@ -29,17 +29,32 @@ void WindowEnvironmentSettingsObject::setup(AK::URL& creation_url, JS::Execution // 3. Let settings object be a new environment settings object whose algorithms are defined as follows: // NOTE: See the functions defined for this class. - auto settings_object = adopt_own(*new WindowEnvironmentSettingsObject(window, execution_context)); - - // FIXME: 4. If reservedEnvironment is non-null, then: - // FIXME: 1. Set settings object's id to reservedEnvironment's id, target browsing context to reservedEnvironment's target browsing context, and active service worker to reservedEnvironment's active service worker. - // FIXME: 2. Set reservedEnvironment's id to the empty string. - - // FIXME: 5. Otherwise, set settings object's id to a new unique opaque string, settings object's target browsing context to null, and settings object's active service worker to null. - settings_object->target_browsing_context = nullptr; - - // FIXME: 6. Set settings object's creation URL to creationURL, settings object's top-level creation URL to topLevelCreationURL, and settings object's top-level origin to topLevelOrigin. + auto settings_object = adopt_own(*new WindowEnvironmentSettingsObject(window, move(execution_context))); + + // 4. If reservedEnvironment is non-null, then: + if (reserved_environment.has_value()) { + // FIXME: 1. Set settings object's id to reservedEnvironment's id, + // target browsing context to reservedEnvironment's target browsing context, + // and active service worker to reservedEnvironment's active service worker. + settings_object->target_browsing_context = reserved_environment->target_browsing_context; + + // FIXME: 2. Set reservedEnvironment's id to the empty string. + } + + // 5. Otherwise, ... + else { + // FIXME: ...set settings object's id to a new unique opaque string, + // settings object's target browsing context to null, + // and settings object's active service worker to null. + settings_object->target_browsing_context = nullptr; + } + + // 6. Set settings object's creation URL to creationURL, + // settings object's top-level creation URL to topLevelCreationURL, + // and settings object's top-level origin to topLevelOrigin. settings_object->creation_url = creation_url; + settings_object->top_level_creation_url = top_level_creation_url; + settings_object->top_level_origin = top_level_origin; // 7. Set realm's [[HostDefined]] field to settings object. realm->set_host_defined(move(settings_object)); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h index e891c4f2bf..f15a2397e1 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h @@ -13,7 +13,7 @@ namespace Web::HTML { class WindowEnvironmentSettingsObject final : public EnvironmentSettingsObject { public: - static void setup(AK::URL& creation_url, JS::ExecutionContext& execution_context /* FIXME: null or an environment reservedEnvironment, a URL topLevelCreationURL, and an origin topLevelOrigin */); + static void setup(AK::URL const& creation_url, NonnullOwnPtr<JS::ExecutionContext>, Optional<Environment>, AK::URL top_level_creation_url, Origin top_level_origin); virtual ~WindowEnvironmentSettingsObject() override = default; @@ -24,7 +24,7 @@ public: virtual CanUseCrossOriginIsolatedAPIs cross_origin_isolated_capability() override; private: - WindowEnvironmentSettingsObject(Window&, JS::ExecutionContext& execution_context); + WindowEnvironmentSettingsObject(Window&, NonnullOwnPtr<JS::ExecutionContext>); NonnullRefPtr<Window> m_window; }; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h index 0dd1e32657..e4ea62459a 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h @@ -18,17 +18,17 @@ class WorkerEnvironmentSettingsObject final : public EnvironmentSettingsObject , public Weakable<WorkerEnvironmentSettingsObject> { public: - WorkerEnvironmentSettingsObject(DOM::Document& document, JS::ExecutionContext& execution_context) - : EnvironmentSettingsObject(execution_context) + WorkerEnvironmentSettingsObject(DOM::Document& document, NonnullOwnPtr<JS::ExecutionContext> execution_context) + : EnvironmentSettingsObject(move(execution_context)) , m_document(document) { } - static WeakPtr<WorkerEnvironmentSettingsObject> setup(DOM::Document& document, JS::ExecutionContext& execution_context /* FIXME: null or an environment reservedEnvironment, a URL topLevelCreationURL, and an origin topLevelOrigin */) + static WeakPtr<WorkerEnvironmentSettingsObject> setup(DOM::Document& document, NonnullOwnPtr<JS::ExecutionContext> execution_context /* FIXME: null or an environment reservedEnvironment, a URL topLevelCreationURL, and an origin topLevelOrigin */) { - auto* realm = execution_context.realm; + auto* realm = execution_context->realm; VERIFY(realm); - auto settings_object = adopt_own(*new WorkerEnvironmentSettingsObject(document, execution_context)); + auto settings_object = adopt_own(*new WorkerEnvironmentSettingsObject(document, move(execution_context))); settings_object->target_browsing_context = nullptr; realm->set_host_defined(move(settings_object)); diff --git a/Userland/Libraries/LibWeb/HTML/Worker.cpp b/Userland/Libraries/LibWeb/HTML/Worker.cpp index 55cebc5afd..f8ee7b36b7 100644 --- a/Userland/Libraries/LibWeb/HTML/Worker.cpp +++ b/Userland/Libraries/LibWeb/HTML/Worker.cpp @@ -24,7 +24,6 @@ Worker::Worker(FlyString const& script_url, WorkerOptions const options, DOM::Do , m_worker_vm(JS::VM::create(adopt_own(m_custom_data))) , m_interpreter(JS::Interpreter::create<JS::GlobalObject>(m_worker_vm)) , m_interpreter_scope(*m_interpreter) - , m_execution_context(m_worker_vm->heap()) , m_implicit_port(MessagePort::create()) { } @@ -153,22 +152,23 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti // FIXME: This is because I don't know all the libraries well enough to properly setup the environment to spec // let alone making it a parallel implementation. - m_execution_context.current_node = nullptr; - m_execution_context.this_value = m_worker_scope; - m_execution_context.function_name = "(global execution context)"sv; - m_execution_context.lexical_environment = &m_worker_realm->global_environment(); - m_execution_context.variable_environment = &m_worker_realm->global_environment(); - m_execution_context.realm = m_worker_realm; + auto execution_context = make<JS::ExecutionContext>(m_worker_vm->heap()); + execution_context->current_node = nullptr; + execution_context->this_value = m_worker_scope; + execution_context->function_name = "(global execution context)"sv; + execution_context->lexical_environment = &m_worker_realm->global_environment(); + execution_context->variable_environment = &m_worker_realm->global_environment(); + execution_context->realm = m_worker_realm; - m_worker_vm->push_execution_context(m_execution_context); - m_worker_realm->set_global_object(*m_worker_scope, m_worker_scope); + m_worker_vm->push_execution_context(*execution_context); + m_worker_realm->set_global_object(m_worker_scope, m_worker_scope); // 8. Let worker global scope be the global object of realm execution context's Realm component. // NOTE: This is the DedicatedWorkerGlobalScope or SharedWorkerGlobalScope object created in the previous step. // 9. Set up a worker environment settings object with realm execution context, // outside settings, and unsafeWorkerCreationTime, and let inside settings be the result. - m_inner_settings = WorkerEnvironmentSettingsObject::setup(*m_document, m_execution_context); + m_inner_settings = WorkerEnvironmentSettingsObject::setup(*m_document, move(execution_context)); // 10. Set worker global scope's name to the value of options's name member. // FIXME: name property requires the SharedWorkerGlobalScope or DedicatedWorkerGlobalScope child class to be used diff --git a/Userland/Libraries/LibWeb/HTML/Worker.h b/Userland/Libraries/LibWeb/HTML/Worker.h index cf3ec36196..f37ff1014a 100644 --- a/Userland/Libraries/LibWeb/HTML/Worker.h +++ b/Userland/Libraries/LibWeb/HTML/Worker.h @@ -88,7 +88,6 @@ private: NonnullOwnPtr<JS::Interpreter> m_interpreter; WeakPtr<WorkerEnvironmentSettingsObject> m_inner_settings; JS::VM::InterpreterExecutionScope m_interpreter_scope; - JS::ExecutionContext m_execution_context; WeakPtr<JS::Realm> m_worker_realm; RefPtr<WorkerDebugConsoleClient> m_console; JS::GlobalObject* m_worker_scope; diff --git a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp index 02d70cdecf..6343f1f7dc 100644 --- a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -17,6 +17,7 @@ #include <LibWeb/DOM/Text.h> #include <LibWeb/HTML/BrowsingContext.h> #include <LibWeb/HTML/HTMLIFrameElement.h> +#include <LibWeb/HTML/NavigationParams.h> #include <LibWeb/HTML/Parser/HTMLParser.h> #include <LibWeb/ImageDecoding.h> #include <LibWeb/Loader/FrameLoader.h> @@ -253,7 +254,25 @@ bool FrameLoader::load(const AK::URL& url, Type type) void FrameLoader::load_html(StringView html, const AK::URL& url) { - auto document = DOM::Document::create(url); + auto response = make<Fetch::Infrastructure::Response>(); + response->url_list().append(url); + HTML::NavigationParams navigation_params { + .id = {}, + .request = nullptr, + .response = move(response), + .origin = HTML::Origin {}, + .policy_container = HTML::PolicyContainer {}, + .final_sandboxing_flag_set = HTML::SandboxingFlagSet {}, + .cross_origin_opener_policy = HTML::CrossOriginOpenerPolicy {}, + .coop_enforcement_result = HTML::CrossOriginOpenerPolicyEnforcementResult {}, + .reserved_environment = {}, + .browsing_context = browsing_context(), + }; + auto document = DOM::Document::create_and_initialize( + DOM::Document::Type::HTML, + "text/html", + move(navigation_params)); + auto parser = HTML::HTMLParser::create(document, html, "utf-8"); parser->run(url); browsing_context().set_active_document(&parser->document()); @@ -348,7 +367,25 @@ void FrameLoader::resource_did_load() dbgln_if(RESOURCE_DEBUG, "This content has MIME type '{}', encoding unknown", resource()->mime_type()); } - auto document = DOM::Document::create(); + auto response = make<Fetch::Infrastructure::Response>(); + response->url_list().append(url); + HTML::NavigationParams navigation_params { + .id = {}, + .request = nullptr, + .response = move(response), + .origin = HTML::Origin {}, + .policy_container = HTML::PolicyContainer {}, + .final_sandboxing_flag_set = HTML::SandboxingFlagSet {}, + .cross_origin_opener_policy = HTML::CrossOriginOpenerPolicy {}, + .coop_enforcement_result = HTML::CrossOriginOpenerPolicyEnforcementResult {}, + .reserved_environment = {}, + .browsing_context = browsing_context(), + }; + auto document = DOM::Document::create_and_initialize( + DOM::Document::Type::HTML, + "text/html", + move(navigation_params)); + document->set_url(url); document->set_encoding(resource()->encoding()); document->set_content_type(resource()->mime_type()); |