diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 0b8211b45be..2b35cc62c2e 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -235,26 +235,25 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type 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, JS::create_heap_function(s_main_thread_vm->heap(), [&finalization_registry] { - // FIXME: 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]'s environment settings object. - auto& realm = *finalization_registry.cleanup_callback().callback().realm(); - auto& entry = host_defined_environment_settings_object(realm); + // 1. Let entry be finalizationRegistry.[[CleanupCallback]].[[Callback]].[[Realm]]. + auto& entry = *finalization_registry.cleanup_callback().callback().realm(); // 2. Check if we can run script with entry. If this returns "do not run", then return. - if (HTML::can_run_script(realm) == HTML::RunScriptDecision::DoNotRun) + if (HTML::can_run_script(entry) == HTML::RunScriptDecision::DoNotRun) return; // 3. Prepare to run script with entry. - entry.prepare_to_run_script(); + HTML::prepare_to_run_script(entry); // 4. Let result be the result of performing CleanupFinalizationRegistry(finalizationRegistry). auto result = finalization_registry.cleanup(); // 5. Clean up after running script with entry. - HTML::clean_up_after_running_script(realm); + HTML::clean_up_after_running_script(entry); // 6. If result is an abrupt completion, then report the exception given by result.[[Value]]. if (result.is_error()) - HTML::report_exception(result, finalization_registry.realm()); + HTML::report_exception(result, entry); })); }; @@ -286,8 +285,8 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) if (HTML::can_run_script(*realm) == HTML::RunScriptDecision::DoNotRun) return; - // FIXME: 2. If realm is not null, then prepare to run script with realm. - job_settings->prepare_to_run_script(); + // 2. If realm is not null, then prepare to run script with realm. + HTML::prepare_to_run_script(*realm); // 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() diff --git a/Userland/Libraries/LibWeb/HTML/Navigation.cpp b/Userland/Libraries/LibWeb/HTML/Navigation.cpp index 9d55a7a093b..4e8aa8b0789 100644 --- a/Userland/Libraries/LibWeb/HTML/Navigation.cpp +++ b/Userland/Libraries/LibWeb/HTML/Navigation.cpp @@ -1402,6 +1402,7 @@ 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(JS::NonnullGCPtr destination_she, Bindings::NavigationType navigation_type) { auto& realm = relevant_realm(*this); @@ -1482,8 +1483,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 settings object. - relevant_settings_object(*this).prepare_to_run_script(); + // 9. Prepare to run script given navigation's relevant realm. + prepare_to_run_script(realm); // 10. Fire an event named currententrychange at navigation using NavigationCurrentEntryChangeEvent, // with its navigationType attribute initialized to navigationType and its from initialized to oldCurrentNHE. diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp index 22fb2539935..cd8994e97c1 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ClassicScript.cpp @@ -88,8 +88,8 @@ JS::Completion ClassicScript::run(RethrowErrors rethrow_errors) if (can_run_script(realm) == RunScriptDecision::DoNotRun) return JS::normal_completion({}); - // 3. Prepare to run script given settings. - settings.prepare_to_run_script(); + // 3. Prepare to run script given realm. + prepare_to_run_script(realm); // 4. Let evaluationStatus be null. JS::Completion evaluation_status; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp index 90f958f2f55..28d25d7b396 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp @@ -123,12 +123,15 @@ RunScriptDecision can_run_script(JS::Realm const& realm) } // https://html.spec.whatwg.org/multipage/webappapis.html#prepare-to-run-script -void EnvironmentSettingsObject::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) { - // 1. Push settings's realm execution context onto the JavaScript execution context stack; it is now the running JavaScript execution context. - global_object().vm().push_execution_context(realm_execution_context()); + // 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)); - // FIXME: 2. Add settings to the currently running task's script evaluation environment settings object set. + // 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 diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h index 54ce9c35257..97fc36567df 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h @@ -96,8 +96,6 @@ public: // https://fetch.spec.whatwg.org/#concept-fetch-group Vector>& fetch_group() { return m_fetch_group; } - void prepare_to_run_script(); - void prepare_to_run_callback(); void clean_up_after_running_callback(); @@ -137,10 +135,12 @@ private: }; JS::ExecutionContext const& execution_context_of_realm(JS::Realm const&); +inline JS::ExecutionContext& execution_context_of_realm(JS::Realm& realm) { return const_cast(execution_context_of_realm(const_cast(realm))); } 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&); EnvironmentSettingsObject& incumbent_settings_object(); diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp index c74c81cf456..ebbdf984f6a 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleScript.cpp @@ -133,8 +133,8 @@ JS::Promise* JavaScriptModuleScript::run(PreventErrorReporting) return promise; } - // 3. Prepare to run script given settings. - settings.prepare_to_run_script(); + // 3. Prepare to run script given realm. + prepare_to_run_script(realm); // 4. Let evaluationPromise be null. JS::Promise* evaluation_promise = nullptr; diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp index 45879133692..23e6e7bd94e 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/Scripting/TemporaryExecutionContext.cpp @@ -13,7 +13,7 @@ TemporaryExecutionContext::TemporaryExecutionContext(EnvironmentSettingsObject& : m_environment_settings(environment_settings) , m_callbacks_enabled(callbacks_enabled) { - m_environment_settings->prepare_to_run_script(); + prepare_to_run_script(m_environment_settings->realm()); if (m_callbacks_enabled == CallbacksEnabled::Yes) m_environment_settings->prepare_to_run_callback(); } diff --git a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp index e65be7ef0dc..caf683547b9 100644 --- a/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp +++ b/Userland/Libraries/LibWeb/HTML/StructuredSerialize.cpp @@ -1305,8 +1305,7 @@ WebIDL::ExceptionOr structured_deserialize(JS::VM& vm, SerializationR memory = DeserializationMemory { vm.heap() }; // IMPLEMENTATION DEFINED: We need to make sure there's an execution context for target_realm on the stack before constructing these JS objects - auto& target_settings = Bindings::host_defined_environment_settings_object(target_realm); - target_settings.prepare_to_run_script(); + prepare_to_run_script(target_realm); auto result = TRY(structured_deserialize_internal(vm, serialized.span(), target_realm, *memory)); diff --git a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index 49ead9af035..72e1767b92a 100644 --- a/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Userland/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -279,8 +279,8 @@ JS::ThrowCompletionOr execute_a_function_body(HTML::Window const& win // 5. If body begins with a directive prologue that contains a use strict directive then let strict be true, otherwise let strict be false. // NOTE: Handled in step 8 below. - // 6. Prepare to run a script with environment settings. - environment_settings.prepare_to_run_script(); + // 6. Prepare to run a script with realm. + HTML::prepare_to_run_script(realm); // 7. Prepare to run a callback with environment settings. environment_settings.prepare_to_run_callback(); diff --git a/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp b/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp index a69d944bd89..9d2c9c3cce3 100644 --- a/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp +++ b/Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp @@ -131,6 +131,8 @@ inline JS::Completion clean_up_on_return(HTML::EnvironmentSettingsObject& stored return JS::Value { rejected_promise->promise() }; } +// 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(WebIDL::CallbackType& callback, String const& operation_name, Optional this_argument, JS::MarkedVector args) { // 1. Let completion be an uninitialized variable. @@ -143,17 +145,17 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String // 3. Let O be the ECMAScript object corresponding to value. auto& object = callback.callback; - // 4. Let realm be O’s associated Realm. - auto& realm = object->shape().realm(); + // 4. Let relevant realm be O’s associated Realm. + auto& relevant_realm = object->shape().realm(); - // 5. Let relevant settings be realm’s settings object. - auto& relevant_settings = Bindings::host_defined_environment_settings_object(realm); + // 5. Let relevant settings be relvant realm’s settings object. + auto& relevant_settings = Bindings::host_defined_environment_settings_object(relevant_realm); // 6. Let stored settings be value’s callback context. auto& stored_settings = callback.callback_context; - // 7. Prepare to run script with relevant settings. - relevant_settings.prepare_to_run_script(); + // 7. Prepare to run script with relevant realm. + HTML::prepare_to_run_script(relevant_realm); // 8. Prepare to run a callback with stored settings. stored_settings->prepare_to_run_callback(); @@ -174,7 +176,7 @@ JS::Completion call_user_object_operation(WebIDL::CallbackType& callback, String // 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 = realm.vm().template throw_completion(JS::ErrorType::NotAFunction, get_result.value().to_string_without_side_effects()); + completion = relevant_realm.vm().template throw_completion(JS::ErrorType::NotAFunction, get_result.value().to_string_without_side_effects()); return clean_up_on_return(stored_settings, relevant_settings, completion, callback.operation_returns_promise); } @@ -240,7 +242,7 @@ JS::Completion invoke_callback(WebIDL::CallbackType& callback, Optionalprepare_to_run_callback(); @@ -281,13 +283,13 @@ JS::Completion construct(WebIDL::CallbackType& callback, JS::MarkedVector(JS::ErrorType::NotAConstructor, JS::Value(function_object).to_string_without_side_effects()); // 5. Let relevant settings be realm’s settings object. - auto& relevant_settings = Bindings::host_defined_environment_settings_object(realm); + // NOTE: Not needed after ShadowRealm implementation. // 6. Let stored settings be callable’s callback context. auto& stored_settings = callback.callback_context; // 7. Prepare to run script with relevant settings. - relevant_settings.prepare_to_run_script(); + HTML::prepare_to_run_script(realm); // 8. Prepare to run a callback with stored settings. stored_settings->prepare_to_run_callback();