Skip to content
Permalink
Browse files
Implement importmaps
https://bugs.webkit.org/show_bug.cgi?id=220823
<rdar://73478498>

Reviewed by Youenn Fablet.

This patch implements import-maps[1], which integrates mapping between module specifier and actual URL so that we can import
modules with arbitrary module specifier. This helps integrating existing node.js / bun etc. modules into the web page without
bundlers.

1. JSC integrates importMapStatusPromise into its module loader pipeline. This makes us to wait for the importmap loading cleanly.
2. Fix a bug that <script type="module" src="URL">'s src is resolved. The spec does not resolve this URL and handle it as normal URL.
   The reason is that we would like to preload this resource so we need to have an URL here.
3. Fix WCIG import-mpas' tests in WPT. These tests are indeterministic, so we modified WPT testharness.js and tests to make it deterministic.
4. For now, we workaround the iframe 'load' event issue which blocks testing in WPT import-maps by modifying testharness.js. We should fix this
   issue in WebKit side later. They are located in LayoutTests/http/wpt/import-maps/data-driven.
   It should be removed once the issues are solved. https://bugs.webkit.org/show_bug.cgi?id=245772
5. "importmap" <script> type and LoadableImportMap is integrated in WebCore. We share most of code with LoadableClassicScript by factoring out the
   common part as LoadableNonModuleScriptBase.
6. Core algorithm of ImportMap resolution is defined in JSC::ImportMap in runtime/ImportMap.h. This map is per JSGlobalObject, and implements the
   resolution algorithm. We would like to integrate this well in normal JSC framework in the future.
7. HTML script preloader is correctly configured to preload importmap as well.
8. Some of WPT tests are failing because of www1.localhost domain resolution issue.

[1]: https://github.com/WICG/import-maps

* LayoutTests/TestExpectations:
* LayoutTests/imported/w3c/resources/import-expectations.json:
* 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/specifier-error-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/import-maps/META.yml: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/README.md: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/dynamic-import-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/dynamic-import.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload-link-header-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload-link-header.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload-link-header.html.headers: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/script-tag-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/script-tag-inline-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/script-tag-inline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/script-tag.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/worker-request-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/acquiring/worker-request.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare-specifiers.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare-specifiers.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/README.md: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/__dir__.headers: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/bare: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/cross-origin-bare: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/to-bare: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/to-data: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/bare/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/applied-to-target-dynamic.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/applied-to-target-dynamic.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/applied-to-target.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/applied-to-target.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/hash-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/hash-failure-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/hash-failure.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/hash.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/nonce-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/nonce-failure-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/nonce-failure.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/nonce.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/unsafe-inline-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/unsafe-inline.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/csp/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/README.md: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/resolving-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/resolving.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/resources/test-helper-iframe.js: Added.
(event.catch):
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/resources/test-helper.js: Added.
(createTestIframe):
(resolve):
(async runTests):
(async export.async runTestsFromJSON):
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/resources/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/tools/format_json.py: Added.
(main):
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/tools/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-driven/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-url-specifiers.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/data-url-specifiers.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/http-url-like-specifiers.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/http-url-like-specifiers.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/import-maps-base-url.sub-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/import-maps-base-url.sub.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/module-map-key-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/module-map-key.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/multiple-import-maps/basic-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/multiple-import-maps/basic.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/multiple-import-maps/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/multiple-import-maps/with-errors-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/multiple-import-maps/with-errors.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/not-as-classic-script-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/not-as-classic-script.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/resources/empty.js: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/resources/inject-base.js: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/resources/log.js: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/resources/log.js.headers: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/resources/test-helper.js: Added.
(getHandlers):
(testInIframe):
(testScriptElement):
(testStaticImportInjectBase):
* LayoutTests/imported/w3c/web-platform-tests/import-maps/resources/w3c-import.log: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/script-supports-importmap-expected.txt: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/script-supports-importmap.html: Added.
* LayoutTests/imported/w3c/web-platform-tests/import-maps/static-import.py: Added.
(main):
* LayoutTests/imported/w3c/web-platform-tests/import-maps/w3c-import.log: Added.
* LayoutTests/tests-options.json:
* Source/JavaScriptCore/API/JSAPIGlobalObject.mm:
(JSC::JSAPIGlobalObject::moduleLoaderImportModule):
(JSC::JSAPIGlobalObject::loadAndEvaluateJSScriptModule):
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Sources.txt:
* Source/JavaScriptCore/builtins/BuiltinNames.h:
* Source/JavaScriptCore/builtins/ModuleLoader.js:
(visibility.PrivateRecursive.async loadModule):
(visibility.PrivateRecursive.async loadAndEvaluateModule):
(visibility.PrivateRecursive.async requestImportModule):
* Source/JavaScriptCore/bytecode/LinkTimeConstant.h:
* Source/JavaScriptCore/jsc.cpp:
(GlobalObject::moduleLoaderImportModule):
* Source/JavaScriptCore/parser/SourceProvider.h:
* Source/JavaScriptCore/runtime/Completion.cpp:
(JSC::loadModule):
(JSC::importModule):
* Source/JavaScriptCore/runtime/Completion.h:
* Source/JavaScriptCore/runtime/ImportMap.cpp: Added.
(JSC::ImportMap::resolveImportMatch):
(JSC::parseURLLikeModuleSpecifier):
(JSC::ImportMap::resolve const):
(JSC::normalizeSpecifierKey):
(JSC::sortAndNormalizeSpecifierMap):
(JSC::ImportMap::registerImportMap):
* Source/JavaScriptCore/runtime/ImportMap.h: Copied from Source/WebCore/dom/ScriptElementCachedScriptFetcher.h.
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildrenImpl):
(JSC::JSGlobalObject::isAcquiringImportMaps const):
(JSC::JSGlobalObject::setAcquiringImportMaps):
(JSC::JSGlobalObject::setPendingImportMaps):
(JSC::JSGlobalObject::clearPendingImportMaps):
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::importMap const):
(JSC::JSGlobalObject::importMap):
(JSC::JSGlobalObject::importMapStatusPromise const):
* Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h:
* Source/JavaScriptCore/runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::loadModule):
(JSC::JSModuleLoader::requestImportModule):
* Source/JavaScriptCore/runtime/JSModuleLoader.h:
* Source/JavaScriptCore/runtime/LazyProperty.h:
(JSC::LazyProperty::isInitialized const):
* Source/WTF/wtf/JSONValues.cpp:
(WTF::JSONImpl::Value::parseJSON):
* Source/WTF/wtf/JSONValues.h:
* Source/WebCore/Headers.cmake:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/bindings/js/JSExecState.h:
(WebCore::JSExecState::loadModule):
* Source/WebCore/bindings/js/ModuleFetchFailureKind.h:
* Source/WebCore/bindings/js/ScriptController.cpp:
(WebCore::ScriptController::loadModuleScriptInWorld):
(WebCore::ScriptController::loadModuleScript):
(WebCore::ScriptController::setupModuleScriptHandlers):
(WebCore::ScriptController::reportExceptionFromScriptError):
(WebCore::ScriptController::registerImportMap):
(WebCore::ScriptController::isAcquiringImportMaps):
(WebCore::ScriptController::setAcquiringImportMaps):
(WebCore::ScriptController::setPendingImportMaps):
(WebCore::ScriptController::clearPendingImportMaps):
* Source/WebCore/bindings/js/ScriptController.h:
* Source/WebCore/bindings/js/ScriptModuleLoader.cpp:
(WebCore::resolveModuleSpecifier):
(WebCore::ScriptModuleLoader::resolve):
(WebCore::ScriptModuleLoader::responseURLFromRequestURL):
(WebCore::ScriptModuleLoader::importModule):
(WebCore::ScriptModuleLoader::createImportMetaProperties):
* Source/WebCore/dom/CurrentScriptIncrementer.h:
(WebCore::CurrentScriptIncrementer::CurrentScriptIncrementer):
* Source/WebCore/dom/Document.cpp:
(WebCore::Document::baseURLForComplete const):
(WebCore::Document::completeURL const):
* Source/WebCore/dom/Document.h:
* Source/WebCore/dom/InlineClassicScript.h:
* Source/WebCore/dom/LoadableClassicScript.cpp:
(WebCore::LoadableClassicScript::takeError):
(WebCore::LoadableClassicScript::notifyFinished):
(WebCore::LoadableClassicScript::error const): Deleted.
* Source/WebCore/dom/LoadableClassicScript.h:
* Source/WebCore/dom/LoadableImportMap.cpp: Copied from Source/WebCore/dom/LoadableClassicScript.cpp.
(WebCore::LoadableImportMap::create):
(WebCore::LoadableImportMap::LoadableImportMap):
(WebCore::LoadableImportMap::~LoadableImportMap):
(WebCore::LoadableImportMap::isLoaded const):
(WebCore::LoadableImportMap::takeError):
(WebCore::LoadableImportMap::wasCanceled const):
(WebCore::LoadableImportMap::notifyFinished):
(WebCore::LoadableImportMap::execute):
(WebCore::LoadableImportMap::load):
* Source/WebCore/dom/LoadableImportMap.h: Copied from Source/WebCore/dom/LoadableClassicScript.h.
(isType):
* Source/WebCore/dom/LoadableModuleScript.cpp:
(WebCore::LoadableModuleScript::takeError):
(WebCore::LoadableModuleScript::error const): Deleted.
* Source/WebCore/dom/LoadableModuleScript.h:
* Source/WebCore/dom/LoadableScript.h:
* Source/WebCore/dom/PendingScript.cpp:
(WebCore::PendingScript::takeError):
(WebCore::PendingScript::error const): Deleted.
* Source/WebCore/dom/PendingScript.h:
* Source/WebCore/dom/ScriptElement.cpp:
(WebCore::ScriptElement::ScriptElement):
(WebCore::ScriptElement::determineScriptType const):
(WebCore::ScriptElement::prepareScript):
(WebCore::ScriptElement::requestModuleScript):
(WebCore::ScriptElement::requestImportMap):
(WebCore::ScriptElement::registerImportMap):
(WebCore::ScriptElement::executeModuleScript):
(WebCore::ScriptElement::executeScriptAndDispatchEvent):
(WebCore::ScriptElement::executePendingScript):
* Source/WebCore/dom/ScriptElement.h:
(WebCore::ScriptElement::scriptType const):
* Source/WebCore/dom/ScriptElementCachedScriptFetcher.h:
(WebCore::ScriptElementCachedScriptFetcher::isClassicScript const):
(WebCore::ScriptElementCachedScriptFetcher::isModuleScript const):
(WebCore::ScriptElementCachedScriptFetcher::isImportMap const):
* Source/WebCore/dom/ScriptType.h: Copied from Source/WebCore/dom/InlineClassicScript.h.
* Source/WebCore/html/HTMLScriptElement.h:
* Source/WebCore/html/parser/CSSPreloadScanner.cpp:
(WebCore::CSSPreloadScanner::emitRule):
* Source/WebCore/html/parser/HTMLPreloadScanner.cpp:
(WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest):
(WebCore::TokenPreloadScanner::StartTagScanner::processAttribute):
(WebCore::TokenPreloadScanner::StartTagScanner::shouldPreload):
* Source/WebCore/html/parser/HTMLResourcePreloader.cpp:
(WebCore::PreloadRequest::resourceRequest):
* Source/WebCore/html/parser/HTMLResourcePreloader.h:
(WebCore::PreloadRequest::PreloadRequest):
* Source/WebCore/html/parser/HTMLScriptRunner.cpp:
(WebCore::HTMLScriptRunner::runScript):
* Source/WebCore/page/csp/ContentSecurityPolicy.h:
* Source/WebCore/workers/WorkerOrWorkletScriptController.cpp:
(WebCore::WorkerOrWorkletScriptController::loadModuleSynchronously):
(WebCore::WorkerOrWorkletScriptController::loadAndEvaluateModule):
* Source/WebCore/xml/parser/XMLDocumentParserLibxml2.cpp:
(WebCore::XMLDocumentParser::endElementNs):

