mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibWeb: Remove ShadowRealm HTML integration
This commit is contained in:
committed by
Shannon Booth
parent
f27bc38aa7
commit
bb0f244667
Notes:
github-actions[bot]
2026-04-05 11:58:52 +00:00
Author: https://github.com/shannonbooth Commit: https://github.com/LadybirdBrowser/ladybird/commit/bb0f244667d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8753
@@ -35,7 +35,7 @@ GC::Ref<Animation> Animation::create(JS::Realm& realm, GC::Ptr<AnimationEffect>
|
||||
// a timeline argument is missing, passing the default document timeline of the Document associated with the
|
||||
// Window that is the current global object.
|
||||
if (!timeline.has_value()) {
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
timeline = window.associated_document().timeline();
|
||||
}
|
||||
animation->set_timeline(timeline.release_value());
|
||||
|
||||
@@ -44,7 +44,7 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> AudioConstructor::construct(FunctionO
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 1. Let document be the current global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
auto& document = window.associated_document();
|
||||
|
||||
// 2. Let audio be the result of creating an element given document, "audio", and the HTML namespace.
|
||||
|
||||
@@ -39,14 +39,13 @@ JS::ThrowCompletionOr<JS::Value> ImageConstructor::call()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-image
|
||||
// https://whatpr.org/html/9893/embedded-content.html#dom-image
|
||||
// https://webidl.spec.whatwg.org/#legacy-factory-functions
|
||||
JS::ThrowCompletionOr<GC::Ref<JS::Object>> ImageConstructor::construct(FunctionObject& new_target)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 1. Let document be the current principal global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
// 1. Let document be the current global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
auto& document = window.associated_document();
|
||||
|
||||
// 2. Let img be the result of creating an element given document, "img", and the HTML namespace.
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/PrincipalHostDefined.h>
|
||||
#include <LibWeb/Bindings/SyntheticHostDefined.h>
|
||||
|
||||
namespace Web::Bindings {
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Bindings/SyntheticHostDefined.h>
|
||||
#include <LibWeb/Bindings/WindowExposedInterfaces.h>
|
||||
#include <LibWeb/ContentSecurityPolicy/BlockingAlgorithms.h>
|
||||
#include <LibWeb/ContentSecurityPolicy/Directives/KeywordSources.h>
|
||||
@@ -39,7 +38,6 @@
|
||||
#include <LibWeb/HTML/Scripting/ModuleScript.h>
|
||||
#include <LibWeb/HTML/Scripting/Script.h>
|
||||
#include <LibWeb/HTML/Scripting/SimilarOriginWindowAgent.h>
|
||||
#include <LibWeb/HTML/Scripting/SyntheticRealmSettings.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/HTML/Scripting/WorkerAgent.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
@@ -132,7 +130,6 @@ void initialize_main_thread_vm(AgentType 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;
|
||||
|
||||
@@ -157,12 +154,12 @@ void initialize_main_thread_vm(AgentType type)
|
||||
return;
|
||||
}
|
||||
|
||||
// 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();
|
||||
// 3. Let settingsObject be the current settings object.
|
||||
// 4. If script is not null, then set settings object to script's settings object.
|
||||
auto& settings_object = script ? script->settings_object() : HTML::current_settings_object();
|
||||
|
||||
// 5. Let global be realm's global object.
|
||||
auto& global_mixin = as<HTML::UniversalGlobalScopeMixin>(realm.global_object());
|
||||
// 5. Let global be settingsObject's global object.
|
||||
auto& global_mixin = as<HTML::UniversalGlobalScopeMixin>(settings_object.global_object());
|
||||
auto& global = global_mixin.this_impl();
|
||||
|
||||
switch (operation) {
|
||||
@@ -208,18 +205,17 @@ void initialize_main_thread_vm(AgentType type)
|
||||
};
|
||||
|
||||
// 8.1.5.4.1 HostCallJobCallback(callback, V, argumentsList), https://html.spec.whatwg.org/multipage/webappapis.html#hostcalljobcallback
|
||||
// https://whatpr.org/html/9893/webappapis.html#hostcalljobcallback
|
||||
s_main_thread_vm->host_call_job_callback = [](JS::JobCallback& callback, JS::Value this_value, ReadonlySpan<JS::Value> arguments_list) {
|
||||
auto& callback_host_defined = as<WebEngineCustomJobCallbackData>(*callback.custom_data());
|
||||
|
||||
// 1. Let incumbent realm be callback.[[HostDefined]].[[IncumbentRealm]].
|
||||
auto& incumbent_realm = callback_host_defined.incumbent_realm;
|
||||
// 1. Let incumbent settings be callback.[[HostDefined]].[[IncumbentSettings]].
|
||||
auto& incumbent_settings = callback_host_defined.incumbent_settings;
|
||||
|
||||
// 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(incumbent_realm);
|
||||
// 3. Prepare to run a callback with incumbent settings.
|
||||
HTML::prepare_to_run_callback(incumbent_settings);
|
||||
|
||||
// 4. If script execution context is not null, then push script execution context onto the JavaScript execution context stack.
|
||||
if (script_execution_context)
|
||||
@@ -234,8 +230,8 @@ void initialize_main_thread_vm(AgentType type)
|
||||
s_main_thread_vm->pop_execution_context();
|
||||
}
|
||||
|
||||
// 7. Clean up after running a callback with incumbent realm.
|
||||
HTML::clean_up_after_running_callback(incumbent_realm);
|
||||
// 7. Clean up after running a callback with incumbent settings.
|
||||
HTML::clean_up_after_running_callback(incumbent_settings);
|
||||
|
||||
// 8. Return result.
|
||||
return result;
|
||||
@@ -248,8 +244,8 @@ void initialize_main_thread_vm(AgentType type)
|
||||
|
||||
// 2. Queue a global task on the JavaScript engine task source given global to perform the following steps:
|
||||
HTML::queue_global_task(HTML::Task::Source::JavaScriptEngine, global, GC::create_function(s_main_thread_vm->heap(), [&finalization_registry] {
|
||||
// 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]].
|
||||
auto& entry = *finalization_registry.cleanup_callback().callback().realm();
|
||||
// 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]'s environment settings object.
|
||||
auto& entry = HTML::principal_realm_settings_object(*finalization_registry.cleanup_callback().callback().realm());
|
||||
|
||||
// 2. Prepare to run script with entry.
|
||||
HTML::prepare_to_run_script(entry);
|
||||
@@ -262,12 +258,11 @@ void initialize_main_thread_vm(AgentType type)
|
||||
|
||||
// 5. If result is an abrupt completion, then report the exception given by result.[[Value]].
|
||||
if (result.is_error())
|
||||
HTML::report_exception(result, entry);
|
||||
HTML::report_exception(result, entry.realm());
|
||||
}));
|
||||
};
|
||||
|
||||
// 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 = [](GC::Ref<GC::Function<JS::ThrowCompletionOr<JS::Value>()>> job, JS::Realm* realm) {
|
||||
auto& vm = *s_main_thread_vm;
|
||||
|
||||
@@ -276,28 +271,33 @@ void initialize_main_thread_vm(AgentType type)
|
||||
// This means taking it here now and passing it through to the lambda.
|
||||
auto script_or_module = vm.get_active_script_or_module();
|
||||
|
||||
// 1. Queue a microtask to perform the following steps:
|
||||
// 1. If realm is not null, then let job settings be the settings object for realm. Otherwise, let job settings be null.
|
||||
GC::Ptr<HTML::EnvironmentSettingsObject> job_settings;
|
||||
if (realm)
|
||||
job_settings = &HTML::principal_realm_settings_object(*realm);
|
||||
|
||||
// 2. 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() : vm.heap();
|
||||
HTML::queue_a_microtask(script ? script->settings_object().responsible_document().ptr() : nullptr, GC::create_function(heap, [&vm, realm, job = move(job), script_or_module = move(script_or_module)] {
|
||||
HTML::queue_a_microtask(script ? script->settings_object().responsible_document().ptr() : nullptr, GC::create_function(heap, [&vm, job_settings, 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<JS::ExecutionContext> dummy_execution_context;
|
||||
|
||||
if (realm) {
|
||||
// 1. If realm is not null, then prepare to run script with realm.
|
||||
HTML::prepare_to_run_script(*realm);
|
||||
if (job_settings) {
|
||||
// 1. If job settings is not null, then prepare to run script with job settings.
|
||||
HTML::prepare_to_run_script(*job_settings);
|
||||
|
||||
// IMPLEMENTATION DEFINED: Additionally to preparing to run a script, we also prepare to run a callback here. This matches WebIDL's
|
||||
// invoke_callback() / call_user_object_operation() functions, and prevents a crash in host_make_job_callback()
|
||||
// when getting the incumbent settings object.
|
||||
HTML::prepare_to_run_callback(*realm);
|
||||
HTML::prepare_to_run_callback(*job_settings);
|
||||
|
||||
// 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.
|
||||
HTML::execution_context_of_realm(*realm).script_or_module = script_or_module;
|
||||
job_settings->realm_execution_context().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.
|
||||
@@ -310,15 +310,15 @@ void initialize_main_thread_vm(AgentType type)
|
||||
// 2. Let result be job().
|
||||
auto result = job->function()();
|
||||
|
||||
// 3. If realm is not null, then clean up after running script with job settings.
|
||||
if (realm) {
|
||||
// 3. If job settings is not null, then clean up after running script with job settings.
|
||||
if (job_settings) {
|
||||
// IMPLEMENTATION DEFINED: Disassociate the realm execution context from the script or module.
|
||||
HTML::execution_context_of_realm(*realm).script_or_module = Empty {};
|
||||
job_settings->realm_execution_context().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);
|
||||
HTML::clean_up_after_running_callback(*job_settings);
|
||||
|
||||
HTML::clean_up_after_running_script(*realm);
|
||||
HTML::clean_up_after_running_script(*job_settings);
|
||||
} else {
|
||||
// Pop off the dummy execution context. See the above FIXME block about why this is done.
|
||||
vm.pop_execution_context();
|
||||
@@ -326,7 +326,7 @@ void initialize_main_thread_vm(AgentType type)
|
||||
|
||||
// 4. If result is an abrupt completion, then report the exception given by result.[[Value]].
|
||||
if (result.is_error())
|
||||
HTML::report_exception(result, *realm);
|
||||
HTML::report_exception(result, job_settings->realm());
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -335,10 +335,9 @@ void initialize_main_thread_vm(AgentType type)
|
||||
};
|
||||
|
||||
// 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) -> GC::Ref<JS::JobCallback> {
|
||||
// 1. Let incumbent realm be the incumbent realm.
|
||||
auto& incumbent_realm = HTML::incumbent_realm();
|
||||
// 1. Let incumbent settings be the incumbent settings object.
|
||||
auto& incumbent_settings = HTML::incumbent_settings_object();
|
||||
|
||||
// 2. Let active script be the active script.
|
||||
auto* script = active_script();
|
||||
@@ -347,11 +346,11 @@ void initialize_main_thread_vm(AgentType type)
|
||||
OwnPtr<JS::ExecutionContext> 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 realm, and its ScriptOrModule set to active script's record.
|
||||
// its Realm field set to active script's settings object's realm, and its ScriptOrModule set to active script's record.
|
||||
if (script) {
|
||||
script_execution_context = JS::ExecutionContext::create(0, ReadonlySpan<JS::Value> {}, 0);
|
||||
script_execution_context->function = nullptr;
|
||||
script_execution_context->realm = &script->realm();
|
||||
script_execution_context->realm = &script->settings_object().realm();
|
||||
if (is<HTML::ClassicScript>(script)) {
|
||||
script_execution_context->script_or_module = GC::Ref<JS::Script>(*as<HTML::ClassicScript>(script)->script_record());
|
||||
} else if (is<HTML::ModuleScript>(script)) {
|
||||
@@ -363,8 +362,8 @@ void initialize_main_thread_vm(AgentType type)
|
||||
}
|
||||
}
|
||||
|
||||
// 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)));
|
||||
// 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)));
|
||||
return JS::JobCallback::create(*s_main_thread_vm, callable, move(host_defined));
|
||||
};
|
||||
|
||||
@@ -416,17 +415,16 @@ void initialize_main_thread_vm(AgentType type)
|
||||
};
|
||||
|
||||
// 8.1.6.7.3 HostLoadImportedModule(referrer, moduleRequest, loadState, payload), https://html.spec.whatwg.org/multipage/webappapis.html#hostloadimportedmodule
|
||||
// https://whatpr.org/html/9893/webappapis.html#hostloadimportedmodule
|
||||
s_main_thread_vm->host_load_imported_module = [](JS::ImportedModuleReferrer referrer, JS::ModuleRequest const& module_request, GC::Ptr<JS::GraphLoadingState::HostDefined> load_state, JS::ImportedModulePayload payload) -> void {
|
||||
auto& vm = *s_main_thread_vm;
|
||||
|
||||
// 1. Let moduleMapRealm be the current realm.
|
||||
auto* module_map_realm = vm.current_realm();
|
||||
// 1. Let settingsObject be the current settings object.
|
||||
GC::Ref<HTML::EnvironmentSettingsObject> settings_object = HTML::current_settings_object();
|
||||
|
||||
// 2. If moduleMapRealm's global object implements WorkletGlobalScope or ServiceWorkerGlobalScope and loadState is undefined, then:
|
||||
if ((is<HTML::WorkletGlobalScope>(module_map_realm->global_object()) || is<ServiceWorker::ServiceWorkerGlobalScope>(module_map_realm->global_object())) && !load_state) {
|
||||
// 2. If settingsObject's global object implements WorkletGlobalScope or ServiceWorkerGlobalScope and loadState is undefined, then:
|
||||
if ((is<HTML::WorkletGlobalScope>(settings_object->global_object()) || is<ServiceWorker::ServiceWorkerGlobalScope>(settings_object->global_object())) && !load_state) {
|
||||
// 1. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, ThrowCompletion(a new TypeError)).
|
||||
auto completion = JS::throw_completion(JS::TypeError::create(*module_map_realm, "Dynamic Import not available for Worklets or ServiceWorkers"_string));
|
||||
auto completion = JS::throw_completion(JS::TypeError::create(settings_object->realm(), "Dynamic Import not available for Worklets or ServiceWorkers"_string));
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
||||
// 2. Return.
|
||||
@@ -447,18 +445,17 @@ void initialize_main_thread_vm(AgentType type)
|
||||
// 1. Set referencingScript to referrer.[[HostDefined]].
|
||||
referencing_script = as<HTML::Script>(referrer.has<GC::Ref<JS::Script>>() ? *referrer.get<GC::Ref<JS::Script>>()->host_defined() : *referrer.get<GC::Ref<JS::CyclicModule>>()->host_defined());
|
||||
|
||||
// 2. Set fetchReferrer to referencingScript's base URL.
|
||||
// 2. Set settingsObject to referencingScript's settings object.
|
||||
settings_object = referencing_script->settings_object();
|
||||
|
||||
// 3. Set fetchReferrer to referencingScript's base URL.
|
||||
fetch_referrer = referencing_script->base_url().value();
|
||||
|
||||
// FIXME: 3. Set originalFetchOptions to referencingScript's fetch options.
|
||||
|
||||
// 4. Set moduleMapRealm to referencingScript's realm.
|
||||
module_map_realm = &referencing_script->realm();
|
||||
// FIXME: 4. Set originalFetchOptions to referencingScript's fetch options.
|
||||
}
|
||||
|
||||
// 7. If referrer is a Cyclic Module Record and moduleRequest is equal to the first element of referrer.[[RequestedModules]], then:
|
||||
if (referrer.has<GC::Ref<JS::CyclicModule>>()) {
|
||||
// FIXME: Why do we need to check requested modules is empty here?
|
||||
if (auto const& requested_modules = referrer.get<GC::Ref<JS::CyclicModule>>()->requested_modules(); !requested_modules.is_empty() && module_request == requested_modules.first()) {
|
||||
// 1. For each ModuleRequest record requested of referrer.[[RequestedModules]]:
|
||||
for (auto const& module_request : referrer.get<GC::Ref<JS::CyclicModule>>()->requested_modules()) {
|
||||
@@ -468,7 +465,7 @@ void initialize_main_thread_vm(AgentType type)
|
||||
continue;
|
||||
|
||||
// 1. Let error be a new SyntaxError exception.
|
||||
auto error = JS::SyntaxError::create(*module_map_realm, "Module request attributes must only contain a type attribute"_string);
|
||||
auto error = JS::SyntaxError::create(settings_object->realm(), "Module request attributes must only contain a type attribute"_string);
|
||||
|
||||
// 2. If loadState is not undefined and loadState.[[ErrorToRethrow]] is null, set loadState.[[ErrorToRethrow]] to error.
|
||||
if (auto* load_state_as_fetch_context = as<HTML::FetchContext>(load_state.ptr());
|
||||
@@ -507,10 +504,10 @@ void initialize_main_thread_vm(AgentType type)
|
||||
// 4. Let moduleType be the result of running the module type from module request steps given moduleRequest.
|
||||
auto module_type = HTML::module_type_from_module_request(module_request);
|
||||
|
||||
// 5. If the result of running the module type allowed steps given moduleType and moduleMapRealm is false, then:
|
||||
if (!HTML::module_type_allowed(*module_map_realm, module_type)) {
|
||||
// 5. If the result of running the module type allowed steps given moduleType and settingsObject is false, then:
|
||||
if (!HTML::module_type_allowed(settings_object, module_type)) {
|
||||
// 1. Let error be a new TypeError exception.
|
||||
auto error = JS::TypeError::create(*module_map_realm, MUST(String::formatted("Module type '{}' is not supported", module_type)));
|
||||
auto error = JS::TypeError::create(settings_object->realm(), MUST(String::formatted("Module type '{}' is not supported", module_type)));
|
||||
|
||||
// 2. If loadState is not undefined and loadState.[[ErrorToRethrow]] is null, set loadState.[[ErrorToRethrow]] to error.
|
||||
if (auto* load_state_as_fetch_context = as<HTML::FetchContext>(load_state.ptr());
|
||||
@@ -548,24 +545,21 @@ void initialize_main_thread_vm(AgentType type)
|
||||
|
||||
// 2. Perform FinishLoadingImportedModule(referrer, moduleRequest, payload, ThrowCompletion(resolutionError)).
|
||||
auto completion = exception_to_throw_completion(main_thread_vm(), url.exception());
|
||||
HTML::TemporaryExecutionContext context { *module_map_realm };
|
||||
HTML::TemporaryExecutionContext context { settings_object->realm() };
|
||||
JS::finish_loading_imported_module(referrer, module_request, payload, completion);
|
||||
|
||||
// 3. Return.
|
||||
return;
|
||||
}
|
||||
|
||||
// 10. Let settingsObject be moduleMapRealm's principal realm's settings object.
|
||||
auto& settings_object = HTML::principal_realm_settings_object(HTML::principal_realm(*module_map_realm));
|
||||
|
||||
// 11. Let fetchOptions be the result of getting the descendant script fetch options given originalFetchOptions, url, and settingsObject.
|
||||
// 10. Let fetchOptions be the result of getting the descendant script fetch options given originalFetchOptions, url, and settingsObject.
|
||||
auto fetch_options = HTML::get_descendant_script_fetch_options(original_fetch_options, url.value(), settings_object);
|
||||
|
||||
// 12. Let destination be "script".
|
||||
// 11. Let destination be "script".
|
||||
auto destination = Fetch::Infrastructure::Request::Destination::Script;
|
||||
|
||||
// 13. Let fetchClient be moduleMapRealm's principal realm's settings object.
|
||||
GC::Ref fetch_client { HTML::principal_realm_settings_object(HTML::principal_realm(*module_map_realm)) };
|
||||
// 12. Let fetchClient be settingsObject.
|
||||
GC::Ref fetch_client { settings_object };
|
||||
|
||||
// 15. If loadState is not undefined, then:
|
||||
HTML::PerformTheFetchHook perform_fetch;
|
||||
@@ -582,8 +576,8 @@ void initialize_main_thread_vm(AgentType type)
|
||||
perform_fetch = fetch_context.perform_fetch;
|
||||
}
|
||||
|
||||
auto on_single_fetch_complete = HTML::create_on_fetch_script_complete(module_map_realm->heap(), [referrer, module_map_realm, load_state, module_request, payload](GC::Ptr<HTML::Script> const& module_script) -> void {
|
||||
auto& realm = *module_map_realm;
|
||||
auto on_single_fetch_complete = HTML::create_on_fetch_script_complete(settings_object->heap(), [referrer, settings_object, load_state, module_request, payload](GC::Ptr<HTML::Script> const& module_script) -> void {
|
||||
auto& realm = settings_object->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
|
||||
@@ -638,10 +632,10 @@ void initialize_main_thread_vm(AgentType type)
|
||||
stack.deallocate(stack_mark);
|
||||
});
|
||||
|
||||
// 16. Fetch a single imported module script given url, fetchClient, destination, fetchOptions, moduleMapRealm, fetchReferrer,
|
||||
// 16. Fetch a single imported module script given url, fetchClient, destination, fetchOptions, settingsObject, 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(*module_map_realm, url.release_value(), *fetch_client, destination, fetch_options, *module_map_realm, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete);
|
||||
HTML::fetch_single_imported_module_script(settings_object->realm(), url.release_value(), *fetch_client, destination, fetch_options, settings_object, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete);
|
||||
};
|
||||
|
||||
s_main_thread_vm->host_unrecognized_date_string = [](StringView date) {
|
||||
@@ -722,9 +716,9 @@ void queue_mutation_observer_microtask()
|
||||
// callback this value mo.
|
||||
if (!records.is_empty()) {
|
||||
auto& callback = mutation_observer->callback();
|
||||
auto& realm = callback.callback_context;
|
||||
auto& settings = callback.callback_context;
|
||||
|
||||
auto wrapped_records = MUST(JS::Array::create(realm, 0));
|
||||
auto wrapped_records = MUST(JS::Array::create(settings->realm(), 0));
|
||||
for (size_t i = 0; i < records.size(); ++i) {
|
||||
auto& record = records.at(i);
|
||||
auto property_index = JS::PropertyKey { i };
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
namespace Web::Bindings {
|
||||
|
||||
struct WebEngineCustomJobCallbackData final : public JS::JobCallback::CustomData {
|
||||
WebEngineCustomJobCallbackData(JS::Realm& incumbent_realm, OwnPtr<JS::ExecutionContext> active_script_context)
|
||||
: incumbent_realm(incumbent_realm)
|
||||
WebEngineCustomJobCallbackData(HTML::EnvironmentSettingsObject& incumbent_settings, OwnPtr<JS::ExecutionContext> active_script_context)
|
||||
: incumbent_settings(incumbent_settings)
|
||||
, active_script_context(move(active_script_context))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~WebEngineCustomJobCallbackData() override = default;
|
||||
|
||||
GC::Ref<JS::Realm> incumbent_realm;
|
||||
GC::Ref<HTML::EnvironmentSettingsObject> incumbent_settings;
|
||||
OwnPtr<JS::ExecutionContext> active_script_context;
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ JS::ThrowCompletionOr<JS::Value> OptionConstructor::call()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option
|
||||
// https://whatpr.org/html/9893/form-elements.html#dom-option
|
||||
// https://webidl.spec.whatwg.org/#legacy-factory-functions
|
||||
JS::ThrowCompletionOr<GC::Ref<JS::Object>> OptionConstructor::construct(FunctionObject& new_target)
|
||||
{
|
||||
@@ -53,8 +52,8 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> OptionConstructor::construct(Function
|
||||
if (text_value.is_undefined())
|
||||
text_value = &vm.empty_string();
|
||||
|
||||
// 1. Let document be the current principal global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
// 1. Let document be the current global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
auto& document = window.associated_document();
|
||||
|
||||
// 2. Let option be the result of creating an element given document, "option", and the HTML namespace.
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/SyntheticHostDefined.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
|
||||
namespace Web::Bindings {
|
||||
|
||||
void SyntheticHostDefined::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
HostDefined::visit_edges(visitor);
|
||||
synthetic_realm_settings.visit_edges(visitor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/HostDefined.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/HTML/Scripting/SyntheticRealmSettings.h>
|
||||
|
||||
namespace Web::Bindings {
|
||||
|
||||
struct SyntheticHostDefined final : public HostDefined {
|
||||
SyntheticHostDefined(HTML::SyntheticRealmSettings synthetic_realm_settings, GC::Ref<Intrinsics> intrinsics)
|
||||
: HostDefined(intrinsics)
|
||||
, synthetic_realm_settings(move(synthetic_realm_settings))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~SyntheticHostDefined() override = default;
|
||||
virtual void visit_edges(JS::Cell::Visitor& visitor) override;
|
||||
virtual bool is_synthetic_host_defined() const override { return true; }
|
||||
|
||||
HTML::SyntheticRealmSettings synthetic_realm_settings;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool JS::Realm::HostDefined::fast_is<Web::Bindings::SyntheticHostDefined>() const { return is_synthetic_host_defined(); }
|
||||
@@ -39,7 +39,6 @@ set(SOURCES
|
||||
Bindings/OptionConstructor.cpp
|
||||
Bindings/PlatformObject.cpp
|
||||
Bindings/PrincipalHostDefined.cpp
|
||||
Bindings/SyntheticHostDefined.cpp
|
||||
Clipboard/Clipboard.cpp
|
||||
Clipboard/ClipboardEvent.cpp
|
||||
Clipboard/ClipboardItem.cpp
|
||||
@@ -660,7 +659,6 @@ set(SOURCES
|
||||
HTML/Scripting/Script.cpp
|
||||
HTML/Scripting/SerializedEnvironmentSettingsObject.cpp
|
||||
HTML/Scripting/SimilarOriginWindowAgent.cpp
|
||||
HTML/Scripting/SyntheticRealmSettings.cpp
|
||||
HTML/Scripting/TemporaryExecutionContext.cpp
|
||||
HTML/Scripting/WindowEnvironmentSettingsObject.cpp
|
||||
HTML/Scripting/WorkerAgent.cpp
|
||||
|
||||
@@ -39,7 +39,7 @@ WebIDL::ExceptionOr<GC::Ref<CSSStyleSheet>> CSSStyleSheet::construct_impl(JS::Re
|
||||
// 1. Construct a new CSSStyleSheet object sheet.
|
||||
auto sheet = create(realm, CSSRuleList::create(realm), CSS::MediaList::create(realm, {}), {});
|
||||
|
||||
// 2. Set sheet’s location to the base URL of the associated Document for the current global object.
|
||||
// 2. Set sheet’s location to the base URL of the associated Document for the current principal global object.
|
||||
auto associated_document = as<HTML::Window>(realm.global_object()).document();
|
||||
sheet->set_location(associated_document->base_url());
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ GC::Ptr<PolicyList> PolicyList::from_object(JS::Object& object)
|
||||
// 2. If object is a Window or a WorkerGlobalScope or a WorkletGlobalScope, return environment settings object’s
|
||||
// policy container's CSP list.
|
||||
if (is<HTML::Window>(object) || is<HTML::WorkerGlobalScope>(object)) {
|
||||
auto& settings = HTML::relevant_principal_settings_object(object);
|
||||
auto& settings = HTML::relevant_settings_object(object);
|
||||
return settings.policy_container()->csp_list;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,13 +99,13 @@ URL::URL Violation::url() const
|
||||
}
|
||||
|
||||
auto& universal_scope = as<HTML::UniversalGlobalScopeMixin>(*m_global_object);
|
||||
auto& principal_global = HTML::relevant_principal_global_object(universal_scope.this_impl());
|
||||
auto& global = HTML::relevant_global_object(universal_scope.this_impl());
|
||||
|
||||
if (auto* window = as_if<HTML::Window>(principal_global)) {
|
||||
if (auto* window = as_if<HTML::Window>(global)) {
|
||||
return window->associated_document().url();
|
||||
}
|
||||
|
||||
if (auto* worker = as_if<HTML::WorkerGlobalScope>(principal_global)) {
|
||||
if (auto* worker = as_if<HTML::WorkerGlobalScope>(global)) {
|
||||
return worker->url();
|
||||
}
|
||||
|
||||
@@ -414,9 +414,8 @@ void Violation::report_a_violation(JS::Realm& realm)
|
||||
|
||||
// origin
|
||||
// violation's global object's relevant settings object's origin
|
||||
// FIXME: File spec issue that global object can be null, so we use the realm to get the ESO
|
||||
// instead, and cross ShadowRealm boundaries with the principal realm.
|
||||
auto& environment_settings_object = Bindings::principal_host_defined_environment_settings_object(HTML::principal_realm(realm));
|
||||
// FIXME: File spec issue that global object can be null, so we use the realm to get the ESO instead.
|
||||
auto& environment_settings_object = Bindings::principal_host_defined_environment_settings_object(realm);
|
||||
request->set_origin(environment_settings_object.origin());
|
||||
|
||||
// traversable for user prompts
|
||||
|
||||
@@ -15,7 +15,7 @@ GC_DEFINE_ALLOCATOR(PasswordCredential);
|
||||
WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> PasswordCredential::construct_impl(JS::Realm& realm, GC::Ref<HTML::HTMLFormElement> form)
|
||||
{
|
||||
// 1. Let origin be the current settings object's origin.
|
||||
auto origin = HTML::current_principal_settings_object().origin();
|
||||
auto origin = HTML::current_settings_object().origin();
|
||||
|
||||
// 2. Let r be the result of executing Create a PasswordCredential from an HTMLFormElement given form and origin.
|
||||
// 3. If r is an exception, throw r. Otherwise, return r.
|
||||
@@ -26,7 +26,7 @@ WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> PasswordCredential::construct_i
|
||||
WebIDL::ExceptionOr<GC::Ref<PasswordCredential>> PasswordCredential::construct_impl(JS::Realm& realm, PasswordCredentialData const& data)
|
||||
{
|
||||
// AD-HOC: Let origin be the current settings object's origin.
|
||||
auto origin = HTML::current_principal_settings_object().origin();
|
||||
auto origin = HTML::current_settings_object().origin();
|
||||
|
||||
// 1. Let r be the result of executing Create a PasswordCredential from PasswordCredentialData on data.
|
||||
// 2. If r is an exception, throw r.
|
||||
|
||||
@@ -485,7 +485,7 @@ GC::Ref<Document> Document::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
// The new Document() constructor steps are to set this’s origin to the origin of current global object’s associated Document. [HTML]
|
||||
auto document = Document::create(realm);
|
||||
document->set_origin(as<HTML::Window>(HTML::current_principal_global_object()).associated_document().origin());
|
||||
document->set_origin(as<HTML::Window>(HTML::current_global_object()).associated_document().origin());
|
||||
return document;
|
||||
}
|
||||
|
||||
@@ -7266,7 +7266,7 @@ WebIDL::ExceptionOr<GC::Root<DOM::Document>> Document::parse_html_unsafe(JS::VM&
|
||||
// TrustedHTML, this's relevant global object, html, "Document parseHTMLUnsafe", and "script".
|
||||
auto const compliant_html = TRY(TrustedTypes::get_trusted_type_compliant_string(
|
||||
TrustedTypes::TrustedTypeName::TrustedHTML,
|
||||
HTML::current_principal_global_object(),
|
||||
HTML::current_global_object(),
|
||||
html,
|
||||
TrustedTypes::InjectionSink::Document_parseHTMLUnsafe,
|
||||
TrustedTypes::Script.to_string()));
|
||||
|
||||
@@ -2174,19 +2174,17 @@ void Node::serialize_tree_as_json(JsonObjectSerializer<StringBuilder>& object) c
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-n-script
|
||||
bool Node::is_scripting_enabled() const
|
||||
{
|
||||
// Scripting is enabled for a node node if node's node document's browsing context is non-null, and scripting is enabled for node's relevant realm.
|
||||
return document().browsing_context() && HTML::is_scripting_enabled(HTML::relevant_realm(*this));
|
||||
// Scripting is enabled for a platform object object, when object's scripting is not disabled.
|
||||
return !is_scripting_disabled();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-noscript
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-n-script
|
||||
bool Node::is_scripting_disabled() const
|
||||
{
|
||||
// Scripting is disabled for a node when scripting is not enabled, i.e., when its node document's browsing context is null or when scripting is disabled for its relevant realm.
|
||||
return !is_scripting_enabled();
|
||||
// Scripting is disabled for a node when scripting is not enabled, i.e., when its node document's browsing context is null or when scripting is disabled for its relevant settings object.
|
||||
return !document().browsing_context() || HTML::is_scripting_disabled(HTML::relevant_settings_object(*this));
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-shadow-including-descendant
|
||||
|
||||
@@ -44,7 +44,7 @@ void Text::visit_edges(Cell::Visitor& visitor)
|
||||
WebIDL::ExceptionOr<GC::Ref<Text>> Text::construct_impl(JS::Realm& realm, Utf16String data)
|
||||
{
|
||||
// The new Text(data) constructor steps are to set this’s data to data and this’s node document to current global object’s associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
return realm.create<Text>(window.associated_document(), move(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ void DOMURL::revoke_object_url(JS::VM&, StringView url)
|
||||
return;
|
||||
|
||||
// 5. Let isAuthorized be the result of checking for same-partition blob URL usage with entry and the current settings object.
|
||||
bool is_authorized = FileAPI::check_for_same_partition_blob_url_usage(entry.value(), HTML::current_principal_settings_object());
|
||||
bool is_authorized = FileAPI::check_for_same_partition_blob_url_usage(entry.value(), HTML::current_settings_object());
|
||||
|
||||
// 6. If isAuthorized is false, then return.
|
||||
if (!is_authorized)
|
||||
|
||||
@@ -2081,7 +2081,7 @@ GC::Ref<PendingResponse> nonstandard_resource_loader_file_or_http_network_fetch(
|
||||
|
||||
auto request = fetch_params.request();
|
||||
|
||||
auto& page = Bindings::principal_host_defined_page(HTML::principal_realm(realm));
|
||||
auto& page = Bindings::principal_host_defined_page(realm);
|
||||
|
||||
LoadRequest load_request { request->header_list() };
|
||||
load_request.set_url(request->current_url());
|
||||
|
||||
@@ -178,7 +178,7 @@ WebIDL::ExceptionOr<GC::Ref<Response>> Response::redirect(JS::VM& vm, String con
|
||||
auto& realm = *vm.current_realm();
|
||||
|
||||
// 1. Let parsedURL be the result of parsing url with current settings object’s API base URL.
|
||||
auto api_base_url = HTML::current_principal_settings_object().api_base_url();
|
||||
auto api_base_url = HTML::current_settings_object().api_base_url();
|
||||
auto parsed_url = DOMURL::parse(url, api_base_url);
|
||||
|
||||
// 2. If parsedURL is failure, then throw a TypeError.
|
||||
|
||||
@@ -34,7 +34,7 @@ ErrorOr<Utf16String> generate_new_blob_url()
|
||||
TRY(result.try_append("blob:"sv));
|
||||
|
||||
// 3. Let settings be the current settings object
|
||||
auto& settings = HTML::current_principal_settings_object();
|
||||
auto& settings = HTML::current_settings_object();
|
||||
|
||||
// 4. Let origin be settings’s origin.
|
||||
auto origin = settings.origin();
|
||||
@@ -70,7 +70,7 @@ ErrorOr<Utf16String> add_entry_to_blob_url_store(BlobURLEntry::Object object)
|
||||
auto url = TRY(generate_new_blob_url());
|
||||
|
||||
// 3. Let entry be a new blob URL entry consisting of object and the current settings object.
|
||||
BlobURLEntry entry { object, HTML::current_principal_settings_object() };
|
||||
BlobURLEntry entry { object, HTML::current_settings_object() };
|
||||
|
||||
// 4. Set store[url] to entry.
|
||||
TRY(store.try_set(url.to_utf8_but_should_be_ported_to_utf16(), move(entry)));
|
||||
|
||||
@@ -887,7 +887,6 @@ struct SerializedPolicyContainer;
|
||||
struct SerializedTransferRecord;
|
||||
struct SourceSnapshotParams;
|
||||
struct StructuredSerializeOptions;
|
||||
struct SyntheticRealmSettings;
|
||||
struct ToggleTaskTracker;
|
||||
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ GC::Ref<WebIDL::Promise> GamepadHapticActuator::play_effect(Bindings::GamepadHap
|
||||
return WebIDL::create_rejected_promise_from_exception(realm, WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid effect"_string });
|
||||
|
||||
// 2. Let document be the current settings object's relevant global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_settings_object().global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_settings_object().global_object());
|
||||
auto& document = window.associated_document();
|
||||
|
||||
// 3. If document is null or document is not fully active or document's visibility state is "hidden", return a
|
||||
@@ -225,7 +225,7 @@ GC::Ref<WebIDL::Promise> GamepadHapticActuator::reset()
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. Let document be the current settings object's relevant global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_settings_object().global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_settings_object().global_object());
|
||||
auto& document = window.associated_document();
|
||||
|
||||
// 2. If document is null or document is not fully active or document's visibility state is "hidden", return a
|
||||
|
||||
@@ -27,7 +27,7 @@ WebIDL::ExceptionOr<GC::RootVector<GC::Ptr<Gamepad>>> NavigatorGamepadPartial::g
|
||||
auto& heap = realm.heap();
|
||||
|
||||
// 1. Let doc be the current global object's associated Document.
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
auto& document = window.associated_document();
|
||||
|
||||
// 2. If doc is null or doc is not fully active, then return an empty list.
|
||||
|
||||
@@ -82,15 +82,13 @@ JS::ThrowCompletionOr<JS::PropertyDescriptor> cross_origin_property_fallback(JS:
|
||||
}
|
||||
|
||||
// 7.2.3.3 IsPlatformObjectSameOrigin ( O ), https://html.spec.whatwg.org/multipage/nav-history-apis.html#isplatformobjectsameorigin-(-o-)
|
||||
// https://whatpr.org/html/9893/nav-history-apis.html#isplatformobjectsameorigin-(-o-)
|
||||
bool is_platform_object_same_origin(JS::Object const& object)
|
||||
{
|
||||
// 1. Return true if the current principal settings object's origin is same origin-domain with O's relevant settings object's origin, and false otherwise.
|
||||
return HTML::current_principal_settings_object().origin().is_same_origin_domain(HTML::relevant_settings_object(object).origin());
|
||||
// 1. Return true if the current settings object's origin is same origin-domain with O's relevant settings object's origin, and false otherwise.
|
||||
return HTML::current_settings_object().origin().is_same_origin_domain(HTML::relevant_settings_object(object).origin());
|
||||
}
|
||||
|
||||
// 7.2.3.4 CrossOriginGetOwnPropertyHelper ( O, P ), https://html.spec.whatwg.org/multipage/nav-history-apis.html#crossorigingetownpropertyhelper-(-o,-p-)
|
||||
// https://whatpr.org/html/9893/nav-history-apis.html#crossorigingetownpropertyhelper-(-o,-p-)
|
||||
Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HTML::Location*, HTML::Window*> const& object, JS::PropertyKey const& property_key)
|
||||
{
|
||||
auto& vm = Bindings::main_thread_vm();
|
||||
@@ -98,9 +96,9 @@ Optional<JS::PropertyDescriptor> cross_origin_get_own_property_helper(Variant<HT
|
||||
auto const* object_ptr = object.visit([](auto* o) { return static_cast<JS::Object const*>(o); });
|
||||
auto const object_const_variant = object.visit([](auto* o) { return Variant<HTML::Location const*, HTML::Window const*> { o }; });
|
||||
|
||||
// 1. Let crossOriginKey be a tuple consisting of the current principal settings object, O's relevant settings object, and P.
|
||||
// 1. Let crossOriginKey be a tuple consisting of the current settings object, O's relevant settings object, and P.
|
||||
auto cross_origin_key = CrossOriginKey {
|
||||
.current_principal_settings_object = (FlatPtr)&HTML::current_principal_settings_object(),
|
||||
.current_settings_object = (FlatPtr)&HTML::current_settings_object(),
|
||||
.relevant_settings_object = (FlatPtr)&HTML::relevant_settings_object(*object_ptr),
|
||||
.property_key = property_key,
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@ struct CrossOriginProperty {
|
||||
};
|
||||
|
||||
struct CrossOriginKey {
|
||||
FlatPtr current_principal_settings_object;
|
||||
FlatPtr current_settings_object;
|
||||
FlatPtr relevant_settings_object;
|
||||
JS::PropertyKey property_key;
|
||||
};
|
||||
@@ -39,12 +39,12 @@ struct Traits<Web::HTML::CrossOriginKey> : public DefaultTraits<Web::HTML::Cross
|
||||
{
|
||||
return pair_int_hash(
|
||||
Traits<JS::PropertyKey>::hash(key.property_key),
|
||||
pair_int_hash(ptr_hash(key.current_principal_settings_object), ptr_hash(key.relevant_settings_object)));
|
||||
pair_int_hash(ptr_hash(key.current_settings_object), ptr_hash(key.relevant_settings_object)));
|
||||
}
|
||||
|
||||
static bool equals(Web::HTML::CrossOriginKey const& a, Web::HTML::CrossOriginKey const& b)
|
||||
{
|
||||
return a.current_principal_settings_object == b.current_principal_settings_object
|
||||
return a.current_settings_object == b.current_settings_object
|
||||
&& a.relevant_settings_object == b.relevant_settings_object
|
||||
&& Traits<JS::PropertyKey>::equals(a.property_key, b.property_key);
|
||||
}
|
||||
|
||||
@@ -657,9 +657,9 @@ void EventLoop::unregister_document(Badge<DOM::Document>, DOM::Document& documen
|
||||
VERIFY(did_remove);
|
||||
}
|
||||
|
||||
void EventLoop::push_onto_backup_incumbent_realm_stack(JS::Realm& realm)
|
||||
void EventLoop::push_onto_backup_incumbent_realm_stack(GC::Ref<EnvironmentSettingsObject> environment_settings_object)
|
||||
{
|
||||
m_backup_incumbent_realm_stack.append(realm);
|
||||
m_backup_incumbent_realm_stack.append(environment_settings_object);
|
||||
}
|
||||
|
||||
void EventLoop::pop_backup_incumbent_realm_stack()
|
||||
@@ -667,7 +667,7 @@ void EventLoop::pop_backup_incumbent_realm_stack()
|
||||
m_backup_incumbent_realm_stack.take_last();
|
||||
}
|
||||
|
||||
JS::Realm& EventLoop::top_of_backup_incumbent_realm_stack()
|
||||
EnvironmentSettingsObject& EventLoop::top_of_backup_incumbent_realm_stack()
|
||||
{
|
||||
return m_backup_incumbent_realm_stack.last();
|
||||
}
|
||||
@@ -741,7 +741,7 @@ EventLoop::PauseHandle EventLoop::pause()
|
||||
m_execution_paused = true;
|
||||
|
||||
// 1. Let global be the current global object.
|
||||
auto& global = current_principal_global_object();
|
||||
auto& global = current_global_object();
|
||||
|
||||
// 2. Let timeBeforePause be the current high resolution time given global.
|
||||
auto time_before_pause = HighResolutionTime::current_high_resolution_time(global);
|
||||
|
||||
@@ -80,9 +80,9 @@ public:
|
||||
|
||||
Vector<GC::Root<HTML::Window>> same_loop_windows() const;
|
||||
|
||||
void push_onto_backup_incumbent_realm_stack(JS::Realm&);
|
||||
void push_onto_backup_incumbent_realm_stack(GC::Ref<EnvironmentSettingsObject>);
|
||||
void pop_backup_incumbent_realm_stack();
|
||||
JS::Realm& top_of_backup_incumbent_realm_stack();
|
||||
EnvironmentSettingsObject& top_of_backup_incumbent_realm_stack();
|
||||
bool is_backup_incumbent_realm_stack_empty() const { return m_backup_incumbent_realm_stack.is_empty(); }
|
||||
|
||||
void register_environment_settings_object(Badge<EnvironmentSettingsObject>, EnvironmentSettingsObject&);
|
||||
@@ -131,8 +131,7 @@ private:
|
||||
Vector<RawPtr<EnvironmentSettingsObject>> m_related_environment_settings_objects;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack
|
||||
// https://whatpr.org/html/9893/webappapis.html#backup-incumbent-realm-stack
|
||||
Vector<GC::Ref<JS::Realm>> m_backup_incumbent_realm_stack;
|
||||
Vector<GC::Ref<EnvironmentSettingsObject>> m_backup_incumbent_realm_stack;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#termination-nesting-level
|
||||
size_t m_termination_nesting_level { 0 };
|
||||
|
||||
@@ -199,7 +199,6 @@ void HTMLScriptElement::execute_script()
|
||||
|
||||
// https://w3c.github.io/trusted-types/dist/spec/#slot-value-verification
|
||||
// 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.
|
||||
@@ -501,9 +500,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's realm, base URL, and options.
|
||||
// 1. Let script be the result of creating a classic script using source text, settings object, base URL, and options.
|
||||
// FIXME: Pass options.
|
||||
auto script = ClassicScript::create(m_document->url().to_byte_string(), source_text_utf8, settings_object.realm(), base_url, m_source_line_number);
|
||||
auto script = ClassicScript::create(m_document->url().to_byte_string(), source_text_utf8, settings_object, base_url, m_source_line_number);
|
||||
|
||||
// 2. Mark as ready el given script.
|
||||
mark_as_ready(Result(move(script)));
|
||||
|
||||
@@ -2281,7 +2281,6 @@ void Navigable::navigate_to_a_fragment(URL::URL const& url, HistoryHandlingBehav
|
||||
}
|
||||
|
||||
// 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
|
||||
GC::Ptr<DOM::Document> Navigable::evaluate_javascript_url(URL::URL const& url, URL::Origin const& new_document_origin, UserNavigationInvolvement user_involvement, String navigation_id)
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
@@ -2303,8 +2302,8 @@ GC::Ptr<DOM::Document> Navigable::evaluate_javascript_url(URL::URL const& url, U
|
||||
// 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's realm, baseURL, and the default classic script fetch options.
|
||||
auto script = HTML::ClassicScript::create("(javascript url)", script_source, settings.realm(), 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);
|
||||
|
||||
// 7. Let evaluationStatus be the result of running the classic script script.
|
||||
auto evaluation_status = script->run();
|
||||
|
||||
@@ -1458,7 +1458,6 @@ void Navigation::initialize_the_navigation_api_entries_for_a_new_document(Vector
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#update-the-navigation-api-entries-for-a-same-document-navigation
|
||||
// https://whatpr.org/html/9893/nav-history-apis.html#update-the-navigation-api-entries-for-a-same-document-navigation
|
||||
void Navigation::update_the_navigation_api_entries_for_a_same_document_navigation(NonnullRefPtr<SessionHistoryEntry> destination_she, Bindings::NavigationType navigation_type)
|
||||
{
|
||||
auto& realm = relevant_realm(*this);
|
||||
@@ -1539,8 +1538,8 @@ void Navigation::update_the_navigation_api_entries_for_a_same_document_navigatio
|
||||
if (m_ongoing_api_method_tracker != nullptr)
|
||||
notify_about_the_committed_to_entry(*m_ongoing_api_method_tracker, *current_entry());
|
||||
|
||||
// 9. Prepare to run script given navigation's relevant realm.
|
||||
prepare_to_run_script(realm);
|
||||
// 9. Prepare to run script given navigation's relevant settings object.
|
||||
prepare_to_run_script(relevant_settings_object(*this));
|
||||
|
||||
// 10. Fire an event named currententrychange at navigation using NavigationCurrentEntryChangeEvent,
|
||||
// with its navigationType attribute initialized to navigationType and its from initialized to oldCurrentNHE.
|
||||
@@ -1555,8 +1554,8 @@ void Navigation::update_the_navigation_api_entries_for_a_same_document_navigatio
|
||||
disposed_nhe->dispatch_event(DOM::Event::create(realm, EventNames::dispose, {}));
|
||||
}
|
||||
|
||||
// 12. Clean up after running script given navigation's relevant realm.
|
||||
clean_up_after_running_script(relevant_realm(*this));
|
||||
// 12. Clean up after running script given navigation's relevant settings object.
|
||||
clean_up_after_running_script(relevant_settings_object(*this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ bool Navigator::pdf_viewer_enabled() const
|
||||
{
|
||||
// The NavigatorPlugins mixin's pdfViewerEnabled getter steps are to return the user agent's PDF viewer supported.
|
||||
// NOTE: The NavigatorPlugins mixin should only be exposed on the Window object.
|
||||
auto const& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto const& window = as<HTML::Window>(HTML::current_global_object());
|
||||
return window.page().pdf_viewer_supported();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ bool Navigator::webdriver() const
|
||||
// Returns true if webdriver-active flag is set, false otherwise.
|
||||
|
||||
// NOTE: The NavigatorAutomationInformation interface should not be exposed on WorkerNavigator.
|
||||
auto const& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto const& window = as<HTML::Window>(HTML::current_global_object());
|
||||
return window.page().is_webdriver_active();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,23 +19,22 @@ namespace Web::HTML {
|
||||
GC_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
|
||||
GC::Ref<ClassicScript> ClassicScript::create(ByteString filename, StringView source, JS::Realm& realm, URL::URL base_url, size_t source_line_number, MutedErrors muted_errors)
|
||||
GC::Ref<ClassicScript> ClassicScript::create(ByteString filename, StringView source, EnvironmentSettingsObject& settings, URL::URL base_url, size_t source_line_number, MutedErrors muted_errors)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
auto& vm = settings.vm();
|
||||
|
||||
// 1. If muted errors is true, then set baseURL to about:blank.
|
||||
if (muted_errors == MutedErrors::Yes)
|
||||
base_url = URL::about_blank();
|
||||
|
||||
// 2. If scripting is disabled for realm, then set source to the empty string.
|
||||
if (is_scripting_disabled(realm))
|
||||
// FIXME: 2. If scripting is disabled for settings and bypassDisabledScripting is false, then set source to the empty string.
|
||||
if (is_scripting_disabled(settings))
|
||||
source = ""sv;
|
||||
|
||||
// 3. Let script be a new classic script that this algorithm will subsequently initialize.
|
||||
// 4. Set script's realm to realm.
|
||||
// 4. Set script's settings object to settings.
|
||||
// 5. Set script's base URL to baseURL.
|
||||
auto script = vm.heap().allocate<ClassicScript>(move(base_url), move(filename), realm);
|
||||
auto script = vm.heap().allocate<ClassicScript>(move(base_url), move(filename), settings);
|
||||
|
||||
// FIXME: 6. Set script's fetch options to options.
|
||||
|
||||
@@ -48,9 +47,9 @@ GC::Ref<ClassicScript> ClassicScript::create(ByteString filename, StringView sou
|
||||
|
||||
// FIXME: 9. Record classic script creation time given script and sourceURLForWindowScripts .
|
||||
|
||||
// 10. Let result be ParseScript(source, realm, script).
|
||||
// 10. Let result be ParseScript(source, settings's realm, script).
|
||||
auto parse_timer = Core::ElapsedTimer::start_new();
|
||||
auto result = JS::Script::parse(source, realm, script->filename(), script, source_line_number);
|
||||
auto result = JS::Script::parse(source, settings.realm(), script->filename(), script, source_line_number);
|
||||
dbgln_if(HTML_SCRIPT_DEBUG, "ClassicScript: Parsed {} in {}ms", script->filename(), parse_timer.elapsed_milliseconds());
|
||||
|
||||
// 11. If result is a list of errors, then:
|
||||
@@ -59,7 +58,7 @@ GC::Ref<ClassicScript> ClassicScript::create(ByteString filename, StringView sou
|
||||
dbgln_if(HTML_SCRIPT_DEBUG, "ClassicScript: Failed to parse: {}", parse_error.to_string());
|
||||
|
||||
// 1. Set script's parse error and its error to rethrow to result[0].
|
||||
script->set_parse_error(JS::SyntaxError::create(realm, parse_error.to_string()));
|
||||
script->set_parse_error(JS::SyntaxError::create(settings.realm(), parse_error.to_string()));
|
||||
script->set_error_to_rethrow(script->parse_error());
|
||||
|
||||
// 2. Return script.
|
||||
@@ -73,14 +72,15 @@ GC::Ref<ClassicScript> ClassicScript::create(ByteString filename, StringView sou
|
||||
return script;
|
||||
}
|
||||
|
||||
GC::Ref<ClassicScript> ClassicScript::create_from_pre_parsed(ByteString filename, NonnullRefPtr<JS::SourceCode const> source_code, JS::Realm& realm, URL::URL base_url, JS::FFI::ParsedProgram* parsed, MutedErrors muted_errors)
|
||||
GC::Ref<ClassicScript> ClassicScript::create_from_pre_parsed(ByteString filename, NonnullRefPtr<JS::SourceCode const> source_code, EnvironmentSettingsObject& settings, URL::URL base_url, JS::FFI::ParsedProgram* parsed, MutedErrors muted_errors)
|
||||
{
|
||||
auto& realm = settings.realm();
|
||||
auto& vm = realm.vm();
|
||||
|
||||
if (muted_errors == MutedErrors::Yes)
|
||||
base_url = URL::about_blank();
|
||||
|
||||
auto script = vm.heap().allocate<ClassicScript>(move(base_url), move(filename), realm);
|
||||
auto script = vm.heap().allocate<ClassicScript>(move(base_url), move(filename), settings);
|
||||
|
||||
script->m_muted_errors = muted_errors;
|
||||
script->set_parse_error(JS::js_null());
|
||||
@@ -106,20 +106,20 @@ GC::Ref<ClassicScript> ClassicScript::create_from_pre_parsed(ByteString filename
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#run-a-classic-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#run-a-classic-script
|
||||
JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, GC::Ptr<JS::Environment> lexical_environment_override)
|
||||
{
|
||||
// 1. Let realm be the realm of script.
|
||||
auto& realm = this->realm();
|
||||
// 1. Let settings be the settings object of script.
|
||||
auto& settings = this->settings_object();
|
||||
auto& realm = settings.realm();
|
||||
|
||||
// 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)
|
||||
// 2. Check if we can run script with settings. If this returns "do not run", then return NormalCompletion(empty).
|
||||
if (can_run_script(settings) == RunScriptDecision::DoNotRun)
|
||||
return JS::normal_completion(JS::js_undefined());
|
||||
|
||||
// FIXME: 3. Record classic script execution start time given script.
|
||||
|
||||
// 4. Prepare to run script given realm.
|
||||
prepare_to_run_script(realm);
|
||||
// 4. Prepare to run script given settings.
|
||||
prepare_to_run_script(settings);
|
||||
|
||||
// 5. Let evaluationStatus be null.
|
||||
JS::Completion evaluation_status;
|
||||
@@ -143,8 +143,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, GC::Ptr<JS::Envi
|
||||
if (evaluation_status.is_abrupt()) {
|
||||
// 1. If rethrow errors is true and script's muted errors is false, then:
|
||||
if (rethrow_errors == RethrowErrors::Yes && m_muted_errors == MutedErrors::No) {
|
||||
// 1. Clean up after running script with realm.
|
||||
clean_up_after_running_script(realm);
|
||||
// 1. Clean up after running script with settings.
|
||||
clean_up_after_running_script(settings);
|
||||
|
||||
// 2. Rethrow evaluationStatus.[[Value]].
|
||||
return JS::throw_completion(evaluation_status.value());
|
||||
@@ -152,8 +152,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, GC::Ptr<JS::Envi
|
||||
|
||||
// 2. If rethrow errors is true and script's muted errors is true, then:
|
||||
if (rethrow_errors == RethrowErrors::Yes && m_muted_errors == MutedErrors::Yes) {
|
||||
// 1. Clean up after running script with realm.
|
||||
clean_up_after_running_script(realm);
|
||||
// 1. Clean up after running script with settings.
|
||||
clean_up_after_running_script(settings);
|
||||
|
||||
// 2. Throw a "NetworkError" DOMException.
|
||||
return throw_completion(WebIDL::NetworkError::create(realm, "Script error."_utf16));
|
||||
@@ -162,19 +162,19 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, GC::Ptr<JS::Envi
|
||||
// 3. Otherwise, rethrow errors is false. Perform the following steps:
|
||||
VERIFY(rethrow_errors == RethrowErrors::No);
|
||||
|
||||
// 1. Report an exception given by evaluationStatus.[[Value]] for realms's global object.
|
||||
auto& window_or_worker = as<WindowOrWorkerGlobalScopeMixin>(realm.global_object());
|
||||
// 1. Report an exception given by evaluationStatus.[[Value]] for script's settings object's global object.
|
||||
auto& window_or_worker = as<WindowOrWorkerGlobalScopeMixin>(settings.global_object());
|
||||
window_or_worker.report_an_exception(evaluation_status.value());
|
||||
|
||||
// 2. Clean up after running script with realm.
|
||||
clean_up_after_running_script(realm);
|
||||
// 2. Clean up after running script with settings.
|
||||
clean_up_after_running_script(settings);
|
||||
|
||||
// 3. Return evaluationStatus.
|
||||
return evaluation_status;
|
||||
}
|
||||
|
||||
// 9. Clean up after running script with realm.
|
||||
clean_up_after_running_script(realm);
|
||||
// 9. Clean up after running script with settings.
|
||||
clean_up_after_running_script(settings);
|
||||
|
||||
// 10. If evaluationStatus is a normal completion, then return evaluationStatus.
|
||||
VERIFY(!evaluation_status.is_abrupt());
|
||||
@@ -184,8 +184,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors, GC::Ptr<JS::Envi
|
||||
// Return ThrowCompletion(a new "QuotaExceededError" DOMException).
|
||||
}
|
||||
|
||||
ClassicScript::ClassicScript(URL::URL base_url, ByteString filename, JS::Realm& realm)
|
||||
: Script(move(base_url), move(filename), realm)
|
||||
ClassicScript::ClassicScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject& settings)
|
||||
: Script(move(base_url), move(filename), settings)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ public:
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
static GC::Ref<ClassicScript> create(ByteString filename, StringView source, JS::Realm&, URL::URL base_url, size_t source_line_number = 1, MutedErrors = MutedErrors::No);
|
||||
static GC::Ref<ClassicScript> create_from_pre_parsed(ByteString filename, NonnullRefPtr<JS::SourceCode const> source_code, JS::Realm&, URL::URL base_url, JS::FFI::ParsedProgram* parsed, MutedErrors = MutedErrors::No);
|
||||
static GC::Ref<ClassicScript> create(ByteString filename, StringView source, EnvironmentSettingsObject&, URL::URL base_url, size_t source_line_number = 1, MutedErrors = MutedErrors::No);
|
||||
static GC::Ref<ClassicScript> create_from_pre_parsed(ByteString filename, NonnullRefPtr<JS::SourceCode const> source_code, EnvironmentSettingsObject&, URL::URL base_url, JS::FFI::ParsedProgram* parsed, MutedErrors = MutedErrors::No);
|
||||
|
||||
JS::Script* script_record() { return m_script_record; }
|
||||
JS::Script const* script_record() const { return m_script_record; }
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
MutedErrors muted_errors() const { return m_muted_errors; }
|
||||
|
||||
private:
|
||||
ClassicScript(URL::URL base_url, ByteString filename, JS::Realm&);
|
||||
ClassicScript(URL::URL base_url, ByteString filename, EnvironmentSettingsObject&);
|
||||
|
||||
virtual bool is_classic_script() const final { return true; }
|
||||
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
* Copyright (c) 2021-2025, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2022, networkException <networkexception@serenityos.org>
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
* Copyright (c) 2024-2026, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/Bindings/PrincipalHostDefined.h>
|
||||
#include <LibWeb/Bindings/SyntheticHostDefined.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOMURL/DOMURL.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/FetchRecord.h>
|
||||
@@ -130,18 +129,17 @@ EventLoop& EnvironmentSettingsObject::responsible_event_loop()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#check-if-we-can-run-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#check-if-we-can-run-script
|
||||
RunScriptDecision can_run_script(JS::Realm const& realm)
|
||||
RunScriptDecision can_run_script(EnvironmentSettingsObject const& settings)
|
||||
{
|
||||
// 1. If the global object specified by realm is a Window object whose Document object is not fully active, then
|
||||
// return "do not run".
|
||||
if (auto const* window = as_if<Window>(realm.global_object())) {
|
||||
// 1. If the global object specified by settings is a Window object whose Document object is not fully active,
|
||||
// then return "do not run".
|
||||
if (auto const* window = as_if<Window>(settings.global_object())) {
|
||||
if (!window->associated_document().is_fully_active())
|
||||
return RunScriptDecision::DoNotRun;
|
||||
}
|
||||
|
||||
// 2. If scripting is disabled for realm, then return "do not run".
|
||||
if (is_scripting_disabled(realm))
|
||||
// 2. If scripting is disabled for settings, then return "do not run".
|
||||
if (is_scripting_disabled(settings))
|
||||
return RunScriptDecision::DoNotRun;
|
||||
|
||||
// 3. Return "run".
|
||||
@@ -149,41 +147,23 @@ RunScriptDecision can_run_script(JS::Realm const& realm)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#prepare-to-run-script
|
||||
// https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#prepare-to-run-script
|
||||
void prepare_to_run_script(JS::Realm& realm)
|
||||
void prepare_to_run_script(EnvironmentSettingsObject& settings)
|
||||
{
|
||||
// 1. Push realms's execution context onto the JavaScript execution context stack; it is now the running JavaScript execution context.
|
||||
realm.global_object().vm().push_execution_context(execution_context_of_realm(realm));
|
||||
// 1. Push settings's realm execution context onto the JavaScript execution context stack; it is now the running JavaScript execution context.
|
||||
settings.realm().vm().push_execution_context(settings.realm_execution_context());
|
||||
|
||||
// FIXME: 2. If realm is a principal realm, then:
|
||||
// FIXME: 2.1 Let settings be realm's settings object.
|
||||
// FIXME: 2.2 Add settings to the currently running task's script evaluation environment settings object set.
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#concept-realm-execution-context
|
||||
JS::ExecutionContext const& execution_context_of_realm(JS::Realm const& realm)
|
||||
{
|
||||
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<Bindings::PrincipalHostDefined>(*realm.host_defined()))
|
||||
return static_cast<Bindings::PrincipalHostDefined const&>(*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 *as<Bindings::SyntheticHostDefined>(*realm.host_defined()).synthetic_realm_settings.execution_context;
|
||||
// FIXME: 2. Add settings to the surrounding agent's event loop's currently running task's script evaluation environment settings object set.
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#clean-up-after-running-script
|
||||
void clean_up_after_running_script(JS::Realm const& realm)
|
||||
void clean_up_after_running_script(EnvironmentSettingsObject const& settings)
|
||||
{
|
||||
auto& vm = realm.global_object().vm();
|
||||
auto& vm = settings.global_object().vm();
|
||||
|
||||
// 1. Assert: realm's execution context is the running JavaScript execution context.
|
||||
VERIFY(&execution_context_of_realm(realm) == &vm.running_execution_context());
|
||||
// 1. Assert: settings's realm execution context is the running JavaScript execution context.
|
||||
VERIFY(&settings.realm_execution_context() == &vm.running_execution_context());
|
||||
|
||||
// 2. Remove realm's execution context from the JavaScript execution context stack.
|
||||
// 2. Remove settings's realm execution context from the JavaScript execution context stack.
|
||||
vm.pop_execution_context();
|
||||
|
||||
// 3. If the JavaScript execution context stack is now empty, perform a microtask checkpoint. (If this runs scripts, these algorithms will be invoked reentrantly.)
|
||||
@@ -206,14 +186,14 @@ static JS::ExecutionContext* top_most_script_having_execution_context(JS::VM& vm
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#prepare-to-run-a-callback
|
||||
void prepare_to_run_callback(JS::Realm& realm)
|
||||
void prepare_to_run_callback(EnvironmentSettingsObject& settings)
|
||||
{
|
||||
auto& vm = realm.global_object().vm();
|
||||
auto& vm = settings.global_object().vm();
|
||||
|
||||
// 1. Push realm onto the backup incumbent settings object stack.
|
||||
// 1. Push settings onto the backup incumbent settings object stack.
|
||||
// NOTE: The spec doesn't say which event loop's stack to put this on. However, all the examples of the incumbent settings object use iframes and cross browsing context communication to demonstrate the concept.
|
||||
// This means that it must rely on some global state that can be accessed by all browsing contexts, which is the main thread event loop.
|
||||
HTML::main_thread_event_loop().push_onto_backup_incumbent_realm_stack(realm);
|
||||
HTML::main_thread_event_loop().push_onto_backup_incumbent_realm_stack(settings);
|
||||
|
||||
// 2. Let context be the topmost script-having execution context.
|
||||
auto* context = top_most_script_having_execution_context(vm);
|
||||
@@ -269,10 +249,9 @@ Optional<String> EnvironmentSettingsObject::encoding_parse_and_serialize_url(Str
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#clean-up-after-running-a-callback
|
||||
// https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#clean-up-after-running-a-callback
|
||||
void clean_up_after_running_callback(JS::Realm const& realm)
|
||||
void clean_up_after_running_callback(EnvironmentSettingsObject const& settings)
|
||||
{
|
||||
auto& vm = realm.global_object().vm();
|
||||
auto& vm = settings.global_object().vm();
|
||||
|
||||
// 1. Let context be the topmost script-having execution context.
|
||||
auto* context = top_most_script_having_execution_context(vm);
|
||||
@@ -282,28 +261,27 @@ void clean_up_after_running_callback(JS::Realm const& realm)
|
||||
context->skip_when_determining_incumbent_counter--;
|
||||
}
|
||||
|
||||
// 3. Assert: the topmost entry of the backup incumbent realm stack is realm.
|
||||
// 3. Assert: the topmost entry of the backup incumbent realm stack is settings.
|
||||
auto& event_loop = HTML::main_thread_event_loop();
|
||||
VERIFY(&event_loop.top_of_backup_incumbent_realm_stack() == &realm);
|
||||
VERIFY(&event_loop.top_of_backup_incumbent_realm_stack() == &settings);
|
||||
|
||||
// 4. Remove realm from the backup incumbent realm stack.
|
||||
// 4. Remove settings from the backup incumbent realm stack.
|
||||
event_loop.pop_backup_incumbent_realm_stack();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-environment-script
|
||||
bool is_scripting_enabled(JS::Realm const& realm)
|
||||
bool is_scripting_enabled(EnvironmentSettingsObject const& settings)
|
||||
{
|
||||
// Scripting is enabled for a realm realm when all of the following conditions are true:
|
||||
// Scripting is enabled for an environment settings object settings when all of the following conditions are true:
|
||||
// The user agent supports scripting.
|
||||
// NOTE: This is always true in LibWeb :^)
|
||||
|
||||
// FIXME: Do the right thing for workers.
|
||||
if (!is<HTML::Window>(realm.global_object()))
|
||||
if (!is<HTML::Window>(settings.global_object()))
|
||||
return true;
|
||||
|
||||
// The user has not disabled scripting for realm at this time. (User agents may provide users with the option to disable scripting globally, or in a finer-grained manner, e.g., on a per-origin basis, down to the level of individual realms.)
|
||||
auto const& document = as<HTML::Window>(realm.global_object()).associated_document();
|
||||
auto const& document = as<HTML::Window>(settings.global_object()).associated_document();
|
||||
|
||||
// NB: about:settings and about:processes are internal pages using javascript, so we do not consider user configuration for these pages.
|
||||
if (document.url() != URL::about_settings()
|
||||
@@ -319,32 +297,30 @@ bool is_scripting_enabled(JS::Realm const& realm)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-noscript
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-environment-noscript
|
||||
bool is_scripting_disabled(JS::Realm const& realm)
|
||||
bool is_scripting_disabled(EnvironmentSettingsObject const& settings)
|
||||
{
|
||||
// Scripting is disabled for a realm when scripting is not enabled for it, i.e., when any of the above conditions are false.
|
||||
return !is_scripting_enabled(realm);
|
||||
// Scripting is disabled for an environment settings object when scripting is not enabled for it, i.e., when any of the above conditions are false.
|
||||
return !is_scripting_enabled(settings);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#module-type-allowed
|
||||
// https://whatpr.org/html/9893/webappapis.html#module-type-allowed
|
||||
bool module_type_allowed(JS::Realm const&, StringView module_type)
|
||||
bool module_type_allowed(EnvironmentSettingsObject const&, StringView module_type)
|
||||
{
|
||||
// 1. If moduleType is not "javascript-or-wasm", "css", or "json", then return false.
|
||||
if (module_type != "javascript-or-wasm"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 realm, then return false.
|
||||
// FIXME: 2. If moduleType is "css" and the CSSStyleSheet interface is not exposed in settings's realm, then return false.
|
||||
|
||||
// 3. Return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#add-module-to-resolved-module-set
|
||||
void add_module_to_resolved_module_set(JS::Realm& realm, String const& serialized_base_url, String const& normalized_specifier, Optional<URL::URL> const& as_url)
|
||||
void add_module_to_resolved_module_set(EnvironmentSettingsObject& settings_object, String const& serialized_base_url, String const& normalized_specifier, Optional<URL::URL> const& as_url)
|
||||
{
|
||||
// 1. Let global be realm's global object.
|
||||
auto& global = realm.global_object();
|
||||
// 1. Let global be settingsObject's global object.
|
||||
auto& global = settings_object.global_object();
|
||||
|
||||
// 2. If global does not implement Window, then return.
|
||||
if (!is<Window>(global))
|
||||
@@ -361,26 +337,18 @@ void add_module_to_resolved_module_set(JS::Realm& realm, String const& serialize
|
||||
};
|
||||
|
||||
// 4. Append record to global's resolved module set.
|
||||
return as<Window>(global).append_resolved_module(move(resolution));
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-realm-module-map
|
||||
ModuleMap& module_map_of_realm(JS::Realm& realm)
|
||||
{
|
||||
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<Bindings::PrincipalHostDefined>(*realm.host_defined()))
|
||||
return static_cast<Bindings::PrincipalHostDefined const&>(*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 *as<Bindings::SyntheticHostDefined>(*realm.host_defined()).synthetic_realm_settings.module_map;
|
||||
as<Window>(global).append_resolved_module(move(resolution));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-incumbent-realm
|
||||
// https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#concept-incumbent-realm
|
||||
JS::Realm& incumbent_realm()
|
||||
{
|
||||
// Then, the incumbent realm is the realm of the incumbent settings object.
|
||||
return incumbent_settings_object().realm();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#incumbent-settings-object
|
||||
EnvironmentSettingsObject& incumbent_settings_object()
|
||||
{
|
||||
auto& event_loop = HTML::main_thread_event_loop();
|
||||
auto& vm = event_loop.vm();
|
||||
@@ -399,16 +367,8 @@ JS::Realm& incumbent_realm()
|
||||
return event_loop.top_of_backup_incumbent_realm_stack();
|
||||
}
|
||||
|
||||
// 3. Return context's Realm component.
|
||||
return *context->realm;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#incumbent-settings-object
|
||||
// https://whatpr.org/html/9893/b8ea975...df5706b/webappapis.html#incumbent-settings-object
|
||||
EnvironmentSettingsObject& incumbent_settings_object()
|
||||
{
|
||||
// Then, the incumbent settings object is the incumbent realm's principal realm settings object.
|
||||
return principal_realm_settings_object(principal_realm(incumbent_realm()));
|
||||
// 3. Return context's Realm component's settings object.
|
||||
return principal_realm_settings_object(*context->realm);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-incumbent-global
|
||||
@@ -418,35 +378,6 @@ JS::Object& incumbent_global_object()
|
||||
return incumbent_settings_object().global_object();
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#current-principal-realm
|
||||
JS::Realm& current_principal_realm()
|
||||
{
|
||||
auto& event_loop = HTML::main_thread_event_loop();
|
||||
auto& vm = event_loop.vm();
|
||||
|
||||
// The current principal realm is the principal realm of the current realm.
|
||||
return principal_realm(*vm.current_realm());
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-principal-realm-of-realm
|
||||
JS::Realm& principal_realm(GC::Ref<JS::Realm> realm)
|
||||
{
|
||||
VERIFY(realm->host_defined());
|
||||
|
||||
// 1. If realm.[[HostDefined]] is a synthetic realm settings object, then:
|
||||
if (is<Bindings::SyntheticHostDefined>(*realm->host_defined())) {
|
||||
// 1. Assert: realm is a synthetic realm.
|
||||
// 2. Set realm to the principal realm of realm.[[HostDefined]].
|
||||
realm = static_cast<Bindings::SyntheticHostDefined const&>(*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<Bindings::PrincipalHostDefined>(*realm->host_defined()));
|
||||
|
||||
// 3. Return realm.
|
||||
return realm;
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-realm-settings-object
|
||||
EnvironmentSettingsObject& principal_realm_settings_object(JS::Realm& realm)
|
||||
{
|
||||
@@ -455,19 +386,17 @@ EnvironmentSettingsObject& principal_realm_settings_object(JS::Realm& realm)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#current-settings-object
|
||||
// https://whatpr.org/html/9893/webappapis.html#current-principal-settings-object
|
||||
EnvironmentSettingsObject& current_principal_settings_object()
|
||||
EnvironmentSettingsObject& current_settings_object()
|
||||
{
|
||||
// Then, the current principal settings object is the environment settings object of the current principal realm.
|
||||
return principal_realm_settings_object(current_principal_realm());
|
||||
// Then, the current settings object is the environment settings object of the current realm.
|
||||
return principal_realm_settings_object(*Bindings::main_thread_vm().current_realm());
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#current-global-object
|
||||
// https://whatpr.org/html/9893/webappapis.html#current-principal-global-object
|
||||
JS::Object& current_principal_global_object()
|
||||
JS::Object& current_global_object()
|
||||
{
|
||||
// Similarly, the current principal global object is the global object of the current principal realm.
|
||||
return current_principal_realm().global_object();
|
||||
// Similarly, the current global object is the global object of the current realm.
|
||||
return Bindings::main_thread_vm().current_realm()->global_object();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm
|
||||
@@ -477,17 +406,10 @@ JS::Realm& relevant_realm(JS::Object const& object)
|
||||
return object.shape().realm();
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#relevant-principal-realm
|
||||
JS::Realm& relevant_principal_realm(JS::Object const& object)
|
||||
{
|
||||
// The relevant principal realm for a platform object o is o's relevant realm's principal realm.
|
||||
return principal_realm(relevant_realm(object));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-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.
|
||||
// Then, the relevant settings object for a platform object o is the environment settings object of the relevant realm for o.
|
||||
return Bindings::principal_host_defined_environment_settings_object(relevant_realm(object));
|
||||
}
|
||||
|
||||
@@ -497,13 +419,6 @@ EnvironmentSettingsObject& relevant_settings_object(DOM::Node const& node)
|
||||
return const_cast<DOM::Document&>(node.document()).relevant_settings_object();
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#relevant-principal-settings-object
|
||||
EnvironmentSettingsObject& relevant_principal_settings_object(JS::Object const& object)
|
||||
{
|
||||
// The relevant principal settings object for a platform object o is o's relevant principal realm's environment settings object.
|
||||
return Bindings::principal_host_defined_environment_settings_object(relevant_principal_realm(object));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-global
|
||||
JS::Object& relevant_global_object(JS::Object const& object)
|
||||
{
|
||||
@@ -511,22 +426,14 @@ JS::Object& relevant_global_object(JS::Object const& object)
|
||||
return relevant_realm(object).global_object();
|
||||
}
|
||||
|
||||
// https://whatpr.org/html/9893/webappapis.html#relevant-principal-global
|
||||
JS::Object& relevant_principal_global_object(JS::Object const& object)
|
||||
{
|
||||
// The relevant principal global object for a platform object o is o's relevant principal realm's global object.
|
||||
return relevant_principal_realm(object).global_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 principal realm of the entry execution context's Realm component.
|
||||
// The entry realm is the entry execution context's Realm component.
|
||||
auto entry_execution_context = vm.execution_context_stack().last_matching([](JS::ExecutionContext* context) {
|
||||
if (!context->realm)
|
||||
return false;
|
||||
|
||||
@@ -197,41 +197,33 @@ private:
|
||||
bool m_discarded { false };
|
||||
};
|
||||
|
||||
JS::ExecutionContext const& execution_context_of_realm(JS::Realm const&);
|
||||
inline JS::ExecutionContext& execution_context_of_realm(JS::Realm& realm) { return const_cast<JS::ExecutionContext&>(execution_context_of_realm(const_cast<JS::Realm const&>(realm))); }
|
||||
RunScriptDecision can_run_script(EnvironmentSettingsObject const&);
|
||||
bool is_scripting_enabled(EnvironmentSettingsObject const&);
|
||||
bool is_scripting_disabled(EnvironmentSettingsObject const&);
|
||||
void prepare_to_run_script(EnvironmentSettingsObject&);
|
||||
void clean_up_after_running_script(EnvironmentSettingsObject const&);
|
||||
WEB_API void prepare_to_run_callback(EnvironmentSettingsObject&);
|
||||
WEB_API void clean_up_after_running_callback(EnvironmentSettingsObject const&);
|
||||
WEB_API bool module_type_allowed(EnvironmentSettingsObject const&, StringView module_type);
|
||||
|
||||
RunScriptDecision can_run_script(JS::Realm const&);
|
||||
bool is_scripting_enabled(JS::Realm const&);
|
||||
bool is_scripting_disabled(JS::Realm const&);
|
||||
void prepare_to_run_script(JS::Realm&);
|
||||
void clean_up_after_running_script(JS::Realm const&);
|
||||
WEB_API void prepare_to_run_callback(JS::Realm&);
|
||||
WEB_API void clean_up_after_running_callback(JS::Realm const&);
|
||||
WEB_API ModuleMap& module_map_of_realm(JS::Realm&);
|
||||
WEB_API bool module_type_allowed(JS::Realm const&, StringView module_type);
|
||||
WEB_API void add_module_to_resolved_module_set(EnvironmentSettingsObject&, String const& serialized_base_url, String const& normalized_specifier, Optional<URL::URL> const& as_url);
|
||||
|
||||
WEB_API void add_module_to_resolved_module_set(JS::Realm&, String const& serialized_base_url, String const& normalized_specifier, Optional<URL::URL> const& as_url);
|
||||
|
||||
EnvironmentSettingsObject& incumbent_settings_object();
|
||||
WEB_API EnvironmentSettingsObject& incumbent_settings_object();
|
||||
WEB_API JS::Realm& incumbent_realm();
|
||||
|
||||
JS::Object& incumbent_global_object();
|
||||
|
||||
JS::Realm& current_principal_realm();
|
||||
EnvironmentSettingsObject& principal_realm_settings_object(JS::Realm&);
|
||||
EnvironmentSettingsObject& current_principal_settings_object();
|
||||
EnvironmentSettingsObject& current_settings_object();
|
||||
|
||||
WEB_API JS::Realm& principal_realm(GC::Ref<JS::Realm>);
|
||||
WEB_API JS::Object& current_principal_global_object();
|
||||
WEB_API JS::Object& current_global_object();
|
||||
|
||||
WEB_API JS::Realm& relevant_realm(JS::Object const&);
|
||||
JS::Realm& relevant_principal_realm(JS::Object const&);
|
||||
|
||||
WEB_API EnvironmentSettingsObject& relevant_settings_object(JS::Object const&);
|
||||
EnvironmentSettingsObject& relevant_settings_object(DOM::Node const&);
|
||||
WEB_API EnvironmentSettingsObject& relevant_principal_settings_object(JS::Object const&);
|
||||
|
||||
WEB_API JS::Object& relevant_global_object(JS::Object const&);
|
||||
WEB_API JS::Object& relevant_principal_global_object(JS::Object const&);
|
||||
|
||||
JS::Realm& entry_realm();
|
||||
EnvironmentSettingsObject& entry_settings_object();
|
||||
|
||||
@@ -133,19 +133,18 @@ String module_type_from_module_request(JS::ModuleRequest const& module_request)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier
|
||||
// https://whatpr.org/html/9893/webappapis.html#resolve-a-module-specifier
|
||||
WebIDL::ExceptionOr<URL::URL> resolve_module_specifier(Optional<Script&> referring_script, String const& specifier)
|
||||
{
|
||||
auto& vm = Bindings::main_thread_vm();
|
||||
|
||||
// 1. Let realm and baseURL be null.
|
||||
GC::Ptr<JS::Realm> realm;
|
||||
// 1. Let settingsObject and baseURL be null.
|
||||
GC::Ptr<EnvironmentSettingsObject> settings_object;
|
||||
Optional<URL::URL> base_url;
|
||||
|
||||
// 2. If referringScript is not null, then:
|
||||
if (referring_script.has_value()) {
|
||||
// 1. Set realm to referringScript's realm.
|
||||
realm = referring_script->realm();
|
||||
// 1. Set settingsObject to referringScript's settings object.
|
||||
settings_object = referring_script->settings_object();
|
||||
|
||||
// 2. Set baseURL to referringScript's base URL.
|
||||
base_url = referring_script->base_url();
|
||||
@@ -155,19 +154,19 @@ WebIDL::ExceptionOr<URL::URL> resolve_module_specifier(Optional<Script&> referri
|
||||
// 1. Assert: there is a current realm.
|
||||
VERIFY(vm.current_realm());
|
||||
|
||||
// 2. Set realm to the current realm.
|
||||
realm = *vm.current_realm();
|
||||
// 2. Set settingsObject to the current settings object.
|
||||
settings_object = current_settings_object();
|
||||
|
||||
// 3. Set baseURL to realm's principal realm's settings object's API base URL.
|
||||
base_url = Bindings::principal_host_defined_environment_settings_object(HTML::principal_realm(*realm)).api_base_url();
|
||||
// 3. Set baseURL to settingsObject's API base URL.
|
||||
base_url = settings_object->api_base_url();
|
||||
}
|
||||
|
||||
// 4. Let importMap be an empty import map.
|
||||
ImportMap import_map;
|
||||
|
||||
// 5. If realm's global object implements Window, then set importMap to settingsObject's global object's import map.
|
||||
if (is<Window>(realm->global_object()))
|
||||
import_map = as<Window>(realm->global_object()).import_map();
|
||||
// 5. If settingsObject's global object implements Window, then set importMap to settingsObject's global object's import map.
|
||||
if (auto* window = as_if<Window>(settings_object->global_object()))
|
||||
import_map = window->import_map();
|
||||
|
||||
// 6. Let serializedBaseURL be baseURL, serialized.
|
||||
auto serialized_base_url = base_url->serialize();
|
||||
@@ -213,8 +212,8 @@ WebIDL::ExceptionOr<URL::URL> resolve_module_specifier(Optional<Script&> referri
|
||||
|
||||
// 13. If result is not null, then:
|
||||
if (result.has_value()) {
|
||||
// 1. Add module to resolved module set given realm, serializedBaseURL, normalizedSpecifier, and asURL.
|
||||
add_module_to_resolved_module_set(*realm, serialized_base_url, normalized_specifier, as_url);
|
||||
// 1. Add module to resolved module set given settingsObject, serializedBaseURL, normalizedSpecifier, and asURL.
|
||||
add_module_to_resolved_module_set(*settings_object, serialized_base_url, normalized_specifier, as_url);
|
||||
|
||||
// 2. Return result.
|
||||
return result.release_value();
|
||||
@@ -433,7 +432,7 @@ void fetch_classic_script(GC::Ref<HTMLScriptElement> element, URL::URL const& ur
|
||||
// If the Rust pipeline is available, parse off the main thread.
|
||||
if (JS::RustIntegration::rust_pipeline_available()) {
|
||||
auto on_complete_root = GC::make_root(on_complete);
|
||||
auto realm_root = GC::make_root(settings_object.realm());
|
||||
auto settings_root = GC::make_root(settings_object);
|
||||
auto response_url_string = response_url.to_byte_string();
|
||||
auto source_code = JS::SourceCode::create(
|
||||
String::from_utf8(response_url_string.view()).release_value_but_fixme_should_propagate_errors(),
|
||||
@@ -442,12 +441,12 @@ void fetch_classic_script(GC::Ref<HTMLScriptElement> element, URL::URL const& ur
|
||||
parse_off_thread(move(source_code), JS::RustIntegration::ProgramType::Script, 1,
|
||||
[response_url = move(response_url), response_url_string = move(response_url_string),
|
||||
muted_errors, on_complete_root = move(on_complete_root),
|
||||
realm_root = move(realm_root)](auto* parsed, auto source_code) mutable {
|
||||
auto script = ClassicScript::create_from_pre_parsed(move(response_url_string), move(source_code), *realm_root, move(response_url), parsed, muted_errors);
|
||||
settings_root = move(settings_root)](auto* parsed, auto source_code) mutable {
|
||||
auto script = ClassicScript::create_from_pre_parsed(move(response_url_string), move(source_code), *settings_root, move(response_url), parsed, muted_errors);
|
||||
on_complete_root->function()(script);
|
||||
});
|
||||
} else {
|
||||
auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object.realm(), response_url, 1, muted_errors);
|
||||
auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url, 1, muted_errors);
|
||||
|
||||
// 8. Run onComplete given script.
|
||||
on_complete->function()(script);
|
||||
@@ -511,10 +510,10 @@ WebIDL::ExceptionOr<void> 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<ByteBuffer>()).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
// 5. Let script be the result of creating a classic script using sourceText, settingsObject's realm,
|
||||
// 5. Let script be the result of creating a classic script using sourceText, settingsObject,
|
||||
// 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.realm(), response_url);
|
||||
auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url);
|
||||
|
||||
// 6. Run onComplete given script.
|
||||
on_complete->function()(script);
|
||||
@@ -604,9 +603,9 @@ WebIDL::ExceptionOr<GC::Ref<ClassicScript>> fetch_a_classic_worker_imported_scri
|
||||
// 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's realm, 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, 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.realm(), response_url, 1, muted_errors);
|
||||
auto script = ClassicScript::create(response_url.to_byte_string(), source_text, settings_object, response_url, 1, muted_errors);
|
||||
|
||||
// 11. Return script.
|
||||
return script;
|
||||
@@ -619,7 +618,6 @@ WebIDL::ExceptionOr<void> 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<void> 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();
|
||||
@@ -651,9 +649,9 @@ WebIDL::ExceptionOr<void> fetch_worklet_module_worker_script_graph(URL::URL cons
|
||||
fetch_descendants_of_and_link_a_module_script(realm, as<ModuleScript>(*result), fetch_client, destination, move(perform_fetch), on_complete);
|
||||
});
|
||||
|
||||
// 2. Fetch a single module script given url, fetchClient, destination, options, settingsObject's realm, "client", true,
|
||||
// 2. Fetch a single module script given url, fetchClient, destination, options, settingsObject, "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.realm(), 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, Fetch::Infrastructure::Request::Referrer::Client, {}, TopLevelModule::Yes, move(perform_fetch), on_single_fetch_complete);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -674,13 +672,12 @@ 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,
|
||||
JS::Realm& module_map_realm,
|
||||
EnvironmentSettingsObject& settings_object,
|
||||
Web::Fetch::Infrastructure::Request::ReferrerType const& referrer,
|
||||
Optional<JS::ModuleRequest> const& module_request,
|
||||
TopLevelModule is_top_level,
|
||||
@@ -694,13 +691,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 moduleMapRealm is true.
|
||||
// 3. Assert: the result of running the module type allowed steps given moduleType and settingsObject 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(module_type_allowed(module_map_realm, module_type));
|
||||
VERIFY(module_type_allowed(settings_object, module_type));
|
||||
|
||||
// 4. Let moduleMap be moduleMapRealm's module map.
|
||||
auto& module_map = module_map_of_realm(module_map_realm);
|
||||
// 4. Let moduleMap be settingsObject's module map.
|
||||
auto& module_map = settings_object.module_map();
|
||||
|
||||
// 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.
|
||||
@@ -750,7 +747,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, &module_map_realm, on_complete](GC::Ref<Fetch::Infrastructure::Response> response, Fetch::Infrastructure::FetchAlgorithms::BodyBytes body_bytes) {
|
||||
auto process_response_consume_body = [&module_map, url, module_type, &settings_object, on_complete](GC::Ref<Fetch::Infrastructure::Response> response, Fetch::Infrastructure::FetchAlgorithms::BodyBytes body_bytes) {
|
||||
// 1. If any of the following are true:
|
||||
// - bodyBytes is null or failure; or
|
||||
// - response's status is not an ok status,
|
||||
@@ -775,7 +772,7 @@ void fetch_single_module_script(JS::Realm& realm,
|
||||
// options.
|
||||
// FIXME: Pass options.
|
||||
if (mime_type.has_value() && mime_type->essence() == "application/wasm"sv && module_type == "javascript-or-wasm") {
|
||||
module_script = ModuleScript::create_a_webassembly_module_script(url.to_byte_string(), body_bytes.get<ByteBuffer>(), module_map_realm, response->url().value_or({})).release_value_but_fixme_should_propagate_errors();
|
||||
module_script = ModuleScript::create_a_webassembly_module_script(url.to_byte_string(), body_bytes.get<ByteBuffer>(), settings_object, response->url().value_or({})).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
// 7. Otherwise
|
||||
@@ -793,7 +790,7 @@ void fetch_single_module_script(JS::Realm& realm,
|
||||
// If the Rust pipeline is available, parse off the main thread.
|
||||
if (JS::RustIntegration::rust_pipeline_available()) {
|
||||
auto on_complete_root = GC::make_root(on_complete);
|
||||
auto realm_root = GC::make_root(&module_map_realm);
|
||||
auto settings_root = GC::make_root(settings_object);
|
||||
auto url_string = url.to_byte_string();
|
||||
auto response_url = response->url().value_or({});
|
||||
auto module_type_string = module_type.to_byte_string();
|
||||
@@ -805,26 +802,28 @@ void fetch_single_module_script(JS::Realm& realm,
|
||||
[url = move(url), url_string = move(url_string), response_url = move(response_url),
|
||||
module_type_string = move(module_type_string),
|
||||
on_complete_root = move(on_complete_root),
|
||||
realm_root = move(realm_root)](auto* parsed, auto source_code) mutable {
|
||||
auto module_script = ModuleScript::create_from_pre_parsed(url_string, move(source_code), *realm_root, move(response_url), parsed).release_value_but_fixme_should_propagate_errors();
|
||||
auto& mm = module_map_of_realm(*realm_root);
|
||||
mm.set(url, module_type_string, { ModuleMap::EntryType::ModuleScript, module_script });
|
||||
settings_root = move(settings_root)](auto* parsed, auto source_code) mutable {
|
||||
auto module_script = ModuleScript::create_from_pre_parsed(url_string, move(source_code), *settings_root, move(response_url), parsed).release_value_but_fixme_should_propagate_errors();
|
||||
settings_root->module_map().set(url, module_type_string, { ModuleMap::EntryType::ModuleScript, module_script });
|
||||
on_complete_root->function()(module_script);
|
||||
});
|
||||
return;
|
||||
}
|
||||
module_script = ModuleScript::create_a_javascript_module_script(url.to_byte_string(), source_text, module_map_realm, response->url().value_or({})).release_value_but_fixme_should_propagate_errors();
|
||||
module_script = ModuleScript::create_a_javascript_module_script(url.to_byte_string(), source_text, settings_object, response->url().value_or({})).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
// 3. 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 moduleMapRealm.
|
||||
// FIXME: 3. If mimeType is a JavaScript MIME type and moduleType is "javascript-or-wasm", then set moduleScript to
|
||||
// the result of creating a JavaScript module script given sourceText, settingsObject, response's URL, and options.
|
||||
|
||||
// 4. 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.
|
||||
if (mime_type.has_value() && mime_type->essence() == "text/css"sv && module_type == "css")
|
||||
module_script = ModuleScript::create_a_css_module_script(url.to_byte_string(), source_text, module_map_realm).release_value_but_fixme_should_propagate_errors();
|
||||
module_script = ModuleScript::create_a_css_module_script(url.to_byte_string(), source_text, settings_object).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
// 4. 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 moduleMapRealm.
|
||||
// creating a JSON module script given sourceText and settingsObject.
|
||||
if (mime_type.has_value() && mime_type->is_json() && module_type == "json")
|
||||
module_script = ModuleScript::create_a_json_module_script(url.to_byte_string(), source_text, module_map_realm).release_value_but_fixme_should_propagate_errors();
|
||||
module_script = ModuleScript::create_a_json_module_script(url.to_byte_string(), source_text, settings_object).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
// 8. Set moduleMap[(url, moduleType)] to moduleScript, and run onComplete given moduleScript.
|
||||
@@ -842,7 +841,6 @@ 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)
|
||||
{
|
||||
auto steps = create_on_fetch_script_complete(realm.heap(), [&realm, &settings_object, on_complete, url](auto result) mutable {
|
||||
@@ -857,15 +855,15 @@ 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);
|
||||
});
|
||||
|
||||
// 1. 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);
|
||||
// 1. 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);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/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. Let script be the result of creating a JavaScript module script using sourceText, settingsObject's realm, baseURL, and options.
|
||||
auto script = ModuleScript::create_a_javascript_module_script(filename, source_text.view(), settings_object.realm(), base_url).release_value_but_fixme_should_propagate_errors();
|
||||
// 1. Let script be the result of creating a JavaScript module script using sourceText, settingsObject, baseURL, and options.
|
||||
auto script = ModuleScript::create_a_javascript_module_script(filename, source_text.view(), settings_object, base_url).release_value_but_fixme_should_propagate_errors();
|
||||
|
||||
// 2. Fetch the descendants of and link script, given settingsObject, "script", and onComplete.
|
||||
fetch_descendants_of_and_link_a_module_script(realm, *script, settings_object, Fetch::Infrastructure::Request::Destination::Script, nullptr, on_complete);
|
||||
@@ -877,7 +875,7 @@ void fetch_single_imported_module_script(JS::Realm& realm,
|
||||
EnvironmentSettingsObject& fetch_client,
|
||||
Fetch::Infrastructure::Request::Destination destination,
|
||||
ScriptFetchOptions const& options,
|
||||
JS::Realm& module_map_realm,
|
||||
EnvironmentSettingsObject& settings_object,
|
||||
Fetch::Infrastructure::Request::ReferrerType referrer,
|
||||
JS::ModuleRequest const& module_request,
|
||||
PerformTheFetchHook perform_fetch,
|
||||
@@ -891,16 +889,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 moduleMapRealm is false,
|
||||
// 3. If the result of running the module type allowed steps given moduleType and settingsObject is false,
|
||||
// then run onComplete given null, and return.
|
||||
if (!module_type_allowed(module_map_realm, module_type)) {
|
||||
if (!module_type_allowed(settings_object, module_type)) {
|
||||
on_complete->function()(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Fetch a single module script given url, fetchClient, destination, options, moduleMapRealm, referrer, moduleRequest, false,
|
||||
// 4. Fetch a single module script given url, fetchClient, destination, options, settingsObject, referrer, moduleRequest, false,
|
||||
// and onComplete. If performFetch was given, pass it along as well.
|
||||
fetch_single_module_script(realm, url, fetch_client, destination, options, module_map_realm, referrer, module_request, TopLevelModule::No, perform_fetch, on_complete);
|
||||
fetch_single_module_script(realm, url, fetch_client, destination, options, settings_object, 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
|
||||
@@ -940,7 +938,7 @@ void fetch_descendants_of_and_link_a_module_script(JS::Realm& realm,
|
||||
// resulting in the event loop hanging forever awaiting for the script to be ready for parser
|
||||
// execution.
|
||||
realm.vm().push_execution_context(fetch_client.realm_execution_context());
|
||||
prepare_to_run_callback(realm);
|
||||
prepare_to_run_callback(fetch_client);
|
||||
|
||||
// 5. Let loadingPromise be record.LoadRequestedModules(state).
|
||||
auto loading_promise = record.visit(
|
||||
@@ -982,7 +980,7 @@ void fetch_descendants_of_and_link_a_module_script(JS::Realm& realm,
|
||||
return JS::js_undefined();
|
||||
}));
|
||||
|
||||
clean_up_after_running_callback(realm);
|
||||
clean_up_after_running_callback(fetch_client);
|
||||
|
||||
realm.vm().pop_execution_context();
|
||||
}
|
||||
|
||||
@@ -96,12 +96,12 @@ WEB_API WebIDL::ExceptionOr<void> fetch_module_worker_script_graph(URL::URL cons
|
||||
WebIDL::ExceptionOr<void> fetch_worklet_module_worker_script_graph(URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, EnvironmentSettingsObject& settings_object, PerformTheFetchHook, OnFetchScriptComplete);
|
||||
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&, JS::Realm& module_map_realm, 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&, EnvironmentSettingsObject&, Fetch::Infrastructure::Request::ReferrerType, JS::ModuleRequest const&, PerformTheFetchHook, OnFetchScriptComplete on_complete);
|
||||
|
||||
void fetch_descendants_of_and_link_a_module_script(JS::Realm&, ModuleScript&, 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&, JS::Realm& module_map_realm, Web::Fetch::Infrastructure::Request::ReferrerType const&, Optional<JS::ModuleRequest> const&, TopLevelModule, PerformTheFetchHook, OnFetchScriptComplete callback);
|
||||
void fetch_single_module_script(JS::Realm&, URL::URL const&, EnvironmentSettingsObject& fetch_client, Fetch::Infrastructure::Request::Destination, ScriptFetchOptions const&, EnvironmentSettingsObject&, Web::Fetch::Infrastructure::Request::ReferrerType const&, Optional<JS::ModuleRequest> const&, TopLevelModule, PerformTheFetchHook, OnFetchScriptComplete callback);
|
||||
|
||||
}
|
||||
|
||||
@@ -22,23 +22,24 @@ GC_DEFINE_ALLOCATOR(ModuleScript);
|
||||
|
||||
ModuleScript::~ModuleScript() = default;
|
||||
|
||||
ModuleScript::ModuleScript(Optional<URL::URL> base_url, ByteString filename, JS::Realm& realm)
|
||||
: Script(move(base_url), move(filename), realm)
|
||||
ModuleScript::ModuleScript(Optional<URL::URL> base_url, ByteString filename, EnvironmentSettingsObject& settings)
|
||||
: Script(move(base_url), move(filename), settings)
|
||||
{
|
||||
}
|
||||
|
||||
// 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<GC::Ptr<ModuleScript>> ModuleScript::create_a_javascript_module_script(ByteString const& filename, StringView source, JS::Realm& realm, URL::URL base_url)
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_javascript_module_script(ByteString const& filename, StringView source, EnvironmentSettingsObject& settings, URL::URL base_url)
|
||||
{
|
||||
// 1. If scripting is disabled for realm, then set source to the empty string.
|
||||
if (HTML::is_scripting_disabled(realm))
|
||||
auto& realm = settings.realm();
|
||||
|
||||
// 1. If scripting is disabled for settings, then set source to the empty string.
|
||||
if (HTML::is_scripting_disabled(settings))
|
||||
source = ""sv;
|
||||
|
||||
// 2. Let script be a new module script that this algorithm will subsequently initialize.
|
||||
// 3. Set script's realm to realm.
|
||||
// 3. Set script's settings object to settings.
|
||||
// 4. Set script's base URL to baseURL.
|
||||
auto script = realm.create<ModuleScript>(move(base_url), filename, realm);
|
||||
auto script = realm.create<ModuleScript>(move(base_url), filename, settings);
|
||||
|
||||
// FIXME: 5. Set script's fetch options to options.
|
||||
|
||||
@@ -68,9 +69,10 @@ WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_javascript_mod
|
||||
return script;
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_from_pre_parsed(ByteString const& filename, NonnullRefPtr<JS::SourceCode const> source_code, JS::Realm& realm, URL::URL base_url, JS::FFI::ParsedProgram* parsed)
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_from_pre_parsed(ByteString const& filename, NonnullRefPtr<JS::SourceCode const> source_code, EnvironmentSettingsObject& settings, URL::URL base_url, JS::FFI::ParsedProgram* parsed)
|
||||
{
|
||||
auto script = realm.create<ModuleScript>(move(base_url), filename, realm);
|
||||
auto& realm = settings.realm();
|
||||
auto script = realm.create<ModuleScript>(move(base_url), filename, settings);
|
||||
|
||||
script->set_parse_error(JS::js_null());
|
||||
script->set_error_to_rethrow(JS::js_null());
|
||||
@@ -89,13 +91,14 @@ WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_from_pre_parsed(
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-css-module-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#creating-a-css-module-script
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_css_module_script(ByteString const& filename, StringView source, JS::Realm& realm)
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_css_module_script(ByteString const& filename, StringView source, EnvironmentSettingsObject& settings)
|
||||
{
|
||||
auto& realm = settings.realm();
|
||||
|
||||
// 1. Let script be a new module script that this algorithm will subsequently initialize.
|
||||
// 2. Set script's realm to realm.
|
||||
// 2. Set script's settings object to settings.
|
||||
// 3. Set script's base URL and fetch options to null.
|
||||
auto script = realm.create<ModuleScript>(Optional<URL::URL> {}, filename, realm);
|
||||
auto script = realm.create<ModuleScript>(Optional<URL::URL> {}, filename, settings);
|
||||
|
||||
// 4. Set script's parse error and error to rethrow to null.
|
||||
script->set_parse_error(JS::js_null());
|
||||
@@ -121,14 +124,15 @@ WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_css_module_scr
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-json-module-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#creating-a-json-module-script
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_json_module_script(ByteString const& filename, StringView source, JS::Realm& realm)
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_json_module_script(ByteString const& filename, StringView source, EnvironmentSettingsObject& settings)
|
||||
{
|
||||
auto& realm = settings.realm();
|
||||
|
||||
// 1. Let script be a new module script that this algorithm will subsequently initialize.
|
||||
// 2. Set script's realm to realm.
|
||||
// 2. Set script's settings object to settings.
|
||||
// 3. Set script's base URL and fetch options to null.
|
||||
// FIXME: Set options.
|
||||
auto script = realm.create<ModuleScript>(Optional<URL::URL> {}, filename, realm);
|
||||
auto script = realm.create<ModuleScript>(Optional<URL::URL> {}, filename, settings);
|
||||
|
||||
// 4. Set script's parse error and error to rethrow to null.
|
||||
script->set_parse_error(JS::js_null());
|
||||
@@ -151,22 +155,23 @@ WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_json_module_sc
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-webassembly-module-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#creating-a-webassembly-module-script
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_webassembly_module_script(ByteString const& filename, ByteBuffer body_bytes, JS::Realm& realm, URL::URL base_url)
|
||||
WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_webassembly_module_script(ByteString const& filename, ByteBuffer body_bytes, EnvironmentSettingsObject& settings, URL::URL base_url)
|
||||
{
|
||||
// 1. If scripting is disabled for realm, then set bodyBytes to the byte sequence 0x00 0x61 0x73 0x6d 0x01 0x00 0x00 0x00.
|
||||
auto& realm = settings.realm();
|
||||
|
||||
// 1. If scripting is disabled for settings, then set bodyBytes to the byte sequence 0x00 0x61 0x73 0x6D 0x01 0x00 0x00 0x00.
|
||||
// NOTE: This byte sequence corresponds to an empty WebAssembly module with only the magic bytes and version number provided.
|
||||
if (HTML::is_scripting_disabled(realm)) {
|
||||
if (HTML::is_scripting_disabled(settings)) {
|
||||
auto byte_sequence = "\x00\x61\x73\x6d\x01\x00\x00\x00"sv.bytes();
|
||||
body_bytes = MUST(ByteBuffer::create_uninitialized(byte_sequence.size()));
|
||||
byte_sequence.copy_to(body_bytes);
|
||||
}
|
||||
|
||||
// 2. Let script be a new module script that this algorithm will subsequently initialize.
|
||||
// 3. Set script's realm to realm.
|
||||
// 3. Set script's settings object to settings.
|
||||
// 4. Set script's base URL to baseURL.
|
||||
// FIXME: 5. Set script's fetch options to options.
|
||||
auto script = realm.create<ModuleScript>(base_url, filename, realm);
|
||||
auto script = settings.realm().create<ModuleScript>(base_url, filename, settings);
|
||||
|
||||
// 6. Set script's parse error and error to rethrow to null.
|
||||
script->set_parse_error(JS::js_null());
|
||||
@@ -194,21 +199,21 @@ WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> ModuleScript::create_a_webassembly_mo
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#run-a-module-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#run-a-module-script
|
||||
WebIDL::Promise* ModuleScript::run(PreventErrorReporting prevent_error_reporting)
|
||||
{
|
||||
// 1. Let realm be the realm of script.
|
||||
auto& realm = this->realm();
|
||||
// 1. Let settings be the settings object of script.
|
||||
auto& settings = this->settings_object();
|
||||
auto& realm = settings.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) {
|
||||
if (can_run_script(settings) == RunScriptDecision::DoNotRun) {
|
||||
return WebIDL::create_resolved_promise(realm, JS::js_undefined());
|
||||
}
|
||||
|
||||
// FIXME: 3. Record module script execution start time given script.
|
||||
|
||||
// 4. Prepare to run script given realm.
|
||||
prepare_to_run_script(realm);
|
||||
// 4. Prepare to run script given settings.
|
||||
prepare_to_run_script(settings);
|
||||
|
||||
// 5. Let evaluationPromise be null.
|
||||
GC::Ptr<WebIDL::Promise> evaluation_promise = nullptr;
|
||||
@@ -260,8 +265,8 @@ WebIDL::Promise* ModuleScript::run(PreventErrorReporting prevent_error_reporting
|
||||
}));
|
||||
}
|
||||
|
||||
// 9. Clean up after running script with realm.
|
||||
clean_up_after_running_script(realm);
|
||||
// 9. Clean up after running script with settings.
|
||||
clean_up_after_running_script(settings);
|
||||
|
||||
// 10. Return evaluationPromise.
|
||||
return evaluation_promise;
|
||||
|
||||
@@ -30,12 +30,12 @@ class WEB_API ModuleScript : public Script {
|
||||
public:
|
||||
virtual ~ModuleScript() override;
|
||||
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create(ByteString const& filename, StringView source, JS::Realm&, URL::URL base_url);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_from_pre_parsed(ByteString const& filename, NonnullRefPtr<JS::SourceCode const> source_code, JS::Realm&, URL::URL base_url, JS::FFI::ParsedProgram* parsed);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_javascript_module_script(ByteString const& filename, StringView source, JS::Realm&, URL::URL base_url);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_css_module_script(ByteString const& filename, StringView source, JS::Realm&);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_json_module_script(ByteString const& filename, StringView source, JS::Realm&);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_webassembly_module_script(ByteString const& filename, ByteBuffer body_bytes, JS::Realm&, URL::URL base_url);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create(ByteString const& filename, StringView source, EnvironmentSettingsObject&, URL::URL base_url);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_from_pre_parsed(ByteString const& filename, NonnullRefPtr<JS::SourceCode const> source_code, EnvironmentSettingsObject&, URL::URL base_url, JS::FFI::ParsedProgram* parsed);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_javascript_module_script(ByteString const& filename, StringView source, EnvironmentSettingsObject&, URL::URL base_url);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_css_module_script(ByteString const& filename, StringView source, EnvironmentSettingsObject&);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_json_module_script(ByteString const& filename, StringView source, EnvironmentSettingsObject&);
|
||||
static WebIDL::ExceptionOr<GC::Ptr<ModuleScript>> create_a_webassembly_module_script(ByteString const& filename, ByteBuffer body_bytes, EnvironmentSettingsObject&, URL::URL base_url);
|
||||
|
||||
enum class PreventErrorReporting {
|
||||
Yes,
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
ModuleScriptRecord record() const { return m_record; }
|
||||
|
||||
protected:
|
||||
ModuleScript(Optional<URL::URL> base_url, ByteString filename, JS::Realm&);
|
||||
ModuleScript(Optional<URL::URL> base_url, ByteString filename, EnvironmentSettingsObject&);
|
||||
|
||||
private:
|
||||
virtual bool is_module_script() const final { return true; }
|
||||
|
||||
@@ -11,20 +11,18 @@ namespace Web::HTML {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(Script);
|
||||
|
||||
Script::Script(Optional<URL::URL> base_url, ByteString filename, JS::Realm& realm)
|
||||
Script::Script(Optional<URL::URL> base_url, ByteString filename, EnvironmentSettingsObject& settings)
|
||||
: m_base_url(move(base_url))
|
||||
, m_filename(move(filename))
|
||||
, m_realm(realm)
|
||||
, m_settings(settings)
|
||||
{
|
||||
}
|
||||
|
||||
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()));
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void Script::visit_host_defined_self(JS::Cell::Visitor& visitor)
|
||||
@@ -35,7 +33,7 @@ void Script::visit_host_defined_self(JS::Cell::Visitor& visitor)
|
||||
void Script::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_realm);
|
||||
visitor.visit(m_settings);
|
||||
visitor.visit(m_parse_error);
|
||||
visitor.visit(m_error_to_rethrow);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-script
|
||||
// https://whatpr.org/html/9893/webappapis.html#concept-script
|
||||
class WEB_API Script
|
||||
: public JS::Cell
|
||||
, public JS::Script::HostDefined {
|
||||
@@ -28,7 +27,6 @@ public:
|
||||
Optional<URL::URL> const& base_url() const { return m_base_url; }
|
||||
ByteString const& filename() const { return m_filename; }
|
||||
|
||||
JS::Realm& realm() { return m_realm; }
|
||||
EnvironmentSettingsObject& settings_object();
|
||||
|
||||
[[nodiscard]] JS::Value error_to_rethrow() const { return m_error_to_rethrow; }
|
||||
@@ -38,7 +36,7 @@ public:
|
||||
void set_parse_error(JS::Value value) { m_parse_error = value; }
|
||||
|
||||
protected:
|
||||
Script(Optional<URL::URL> base_url, ByteString filename, JS::Realm&);
|
||||
Script(Optional<URL::URL> base_url, ByteString filename, EnvironmentSettingsObject&);
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
@@ -48,7 +46,10 @@ private:
|
||||
|
||||
Optional<URL::URL> m_base_url;
|
||||
ByteString m_filename;
|
||||
GC::Ref<JS::Realm> m_realm;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#settings-object
|
||||
// An environment settings object, containing various settings that are shared with other scripts in the same context.
|
||||
GC::Ref<EnvironmentSettingsObject> m_settings;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-parse-error
|
||||
JS::Value m_parse_error;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/HTML/Scripting/ModuleMap.h>
|
||||
#include <LibWeb/HTML/Scripting/SyntheticRealmSettings.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
void SyntheticRealmSettings::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
execution_context->visit_edges(visitor);
|
||||
visitor.visit(principal_realm);
|
||||
visitor.visit(module_map);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGC/Ptr.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
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<JS::ExecutionContext> execution_context;
|
||||
|
||||
// A principal realm
|
||||
// The principal realm which this synthetic realm exists within.
|
||||
GC::Ref<JS::Realm> principal_realm;
|
||||
|
||||
// A module map
|
||||
// A module map that is used when importing JavaScript modules.
|
||||
GC::Ref<ModuleMap> module_map;
|
||||
|
||||
void visit_edges(JS::Cell::Visitor&);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -10,19 +10,24 @@
|
||||
namespace Web::HTML {
|
||||
|
||||
TemporaryExecutionContext::TemporaryExecutionContext(JS::Realm& realm, CallbacksEnabled callbacks_enabled)
|
||||
: m_realm(realm)
|
||||
: TemporaryExecutionContext(principal_realm_settings_object(realm), callbacks_enabled)
|
||||
{
|
||||
}
|
||||
|
||||
TemporaryExecutionContext::TemporaryExecutionContext(EnvironmentSettingsObject& settings, CallbacksEnabled callbacks_enabled)
|
||||
: m_settings(settings)
|
||||
, m_callbacks_enabled(callbacks_enabled)
|
||||
{
|
||||
prepare_to_run_script(m_realm);
|
||||
prepare_to_run_script(m_settings);
|
||||
if (m_callbacks_enabled == CallbacksEnabled::Yes)
|
||||
prepare_to_run_callback(m_realm);
|
||||
prepare_to_run_callback(m_settings);
|
||||
}
|
||||
|
||||
TemporaryExecutionContext::~TemporaryExecutionContext()
|
||||
{
|
||||
clean_up_after_running_script(m_realm);
|
||||
clean_up_after_running_script(m_settings);
|
||||
if (m_callbacks_enabled == CallbacksEnabled::Yes)
|
||||
clean_up_after_running_callback(m_realm);
|
||||
clean_up_after_running_callback(m_settings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <LibGC/Ptr.h>
|
||||
#include <LibWeb/Export.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
@@ -21,11 +22,12 @@ public:
|
||||
Yes,
|
||||
};
|
||||
|
||||
explicit TemporaryExecutionContext(EnvironmentSettingsObject&, CallbacksEnabled = CallbacksEnabled::No);
|
||||
explicit TemporaryExecutionContext(JS::Realm&, CallbacksEnabled = CallbacksEnabled::No);
|
||||
~TemporaryExecutionContext();
|
||||
|
||||
private:
|
||||
GC::Ref<JS::Realm> m_realm;
|
||||
GC::Ref<EnvironmentSettingsObject> m_settings;
|
||||
CallbacksEnabled m_callbacks_enabled { CallbacksEnabled::No };
|
||||
};
|
||||
|
||||
|
||||
@@ -47,8 +47,8 @@ WebIDL::ExceptionOr<GC::Ref<SharedWorker>> SharedWorker::construct_impl(JS::Real
|
||||
});
|
||||
|
||||
// 3. Let outside settings be this's relevant settings object.
|
||||
// FIXME: We don't have a `this` yet, so use the current principal settings object, as the previous spec did.
|
||||
auto& outside_settings = current_principal_settings_object();
|
||||
// FIXME: We don't have a `this` yet, so use the current settings object, as the previous spec did.
|
||||
auto& outside_settings = current_settings_object();
|
||||
|
||||
// 4. Let urlRecord be the result of encoding-parsing a URL given compliantScriptURL, relative to outsideSettings.
|
||||
auto url = outside_settings.encoding_parse_url(compliant_script_url.to_utf8_but_should_be_ported_to_utf16());
|
||||
|
||||
@@ -127,10 +127,10 @@ static WebIDL::ExceptionOr<void> serialize_array_buffer(JS::VM& vm, TransferData
|
||||
|
||||
// 1. If IsSharedArrayBuffer(value) is true, then:
|
||||
if (array_buffer.is_shared_array_buffer()) {
|
||||
// 1. If the current principal settings object's cross-origin isolated capability is false, then throw a "DataCloneError" DOMException.
|
||||
// 1. If the current settings object's cross-origin isolated capability is false, then throw a "DataCloneError" DOMException.
|
||||
// NOTE: This check is only needed when serializing (and not when deserializing) as the cross-origin isolated capability cannot change
|
||||
// over time and a SharedArrayBuffer cannot leave an agent cluster.
|
||||
if (current_principal_settings_object().cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::No)
|
||||
if (current_settings_object().cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::No)
|
||||
return WebIDL::DataCloneError::create(*vm.current_realm(), "Cannot serialize SharedArrayBuffer when cross-origin isolated"_utf16);
|
||||
|
||||
// 2. If forStorage is true, then throw a "DataCloneError" DOMException.
|
||||
@@ -264,7 +264,6 @@ public:
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal
|
||||
// https://whatpr.org/html/9893/structured-data.html#structuredserializeinternal
|
||||
WebIDL::ExceptionOr<SerializationRecord> serialize(JS::Value value)
|
||||
{
|
||||
TransferDataEncoder serialized;
|
||||
|
||||
@@ -1124,7 +1124,6 @@ GC::Ptr<WindowProxy const> Window::parent() const
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-frameelement
|
||||
// https://whatpr.org/html/9893/nav-history-apis.html#dom-frameelement
|
||||
GC::Ptr<DOM::Element const> Window::frame_element() const
|
||||
{
|
||||
// 1. Let current be this's node navigable.
|
||||
@@ -1141,8 +1140,8 @@ GC::Ptr<DOM::Element const> Window::frame_element() const
|
||||
if (!container)
|
||||
return {};
|
||||
|
||||
// 5. If container's node document's origin is not same origin-domain with the current principal settings object's origin, then return null.
|
||||
if (!container->document().origin().is_same_origin_domain(current_principal_settings_object().origin()))
|
||||
// 5. If container's node document's origin is not same origin-domain with the current settings object's origin, then return null.
|
||||
if (!container->document().origin().is_same_origin_domain(current_settings_object().origin()))
|
||||
return {};
|
||||
|
||||
// 6. Return container.
|
||||
|
||||
@@ -636,10 +636,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.
|
||||
}
|
||||
|
||||
// 8. Let script be the result of creating a classic script given handler, realm, base URL, and fetch options.
|
||||
// 8. Let script be the result of creating a classic script given handler, settings object, base URL, and fetch options.
|
||||
// FIXME: Pass fetch options.
|
||||
auto basename = base_url.basename();
|
||||
auto script = ClassicScript::create(basename, source, this_impl().realm(), move(base_url));
|
||||
auto script = ClassicScript::create(basename, source, settings_object, move(base_url));
|
||||
|
||||
// 9. Run the classic script script.
|
||||
(void)script->run();
|
||||
|
||||
@@ -162,8 +162,8 @@ JS::ThrowCompletionOr<JS::Value> WindowProxy::internal_get(JS::PropertyKey const
|
||||
|
||||
// 1. Let W be the value of the [[Window]] internal slot of this.
|
||||
|
||||
// 2. Check if an access between two browsing contexts should be reported, given the current principal global object's browsing context, W's browsing context, P, and the current principal settings object.
|
||||
check_if_access_between_two_browsing_contexts_should_be_reported(as<Window>(current_principal_global_object()).browsing_context(), m_window->browsing_context(), property_key, current_principal_settings_object());
|
||||
// 2. Check if an access between two browsing contexts should be reported, given the current global object's browsing context, W's browsing context, P, and the current settings object.
|
||||
check_if_access_between_two_browsing_contexts_should_be_reported(as<Window>(current_global_object()).browsing_context(), m_window->browsing_context(), property_key, current_settings_object());
|
||||
|
||||
// 3. If IsPlatformObjectSameOrigin(W) is true, then return ? OrdinaryGet(this, P, Receiver).
|
||||
// NOTE: this is passed rather than W as OrdinaryGet and CrossOriginGet will invoke the [[GetOwnProperty]] internal method.
|
||||
@@ -183,8 +183,8 @@ JS::ThrowCompletionOr<bool> WindowProxy::internal_set(JS::PropertyKey const& pro
|
||||
|
||||
// 1. Let W be the value of the [[Window]] internal slot of this.
|
||||
|
||||
// 2. Check if an access between two browsing contexts should be reported, given the current principal global object's browsing context, W's browsing context, P, and the current principal settings object.
|
||||
check_if_access_between_two_browsing_contexts_should_be_reported(as<Window>(current_principal_global_object()).browsing_context(), m_window->browsing_context(), property_key, current_principal_settings_object());
|
||||
// 2. Check if an access between two browsing contexts should be reported, given the current global object's browsing context, W's browsing context, P, and the current settings object.
|
||||
check_if_access_between_two_browsing_contexts_should_be_reported(as<Window>(current_global_object()).browsing_context(), m_window->browsing_context(), property_key, current_settings_object());
|
||||
|
||||
// 3. If IsPlatformObjectSameOrigin(W) is true, then:
|
||||
if (is_platform_object_same_origin(*m_window)) {
|
||||
|
||||
@@ -41,7 +41,6 @@ void Worker::visit_edges(Cell::Visitor& visitor)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#dom-worker
|
||||
// https://whatpr.org/html/9893/workers.html#dom-worker
|
||||
WebIDL::ExceptionOr<GC::Ref<Worker>> Worker::create(JS::Realm& realm, TrustedTypes::TrustedScriptURLOrString const& script_url, WorkerOptions const& options)
|
||||
{
|
||||
// Returns a new Worker object. scriptURL will be fetched and executed in the background,
|
||||
|
||||
@@ -97,7 +97,6 @@ void WorkerGlobalScope::close_a_worker()
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/workers.html#importing-scripts-and-libraries
|
||||
// https://whatpr.org/html/9893/workers.html#importing-scripts-and-libraries
|
||||
WebIDL::ExceptionOr<void> WorkerGlobalScope::import_scripts(Vector<String> const& urls, PerformTheFetchHook perform_fetch)
|
||||
{
|
||||
// The algorithm may optionally be customized by supplying custom perform the fetch hooks,
|
||||
@@ -106,8 +105,8 @@ WebIDL::ExceptionOr<void> WorkerGlobalScope::import_scripts(Vector<String> const
|
||||
|
||||
// FIXME: 1. If worker global scope's type is "module", throw a TypeError exception.
|
||||
|
||||
// 2. Let settings object be the current principal settings object.
|
||||
auto& settings_object = HTML::current_principal_settings_object();
|
||||
// 2. Let settings object be the current settings object.
|
||||
auto& settings_object = HTML::current_settings_object();
|
||||
|
||||
// 3. If urls is empty, return.
|
||||
if (urls.is_empty())
|
||||
|
||||
@@ -68,7 +68,7 @@ GC::Ptr<NavigationTiming::PerformanceNavigation> Performance::navigation()
|
||||
double Performance::time_origin() const
|
||||
{
|
||||
// The timeOrigin attribute MUST return the number of milliseconds in the duration returned by get time origin timestamp for the relevant global object of this.
|
||||
return get_time_origin_timestamp(HTML::relevant_principal_global_object(*this));
|
||||
return get_time_origin_timestamp(HTML::relevant_global_object(*this));
|
||||
}
|
||||
|
||||
// https://w3c.github.io/hr-time/#now-method
|
||||
|
||||
@@ -38,7 +38,7 @@ DOMHighResTimeStamp get_time_origin_timestamp(JS::Object const& global)
|
||||
{
|
||||
// To get time origin timestamp, given a global object global, run the following steps, which return a duration:
|
||||
// 1. Let timeOrigin be global's relevant settings object's time origin.
|
||||
auto time_origin = HTML::relevant_principal_settings_object(global).time_origin();
|
||||
auto time_origin = HTML::relevant_settings_object(global).time_origin();
|
||||
|
||||
// 2. Return the duration from the estimated monotonic time of the Unix epoch to timeOrigin.
|
||||
return time_origin - estimated_monotonic_time_of_the_unix_epoch();
|
||||
@@ -72,14 +72,10 @@ DOMHighResTimeStamp current_high_resolution_time(JS::Object const& global)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/hr-time/#dfn-relative-high-resolution-time
|
||||
// https://pr-preview.s3.amazonaws.com/w3c/hr-time/pull/168.html#dfn-relative-high-resolution-time
|
||||
DOMHighResTimeStamp relative_high_resolution_time(DOMHighResTimeStamp time, JS::Object const& global)
|
||||
{
|
||||
// 1. Let settings be the global's relevant principal settings object.
|
||||
auto& settings = HTML::relevant_principal_settings_object(global);
|
||||
|
||||
// 2. Let coarse time be the result of calling coarsen time with time and settings's cross-origin isolated capability.
|
||||
auto coarse_time = coarsen_time(time, settings.cross_origin_isolated_capability());
|
||||
// 1. Let coarse time be the result of calling coarsen time with time and global’s relevant settings object’s cross-origin isolated capability.
|
||||
auto coarse_time = coarsen_time(time, HTML::relevant_settings_object(global).cross_origin_isolated_capability());
|
||||
|
||||
// 2. Return the relative high resolution coarse time for coarse time and global.
|
||||
return relative_high_resolution_coarsen_time(coarse_time, global);
|
||||
@@ -89,7 +85,7 @@ DOMHighResTimeStamp relative_high_resolution_time(DOMHighResTimeStamp time, JS::
|
||||
DOMHighResTimeStamp relative_high_resolution_coarsen_time(DOMHighResTimeStamp coarsen_time, JS::Object const& global)
|
||||
{
|
||||
// The relative high resolution coarse time given a moment from the monotonic clock coarseTime and a global object global, is the duration from global's relevant settings object's time origin to coarseTime.
|
||||
auto time_origin = HTML::relevant_principal_settings_object(global).time_origin();
|
||||
auto time_origin = HTML::relevant_settings_object(global).time_origin();
|
||||
return coarsen_time - time_origin;
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ void Page::did_update_window_rect()
|
||||
template<typename ResponseType>
|
||||
static ResponseType spin_event_loop_until_dialog_closed(PageClient& client, Optional<ResponseType>& response, SourceLocation location = SourceLocation::current())
|
||||
{
|
||||
auto& event_loop = Web::HTML::current_principal_settings_object().responsible_event_loop();
|
||||
auto& event_loop = Web::HTML::current_settings_object().responsible_event_loop();
|
||||
auto pause_handle = event_loop.pause();
|
||||
|
||||
Web::Platform::EventLoopPlugin::the().spin_until(GC::create_function(event_loop.heap(), [&]() {
|
||||
|
||||
@@ -107,9 +107,9 @@ void ResizeObserver::disconnect()
|
||||
void ResizeObserver::invoke_callback(ReadonlySpan<GC::Ref<ResizeObserverEntry>> entries) const
|
||||
{
|
||||
auto& callback = *m_callback;
|
||||
auto& realm = callback.callback_context;
|
||||
auto& settings_object = callback.callback_context;
|
||||
|
||||
auto wrapped_records = MUST(JS::Array::create(realm, 0));
|
||||
auto wrapped_records = MUST(JS::Array::create(settings_object->realm(), 0));
|
||||
for (size_t i = 0; i < entries.size(); ++i) {
|
||||
auto& record = entries.at(i);
|
||||
auto property_index = JS::PropertyKey { i };
|
||||
|
||||
@@ -176,7 +176,7 @@ void SVGScriptElement::process_the_script_element()
|
||||
// Before any script execution occurs, the user agent must wait for scripts may run for the newly-created document to be true for document.
|
||||
VERIFY(m_document->ready_to_run_scripts());
|
||||
|
||||
m_script = HTML::ClassicScript::create(script_url.basename(), script_content, realm(), m_document->base_url(), m_source_line_number);
|
||||
m_script = HTML::ClassicScript::create(script_url.basename(), script_content, HTML::relevant_settings_object(*this), m_document->base_url(), m_source_line_number);
|
||||
|
||||
// FIXME: Note that a load event is dispatched on a 'script' element once it has been processed,
|
||||
// unless it referenced external script content with an invalid IRI reference and 'externalResourcesRequired' was set to 'true'.
|
||||
|
||||
@@ -30,11 +30,11 @@ PerformanceMark::~PerformanceMark() = default;
|
||||
// https://w3c.github.io/user-timing/#dfn-performancemark-constructor
|
||||
WebIDL::ExceptionOr<GC::Ref<PerformanceMark>> PerformanceMark::construct_impl(JS::Realm& realm, String const& mark_name, Web::UserTiming::PerformanceMarkOptions const& mark_options)
|
||||
{
|
||||
auto& current_principal_global_object = HTML::current_principal_global_object();
|
||||
auto& current_global_object = HTML::current_global_object();
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// 1. If the current global object is a Window object and markName uses the same name as a read only attribute in the PerformanceTiming interface, throw a SyntaxError.
|
||||
if (is<HTML::Window>(current_principal_global_object)) {
|
||||
if (is<HTML::Window>(current_global_object)) {
|
||||
bool matched = false;
|
||||
|
||||
#define __ENUMERATE_NAVIGATION_TIMING_ENTRY_NAME(name, _) \
|
||||
@@ -69,7 +69,7 @@ WebIDL::ExceptionOr<GC::Ref<PerformanceMark>> PerformanceMark::construct_impl(JS
|
||||
}
|
||||
// 2. Otherwise, set it to the value that would be returned by the Performance object's now() method.
|
||||
else {
|
||||
start_time = HighResolutionTime::current_high_resolution_time(current_principal_global_object);
|
||||
start_time = HighResolutionTime::current_high_resolution_time(current_global_object);
|
||||
}
|
||||
|
||||
// 6. Set entry's duration attribute to 0.
|
||||
|
||||
@@ -25,7 +25,7 @@ GC_DEFINE_ALLOCATOR(AudioContext);
|
||||
WebIDL::ExceptionOr<GC::Ref<AudioContext>> AudioContext::construct_impl(JS::Realm& realm, Optional<AudioContextOptions> const& context_options)
|
||||
{
|
||||
// If the current settings object’s responsible document is NOT fully active, throw an InvalidStateError and abort these steps.
|
||||
auto& settings = HTML::current_principal_settings_object();
|
||||
auto& settings = HTML::current_settings_object();
|
||||
|
||||
// FIXME: Not all settings objects currently return a responsible document.
|
||||
// Therefore we only fail this check if responsible document is not null.
|
||||
|
||||
@@ -216,7 +216,7 @@ WebIDL::ExceptionOr<void> BaseAudioContext::verify_audio_options_inside_nominal_
|
||||
|
||||
void BaseAudioContext::queue_a_media_element_task(GC::Ref<GC::Function<void()>> steps)
|
||||
{
|
||||
auto task = HTML::Task::create(vm(), m_media_element_event_task_source.source, HTML::current_principal_settings_object().responsible_document(), steps);
|
||||
auto task = HTML::Task::create(vm(), m_media_element_event_task_source.source, HTML::current_settings_object().responsible_document(), steps);
|
||||
(void)HTML::main_thread_event_loop().task_queue().add(task);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ static JS::ThrowCompletionOr<JS::Value> execute_a_function_body(HTML::BrowsingCo
|
||||
if (!rust_compilation.has_value() || rust_compilation->is_error())
|
||||
return JS::js_null();
|
||||
|
||||
// 6. Prepare to run a script with realm.
|
||||
HTML::prepare_to_run_script(realm);
|
||||
// 6. Prepare to run script with environment settings.
|
||||
HTML::prepare_to_run_script(environment_settings);
|
||||
|
||||
// 7. Prepare to run a callback with environment settings.
|
||||
HTML::prepare_to_run_callback(realm);
|
||||
HTML::prepare_to_run_callback(environment_settings);
|
||||
|
||||
// 8. Let function be the result of calling FunctionCreate.
|
||||
auto function = JS::ECMAScriptFunctionObject::create_from_function_data(
|
||||
@@ -82,10 +82,10 @@ static JS::ThrowCompletionOr<JS::Value> execute_a_function_body(HTML::BrowsingCo
|
||||
auto completion = JS::call(realm.vm(), *function, window, parameters);
|
||||
|
||||
// 10. Clean up after running a callback with environment settings.
|
||||
HTML::clean_up_after_running_callback(realm);
|
||||
HTML::clean_up_after_running_callback(environment_settings);
|
||||
|
||||
// 11. Clean up after running a script with realm.
|
||||
HTML::clean_up_after_running_script(realm);
|
||||
// 11. Clean up after running a script with environment settings.
|
||||
HTML::clean_up_after_running_script(environment_settings);
|
||||
|
||||
// 12. Return completion.
|
||||
return completion;
|
||||
|
||||
@@ -114,16 +114,15 @@ ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source)
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#call-user-object-operation-return
|
||||
// https://whatpr.org/webidl/1437.html#call-user-object-operation-return
|
||||
inline JS::Completion clean_up_on_return(JS::Realm& stored_realm, JS::Realm& relevant_realm, JS::Completion& completion, OperationReturnsPromise operation_returns_promise)
|
||||
inline JS::Completion clean_up_on_return(HTML::EnvironmentSettingsObject& stored_settings, HTML::EnvironmentSettingsObject& relevant_settings, JS::Completion& completion, OperationReturnsPromise operation_returns_promise)
|
||||
{
|
||||
// Return: at this point completion will be set to an ECMAScript completion value.
|
||||
|
||||
// 1. Clean up after running a callback with stored realm.
|
||||
HTML::clean_up_after_running_callback(stored_realm);
|
||||
// 1. Clean up after running a callback with stored settings.
|
||||
HTML::clean_up_after_running_callback(stored_settings);
|
||||
|
||||
// 2. Clean up after running script with relevant realm.
|
||||
HTML::clean_up_after_running_script(relevant_realm);
|
||||
// 2. Clean up after running script with relevant settings.
|
||||
HTML::clean_up_after_running_script(relevant_settings);
|
||||
|
||||
// 3. If completion is a normal completion, return completion.
|
||||
if (completion.type() == JS::Completion::Type::Normal)
|
||||
@@ -134,7 +133,7 @@ inline JS::Completion clean_up_on_return(JS::Realm& stored_realm, JS::Realm& rel
|
||||
return completion;
|
||||
|
||||
// 5. Let rejectedPromise be ! Call(%Promise.reject%, %Promise%, «completion.[[Value]]»).
|
||||
auto rejected_promise = create_rejected_promise(relevant_realm, completion.release_value());
|
||||
auto rejected_promise = create_rejected_promise(relevant_settings.realm(), completion.release_value());
|
||||
|
||||
// 6. Return the result of converting rejectedPromise to the operation’s return type.
|
||||
// Note: The operation must return a promise, so no conversion is necessary
|
||||
@@ -142,7 +141,6 @@ inline JS::Completion clean_up_on_return(JS::Realm& stored_realm, JS::Realm& rel
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#call-a-user-objects-operation
|
||||
// https://whatpr.org/webidl/1437.html#call-a-user-objects-operation
|
||||
JS::Completion call_user_object_operation(CallbackType& callback, Utf16FlyString const& operation_name, Optional<JS::Value> this_argument, ReadonlySpan<JS::Value> args)
|
||||
{
|
||||
// 1. Let completion be an uninitialized variable.
|
||||
@@ -155,22 +153,25 @@ JS::Completion call_user_object_operation(CallbackType& callback, Utf16FlyString
|
||||
// 3. Let O be the ECMAScript object corresponding to value.
|
||||
auto& object = callback.callback;
|
||||
|
||||
// 4. Let relevant realm be O’s associated Realm.
|
||||
auto& relevant_realm = object->shape().realm();
|
||||
// 4. Let realm be O’s associated realm.
|
||||
auto& realm = object->shape().realm();
|
||||
|
||||
// 5. Let stored realm be value’s callback context.
|
||||
auto& stored_realm = callback.callback_context;
|
||||
// 5. Let relevant settings be realm’s settings object.
|
||||
auto& relevant_settings = HTML::principal_realm_settings_object(realm);
|
||||
|
||||
// 6. Prepare to run script with relevant realm.
|
||||
HTML::prepare_to_run_script(relevant_realm);
|
||||
// 6. Let stored settings be value’s callback context.
|
||||
auto& stored_settings = callback.callback_context;
|
||||
|
||||
// 7. Prepare to run a callback with stored realm.
|
||||
HTML::prepare_to_run_callback(stored_realm);
|
||||
// 7. Prepare to run script with relevant settings.
|
||||
HTML::prepare_to_run_script(relevant_settings);
|
||||
|
||||
// 8. Let X be O.
|
||||
// 8. Prepare to run a callback with stored settings.
|
||||
HTML::prepare_to_run_callback(stored_settings);
|
||||
|
||||
// 9. Let X be O.
|
||||
auto actual_function_object = object;
|
||||
|
||||
// 9. If ! IsCallable(O) is false, then:
|
||||
// 10. If ! IsCallable(O) is false, then:
|
||||
if (!object->is_function()) {
|
||||
// 1. Let getResult be Get(O, opName).
|
||||
auto get_result = object->get(operation_name);
|
||||
@@ -178,13 +179,13 @@ JS::Completion call_user_object_operation(CallbackType& callback, Utf16FlyString
|
||||
// 2. If getResult is an abrupt completion, set completion to getResult and jump to the step labeled return.
|
||||
if (get_result.is_throw_completion()) {
|
||||
completion = get_result.throw_completion();
|
||||
return clean_up_on_return(stored_realm, relevant_realm, completion, callback.operation_returns_promise);
|
||||
return clean_up_on_return(stored_settings, relevant_settings, completion, callback.operation_returns_promise);
|
||||
}
|
||||
|
||||
// 4. If ! IsCallable(X) is false, then set completion to a new Completion{[[Type]]: throw, [[Value]]: a newly created TypeError object, [[Target]]: empty}, and jump to the step labeled return.
|
||||
if (!get_result.value().is_function()) {
|
||||
completion = relevant_realm.vm().template throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, get_result.value());
|
||||
return clean_up_on_return(stored_realm, relevant_realm, completion, callback.operation_returns_promise);
|
||||
completion = realm.vm().template throw_completion<JS::TypeError>(JS::ErrorType::NotAFunction, get_result.value());
|
||||
return clean_up_on_return(stored_settings, relevant_settings, completion, callback.operation_returns_promise);
|
||||
}
|
||||
|
||||
// 3. Set X to getResult.[[Value]].
|
||||
@@ -195,23 +196,23 @@ JS::Completion call_user_object_operation(CallbackType& callback, Utf16FlyString
|
||||
this_argument = object;
|
||||
}
|
||||
|
||||
// FIXME: 10. Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||
// FIXME: 11. Let esArgs be the result of converting args to an ECMAScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||
// For simplicity, we currently make the caller do this. However, this means we can't throw exceptions at this point like the spec wants us to.
|
||||
|
||||
// 11. Let callResult be Call(X, thisArg, esArgs).
|
||||
// 12. Let callResult be Call(X, thisArg, esArgs).
|
||||
auto call_result = JS::call(object->vm(), as<JS::FunctionObject>(*actual_function_object), this_argument.value(), args);
|
||||
|
||||
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||
// 13. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||
if (call_result.is_throw_completion()) {
|
||||
completion = call_result.throw_completion();
|
||||
return clean_up_on_return(stored_realm, relevant_realm, completion, callback.operation_returns_promise);
|
||||
return clean_up_on_return(stored_settings, relevant_settings, completion, callback.operation_returns_promise);
|
||||
}
|
||||
|
||||
// 13. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as the operation’s return type.
|
||||
// 14. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as the operation’s return type.
|
||||
// FIXME: This does no conversion.
|
||||
completion = call_result.value();
|
||||
|
||||
return clean_up_on_return(stored_realm, relevant_realm, completion, callback.operation_returns_promise);
|
||||
return clean_up_on_return(stored_settings, relevant_settings, completion, callback.operation_returns_promise);
|
||||
}
|
||||
|
||||
// https://webidl.spec.whatwg.org/#ref-for-idl-ByteString%E2%91%A7
|
||||
@@ -265,45 +266,48 @@ static auto invoke_callback_impl(CallbackType& callback, Optional<JS::Value> thi
|
||||
// 3. Let F be the ECMAScript object corresponding to callable.
|
||||
auto& function_object = callback.callback;
|
||||
|
||||
// 5. Let relevant realm be F’s associated realm.
|
||||
auto& relevant_realm = function_object->shape().realm();
|
||||
// 5. Let realm be F’s associated realm.
|
||||
auto& realm = function_object->shape().realm();
|
||||
|
||||
// 6. Let relevant settings be realm’s settings object.
|
||||
auto& relevant_settings = HTML::principal_realm_settings_object(realm);
|
||||
|
||||
// 4. If ! IsCallable(F) is false:
|
||||
if (!function_object->is_function()) {
|
||||
// 1. Note: This is only possible when the callback function came from an attribute marked with [LegacyTreatNonObjectAsNull].
|
||||
|
||||
// 2. Return the result of converting undefined to the callback function’s return type.
|
||||
return return_steps(relevant_realm, JS::js_undefined());
|
||||
return return_steps(realm, JS::js_undefined());
|
||||
}
|
||||
|
||||
// 6. Let stored realm be callable’s callback context.
|
||||
auto& stored_realm = callback.callback_context;
|
||||
// 7. Let stored settings be callable’s callback context.
|
||||
auto& stored_settings = callback.callback_context;
|
||||
|
||||
// 7. Prepare to run script with relevant realm.
|
||||
HTML::prepare_to_run_script(relevant_realm);
|
||||
// 8. Prepare to run script with relevant realm.
|
||||
HTML::prepare_to_run_script(relevant_settings);
|
||||
|
||||
// 8. Prepare to run a callback with stored realm.
|
||||
HTML::prepare_to_run_callback(stored_realm);
|
||||
// 9. Prepare to run a callback with stored realm.
|
||||
HTML::prepare_to_run_callback(stored_settings);
|
||||
|
||||
// FIXME: 9. Let jsArgs be the result of converting args to a JavaScript arguments list.
|
||||
// If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||
// FIXME: 10. Let jsArgs be the result of converting args to a JavaScript arguments list.
|
||||
// If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||
|
||||
// 10. Let callResult be Call(F, thisArg, jsArgs).
|
||||
// 11. Let callResult be Call(F, thisArg, jsArgs).
|
||||
auto call_result = JS::call(function_object->vm(), as<JS::FunctionObject>(*function_object), this_argument.value(), args);
|
||||
|
||||
// 11. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||
// 12. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as callable’s
|
||||
// 12. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||
// 13. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as callable’s
|
||||
// return type. If this throws an exception, set completion to the completion value representing the thrown exception.
|
||||
// 13. Return: at this point completion will be set to an IDL value or an abrupt completion.
|
||||
// 14. Return: at this point completion will be set to an IDL value or an abrupt completion.
|
||||
{
|
||||
// 1. Clean up after running a callback with stored realm.
|
||||
HTML::clean_up_after_running_callback(stored_realm);
|
||||
// 1. Clean up after running a callback with stored settings.
|
||||
HTML::clean_up_after_running_callback(stored_settings);
|
||||
|
||||
// 2. Clean up after running script with relevant realm.
|
||||
// 2. Clean up after running script with relevant settings.
|
||||
// FIXME: This method follows an older version of the spec, which takes a realm, so we use F's associated realm instead.
|
||||
HTML::clean_up_after_running_script(relevant_realm);
|
||||
HTML::clean_up_after_running_script(relevant_settings);
|
||||
|
||||
return return_steps(relevant_realm, move(call_result));
|
||||
return return_steps(realm, move(call_result));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,31 +395,34 @@ JS::Completion construct(CallbackType& callable, ReadonlySpan<JS::Value> args)
|
||||
auto& function_object = callable.callback;
|
||||
|
||||
// 3. If IsConstructor(F) is false, throw a TypeError exception.
|
||||
// 4. Let relevant realm be F’s associated realm.
|
||||
auto& relevant_realm = function_object->shape().realm();
|
||||
// 4. Let realm be F’s associated realm.
|
||||
auto& realm = function_object->shape().realm();
|
||||
if (!JS::Value(function_object).is_constructor())
|
||||
return relevant_realm.vm().template throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, JS::Value(function_object));
|
||||
return realm.vm().template throw_completion<JS::TypeError>(JS::ErrorType::NotAConstructor, JS::Value(function_object));
|
||||
|
||||
// 5. Let stored realm be callable’s callback context.
|
||||
auto& stored_realm = callable.callback_context;
|
||||
// 5. Let relevant settings be realm’s settings object.
|
||||
auto& relevant_settings = HTML::principal_realm_settings_object(realm);
|
||||
|
||||
// 6. Prepare to run script with relevant realm.
|
||||
HTML::prepare_to_run_script(relevant_realm);
|
||||
// 6. Let stored settings be callable’s callback context.
|
||||
auto& stored_settings = callable.callback_context;
|
||||
|
||||
// 7. Prepare to run a callback with stored realm.
|
||||
HTML::prepare_to_run_callback(stored_realm);
|
||||
// 7. Prepare to run script with relevant settings.
|
||||
HTML::prepare_to_run_script(relevant_settings);
|
||||
|
||||
// FIXME: 8. Let jsArgs be the result of converting args to a JavaScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||
// 8. Prepare to run a callback with stored settings.
|
||||
HTML::prepare_to_run_callback(stored_settings);
|
||||
|
||||
// FIXME: 9. Let jsArgs be the result of converting args to a JavaScript arguments list. If this throws an exception, set completion to the completion value representing the thrown exception and jump to the step labeled return.
|
||||
// For simplicity, we currently make the caller do this. However, this means we can't throw exceptions at this point like the spec wants us to.
|
||||
|
||||
// 9. Let callResult be Completion(Construct(F, jsArgs)).
|
||||
// 10. Let callResult be Completion(Construct(F, jsArgs)).
|
||||
auto call_result = JS::construct(function_object->vm(), as<JS::FunctionObject>(*function_object), args);
|
||||
|
||||
// 10. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||
// 11. If callResult is an abrupt completion, set completion to callResult and jump to the step labeled return.
|
||||
if (call_result.is_throw_completion()) {
|
||||
completion = call_result.throw_completion();
|
||||
}
|
||||
// 11. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as
|
||||
// 12. Set completion to the result of converting callResult.[[Value]] to an IDL value of the same type as
|
||||
// callable’s return type.
|
||||
// If this throws an exception, set completion to the completion value representing the thrown exception.
|
||||
else {
|
||||
@@ -423,13 +430,13 @@ JS::Completion construct(CallbackType& callable, ReadonlySpan<JS::Value> args)
|
||||
completion = JS::Value(call_result.value());
|
||||
}
|
||||
|
||||
// 12. Return: at this point completion will be set to an IDL value or an abrupt completion.
|
||||
// 13. Return: at this point completion will be set to an IDL value or an abrupt completion.
|
||||
{
|
||||
// 1. Clean up after running a callback with stored realm.
|
||||
HTML::clean_up_after_running_callback(stored_realm);
|
||||
// 1. Clean up after running a callback with stored settings.
|
||||
HTML::clean_up_after_running_callback(stored_settings);
|
||||
|
||||
// 2. Clean up after running script with relevant realm.
|
||||
HTML::clean_up_after_running_script(relevant_realm);
|
||||
// 2. Clean up after running script with relevant settings.
|
||||
HTML::clean_up_after_running_script(relevant_settings);
|
||||
|
||||
// 3. If completion is an abrupt completion, throw completion.[[Value]].
|
||||
if (completion.is_abrupt())
|
||||
|
||||
@@ -13,13 +13,18 @@ namespace Web::WebIDL {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(CallbackType);
|
||||
|
||||
CallbackType::CallbackType(JS::Object& callback, JS::Realm& callback_context, OperationReturnsPromise operation_returns_promise)
|
||||
CallbackType::CallbackType(JS::Object& callback, HTML::EnvironmentSettingsObject& callback_context, OperationReturnsPromise operation_returns_promise)
|
||||
: callback(callback)
|
||||
, callback_context(callback_context)
|
||||
, operation_returns_promise(operation_returns_promise)
|
||||
{
|
||||
}
|
||||
|
||||
CallbackType::CallbackType(JS::Object& callback, JS::Realm& callback_context, OperationReturnsPromise operation_returns_promise)
|
||||
: CallbackType(callback, HTML::principal_realm_settings_object(callback_context), operation_returns_promise)
|
||||
{
|
||||
}
|
||||
|
||||
void CallbackType::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
||||
@@ -24,13 +24,13 @@ class CallbackType final : public JS::Cell {
|
||||
GC_DECLARE_ALLOCATOR(CallbackType);
|
||||
|
||||
public:
|
||||
CallbackType(JS::Object& callback, HTML::EnvironmentSettingsObject& callback_context, OperationReturnsPromise = OperationReturnsPromise::No);
|
||||
CallbackType(JS::Object& callback, JS::Realm& callback_context, OperationReturnsPromise = OperationReturnsPromise::No);
|
||||
|
||||
GC::Ref<JS::Object> callback;
|
||||
|
||||
// https://webidl.spec.whatwg.org/#dfn-callback-context
|
||||
// NOTE: This is a Realm per ShadowRealm proposal https://github.com/whatwg/webidl/pull/1437
|
||||
GC::Ref<JS::Realm> callback_context;
|
||||
GC::Ref<HTML::EnvironmentSettingsObject> callback_context;
|
||||
|
||||
// Non-standard property used to distinguish Promise-returning callbacks in callback-related AOs
|
||||
OperationReturnsPromise operation_returns_promise;
|
||||
|
||||
@@ -205,7 +205,7 @@ ErrorOr<void> WebSocket::establish_web_socket_connection(URL::URL const& url_rec
|
||||
auto additional_headers = HTTP::HeaderList::create();
|
||||
|
||||
auto cookies = ([&] {
|
||||
auto& page = Bindings::principal_host_defined_page(HTML::principal_realm(realm()));
|
||||
auto& page = Bindings::principal_host_defined_page(realm());
|
||||
return page.client().page_did_request_cookie(url_record, HTTP::Cookie::Source::Http).cookie;
|
||||
})();
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ WebIDL::ExceptionOr<GC::Ptr<DOM::Document>> XMLHttpRequest::response_xml()
|
||||
WebIDL::ExceptionOr<void> XMLHttpRequest::set_response_type(Bindings::XMLHttpRequestResponseType response_type)
|
||||
{
|
||||
// 1. If the current global object is not a Window object and the given value is "document", then return.
|
||||
if (!is<HTML::Window>(HTML::current_principal_global_object()) && response_type == Bindings::XMLHttpRequestResponseType::Document)
|
||||
if (!is<HTML::Window>(HTML::current_global_object()) && response_type == Bindings::XMLHttpRequestResponseType::Document)
|
||||
return {};
|
||||
|
||||
// 2. If this’s state is loading or done, then throw an "InvalidStateError" DOMException.
|
||||
@@ -166,7 +166,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::set_response_type(Bindings::XMLHttpReq
|
||||
return WebIDL::InvalidStateError::create(realm(), "Can't readyState when XHR is loading or done"_utf16);
|
||||
|
||||
// 3. If the current global object is a Window object and this’s synchronous flag is set, then throw an "InvalidAccessError" DOMException.
|
||||
if (is<HTML::Window>(HTML::current_principal_global_object()) && m_synchronous)
|
||||
if (is<HTML::Window>(HTML::current_global_object()) && m_synchronous)
|
||||
return WebIDL::InvalidAccessError::create(realm(), "Can't set readyState on synchronous XHR in Window environment"_utf16);
|
||||
|
||||
// 4. Set this’s response type to the given value.
|
||||
@@ -490,7 +490,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::open(String const& method, String cons
|
||||
// 9. If async is false, the current global object is a Window object, and either this’s timeout is
|
||||
// not 0 or this’s response type is not the empty string, then throw an "InvalidAccessError" DOMException.
|
||||
if (!async
|
||||
&& is<HTML::Window>(HTML::current_principal_global_object())
|
||||
&& is<HTML::Window>(HTML::current_global_object())
|
||||
&& (m_timeout != 0 || m_response_type != Bindings::XMLHttpRequestResponseType::Empty)) {
|
||||
return WebIDL::InvalidAccessError::create(realm(), "Synchronous XMLHttpRequests in a Window context do not support timeout or a non-empty responseType"_utf16);
|
||||
}
|
||||
@@ -949,7 +949,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(NullableDocumentOrXMLHttpRequestB
|
||||
}
|
||||
|
||||
// 7. Report timing for this’s fetch controller given the current global object.
|
||||
m_fetch_controller->report_timing(HTML::current_principal_global_object());
|
||||
m_fetch_controller->report_timing(HTML::current_global_object());
|
||||
|
||||
// 8. Run handle response end-of-body for this.
|
||||
TRY(handle_response_end_of_body());
|
||||
@@ -1039,7 +1039,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::set_timeout(u32 timeout)
|
||||
{
|
||||
// 1. If the current global object is a Window object and this’s synchronous flag is set,
|
||||
// then throw an "InvalidAccessError" DOMException.
|
||||
if (is<HTML::Window>(HTML::current_principal_global_object()) && m_synchronous)
|
||||
if (is<HTML::Window>(HTML::current_global_object()) && m_synchronous)
|
||||
return WebIDL::InvalidAccessError::create(realm(), "Use of XMLHttpRequest's timeout attribute is not supported in the synchronous mode in window context."_utf16);
|
||||
|
||||
// 2. Set this’s timeout to the given value.
|
||||
|
||||
@@ -2908,7 +2908,7 @@ static void generate_html_constructor(SourceGenerator& generator, IDL::Construct
|
||||
}
|
||||
|
||||
constructor_generator.append(R"~~~(
|
||||
auto& window = as<HTML::Window>(HTML::current_principal_global_object());
|
||||
auto& window = as<HTML::Window>(HTML::current_global_object());
|
||||
|
||||
// 1. If NewTarget is equal to the active function object, then throw a TypeError.
|
||||
if (&new_target == vm.active_function_object())
|
||||
|
||||
@@ -433,7 +433,7 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global)
|
||||
{
|
||||
static constexpr u8 attr = JS::Attribute::Writable | JS::Attribute::Configurable;
|
||||
|
||||
[[maybe_unused]] bool is_secure_context = HTML::is_secure_context(HTML::relevant_principal_settings_object(global));
|
||||
[[maybe_unused]] bool is_secure_context = HTML::is_secure_context(HTML::relevant_settings_object(global));
|
||||
[[maybe_unused]] bool expose_experimental_interfaces = HTML::UniversalGlobalScopeMixin::expose_experimental_interfaces();
|
||||
)~~~");
|
||||
|
||||
|
||||
@@ -887,10 +887,10 @@ void PageClient::run_javascript(StringView 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, setting's realm, baseURL, and the default classic script fetch options.
|
||||
// Let script be the result of creating a classic script given scriptSource, settings, 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.realm(), move(base_url));
|
||||
auto script = Web::HTML::ClassicScript::create("(client connection run_javascript)", js_source, settings, move(base_url));
|
||||
|
||||
// Let evaluationStatus be the result of running the classic script script.
|
||||
auto evaluation_status = script->run();
|
||||
|
||||
@@ -41,7 +41,7 @@ void WebContentConsoleClient::visit_edges(JS::Cell::Visitor& visitor)
|
||||
void WebContentConsoleClient::handle_input(StringView js_source)
|
||||
{
|
||||
auto& settings = Web::HTML::relevant_settings_object(*m_console_global_environment_extensions);
|
||||
auto script = Web::HTML::ClassicScript::create("(console)", js_source, settings.realm(), settings.api_base_url());
|
||||
auto script = Web::HTML::ClassicScript::create("(console)", js_source, settings, settings.api_base_url());
|
||||
|
||||
auto with_scope = JS::new_object_environment(*m_console_global_environment_extensions, true, &settings.realm().global_environment());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user