From c51cf663476428a8c1af69d6c7d911c37546ba7c Mon Sep 17 00:00:00 2001 From: networkException Date: Mon, 3 Oct 2022 21:06:00 +0200 Subject: [PATCH] LibWeb: Implement two module related host hooks This patch adds support for the HostGetSupportedImportAssertions and HostResolveImportedModule host hooks. Co-authored-by: davidot --- .../LibWeb/Bindings/MainThreadVM.cpp | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 8d15543ac4f..861d912f96d 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2021-2022, Andreas Kling * Copyright (c) 2021, Luke Wilde + * Copyright (c) 2022, networkException * * SPDX-License-Identifier: BSD-2-Clause */ @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -306,10 +308,60 @@ JS::VM& main_thread_vm() // FIXME: Implement 8.1.5.5.1 HostGetImportMetaProperties(moduleRecord), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetimportmetaproperties // FIXME: Implement 8.1.5.5.2 HostImportModuleDynamically(referencingScriptOrModule, moduleRequest, promiseCapability), https://html.spec.whatwg.org/multipage/webappapis.html#hostimportmoduledynamically(referencingscriptormodule,-modulerequest,-promisecapability) // FIXME: Implement 8.1.5.5.3 HostResolveImportedModule(referencingScriptOrModule, moduleRequest), https://html.spec.whatwg.org/multipage/webappapis.html#hostresolveimportedmodule(referencingscriptormodule,-modulerequest) - // FIXME: Implement 8.1.5.5.4 HostGetSupportedImportAssertions(), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetsupportedimportassertions - vm->host_resolve_imported_module = [](JS::ScriptOrModule, JS::ModuleRequest const&) -> JS::ThrowCompletionOr> { - return vm->throw_completion(JS::ErrorType::NotImplemented, "Modules in the browser"); + // 8.1.5.5.4 HostGetSupportedImportAssertions(), https://html.spec.whatwg.org/multipage/webappapis.html#hostgetsupportedimportassertions + vm->host_get_supported_import_assertions = []() -> Vector { + // 1. Return « "type" ». + return { "type"sv }; + }; + + // 8.1.5.5.3 HostResolveImportedModule(referencingScriptOrModule, moduleRequest), https://html.spec.whatwg.org/multipage/webappapis.html#hostresolveimportedmodule(referencingscriptormodule,-modulerequest) + vm->host_resolve_imported_module = [](JS::ScriptOrModule const& referencing_string_or_module, JS::ModuleRequest const& module_request) -> JS::ThrowCompletionOr> { + // 1. Let settings object be the current settings object. + auto* settings_object = &HTML::current_settings_object(); + + // 2. Let base URL be settings object's API base URL. + auto base_url = settings_object->api_base_url(); + + // 3. If referencingScriptOrModule is not null, then: + if (!referencing_string_or_module.has()) { + // 1. Let referencing script be referencingScriptOrModule.[[HostDefined]]. + auto const& referencing_script = verify_cast(referencing_string_or_module.has>() ? referencing_string_or_module.get>()->host_defined() : referencing_string_or_module.get>()->host_defined()); + + // 2. Set settings object to referencing script's settings object. + settings_object = &referencing_script->settings_object(); + + // 3. Set base URL to referencing script's base URL. + base_url = referencing_script->base_url(); + + // 4. Assert: base URL is not null, as referencing script is a classic script or a JavaScript module script. + VERIFY(base_url.is_valid()); + } + + // 4. Let moduleMap be settings object's module map. + auto& module_map = settings_object->module_map(); + + // 5. Let url be the result of resolving a module specifier given base URL and moduleRequest.[[Specifier]]. + auto url = HTML::resolve_module_specifier(module_request, base_url); + + // 6. Assert: url is never failure, because resolving a module specifier must have been previously successful + // with these same two arguments (either while creating the corresponding module script, or in fetch an import() module script graph). + VERIFY(url.is_valid()); + + // 7. 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); + + // 8. Let resolved module script be moduleMap[(url, moduleType)]. (This entry must exist for us to have gotten to this point.) + auto resolved_module = module_map.get(url, module_type).value(); + + // 9. Assert: resolved module script is a module script (i.e., is not null or "fetching"). + VERIFY(resolved_module.type == HTML::ModuleMap::EntryType::ModuleScript); + + // 10. Assert: resolved module script's record is not null. + VERIFY(resolved_module.module_script->record()); + + // 11. Return resolved module script's record. + return JS::NonnullGCPtr(*resolved_module.module_script->record()); }; // NOTE: We push a dummy execution context onto the JS execution context stack,