Canonical link: https://commits.webkit.org/254987@main
  • Loading branch information
Constellation committed Sep 29, 2022
1 parent 9ac61a5 commit 6c1996aea8b85babf563135acc2d05def8aca3cb
Show file tree
Hide file tree
Showing 214 changed files with 6,797 additions and 255 deletions.
@@ -651,7 +651,6 @@ 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 ]
@@ -6057,3 +6056,9 @@ js/ShadowRealm-worker.html [ Pass Failure ]
imported/w3c/web-platform-tests/svg/import/color-prop-05-t-manual.svg [ Skip ]
svg/W3C-SVG-1.1-SE/color-prop-05-t.svg [ Skip ]

# modulepreload is not supported
imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload.html [ Skip ]
imported/w3c/web-platform-tests/import-maps/acquiring/modulepreload-link-header.html [ Skip ]

# WPT meta name="variant" is not supported. And iframe 'load' event has a bug.
imported/w3c/web-platform-tests/import-maps/data-driven/resolving.html [ Skip ]
@@ -0,0 +1,87 @@
# Data-driven import maps tests

In this directory, test inputs and expectations are expressed as JSON files.
This is in order to share the same JSON files between WPT tests and other
implementations that might not run the full WPT suite, e.g. server-side
JavaScript runtimes or the [JavaScript reference implementation](https://github.com/WICG/import-maps/tree/master/reference-implementation).

## Basics

A **test object** describes a set of parameters (import maps and base URLs) and test expectations.
Test expectations consist of the expected resulting URLs for specifiers.

Each JSON file under [resources/](resources/) directory consists of a test object.
A minimum test object would be:

```json
{
"name": "Main test name",
"importMapBaseURL": "https://example.com/import-map-base-url/index.html",
"importMap": {
"imports": {
"a": "/mapped-a.mjs"
}
},
"baseURL": "https://example.com/base-url/app.mjs",
"expectedResults": {
"a": "https://example.com/mapped-a.mjs",
"b": null
}
}
```

Required fields:

- `name`: Test name.
- In WPT tests, this is used for the test name of `promise_test()` together with specifier to be resolved, like `"Main test name: a"`.
- `importMap` (object or string): the import map to be attached.
- `importMapBaseURL` (string): the base URL used for [parsing the import map](https://wicg.github.io/import-maps/#parse-an-import-map-string).
- `expectedResults` (object; string to (string or null)): resolution test cases.
- The keys are specifiers to be resolved.
- The values are expected resolved URLs. If `null`, resolution should fail.
- `baseURL` (string): the base URL used in [resolving a specifier](https://wicg.github.io/import-maps/#resolve-a-module-specifier) for each specifiers.

Optional fields:

- `link` and `details` can be used for e.g. linking to specs or adding more detailed descriptions.
- Currently they are simply ignored by the WPT test helper.

## Nesting and inheritance

We can organize tests by nesting test objects.
A test object can contain child test objects (*subtests*) using `tests` field.
The Keys of the `tests` value are the names of subtests, and values are test objects.

For example:

```json
{
"name": "Main test name",
"importMapBaseURL": "https://example.com/import-map-base-url/index.html",
"importMap": {
"imports": {
"a": "/mapped-a.mjs"
}
},
"tests": {
"Subtest1": {
"baseURL": "https://example.com/base-url1/app.mjs",
"expectedResults": { "a": "https://example.com/mapped-a.mjs" }
},
"Subtest2": {
"baseURL": "https://example.com/base-url2/app.mjs",
"expectedResults": { "b": null }
}
}
}
```

The top-level test object contains two sub test objects, named as `Subtest1` and `Subtest2`, respectively.

Child test objects inherit fields from their parent test object.
In the example above, the child test objects specifies `baseURL` fields, while they inherits other fields (e.g. `importMapBaseURL`) from the top-level test object.

## TODO

The `parsing-*.json` files are not currently used by the WPT harness. We should
convert them to resolution tests.
@@ -0,0 +1,5 @@


PASS Test helper: fetching and sanity checking test JSON: data-url-prefix.json
PASS data: URL prefix: should not resolve since you can't resolve relative to a data: URL: foo/bar

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/test-helper.js";

const filename = "data-url-prefix.json";
promise_test(
() => runTestsFromJSON('resources/' + filename),
"Test helper: fetching and sanity checking test JSON: " + filename);
</script>
@@ -0,0 +1,34 @@


PASS Test helper: fetching and sanity checking test JSON: empty-import-map.json
PASS valid relative specifiers: ./foo
PASS valid relative specifiers: ./foo/bar
PASS valid relative specifiers: ./foo/../bar
PASS valid relative specifiers: ./foo/../../bar
PASS valid relative specifiers: ../foo
PASS valid relative specifiers: ../foo/bar
PASS valid relative specifiers: ../../../foo/bar
PASS valid relative specifiers: /foo
PASS valid relative specifiers: /foo/bar
PASS valid relative specifiers: /../../foo/bar
PASS valid relative specifiers: /../foo/../bar
PASS HTTPS scheme absolute URLs: https://fetch-scheme.net
PASS HTTPS scheme absolute URLs: https:fetch-scheme.org
PASS HTTPS scheme absolute URLs: https://fetch%2Dscheme.com/
PASS HTTPS scheme absolute URLs: https://///fetch-scheme.com///
PASS valid relative URLs that are invalid as specifiers should fail: invalid-specifier
PASS valid relative URLs that are invalid as specifiers should fail: \invalid-specifier
PASS valid relative URLs that are invalid as specifiers should fail: :invalid-specifier
PASS valid relative URLs that are invalid as specifiers should fail: @invalid-specifier
PASS valid relative URLs that are invalid as specifiers should fail: %2E/invalid-specifier
PASS valid relative URLs that are invalid as specifiers should fail: %2E%2E/invalid-specifier
PASS valid relative URLs that are invalid as specifiers should fail: .%2Finvalid-specifier
PASS invalid absolute URLs should fail: https://invalid-url.com:demo
PASS invalid absolute URLs should fail: http://[invalid-url.com]/
PASS non-HTTPS fetch scheme absolute URLs: about:fetch-scheme
PASS non-fetch scheme absolute URLs: about:fetch-scheme
PASS non-fetch scheme absolute URLs: mailto:non-fetch-scheme
PASS non-fetch scheme absolute URLs: import:non-fetch-scheme
PASS non-fetch scheme absolute URLs: javascript:non-fetch-scheme
PASS non-fetch scheme absolute URLs: wss:non-fetch-scheme

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/test-helper.js";

const filename = "empty-import-map.json";
promise_test(
() => runTestsFromJSON('resources/' + filename),
"Test helper: fetching and sanity checking test JSON: " + filename);
</script>
@@ -0,0 +1,10 @@


PASS Test helper: fetching and sanity checking test JSON: overlapping-entries.json
PASS should favor the most-specific key: Overlapping entries with trailing slashes: a
PASS should favor the most-specific key: Overlapping entries with trailing slashes: a/
PASS should favor the most-specific key: Overlapping entries with trailing slashes: a/x
PASS should favor the most-specific key: Overlapping entries with trailing slashes: a/b
PASS should favor the most-specific key: Overlapping entries with trailing slashes: a/b/
PASS should favor the most-specific key: Overlapping entries with trailing slashes: a/b/c

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/test-helper.js";

const filename = "overlapping-entries.json";
promise_test(
() => runTestsFromJSON('resources/' + filename),
"Test helper: fetching and sanity checking test JSON: " + filename);
</script>
@@ -0,0 +1,36 @@


PASS Test helper: fetching and sanity checking test JSON: packages-via-trailing-slashes.json
PASS Package-like scenarios: package main modules: moment
PASS Package-like scenarios: package main modules: lodash-dot
PASS Package-like scenarios: package main modules: lodash-dotdot
PASS Package-like scenarios: package submodules: moment/foo
PASS Package-like scenarios: package submodules: moment/foo?query
PASS Package-like scenarios: package submodules: moment/foo#fragment
PASS Package-like scenarios: package submodules: moment/foo?query#fragment
PASS Package-like scenarios: package submodules: lodash-dot/foo
PASS Package-like scenarios: package submodules: lodash-dotdot/foo
PASS Package-like scenarios: package names that end in a slash should just pass through: moment/
PASS Package-like scenarios: package modules that are not declared should fail: underscore/
PASS Package-like scenarios: package modules that are not declared should fail: underscore/foo
PASS Package-like scenarios: backtracking via ..: mapped/path
PASS Package-like scenarios: backtracking via ..: mapped/path/
PASS Package-like scenarios: backtracking via ..: mapped/path/..
PASS Package-like scenarios: backtracking via ..: mapped/path/../path/
PASS Package-like scenarios: backtracking via ..: mapped/path/../207
PASS Package-like scenarios: backtracking via ..: mapped/path/../207/
PASS Package-like scenarios: backtracking via ..: mapped/path//
PASS Package-like scenarios: backtracking via ..: mapped/path/WICG/import-maps/issues/207/
PASS Package-like scenarios: backtracking via ..: mapped/path//WICG/import-maps/issues/207/
PASS Package-like scenarios: backtracking via ..: mapped/path/../backtrack
PASS Package-like scenarios: backtracking via ..: mapped/path/../../backtrack
PASS Package-like scenarios: backtracking via ..: mapped/path/../../../backtrack
PASS Package-like scenarios: backtracking via ..: moment/../backtrack
PASS Package-like scenarios: backtracking via ..: moment/..
PASS Package-like scenarios: backtracking via ..: mapped/non-ascii-1/
PASS Package-like scenarios: backtracking via ..: mapped/non-ascii-1/../%E3%81%8D%E3%81%A4%E3%81%AD/
PASS Package-like scenarios: backtracking via ..: mapped/non-ascii-1/../きつね/
PASS Package-like scenarios: backtracking via ..: mapped/non-ascii-2/
PASS Package-like scenarios: backtracking via ..: mapped/non-ascii-2/../%E3%81%8D%E3%81%A4%E3%81%AD/
PASS Package-like scenarios: backtracking via ..: mapped/non-ascii-2/../きつね/

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/test-helper.js";

const filename = "packages-via-trailing-slashes.json";
promise_test(
() => runTestsFromJSON('resources/' + filename),
"Test helper: fetching and sanity checking test JSON: " + filename);
</script>
@@ -0,0 +1,33 @@
CONSOLE MESSAGE: value in specifier map cannot be parsed as URL https://:invalid-url:/
CONSOLE MESSAGE: value in specifier map needs to be a string
CONSOLE MESSAGE: address https://example.com/x does not end with '/' while key without-trailing-slashes/b/ ends with '/'
CONSOLE MESSAGE: value in specifier map needs to be a string
CONSOLE MESSAGE: value in specifier map cannot be parsed as URL https://:invalid-url:/
CONSOLE MESSAGE: address https://example.com/x does not end with '/' while key without-trailing-slashes/ ends with '/'
CONSOLE MESSAGE: value in specifier map cannot be parsed as URL https://:invalid-url:/
CONSOLE MESSAGE: address https://example.com/x does not end with '/' while key https://example.com/without-trailing-slashes/ ends with '/'
CONSOLE MESSAGE: value in specifier map needs to be a string


PASS Test helper: fetching and sanity checking test JSON: resolving-null.json
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: null/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: null/b/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: null/b/c/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: invalid-url/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: invalid-url/b/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: invalid-url/b/c/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: without-trailing-slashes/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: without-trailing-slashes/b/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: without-trailing-slashes/b/c/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: prefix-resolution-error/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: prefix-resolution-error/b/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific prefixes: prefix-resolution-error/b/c/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific scopes: null
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific scopes: invalid-url
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific scopes: without-trailing-slashes/x
PASS Entries with errors shouldn't allow fallback: No fallback to less-specific scopes: prefix-resolution-error/x
PASS Entries with errors shouldn't allow fallback: No fallback to absolute URL parsing: https://example.com/null
PASS Entries with errors shouldn't allow fallback: No fallback to absolute URL parsing: https://example.com/invalid-url
PASS Entries with errors shouldn't allow fallback: No fallback to absolute URL parsing: https://example.com/without-trailing-slashes/x
PASS Entries with errors shouldn't allow fallback: No fallback to absolute URL parsing: https://example.com/prefix-resolution-error/x

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/test-helper.js";

const filename = "resolving-null.json";
promise_test(
() => runTestsFromJSON('resources/' + filename),
"Test helper: fetching and sanity checking test JSON: " + filename);
</script>
@@ -0,0 +1,28 @@


PASS Test helper: fetching and sanity checking test JSON: scopes-exact-vs-prefix.json
PASS Exact vs. prefix based matching: Scope without trailing slash only: Non-trailing-slash base URL (exact match): moment
PASS Exact vs. prefix based matching: Scope without trailing slash only: Non-trailing-slash base URL (exact match): moment/foo
PASS Exact vs. prefix based matching: Scope without trailing slash only: Trailing-slash base URL (fail): moment
PASS Exact vs. prefix based matching: Scope without trailing slash only: Trailing-slash base URL (fail): moment/foo
PASS Exact vs. prefix based matching: Scope without trailing slash only: Subpath base URL (fail): moment
PASS Exact vs. prefix based matching: Scope without trailing slash only: Subpath base URL (fail): moment/foo