-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
See whatwg/html#5572. Intent to Ship: https://groups.google.com/a/chromium.org/g/blink-dev/c/ZVODFsnIf74 Fixed: 1296665 Change-Id: I63938700518941d0f65a2a1c7fd13910bd095261 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3456729 Reviewed-by: Kouhei Ueno <kouhei@chromium.org> Reviewed-by: Hiroshige Hayashizaki <hiroshige@chromium.org> Reviewed-by: Yuki Shiino <yukishiino@chromium.org> Commit-Queue: Domenic Denicola <domenic@chromium.org> Cr-Commit-Position: refs/heads/main@{#1021529}
- Loading branch information
Showing
14 changed files
with
289 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
third_party/blink/renderer/core/script/module_import_meta.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright 2022 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "third_party/blink/renderer/core/script/module_import_meta.h" | ||
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" | ||
#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h" | ||
#include "third_party/blink/renderer/core/script/modulator.h" | ||
#include "third_party/blink/renderer/platform/bindings/exception_state.h" | ||
|
||
namespace blink { | ||
|
||
const v8::Local<v8::Function> ModuleImportMeta::MakeResolveV8Function( | ||
Modulator* modulator) const { | ||
ScriptFunction* fn = MakeGarbageCollected<ScriptFunction>( | ||
modulator->GetScriptState(), | ||
MakeGarbageCollected<Resolve>(modulator, url_)); | ||
return fn->V8Function(); | ||
} | ||
|
||
ScriptValue ModuleImportMeta::Resolve::Call(ScriptState* script_state, | ||
ScriptValue value) { | ||
ExceptionState exception_state(script_state->GetIsolate(), | ||
ExceptionContext::Context::kOperationInvoke, | ||
"import.meta", "resolve"); | ||
|
||
const String specifier = NativeValueTraits<IDLString>::NativeValue( | ||
script_state->GetIsolate(), value.V8Value(), exception_state); | ||
if (exception_state.HadException()) { | ||
return ScriptValue(); | ||
} | ||
|
||
String failure_reason = "Unknown failure"; | ||
const KURL result = modulator_->ResolveModuleSpecifier(specifier, KURL(url_), | ||
&failure_reason); | ||
|
||
if (!result.IsValid()) { | ||
exception_state.ThrowTypeError("Failed to resolve module specifier " + | ||
specifier + ": " + failure_reason); | ||
} | ||
|
||
return ScriptValue::From(script_state, ToV8Traits<IDLString>::ToV8( | ||
script_state, result.GetString()) | ||
.ToLocalChecked()); | ||
} | ||
|
||
void ModuleImportMeta::Resolve::Trace(Visitor* visitor) const { | ||
visitor->Trace(modulator_); | ||
ScriptFunction::Callable::Trace(visitor); | ||
} | ||
|
||
} // namespace blink |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
...tml/semantics/scripting-1/the-script-element/module/import-meta/import-meta-object.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// META: global=dedicatedworker-module,sharedworker-module,serviceworker-module | ||
|
||
test(() => { | ||
assert_equals(typeof import.meta, "object"); | ||
assert_not_equals(import.meta, null); | ||
}, "import.meta is an object"); | ||
|
||
test(() => { | ||
import.meta.newProperty = 1; | ||
assert_true(Object.isExtensible(import.meta)); | ||
}, "import.meta is extensible"); | ||
|
||
test(() => { | ||
for (const name of Reflect.ownKeys(import.meta)) { | ||
const desc = Object.getOwnPropertyDescriptor(import.meta, name); | ||
assert_equals(desc.writable, true); | ||
assert_equals(desc.enumerable, true); | ||
assert_equals(desc.configurable, true); | ||
} | ||
}, "import.meta's properties are writable, configurable, and enumerable"); |
57 changes: 57 additions & 0 deletions
57
...tics/scripting-1/the-script-element/module/import-meta/import-meta-resolve-importmap.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<!DOCTYPE html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
|
||
<!-- | ||
More extensive tests of import maps and import.meta.resolve() will be | ||
located in the import maps test suite. This contains some basic tests plus | ||
tests some tricky parts of the import.meta.resolve() algorithm around string | ||
conversion which are only testable with import maps. | ||
--> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"bare": "https://example.com/", | ||
"https://example.com/rewrite": "https://example.com/rewritten", | ||
|
||
"1": "https://example.com/PASS-1", | ||
"null": "https://example.com/PASS-null", | ||
"undefined": "https://example.com/PASS-undefined", | ||
"[object Object]": "https://example.com/PASS-object", | ||
|
||
"./start": "./resources/export-1.mjs", | ||
"./resources/export-1.mjs": "./resources/export-2.mjs" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
test(() => { | ||
assert_equals(import.meta.resolve("bare"), "https://example.com/"); | ||
}, "import.meta.resolve() given an import mapped bare specifier"); | ||
|
||
test(() => { | ||
assert_equals(import.meta.resolve("https://example.com/rewrite"), "https://example.com/rewritten"); | ||
}, "import.meta.resolve() given an import mapped URL-like specifier"); | ||
|
||
test(() => { | ||
assert_equals(import.meta.resolve(), "https://example.com/PASS-undefined", "no-arg case"); | ||
|
||
assert_equals(import.meta.resolve(1), "https://example.com/PASS-1"); | ||
assert_equals(import.meta.resolve(null), "https://example.com/PASS-null"); | ||
assert_equals(import.meta.resolve(undefined), "https://example.com/PASS-undefined"); | ||
|
||
// Only toString() methods are consulted by ToString, not valueOf() ones. | ||
// So this becomes "[object Object]". | ||
assert_equals(import.meta.resolve({ valueOf() { return "./x"; } }), "https://example.com/PASS-object"); | ||
}, "Testing the ToString() step of import.meta.resolve() via import maps"); | ||
|
||
promise_test(async () => { | ||
const one = (await import("./start")).default; | ||
assert_equals(one, 1); | ||
|
||
const two = (await import(import.meta.resolve("./start"))).default; | ||
assert_equals(two, 2); | ||
}, "import(import.meta.resolve(x)) can be different from import(x)"); | ||
</script> |
39 changes: 39 additions & 0 deletions
39
...ripting-1/the-script-element/module/import-meta/import-meta-resolve-multiple-scripts.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!DOCTYPE html> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
|
||
<iframe src="resources/store-import-meta.html"></iframe> | ||
|
||
<script type="module"> | ||
import * as otherImportMeta from "./resources/export-import-meta.mjs"; | ||
setup({ explicit_done: true }); | ||
|
||
window.onload = () => { | ||
test(() => { | ||
assert_not_equals(frames[0].importMetaURL, import.meta.url, | ||
"Precondition check: we've set things up so that the other script has a different import.meta.url"); | ||
|
||
const expected = (new URL("resources/x", location.href)).href; | ||
assert_equals(frames[0].importMetaResolve("./x"), expected); | ||
}, "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"); | ||
|
||
test(() => { | ||
const otherFrameImportMetaResolve = frames[0].importMetaResolve; | ||
|
||
document.querySelector("iframe").remove(); | ||
|
||
const expected = (new URL("resources/x", location.href)).href; | ||
assert_equals(otherFrameImportMetaResolve("./x"), expected); | ||
}, "import.meta.resolve still works if its global has been destroyed (by detaching the iframe)"); | ||
|
||
test(() => { | ||
assert_not_equals(otherImportMeta.url, import.meta.url, | ||
"Precondition check: we've set things up so that the other script has a different import.meta.url"); | ||
|
||
const expected = (new URL("resources/x", location.href)).href; | ||
assert_equals(otherImportMeta.resolve("./x"), expected); | ||
}, "import.meta.resolve resolves URLs relative to the import.meta.url, not relative to the active script when it is called: another module script"); | ||
|
||
done(); | ||
}; | ||
</script> |
77 changes: 77 additions & 0 deletions
77
...ml/semantics/scripting-1/the-script-element/module/import-meta/import-meta-resolve.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// META: global=dedicatedworker-module,sharedworker-module,serviceworker-module | ||
|
||
import { importMetaOnRootModule, importMetaOnDependentModule } | ||
from "./import-meta-root.js"; | ||
|
||
test(() => { | ||
assert_equals(typeof import.meta.resolve, "function"); | ||
assert_equals(import.meta.resolve.name, "resolve"); | ||
assert_equals(import.meta.resolve.length, 1); | ||
assert_equals(Object.getPrototypeOf(import.meta.resolve), Function.prototype); | ||
}, "import.meta.resolve is a function with the right properties"); | ||
|
||
test(() => { | ||
assert_false(isConstructor(import.meta.resolve)); | ||
|
||
assert_throws_js(TypeError, () => new import.meta.resolve("./x")); | ||
}, "import.meta.resolve is not a constructor"); | ||
|
||
test(() => { | ||
// See also tests in ./import-meta-resolve-importmap.html. | ||
|
||
assert_equals(import.meta.resolve({ toString() { return "./x"; } }), resolveURL("x")); | ||
assert_throws_js(TypeError, () => import.meta.resolve(Symbol("./x")), | ||
"symbol"); | ||
assert_throws_js(TypeError, () => import.meta.resolve(), | ||
"no argument (which is treated like \"undefined\")"); | ||
}, "import.meta.resolve ToString()s its argument"); | ||
|
||
test(() => { | ||
assert_equals(import.meta.resolve("./x"), resolveURL("x"), | ||
"current module import.meta"); | ||
assert_equals(importMetaOnRootModule.resolve("./x"), resolveURL("x"), | ||
"sibling module import.meta"); | ||
assert_equals(importMetaOnDependentModule.resolve("./x"), resolveURL("x"), | ||
"dependency module import.meta"); | ||
}, "Relative URL-like specifier resolution"); | ||
|
||
test(() => { | ||
assert_equals(import.meta.resolve("https://example.com/"), "https://example.com/", | ||
"current module import.meta"); | ||
assert_equals(importMetaOnRootModule.resolve("https://example.com/"), "https://example.com/", | ||
"sibling module import.meta"); | ||
assert_equals(importMetaOnDependentModule.resolve("https://example.com/"), "https://example.com/", | ||
"dependency module import.meta"); | ||
}, "Absolute URL-like specifier resolution"); | ||
|
||
test(() => { | ||
const invalidSpecifiers = [ | ||
"https://eggplant:b/c", | ||
"pumpkins.js", | ||
".tomato", | ||
"..zuccini.mjs", | ||
".\\yam.es" | ||
]; | ||
|
||
for (const specifier of invalidSpecifiers) { | ||
assert_throws_js(TypeError, () => import.meta.resolve(specifier), specifier); | ||
} | ||
}, "Invalid module specifiers"); | ||
|
||
test(() => { | ||
const { resolve } = import.meta; | ||
assert_equals(resolve("https://example.com/"), "https://example.com/", "current module import.meta"); | ||
}, "Works fine with no this value"); | ||
|
||
function resolveURL(urlRelativeToThisTest) { | ||
return (new URL(urlRelativeToThisTest, location.href)).href; | ||
} | ||
|
||
function isConstructor(o) { | ||
try { | ||
new (new Proxy(o, { construct: () => ({}) })); | ||
return true; | ||
} catch { | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
...t/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-1.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default 1; |
1 change: 1 addition & 0 deletions
1
...t/html/semantics/scripting-1/the-script-element/module/import-meta/resources/export-2.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default 2; |
2 changes: 2 additions & 0 deletions
2
...antics/scripting-1/the-script-element/module/import-meta/resources/export-import-meta.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const url = import.meta.url; | ||
export const resolve = import.meta.resolve; |
5 changes: 5 additions & 0 deletions
5
...antics/scripting-1/the-script-element/module/import-meta/resources/store-import-meta.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<!DOCTYPE html> | ||
<script type="module"> | ||
window.importMetaURL = import.meta.url; | ||
window.importMetaResolve = import.meta.resolve; | ||
</script> |
3 changes: 0 additions & 3 deletions
3
.../semantics/scripting-1/the-script-element/module/import-meta/import-meta-url-expected.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters