diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index f3f12773149..e02cf2db333 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -126,10 +126,12 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // 8.1.5.3 HostPromiseRejectionTracker(promise, operation), https://html.spec.whatwg.org/multipage/webappapis.html#the-hostpromiserejectiontracker-implementation // https://whatpr.org/html/9893/webappapis.html#the-hostpromiserejectiontracker-implementation s_main_thread_vm->host_promise_rejection_tracker = [](JS::Promise& promise, JS::Promise::RejectionOperation operation) { + auto& vm = *s_main_thread_vm; + // 1. Let script be the running script. // The running script is the script in the [[HostDefined]] field in the ScriptOrModule component of the running JavaScript execution context. HTML::Script* script { nullptr }; - s_main_thread_vm->running_execution_context().script_or_module.visit( + vm.running_execution_context().script_or_module.visit( [&script](JS::NonnullGCPtr& js_script) { script = verify_cast(js_script->host_defined()); }, @@ -147,12 +149,12 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) return; } - // 3. Let settings object be the current settings object. - // 4. If script is not null, then set settings object to script's principal settings object. - auto& settings_object = script ? script->settings_object() : HTML::current_principal_settings_object(); + // 3. Let realm be the current realm. + // 4. If script is not null, then set settings object to script's realm. + auto& realm = script ? script->realm() : *vm.current_realm(); - // 5. Let global be settingsObject's global object. - auto* global_mixin = dynamic_cast(&settings_object.global_object()); + // 5. Let global be realm's global object. + auto* global_mixin = dynamic_cast(&realm.global_object()); VERIFY(global_mixin); auto& global = global_mixin->this_impl(); @@ -203,27 +205,30 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) s_main_thread_vm->host_call_job_callback = [](JS::JobCallback& callback, JS::Value this_value, ReadonlySpan arguments_list) { auto& callback_host_defined = verify_cast(*callback.custom_data()); - // 1. Let incumbent realm be callback.[[HostDefined]].[[IncumbentRealm]]. (NOTE: Not necessary) - // 2. Let script execution context be callback.[[HostDefined]].[[ActiveScriptContext]]. (NOTE: Not necessary) + // 1. Let incumbent realm be callback.[[HostDefined]].[[IncumbentRealm]]. + auto& incumbent_realm = callback_host_defined.incumbent_realm; + + // 2. Let script execution context be callback.[[HostDefined]].[[ActiveScriptContext]]. + auto* script_execution_context = callback_host_defined.active_script_context.ptr(); // 3. Prepare to run a callback with incumbent realm. - HTML::prepare_to_run_callback(callback_host_defined.incumbent_settings->realm()); + HTML::prepare_to_run_callback(incumbent_realm); // 4. If script execution context is not null, then push script execution context onto the JavaScript execution context stack. - if (callback_host_defined.active_script_context) - s_main_thread_vm->push_execution_context(*callback_host_defined.active_script_context); + if (script_execution_context) + s_main_thread_vm->push_execution_context(*script_execution_context); // 5. Let result be Call(callback.[[Callback]], V, argumentsList). auto result = JS::call(*s_main_thread_vm, callback.callback(), this_value, arguments_list); // 6. If script execution context is not null, then pop script execution context from the JavaScript execution context stack. - if (callback_host_defined.active_script_context) { - VERIFY(&s_main_thread_vm->running_execution_context() == callback_host_defined.active_script_context.ptr()); + if (script_execution_context) { + VERIFY(&s_main_thread_vm->running_execution_context() == script_execution_context); s_main_thread_vm->pop_execution_context(); } // 7. Clean up after running a callback with incumbent realm. - HTML::clean_up_after_running_callback(callback_host_defined.incumbent_settings->realm()); + HTML::clean_up_after_running_callback(incumbent_realm); // 8. Return result. return result; @@ -259,25 +264,22 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) }; // 8.1.5.4.3 HostEnqueuePromiseJob(job, realm), https://html.spec.whatwg.org/multipage/webappapis.html#hostenqueuepromisejob + // // https://whatpr.org/html/9893/webappapis.html#hostenqueuepromisejob s_main_thread_vm->host_enqueue_promise_job = [](JS::NonnullGCPtr()>> job, JS::Realm* realm) { - // 1. If realm is not null, then let job settings be the settings object for realm. Otherwise, let job settings be null. - HTML::EnvironmentSettingsObject* job_settings { nullptr }; - if (realm) - job_settings = &host_defined_environment_settings_object(*realm); + auto& vm = *s_main_thread_vm; // IMPLEMENTATION DEFINED: The JS spec says we must take implementation defined steps to make the currently active script or module at the time of HostEnqueuePromiseJob being invoked // also be the active script or module of the job at the time of its invocation. // This means taking it here now and passing it through to the lambda. - auto script_or_module = s_main_thread_vm->get_active_script_or_module(); + auto script_or_module = vm.get_active_script_or_module(); - // 2. Queue a microtask on the surrounding agent's event loop to perform the following steps: + // 1. Queue a microtask to perform the following steps: // This instance of "queue a microtask" uses the "implied document". The best fit for "implied document" here is "If the task is being queued by or for a script, then return the script's settings object's responsible document." // Do note that "implied document" from the spec is handwavy and the spec authors are trying to get rid of it: https://github.com/whatwg/html/issues/4980 auto* script = active_script(); - auto& heap = realm ? realm->heap() : s_main_thread_vm->heap(); - // NOTE: This keeps job_settings alive by keeping realm alive, which is holding onto job_settings. - HTML::queue_a_microtask(script ? script->settings_object().responsible_document().ptr() : nullptr, JS::create_heap_function(heap, [realm, job_settings, job = move(job), script_or_module = move(script_or_module)] { + auto& heap = realm ? realm->heap() : vm.heap(); + HTML::queue_a_microtask(script ? &verify_cast(script->realm().global_object()).associated_document() : nullptr, JS::create_heap_function(heap, [&vm, realm, job = move(job), script_or_module = move(script_or_module)] { // The dummy execution context has to be kept up here to keep it alive for the duration of the function. OwnPtr dummy_execution_context; @@ -296,14 +298,14 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // IMPLEMENTATION DEFINED: Per the previous "implementation defined" comment, we must now make the script or module the active script or module. // Since the only active execution context currently is the realm execution context of job settings, lets attach it here. - job_settings->realm_execution_context().script_or_module = script_or_module; + HTML::execution_context_of_realm(*realm).script_or_module = script_or_module; } else { // FIXME: We need to setup a dummy execution context in case a JS::NativeFunction is called when processing the job. // This is because JS::NativeFunction::call excepts something to be on the execution context stack to be able to get the caller context to initialize the environment. // Do note that the JS spec gives _no_ guarantee that the execution context stack has something on it if HostEnqueuePromiseJob was called with a null realm: https://tc39.es/ecma262/#job-preparedtoevaluatecode dummy_execution_context = JS::ExecutionContext::create(); dummy_execution_context->script_or_module = script_or_module; - s_main_thread_vm->push_execution_context(*dummy_execution_context); + vm.push_execution_context(*dummy_execution_context); } // 3. Let result be job(). @@ -312,7 +314,7 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // 4. If realm is not null, then clean up after running script with job settings. if (realm) { // IMPLEMENTATION DEFINED: Disassociate the realm execution context from the script or module. - job_settings->realm_execution_context().script_or_module = Empty {}; + HTML::execution_context_of_realm(*realm).script_or_module = Empty {}; // IMPLEMENTATION DEFINED: See comment above, we need to clean up the non-standard prepare_to_run_callback() call. HTML::clean_up_after_running_callback(*realm); @@ -320,19 +322,20 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) HTML::clean_up_after_running_script(*realm); } else { // Pop off the dummy execution context. See the above FIXME block about why this is done. - s_main_thread_vm->pop_execution_context(); + vm.pop_execution_context(); } // 5. If result is an abrupt completion, then report the exception given by result.[[Value]]. if (result.is_error()) - HTML::report_exception(result, job_settings->realm()); + HTML::report_exception(result, *realm); })); }; // 8.1.5.4.4 HostMakeJobCallback(callable), https://html.spec.whatwg.org/multipage/webappapis.html#hostmakejobcallback + // https://whatpr.org/html/9893/webappapis.html#hostmakejobcallback s_main_thread_vm->host_make_job_callback = [](JS::FunctionObject& callable) -> JS::NonnullGCPtr { - // 1. Let incumbent settings be the incumbent settings object. - auto& incumbent_settings = HTML::incumbent_settings_object(); + // 1. Let incumbent realm be the incumbent realm. + auto& incumbent_realm = HTML::incumbent_realm(); // 2. Let active script be the active script. auto* script = active_script(); @@ -341,11 +344,11 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) OwnPtr script_execution_context; // 4. If active script is not null, set script execution context to a new JavaScript execution context, with its Function field set to null, - // its Realm field set to active script's settings object's Realm, and its ScriptOrModule set to active script's record. + // its Realm field set to active script's realm, and its ScriptOrModule set to active script's record. if (script) { script_execution_context = JS::ExecutionContext::create(); script_execution_context->function = nullptr; - script_execution_context->realm = &script->settings_object().realm(); + script_execution_context->realm = &script->realm(); if (is(script)) { script_execution_context->script_or_module = JS::NonnullGCPtr(*verify_cast(script)->script_record()); } else if (is(script)) { @@ -360,8 +363,8 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) } } - // 5. Return the JobCallback Record { [[Callback]]: callable, [[HostDefined]]: { [[IncumbentSettings]]: incumbent settings, [[ActiveScriptContext]]: script execution context } }. - auto host_defined = adopt_own(*new WebEngineCustomJobCallbackData(incumbent_settings, move(script_execution_context))); + // 5. Return the JobCallback Record { [[Callback]]: callable, [[HostDefined]]: { [[IncumbentRealm]]: incumbent realm, [[ActiveScriptContext]]: script execution context } }. + auto host_defined = adopt_own(*new WebEngineCustomJobCallbackData(incumbent_realm, move(script_execution_context))); return JS::JobCallback::create(*s_main_thread_vm, callable, move(host_defined)); }; @@ -419,12 +422,11 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // https://whatpr.org/html/9893/webappapis.html#hostloadimportedmodule s_main_thread_vm->host_load_imported_module = [](JS::ImportedModuleReferrer referrer, JS::ModuleRequest const& module_request, JS::GCPtr load_state, JS::ImportedModulePayload payload) -> void { auto& vm = *s_main_thread_vm; - auto& realm = *vm.current_realm(); - // 1. Let settingsObject be the current principal settings object. - Optional settings_object = HTML::current_principal_settings_object(); + // 1. Let moduleMapRealm be the current realm. + auto* module_map_realm = vm.current_realm(); - // FIXME: 2. If settingsObject's global object implements WorkletGlobalScope or ServiceWorkerGlobalScope and loadState is undefined, then: + // FIXME: 2. If moduleMapRealm's global object implements WorkletGlobalScope or ServiceWorkerGlobalScope and loadState is undefined, then: // 3. Let referencingScript be null. Optional referencing_script; @@ -440,19 +442,19 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) // 1. Set referencingScript to referrer.[[HostDefined]]. referencing_script = verify_cast(referrer.has>() ? *referrer.get>()->host_defined() : *referrer.get>()->host_defined()); - // 2. Set settingsObject to referencingScript's settings object. - settings_object = referencing_script->settings_object(); - - // 3. Set fetchReferrer to referencingScript's base URL. + // 2. Set fetchReferrer to referencingScript's base URL. fetch_referrer = referencing_script->base_url(); - // FIXME: 4. Set originalFetchOptions to referencingScript's fetch options. + // FIXME: 3. Set originalFetchOptions to referencingScript's fetch options. + + // 4. Set moduleMapRealm to referencingScript's realm. + module_map_realm = &referencing_script->realm(); } // FIXME: 7. If referrer is a Cyclic Module Record and moduleRequest is equal to the first element of referrer.[[RequestedModules]], then: - // 8. Disallow further import maps given settingsObject. - settings_object->disallow_further_import_maps(); + // 8. Disallow further import maps given moduleMapRealm. + HTML::disallow_further_import_maps(*module_map_realm); // 9. Let url be the result of resolving a module specifier given referencingScript and moduleRequest.[[Specifier]], // catching any exceptions. If they throw an exception, let resolutionError be the thrown exception. @@ -464,21 +466,24 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) auto completion = dom_exception_to_throw_completion(main_thread_vm(), url.exception()); // 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, completion). - HTML::TemporaryExecutionContext context { realm }; + HTML::TemporaryExecutionContext context { *module_map_realm }; JS::finish_loading_imported_module(referrer, module_request, payload, completion); // 3. Return. return; } - // 11. Let fetchOptions be the result of getting the descendant script fetch options given originalFetchOptions, url, and settingsObject. - auto fetch_options = MUST(HTML::get_descendant_script_fetch_options(original_fetch_options, url.value(), *settings_object)); + // 11. Let settingsObject be moduleMapRealm's principal realm's settings object. + auto& settings_object = HTML::principal_realm_settings_object(HTML::principal_realm(*module_map_realm)); - // 12. Let destination be "script". + // 12. Let fetchOptions be the result of getting the descendant script fetch options given originalFetchOptions, url, and settingsObject. + auto fetch_options = MUST(HTML::get_descendant_script_fetch_options(original_fetch_options, url.value(), settings_object)); + + // 13. Let destination be "script". auto destination = Fetch::Infrastructure::Request::Destination::Script; - // 13. Let fetchClient be settingsObject. - JS::NonnullGCPtr fetch_client { *settings_object }; + // 14. Let fetchClient be moduleMapRealm's principal realm's settings object. + JS::NonnullGCPtr fetch_client { HTML::principal_realm_settings_object(HTML::principal_realm(*module_map_realm)) }; // 14. If loadState is not undefined, then: HTML::PerformTheFetchHook perform_fetch; @@ -495,7 +500,8 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) perform_fetch = fetch_context.perform_fetch; } - auto on_single_fetch_complete = HTML::create_on_fetch_script_complete(realm.heap(), [referrer, &realm, load_state, module_request, payload](JS::GCPtr const& module_script) -> void { + auto on_single_fetch_complete = HTML::create_on_fetch_script_complete(module_map_realm->heap(), [referrer, module_map_realm, load_state, module_request, payload](JS::GCPtr const& module_script) -> void { + auto& realm = *module_map_realm; // onSingleFetchComplete given moduleScript is the following algorithm: // 1. Let completion be null. // NOTE: Our JS::Completion does not support non JS::Value types for its [[Value]], a such we @@ -548,10 +554,10 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) vm.pop_execution_context(); }); - // 15. Fetch a single imported module script given url, fetchClient, destination, fetchOptions, settingsObject, fetchReferrer, + // 15. Fetch a single imported module script given url, fetchClient, destination, fetchOptions, moduleMapRealm, fetchReferrer, // moduleRequest, and onSingleFetchComplete as defined below. // If loadState is not undefined and loadState.[[PerformFetch]] is not null, pass loadState.[[PerformFetch]] along as well. - HTML::fetch_single_imported_module_script(realm, url.release_value(), *fetch_client, destination, fetch_options, *settings_object, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete); + 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); }; s_main_thread_vm->host_unrecognized_date_string = [](StringView date) { diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h index e570194a0e2..e490bd211cc 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.h @@ -66,15 +66,15 @@ struct WebEngineCustomData final : public JS::VM::CustomData { }; struct WebEngineCustomJobCallbackData final : public JS::JobCallback::CustomData { - WebEngineCustomJobCallbackData(HTML::EnvironmentSettingsObject& incumbent_settings, OwnPtr active_script_context) - : incumbent_settings(incumbent_settings) + WebEngineCustomJobCallbackData(JS::Realm& incumbent_realm, OwnPtr active_script_context) + : incumbent_realm(incumbent_realm) , active_script_context(move(active_script_context)) { } virtual ~WebEngineCustomJobCallbackData() override = default; - JS::NonnullGCPtr incumbent_settings; + JS::NonnullGCPtr incumbent_realm; OwnPtr active_script_context; }; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp index a204f9c89f4..585ea2ab812 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLScriptElement.cpp @@ -159,6 +159,7 @@ void HTMLScriptElement::execute_script() } // https://html.spec.whatwg.org/multipage/scripting.html#prepare-a-script +// https://whatpr.org/html/9893/scripting.html#prepare-a-script void HTMLScriptElement::prepare_script() { // 1. If el's already started is true, then return. @@ -433,9 +434,9 @@ void HTMLScriptElement::prepare_script() // 2. Switch on el's type: // -> "classic" if (m_script_type == ScriptType::Classic) { - // 1. Let script be the result of creating a classic script using source text, settings object, base URL, and options. + // 1. Let script be the result of creating a classic script using source text, settings object's realm, base URL, and options. // FIXME: Pass options. - auto script = ClassicScript::create(m_document->url().to_byte_string(), source_text, settings_object, base_url, m_source_line_number); + auto script = ClassicScript::create(m_document->url().to_byte_string(), source_text, settings_object.realm(), base_url, m_source_line_number); // 2. Mark as ready el given script. mark_as_ready(Result(move(script))); diff --git a/Userland/Libraries/LibWeb/HTML/Navigable.cpp b/Userland/Libraries/LibWeb/HTML/Navigable.cpp index 19ca8fdac50..deafbed0d77 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigable.cpp @@ -1583,6 +1583,7 @@ WebIDL::ExceptionOr Navigable::navigate_to_a_fragment(URL::URL const& url, } // https://html.spec.whatwg.org/multipage/browsing-the-web.html#evaluate-a-javascript:-url +// https://whatpr.org/html/9893/browsing-the-web.html#evaluate-a-javascript:-url WebIDL::ExceptionOr> Navigable::evaluate_javascript_url(URL::URL const& url, URL::Origin const& new_document_origin, String navigation_id) { auto& vm = this->vm(); @@ -1604,8 +1605,8 @@ WebIDL::ExceptionOr> Navigable::evaluate_javascript_url // 5. Let baseURL be settings's API base URL. auto base_url = settings.api_base_url(); - // 6. Let script be the result of creating a classic script given scriptSource, settings, baseURL, and the default classic script fetch options. - auto script = HTML::ClassicScript::create("(javascript url)", script_source, settings, base_url); + // 6. Let script be the result of creating a classic script given scriptSource, settings's realm, baseURL, and the default classic script fetch options. + auto script = HTML::ClassicScript::create("(javascript url)", script_source, settings.realm(), base_url); // 7. Let evaluationStatus be the result of running the classic script script. auto evaluation_status = script->run(); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp index cd8994e97c1..ff5774733e9 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp @@ -20,9 +20,8 @@ JS_DEFINE_ALLOCATOR(ClassicScript); // https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-classic-script // https://whatpr.org/html/9893/webappapis.html#creating-a-classic-script -JS::NonnullGCPtr ClassicScript::create(ByteString filename, StringView source, EnvironmentSettingsObject& environment_settings_object, URL::URL base_url, size_t source_line_number, MutedErrors muted_errors) +JS::NonnullGCPtr ClassicScript::create(ByteString filename, StringView source, JS::Realm& realm, URL::URL base_url, size_t source_line_number, MutedErrors muted_errors) { - auto& realm = environment_settings_object.realm(); auto& vm = realm.vm(); // 1. If muted errors is true, then set baseURL to about:blank. @@ -34,11 +33,9 @@ JS::NonnullGCPtr ClassicScript::create(ByteString filename, Strin source = ""sv; // 3. Let script be a new classic script that this algorithm will subsequently initialize. - auto script = vm.heap().allocate_without_realm(move(base_url), move(filename), environment_settings_object); - - // FIXME: 4. Set script's realm to realm. (NOTE: This was already done when constructing.) - - // 5. Set script's base URL to baseURL. (NOTE: This was already done when constructing.) + // 4. Set script's realm to realm. + // 5. Set script's base URL to baseURL. + auto script = vm.heap().allocate_without_realm(move(base_url), move(filename), realm); // FIXME: 6. Set script's fetch options to options. @@ -80,11 +77,10 @@ JS::NonnullGCPtr ClassicScript::create(ByteString filename, Strin // https://whatpr.org/html/9893/webappapis.html#run-a-classic-script JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) { - // 1. Let settings be the settings object of script. - auto& settings = settings_object(); - auto& realm = settings.realm(); + // 1. Let realm be the realm of script. + auto& realm = this->realm(); - // 2. Check if we can run script with settings. If this returns "do not run" then return NormalCompletion(empty). + // 2. Check if we can run script with realm. If this returns "do not run" then return NormalCompletion(empty). if (can_run_script(realm) == RunScriptDecision::DoNotRun) return JS::normal_completion({}); @@ -131,8 +127,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) // 3. Otherwise, rethrow errors is false. Perform the following steps: VERIFY(rethrow_errors == RethrowErrors::No); - // 1. Report an exception given by evaluationStatus.[[Value]] for script's settings object's global object. - auto* window_or_worker = dynamic_cast(&settings.global_object()); + // 1. Report an exception given by evaluationStatus.[[Value]] for realms's global object. + auto* window_or_worker = dynamic_cast(&realm.global_object()); VERIFY(window_or_worker); window_or_worker->report_an_exception(*evaluation_status.value()); @@ -154,8 +150,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) // Return Completion { [[Type]]: throw, [[Value]]: a new "QuotaExceededError" DOMException, [[Target]]: empty }. } -ClassicScript::ClassicScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object) - : Script(move(base_url), move(filename), environment_settings_object) +ClassicScript::ClassicScript(URL::URL base_url, ByteString filename, JS::Realm& realm) + : Script(move(base_url), move(filename), realm) { } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h index e2939f550d5..0c46c583bc2 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.h @@ -24,7 +24,7 @@ public: No, Yes, }; - static JS::NonnullGCPtr create(ByteString filename, StringView source, EnvironmentSettingsObject&, URL::URL base_url, size_t source_line_number = 1, MutedErrors = MutedErrors::No); + static JS::NonnullGCPtr create(ByteString filename, StringView source, JS::Realm&, URL::URL base_url, size_t source_line_number = 1, MutedErrors = MutedErrors::No); JS::Script* script_record() { return m_script_record; } JS::Script const* script_record() const { return m_script_record; } @@ -38,7 +38,7 @@ public: MutedErrors muted_errors() const { return m_muted_errors; } private: - ClassicScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object); + ClassicScript(URL::URL base_url, ByteString filename, JS::Realm&); virtual void visit_edges(Cell::Visitor&) override; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 046be503ffc..1ced21521fd 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -260,23 +260,25 @@ bool is_scripting_disabled(JS::Realm const& realm) } // https://html.spec.whatwg.org/multipage/webappapis.html#module-type-allowed -bool EnvironmentSettingsObject::module_type_allowed(StringView module_type) const +// https://whatpr.org/html/9893/webappapis.html#module-type-allowed +bool module_type_allowed(JS::Realm const&, StringView module_type) { // 1. If moduleType is not "javascript", "css", or "json", then return false. if (module_type != "javascript"sv && module_type != "css"sv && module_type != "json"sv) return false; - // FIXME: 2. If moduleType is "css" and the CSSStyleSheet interface is not exposed in settings's Realm, then return false. + // FIXME: 2. If moduleType is "css" and the CSSStyleSheet interface is not exposed in realm, then return false. // 3. Return true. return true; } // https://html.spec.whatwg.org/multipage/webappapis.html#disallow-further-import-maps -void EnvironmentSettingsObject::disallow_further_import_maps() +// https://whatpr.org/html/9893/webappapis.html#disallow-further-import-maps +void disallow_further_import_maps(JS::Realm& realm) { - // 1. Let global be settingsObject's global object. - auto& global = global_object(); + // 1. Let global be realm's global object. + auto& global = realm.global_object(); // 2. If global does not implement Window, then return. if (!is(global)) diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h index f42614f6164..bf26223f3c2 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h @@ -96,10 +96,6 @@ public: // https://fetch.spec.whatwg.org/#concept-fetch-group Vector>& fetch_group() { return m_fetch_group; } - bool module_type_allowed(StringView module_type) const; - - void disallow_further_import_maps(); - SerializedEnvironmentSettingsObject serialize(); JS::NonnullGCPtr storage_manager(); @@ -142,6 +138,8 @@ void clean_up_after_running_script(JS::Realm const&); void prepare_to_run_callback(JS::Realm&); void clean_up_after_running_callback(JS::Realm const&); ModuleMap& module_map_of_realm(JS::Realm&); +bool module_type_allowed(JS::Realm const&, StringView module_type); +void disallow_further_import_maps(JS::Realm&); EnvironmentSettingsObject& incumbent_settings_object(); JS::Realm& incumbent_realm(); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp index f2f2f765264..b09aea275e5 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.cpp @@ -369,11 +369,11 @@ WebIDL::ExceptionOr fetch_classic_script(JS::NonnullGCPtris_cors_cross_origin() ? ClassicScript::MutedErrors::Yes : ClassicScript::MutedErrors::No; - // 7. Let script be the result of creating a classic script given source text, settings object, response's URL, + // 7. Let script be the result of creating a classic script given source text, settings object's realm, response's URL, // options, and muted errors. // FIXME: Pass options. auto response_url = response->url().value_or({}); - auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url, 1, muted_errors); + auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object.realm(), response_url, 1, muted_errors); // 8. Run onComplete given script. on_complete->function()(script); @@ -440,10 +440,10 @@ WebIDL::ExceptionOr fetch_classic_worker_script(URL::URL const& url, Envir VERIFY(decoder.has_value()); auto source_text = TextCodec::convert_input_to_utf8_using_given_decoder_unless_there_is_a_byte_order_mark(*decoder, body_bytes.template get()).release_value_but_fixme_should_propagate_errors(); - // 5. Let script be the result of creating a classic script using sourceText, settingsObject, + // 5. Let script be the result of creating a classic script using sourceText, settingsObject's realm, // response's URL, and the default classic script fetch options. auto response_url = response->url().value_or({}); - auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url); + auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object.realm(), response_url); // 6. Run onComplete given script. on_complete->function()(script); @@ -532,9 +532,9 @@ WebIDL::ExceptionOr> fetch_a_classic_worker_impo // 9. Let mutedErrors be true if response was CORS-cross-origin, and false otherwise. auto muted_errors = response->is_cors_cross_origin() ? ClassicScript::MutedErrors::Yes : ClassicScript::MutedErrors::No; - // 10. Let script be the result of creating a classic script given sourceText, settingsObject, response's URL, the default classic script fetch options, and mutedErrors. + // 10. Let script be the result of creating a classic script given sourceText, settingsObject's realm, response's URL, the default classic script fetch options, and mutedErrors. auto response_url = response->url().value_or({}); - auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url, 1, muted_errors); + auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object.realm(), response_url, 1, muted_errors); // 11. Return script. return script; @@ -547,6 +547,7 @@ WebIDL::ExceptionOr fetch_module_worker_script_graph(URL::URL const& url, } // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-worklet/module-worker-script-graph +// https://whatpr.org/html/9893/webappapis.html#fetch-a-worklet/module-worker-script-graph WebIDL::ExceptionOr fetch_worklet_module_worker_script_graph(URL::URL const& url, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook perform_fetch, OnFetchScriptComplete on_complete) { auto& realm = settings_object.realm(); @@ -578,9 +579,9 @@ WebIDL::ExceptionOr fetch_worklet_module_worker_script_graph(URL::URL cons fetch_descendants_of_and_link_a_module_script(realm, verify_cast(*result), fetch_client, destination, move(perform_fetch), on_complete); }); - // 2. Fetch a single module script given url, fetchClient, destination, options, settingsObject, "client", true, + // 2. Fetch a single module script given url, fetchClient, destination, options, settingsObject's realm, "client", true, // and onSingleFetchComplete as defined below. If performFetch was given, pass it along as well. - fetch_single_module_script(realm, url, fetch_client, destination, options, settings_object, Fetch::Infrastructure::Request::Referrer::Client, {}, TopLevelModule::Yes, move(perform_fetch), on_single_fetch_complete); + fetch_single_module_script(realm, url, fetch_client, destination, options, settings_object.realm(), Fetch::Infrastructure::Request::Referrer::Client, {}, TopLevelModule::Yes, move(perform_fetch), on_single_fetch_complete); return {}; } @@ -613,9 +614,9 @@ void fetch_internal_module_script_graph(JS::Realm& realm, JS::ModuleRequest cons fetch_descendants_of_a_module_script(realm, module_script, fetch_client_settings_object, destination, visited_set, perform_fetch, on_complete); }); - // 5. Fetch a single module script given url, fetch client settings object, destination, options, referringScript's settings object, + // 5. Fetch a single module script given url, fetch client settings object, destination, options, referringScript's settings object's realm, // referringScript's base URL, moduleRequest, false, and onSingleFetchComplete as defined below. If performFetch was given, pass it along as well. - fetch_single_module_script(realm, url, fetch_client_settings_object, destination, options, referring_script.settings_object(), referring_script.base_url(), module_request, TopLevelModule::No, perform_fetch, on_single_fetch_complete); + fetch_single_module_script(realm, url, fetch_client_settings_object, destination, options, referring_script.realm(), referring_script.base_url(), module_request, TopLevelModule::No, perform_fetch, on_single_fetch_complete); } // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendants-of-a-module-script @@ -726,12 +727,13 @@ Fetch::Infrastructure::Request::Destination fetch_destination_from_module_type(F } // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script +// https://whatpr.org/html/9893/webappapis.html#fetch-a-single-module-script void fetch_single_module_script(JS::Realm& realm, URL::URL const& url, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination destination, ScriptFetchOptions const& options, - EnvironmentSettingsObject& settings_object, + JS::Realm& module_map_realm, Web::Fetch::Infrastructure::Request::ReferrerType const& referrer, Optional const& module_request, TopLevelModule is_top_level, @@ -745,13 +747,13 @@ void fetch_single_module_script(JS::Realm& realm, if (module_request.has_value()) module_type = module_type_from_module_request(*module_request); - // 3. Assert: the result of running the module type allowed steps given moduleType and settingsObject is true. + // 3. Assert: the result of running the module type allowed steps given moduleType and moduleMapRealm is true. // Otherwise we would not have reached this point because a failure would have been raised when inspecting moduleRequest.[[Assertions]] // in create a JavaScript module script or fetch a single imported module script. - VERIFY(settings_object.module_type_allowed(module_type)); + VERIFY(module_type_allowed(module_map_realm, module_type)); - // 4. Let moduleMap be settingsObject's module map. - auto& module_map = settings_object.module_map(); + // 4. Let moduleMap be moduleMapRealm's module map. + auto& module_map = module_map_of_realm(module_map_realm); // 5. If moduleMap[(url, moduleType)] is "fetching", wait in parallel until that entry's value changes, // then queue a task on the networking task source to proceed with running the following steps. @@ -801,7 +803,7 @@ void fetch_single_module_script(JS::Realm& realm, // 13. If performFetch was given, run performFetch with request, isTopLevel, and with processResponseConsumeBody as defined below. // Otherwise, fetch request with processResponseConsumeBody set to processResponseConsumeBody as defined below. // In both cases, let processResponseConsumeBody given response response and null, failure, or a byte sequence bodyBytes be the following algorithm: - auto process_response_consume_body = [&module_map, url, module_type, &settings_object, on_complete](JS::NonnullGCPtr response, Fetch::Infrastructure::FetchAlgorithms::BodyBytes body_bytes) { + auto process_response_consume_body = [&module_map, url, module_type, &module_map_realm, on_complete](JS::NonnullGCPtr response, Fetch::Infrastructure::FetchAlgorithms::BodyBytes body_bytes) { // 1. If either of the following conditions are met: // - bodyBytes is null or failure; or // - response's status is not an ok status, @@ -826,10 +828,10 @@ void fetch_single_module_script(JS::Realm& realm, // FIXME: 5. Let referrerPolicy be the result of parsing the `Referrer-Policy` header given response. [REFERRERPOLICY] // FIXME: 6. If referrerPolicy is not the empty string, set options's referrer policy to referrerPolicy. - // 7. If mimeType is a JavaScript MIME type and moduleType is "javascript", then set moduleScript to the result of creating a JavaScript module script given sourceText, settingsObject, response's URL, and options. + // 7. If mimeType is a JavaScript MIME type and moduleType is "javascript", then set moduleScript to the result of creating a JavaScript module script given sourceText, moduleMapRealm, response's URL, and options. // FIXME: Pass options. if (mime_type->is_javascript() && module_type == "javascript") - module_script = JavaScriptModuleScript::create(url.basename(), source_text, settings_object, response->url().value_or({})).release_value_but_fixme_should_propagate_errors(); + module_script = JavaScriptModuleScript::create(url.basename(), source_text, module_map_realm, response->url().value_or({})).release_value_but_fixme_should_propagate_errors(); // FIXME: 8. If the MIME type essence of mimeType is "text/css" and moduleType is "css", then set moduleScript to the result of creating a CSS module script given sourceText and settingsObject. // FIXME: 9. If mimeType is a JSON MIME type and moduleType is "json", then set moduleScript to the result of creating a JSON module script given sourceText and settingsObject. @@ -849,10 +851,11 @@ void fetch_single_module_script(JS::Realm& realm, } // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree +// https://whatpr.org/html/9893/webappapis.html#fetch-a-module-script-tree void fetch_external_module_script_graph(JS::Realm& realm, URL::URL const& url, EnvironmentSettingsObject& settings_object, ScriptFetchOptions const& options, OnFetchScriptComplete on_complete) { - // 1. Disallow further import maps given settingsObject. - settings_object.disallow_further_import_maps(); + // 1. Disallow further import maps given settingsObject's realm. + disallow_further_import_maps(settings_object.realm()); auto steps = create_on_fetch_script_complete(realm.heap(), [&realm, &settings_object, on_complete, url](auto result) mutable { // 1. If result is null, run onComplete given null, and abort these steps. @@ -866,18 +869,19 @@ void fetch_external_module_script_graph(JS::Realm& realm, URL::URL const& url, E fetch_descendants_of_and_link_a_module_script(realm, module_script, settings_object, Fetch::Infrastructure::Request::Destination::Script, nullptr, on_complete); }); - // 2. Fetch a single module script given url, settingsObject, "script", options, settingsObject, "client", true, and with the following steps given result: - fetch_single_module_script(realm, url, settings_object, Fetch::Infrastructure::Request::Destination::Script, options, settings_object, Web::Fetch::Infrastructure::Request::Referrer::Client, {}, TopLevelModule::Yes, nullptr, steps); + // 2. Fetch a single module script given url, settingsObject, "script", options, settingsObject's realm, "client", true, and with the following steps given result: + fetch_single_module_script(realm, url, settings_object, Fetch::Infrastructure::Request::Destination::Script, options, settings_object.realm(), Web::Fetch::Infrastructure::Request::Referrer::Client, {}, TopLevelModule::Yes, nullptr, steps); } // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-an-inline-module-script-graph +// https://whatpr.org/html/9893/webappapis.html#fetch-an-inline-module-script-graph void fetch_inline_module_script_graph(JS::Realm& realm, ByteString const& filename, ByteString const& source_text, URL::URL const& base_url, EnvironmentSettingsObject& settings_object, OnFetchScriptComplete on_complete) { - // 1. Disallow further import maps given settingsObject. - settings_object.disallow_further_import_maps(); + // 1. Disallow further import maps given settingsObject's realm. + disallow_further_import_maps(settings_object.realm()); - // 2. Let script be the result of creating a JavaScript module script using sourceText, settingsObject, baseURL, and options. - auto script = JavaScriptModuleScript::create(filename, source_text.view(), settings_object, base_url).release_value_but_fixme_should_propagate_errors(); + // 2. Let script be the result of creating a JavaScript module script using sourceText, settingsObject's realm, baseURL, and options. + auto script = JavaScriptModuleScript::create(filename, source_text.view(), settings_object.realm(), base_url).release_value_but_fixme_should_propagate_errors(); // 3. If script is null, run onComplete given null, and return. if (!script) { @@ -895,7 +899,7 @@ void fetch_single_imported_module_script(JS::Realm& realm, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination destination, ScriptFetchOptions const& options, - EnvironmentSettingsObject& settings_object, + JS::Realm& module_map_realm, Fetch::Infrastructure::Request::ReferrerType referrer, JS::ModuleRequest const& module_request, PerformTheFetchHook perform_fetch, @@ -909,16 +913,16 @@ void fetch_single_imported_module_script(JS::Realm& realm, // 2. Let moduleType be the result of running the module type from module request steps given moduleRequest. auto module_type = module_type_from_module_request(module_request); - // 3. If the result of running the module type allowed steps given moduleType and settingsObject is false, + // 3. If the result of running the module type allowed steps given moduleType and moduleMapRealm is false, // then run onComplete given null, and return. - if (!settings_object.module_type_allowed(module_type)) { + if (!module_type_allowed(module_map_realm, module_type)) { on_complete->function()(nullptr); return; } - // 4. Fetch a single module script given url, fetchClient, destination, options, settingsObject, referrer, moduleRequest, false, + // 4. Fetch a single module script given url, fetchClient, destination, options, moduleMapRealm, referrer, moduleRequest, false, // and onComplete. If performFetch was given, pass it along as well. - fetch_single_module_script(realm, url, fetch_client, destination, options, settings_object, referrer, module_request, TopLevelModule::No, perform_fetch, on_complete); + fetch_single_module_script(realm, url, fetch_client, destination, options, module_map_realm, referrer, module_request, TopLevelModule::No, perform_fetch, on_complete); } // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-the-descendants-of-and-link-a-module-script diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.h b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.h index 74fdb6f6be8..48b71c44bf6 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Fetching.h @@ -96,12 +96,12 @@ WebIDL::ExceptionOr fetch_worklet_module_worker_script_graph(URL::URL cons void fetch_internal_module_script_graph(JS::Realm&, JS::ModuleRequest const& module_request, EnvironmentSettingsObject& fetch_client_settings_object, Fetch::Infrastructure::Request::Destination, ScriptFetchOptions const&, Script& referring_script, HashTable const& visited_set, PerformTheFetchHook, OnFetchScriptComplete on_complete); void fetch_external_module_script_graph(JS::Realm&, URL::URL const&, EnvironmentSettingsObject& settings_object, ScriptFetchOptions const&, OnFetchScriptComplete on_complete); void fetch_inline_module_script_graph(JS::Realm&, ByteString const& filename, ByteString const& source_text, URL::URL const& base_url, EnvironmentSettingsObject& settings_object, OnFetchScriptComplete on_complete); -void fetch_single_imported_module_script(JS::Realm&, URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, ScriptFetchOptions const&, EnvironmentSettingsObject& settings_object, Fetch::Infrastructure::Request::ReferrerType, JS::ModuleRequest const&, PerformTheFetchHook, OnFetchScriptComplete on_complete); +void fetch_single_imported_module_script(JS::Realm&, URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, ScriptFetchOptions const&, JS::Realm& module_map_realm, Fetch::Infrastructure::Request::ReferrerType, JS::ModuleRequest const&, PerformTheFetchHook, OnFetchScriptComplete on_complete); void fetch_descendants_of_a_module_script(JS::Realm&, JavaScriptModuleScript& module_script, EnvironmentSettingsObject& fetch_client_settings_object, Fetch::Infrastructure::Request::Destination, HashTable visited_set, PerformTheFetchHook, OnFetchScriptComplete callback); void fetch_descendants_of_and_link_a_module_script(JS::Realm&, JavaScriptModuleScript&, EnvironmentSettingsObject&, Fetch::Infrastructure::Request::Destination, PerformTheFetchHook, OnFetchScriptComplete on_complete); Fetch::Infrastructure::Request::Destination fetch_destination_from_module_type(Fetch::Infrastructure::Request::Destination, ByteString const&); -void fetch_single_module_script(JS::Realm&, URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, ScriptFetchOptions const&, EnvironmentSettingsObject& settings_object, Web::Fetch::Infrastructure::Request::ReferrerType const&, Optional const&, TopLevelModule, PerformTheFetchHook, OnFetchScriptComplete callback); +void fetch_single_module_script(JS::Realm&, URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, ScriptFetchOptions const&, JS::Realm& module_map_realm, Web::Fetch::Infrastructure::Request::ReferrerType const&, Optional const&, TopLevelModule, PerformTheFetchHook, OnFetchScriptComplete callback); } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp index ebbdf984f6a..d1aa7c2d679 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp @@ -17,36 +17,30 @@ JS_DEFINE_ALLOCATOR(JavaScriptModuleScript); ModuleScript::~ModuleScript() = default; -ModuleScript::ModuleScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object) - : Script(move(base_url), move(filename), environment_settings_object) +ModuleScript::ModuleScript(URL::URL base_url, ByteString filename, JS::Realm& realm) + : Script(move(base_url), move(filename), realm) { } JavaScriptModuleScript::~JavaScriptModuleScript() = default; -JavaScriptModuleScript::JavaScriptModuleScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object) - : ModuleScript(move(base_url), move(filename), environment_settings_object) +JavaScriptModuleScript::JavaScriptModuleScript(URL::URL base_url, ByteString filename, JS::Realm& realm) + : ModuleScript(move(base_url), move(filename), realm) { } // https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-javascript-module-script // https://whatpr.org/html/9893/webappapis.html#creating-a-javascript-module-script -WebIDL::ExceptionOr> JavaScriptModuleScript::create(ByteString const& filename, StringView source, EnvironmentSettingsObject& settings_object, URL::URL base_url) +WebIDL::ExceptionOr> JavaScriptModuleScript::create(ByteString const& filename, StringView source, JS::Realm& realm, URL::URL base_url) { - auto& realm = settings_object.realm(); - - // 1. If scripting is disabled for settings, then set source to the empty string. + // 1. If scripting is disabled for realm, then set source to the empty string. if (HTML::is_scripting_disabled(realm)) source = ""sv; // 2. Let script be a new module script that this algorithm will subsequently initialize. - auto script = realm.heap().allocate(realm, move(base_url), filename, settings_object); - - // FIXME: 3. Set script's settings object to settings. - // NOTE: This was already done when constructing. - + // 3. Set script's realm to realm. // 4. Set script's base URL to baseURL. - // NOTE: This was already done when constructing. + auto script = realm.heap().allocate(realm, move(base_url), filename, realm); // FIXME: 5. Set script's fetch options to options. @@ -100,8 +94,8 @@ WebIDL::ExceptionOr> JavaScriptModuleScript::c // 4. Let moduleType be the result of running the module type from module request steps given requested. auto module_type = module_type_from_module_request(requested); - // 5. If the result of running the module type allowed steps given moduleType and settings is false, then: - if (!settings_object.module_type_allowed(module_type)) { + // 5. If the result of running the module type allowed steps given moduleType and realm is false, then: + if (!module_type_allowed(realm, module_type)) { // FIXME: 1. Let error be a new TypeError exception. // FIXME: 2. Set script's parse error to error. @@ -122,13 +116,12 @@ WebIDL::ExceptionOr> JavaScriptModuleScript::c // https://whatpr.org/html/9893/webappapis.html#run-a-module-script JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) { - // 1. Let settings be the settings object of script. - auto& settings = settings_object(); - auto& realm = settings.realm(); + // 1. Let realm be the realm of script. + auto& realm = this->realm(); // 2. Check if we can run script with realm. If this returns "do not run", then return a promise resolved with undefined. if (can_run_script(realm) == RunScriptDecision::DoNotRun) { - auto promise = JS::Promise::create(settings.realm()); + auto promise = JS::Promise::create(realm); promise->fulfill(JS::js_undefined()); return promise; } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.h b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.h index 8349af90b73..ff5f003639b 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.h @@ -19,7 +19,7 @@ public: virtual ~ModuleScript() override; protected: - ModuleScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object); + ModuleScript(URL::URL base_url, ByteString filename, JS::Realm&); }; class JavaScriptModuleScript final : public ModuleScript { @@ -29,7 +29,7 @@ class JavaScriptModuleScript final : public ModuleScript { public: virtual ~JavaScriptModuleScript() override; - static WebIDL::ExceptionOr> create(ByteString const& filename, StringView source, EnvironmentSettingsObject&, URL::URL base_url); + static WebIDL::ExceptionOr> create(ByteString const& filename, StringView source, JS::Realm&, URL::URL base_url); enum class PreventErrorReporting { Yes, @@ -42,7 +42,7 @@ public: JS::SourceTextModule* record() { return m_record.ptr(); } protected: - JavaScriptModuleScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object); + JavaScriptModuleScript(URL::URL base_url, ByteString filename, JS::Realm&); private: virtual void visit_edges(JS::Cell::Visitor&) override; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp index d988a697650..b7b2eafa617 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Script.cpp @@ -11,15 +11,22 @@ namespace Web::HTML { JS_DEFINE_ALLOCATOR(Script); -Script::Script(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object) +Script::Script(URL::URL base_url, ByteString filename, JS::Realm& realm) : m_base_url(move(base_url)) , m_filename(move(filename)) - , m_settings_object(environment_settings_object) + , m_realm(realm) { } Script::~Script() = default; +// https://whatpr.org/html/9893/webappapis.html#settings-object +EnvironmentSettingsObject& Script::settings_object() +{ + // The settings object of a script is the settings object of the principal realm of the script's realm. + return principal_realm_settings_object(principal_realm(realm())); +} + void Script::visit_host_defined_self(JS::Cell::Visitor& visitor) { visitor.visit(*this); @@ -28,7 +35,7 @@ void Script::visit_host_defined_self(JS::Cell::Visitor& visitor) void Script::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); - visitor.visit(m_settings_object); + visitor.visit(m_realm); visitor.visit(m_parse_error); visitor.visit(m_error_to_rethrow); } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Script.h b/Userland/Libraries/LibWeb/HTML/Scripting/Script.h index 720054aaac0..c9264affbcf 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Script.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Script.h @@ -14,6 +14,7 @@ namespace Web::HTML { // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script +// https://whatpr.org/html/9893/webappapis.html#concept-script class Script : public JS::Cell , public JS::Script::HostDefined { @@ -26,7 +27,8 @@ public: URL::URL const& base_url() const { return m_base_url; } ByteString const& filename() const { return m_filename; } - EnvironmentSettingsObject& settings_object() { return m_settings_object; } + JS::Realm& realm() { return m_realm; } + EnvironmentSettingsObject& settings_object(); [[nodiscard]] JS::Value error_to_rethrow() const { return m_error_to_rethrow; } void set_error_to_rethrow(JS::Value value) { m_error_to_rethrow = value; } @@ -35,7 +37,7 @@ public: void set_parse_error(JS::Value value) { m_parse_error = value; } protected: - Script(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& environment_settings_object); + Script(URL::URL base_url, ByteString filename, JS::Realm&); virtual void visit_edges(Visitor&) override; @@ -44,7 +46,7 @@ private: URL::URL m_base_url; ByteString m_filename; - JS::NonnullGCPtr m_settings_object; + JS::NonnullGCPtr m_realm; // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-parse-error JS::Value m_parse_error; diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index 6a1efc612b3..887e85a0568 100644 --- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -384,10 +384,10 @@ i32 WindowOrWorkerGlobalScopeMixin::run_timer_initialization_steps(TimerHandler // done by eval(). That is, module script fetches via import() will behave the same in both contexts. } - // 7. Let script be the result of creating a classic script given handler, settings object, base URL, and fetch options. + // 7. Let script be the result of creating a classic script given handler, realm, base URL, and fetch options. // FIXME: Pass fetch options. auto basename = base_url.basename(); - auto script = ClassicScript::create(basename, source, settings_object, move(base_url)); + auto script = ClassicScript::create(basename, source, this_impl().realm(), move(base_url)); // 8. Run the classic script script. (void)script->run(); diff --git a/Userland/Libraries/LibWeb/SVG/SVGScriptElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGScriptElement.cpp index a85f898eef7..35aea884701 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGScriptElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGScriptElement.cpp @@ -64,10 +64,9 @@ void SVGScriptElement::process_the_script_element() HTML::main_thread_event_loop().spin_until(JS::create_heap_function(heap(), [&] { return m_document->ready_to_run_scripts(); })); // FIXME: Support non-inline scripts. - auto& settings_object = document().relevant_settings_object(); auto base_url = document().base_url(); - m_script = HTML::ClassicScript::create(m_document->url().to_byte_string(), inline_script, settings_object, base_url, m_source_line_number); + m_script = HTML::ClassicScript::create(m_document->url().to_byte_string(), inline_script, realm(), base_url, m_source_line_number); (void)m_script->run(); } diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp index d22f3b504fd..ba78b7683ef 100644 --- a/Userland/Services/WebContent/PageClient.cpp +++ b/Userland/Services/WebContent/PageClient.cpp @@ -728,10 +728,10 @@ void PageClient::run_javascript(ByteString const& js_source) // Let baseURL be settings's API base URL. auto base_url = settings.api_base_url(); - // Let script be the result of creating a classic script given scriptSource, settings, baseURL, and the default classic script fetch options. + // Let script be the result of creating a classic script given scriptSource, setting's realm, baseURL, and the default classic script fetch options. // FIXME: This doesn't pass in "default classic script fetch options" // FIXME: What should the filename be here? - auto script = Web::HTML::ClassicScript::create("(client connection run_javascript)", js_source, settings, move(base_url)); + auto script = Web::HTML::ClassicScript::create("(client connection run_javascript)", js_source, settings.realm(), move(base_url)); // Let evaluationStatus be the result of running the classic script script. auto evaluation_status = script->run();