Skip to content
Permalink
Browse files
Implement import.meta.resolve()
https://bugs.webkit.org/show_bug.cgi?id=242163
rdar://96569044

Reviewed by Alexey Shvayka.

This patch implements import.meta.resolve[1], which exposes module specifier resolving feature through import.meta object.

[1]: https://whatpr.org/html/5572/webappapis.html#hostgetimportmetaproperties

* LayoutTests/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-multiple-scripts-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve.any.serviceworker-module-expected.txt:
* Source/WebCore/bindings/js/ScriptModuleLoader.cpp:
(WebCore::ScriptModuleLoader::createImportMetaProperties):

Canonical link: https://commits.webkit.org/254691@main
  • Loading branch information
Constellation committed Sep 20, 2022
1 parent 9c06eb3 commit 78c6d6d7b596a5953915f8066a5e75d19eda8411
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 11 deletions.
@@ -646,6 +646,7 @@ imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/mo
imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html [ Skip ]
imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html [ Skip ]
imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html [ Skip ]
imported/w3c/web-platform-tests/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html [ Skip ]
imported/w3c/web-platform-tests/html/user-activation/activation-trigger-keyboard-enter.html [ Skip ]
imported/w3c/web-platform-tests/html/user-activation/activation-trigger-keyboard-escape.html [ Skip ]
imported/w3c/web-platform-tests/html/user-activation/activation-trigger-mouse-left.html [ Skip ]
@@ -1,6 +1,6 @@

FAIL import.meta.resolve() given an import mapped bare specifier import.meta.resolve is not a function. (In 'import.meta.resolve("bare")', 'import.meta.resolve' is undefined)
FAIL import.meta.resolve() given an import mapped URL-like specifier import.meta.resolve is not a function. (In 'import.meta.resolve("https://example.com/rewrite")', 'import.meta.resolve' is undefined)
FAIL Testing the ToString() step of import.meta.resolve() via import maps import.meta.resolve is not a function. (In 'import.meta.resolve()', 'import.meta.resolve' is undefined)
FAIL import.meta.resolve() given an import mapped bare specifier Module specifier, 'bare' does not start with "/", "./", or "../". Referenced from http://localhost:8800/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html
FAIL import.meta.resolve() given an import mapped URL-like specifier assert_equals: expected "https://example.com/rewritten" but got "https://example.com/rewrite"
FAIL Testing the ToString() step of import.meta.resolve() via import maps Module specifier, 'undefined' does not start with "/", "./", or "../". Referenced from http://localhost:8800/html/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html
FAIL import(import.meta.resolve(x)) can be different from import(x) promise_test: Unhandled rejection with value: object "TypeError: Importing a module script failed."

@@ -1,5 +1,5 @@

FAIL import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another global's inline script frames[0].importMetaResolve is not a function. (In 'frames[0].importMetaResolve("./x")', 'frames[0].importMetaResolve' is undefined)
FAIL import.meta.resolve still works if its global has been destroyed (by detaching the iframe) otherFrameImportMetaResolve is not a function. (In 'otherFrameImportMetaResolve("./x")', 'otherFrameImportMetaResolve' is undefined)
FAIL import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another module script otherImportMeta.resolve is not a function. (In 'otherImportMeta.resolve("./x")', 'otherImportMeta.resolve' is undefined)
PASS import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another global's inline script
PASS import.meta.resolve still works if its global has been destroyed (by detaching the iframe)
PASS import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another module script

@@ -1,9 +1,9 @@

FAIL import.meta.resolve is a function with the right properties assert_equals: expected "function" but got "undefined"
PASS import.meta.resolve is a function with the right properties
PASS import.meta.resolve is not a constructor
FAIL import.meta.resolve ToString()s its argument import.meta.resolve is not a function. (In 'import.meta.resolve({ toString() { return "./x"; } })', 'import.meta.resolve' is undefined)
FAIL Relative URL-like specifier resolution import.meta.resolve is not a function. (In 'import.meta.resolve("./x")', 'import.meta.resolve' is undefined)
FAIL Absolute URL-like specifier resolution import.meta.resolve is not a function. (In 'import.meta.resolve("https://example.com/")', 'import.meta.resolve' is undefined)
PASS import.meta.resolve ToString()s its argument
PASS Relative URL-like specifier resolution
PASS Absolute URL-like specifier resolution
PASS Invalid module specifiers
FAIL Works fine with no this value resolve is not a function. (In 'resolve("https://example.com/")', 'resolve' is undefined)
PASS Works fine with no this value

@@ -52,6 +52,7 @@
#include <JavaScriptCore/AbstractModuleRecord.h>
#include <JavaScriptCore/Completion.h>
#include <JavaScriptCore/JSInternalPromise.h>
#include <JavaScriptCore/JSNativeStdFunction.h>
#include <JavaScriptCore/JSScriptFetchParameters.h>
#include <JavaScriptCore/JSScriptFetcher.h>
#include <JavaScriptCore/JSSourceCode.h>
@@ -395,6 +396,8 @@ JSC::JSInternalPromise* ScriptModuleLoader::importModule(JSC::JSGlobalObject* js

JSC::JSObject* ScriptModuleLoader::createImportMetaProperties(JSC::JSGlobalObject* jsGlobalObject, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSModuleRecord*, JSC::JSValue)
{
// https://html.spec.whatwg.org/multipage/webappapis.html#hostgetimportmetaproperties

auto& vm = jsGlobalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

@@ -407,6 +410,27 @@ JSC::JSObject* ScriptModuleLoader::createImportMetaProperties(JSC::JSGlobalObjec
metaProperties->putDirect(vm, JSC::Identifier::fromString(vm, "url"_s), JSC::jsString(vm, responseURL.string()));
RETURN_IF_EXCEPTION(scope, nullptr);

String resolveName = "resolve"_s;
OwnerType ownerType = m_ownerType;
auto* function = JSC::JSNativeStdFunction::create(vm, jsGlobalObject, 1, resolveName, [ownerType, responseURL](JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) -> JSC::EncodedJSValue {
JSC::VM& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

auto specifier = callFrame->argument(0).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, { });

auto* context = jsCast<JSDOMGlobalObject*>(globalObject)->scriptExecutionContext();
if (UNLIKELY(!context))
return JSC::throwVMTypeError(globalObject, scope);

auto result = resolveModuleSpecifier(*context, ownerType, specifier, responseURL);
if (UNLIKELY(!result))
return JSC::throwVMTypeError(globalObject, scope, result.error());

return JSC::JSValue::encode(JSC::jsString(vm, result->string()));
});
metaProperties->putDirect(vm, JSC::Identifier::fromString(vm, resolveName), function);

return metaProperties;
}

0 comments on commit 78c6d6d

Please sign in to comment.