mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 07:48:38 +09:00
Merge remote-tracking branch 'origin/master' into custom
This commit is contained in:
commit
c28adcb4a9
36 changed files with 353 additions and 254 deletions
|
|
@ -665,6 +665,7 @@ GK_ATOM(noembed, "noembed")
|
|||
GK_ATOM(noframes, "noframes")
|
||||
GK_ATOM(nohref, "nohref")
|
||||
GK_ATOM(noisolation, "noisolation")
|
||||
GK_ATOM(nomodule, "nomodule")
|
||||
GK_ATOM(nonce, "nonce")
|
||||
GK_ATOM(none, "none")
|
||||
GK_ATOM(noresize, "noresize")
|
||||
|
|
|
|||
|
|
@ -653,6 +653,19 @@ nsScriptLoader::CheckContentPolicy(nsIDocument* aDocument,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScriptLoader::ModuleScriptsEnabled()
|
||||
{
|
||||
static bool sEnabledForContent = false;
|
||||
static bool sCachedPref = false;
|
||||
if (!sCachedPref) {
|
||||
sCachedPref = true;
|
||||
Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false);
|
||||
}
|
||||
|
||||
return nsContentUtils::IsChromeDoc(mDocument) || sEnabledForContent;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScriptLoader::ModuleMapContainsModule(nsModuleLoadRequest *aRequest) const
|
||||
{
|
||||
|
|
@ -1230,15 +1243,27 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType,
|
|||
nsCOMPtr<nsIInterfaceRequestor> prompter(do_QueryInterface(docshell));
|
||||
|
||||
nsSecurityFlags securityFlags;
|
||||
// TODO: the spec currently gives module scripts different CORS behaviour to
|
||||
// classic scripts.
|
||||
securityFlags = aRequest->mCORSMode == CORS_NONE
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// According to the spec, module scripts have different behaviour to classic
|
||||
// scripts and always use CORS.
|
||||
securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_NONE) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_OMIT;
|
||||
} else if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else {
|
||||
MOZ_ASSERT(aRequest->mCORSMode == CORS_USE_CREDENTIALS);
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
} else {
|
||||
securityFlags = aRequest->mCORSMode == CORS_NONE
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aRequest->mCORSMode == CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else if (aRequest->mCORSMode == CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
}
|
||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||
|
||||
|
|
@ -1434,7 +1459,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
|
||||
nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement);
|
||||
|
||||
// Step 12. Check that the script is not an eventhandler
|
||||
// Step 13. Check that the script is not an eventhandler
|
||||
if (IsScriptEventHandler(scriptContent)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1448,8 +1473,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
|
||||
nsScriptKind scriptKind = nsScriptKind::Classic;
|
||||
if (!type.IsEmpty()) {
|
||||
// Support type="module" only for chrome documents.
|
||||
if (nsContentUtils::IsChromeDoc(mDocument) && type.LowerCaseEqualsASCII("module")) {
|
||||
if (ModuleScriptsEnabled() && type.LowerCaseEqualsASCII("module")) {
|
||||
scriptKind = nsScriptKind::Module;
|
||||
} else {
|
||||
NS_ENSURE_TRUE(ParseTypeAttribute(type, &version), false);
|
||||
|
|
@ -1469,7 +1493,18 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
}
|
||||
}
|
||||
|
||||
// Step 14. in the HTML5 spec
|
||||
// "In modern user agents that support module scripts, the script element with
|
||||
// the nomodule attribute will be ignored".
|
||||
// "The nomodule attribute must not be specified on module scripts (and will
|
||||
// be ignored if it is)."
|
||||
if (ModuleScriptsEnabled() &&
|
||||
scriptKind == nsScriptKind::Classic &&
|
||||
scriptContent->IsHTMLElement() &&
|
||||
scriptContent->HasAttr(kNameSpaceID_None, nsGkAtoms::nomodule)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 15. and later in the HTML5 spec
|
||||
nsresult rv = NS_OK;
|
||||
RefPtr<nsScriptLoadRequest> request;
|
||||
if (aElement->GetScriptExternal()) {
|
||||
|
|
@ -1577,7 +1612,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
if (!aElement->GetParserCreated() && !request->IsModuleRequest()) {
|
||||
if (!aElement->GetParserCreated()) {
|
||||
// Violate the HTML5 spec in order to make LABjs and the "order" plug-in
|
||||
// for RequireJS work with their Gecko-sniffed code path. See
|
||||
// http://lists.w3.org/Archives/Public/public-html/2010Oct/0088.html
|
||||
|
|
@ -2768,7 +2803,7 @@ nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
|||
}
|
||||
|
||||
// TODO: Preload module scripts.
|
||||
if (nsContentUtils::IsChromeDoc(mDocument) && aType.LowerCaseEqualsASCII("module")) {
|
||||
if (ModuleScriptsEnabled() && aType.LowerCaseEqualsASCII("module")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -568,6 +568,8 @@ private:
|
|||
JS::SourceBufferHolder GetScriptSource(nsScriptLoadRequest* aRequest,
|
||||
nsAutoString& inlineData);
|
||||
|
||||
bool ModuleScriptsEnabled();
|
||||
|
||||
void SetModuleFetchStarted(nsModuleLoadRequest *aRequest);
|
||||
void SetModuleFetchFinishedAndResumeWaitingRequests(nsModuleLoadRequest *aRequest,
|
||||
nsresult aResult);
|
||||
|
|
|
|||
|
|
@ -218,6 +218,18 @@ HTMLScriptElement::SetAsync(bool aValue, ErrorResult& rv)
|
|||
SetHTMLBoolAttr(nsGkAtoms::async, aValue, rv);
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLScriptElement::NoModule()
|
||||
{
|
||||
return GetBoolAttr(nsGkAtoms::nomodule);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLScriptElement::SetNoModule(bool aValue, ErrorResult& aRv)
|
||||
{
|
||||
SetHTMLBoolAttr(nsGkAtoms::nomodule, aValue, aRv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLScriptElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
|
||||
const nsAttrValue* aValue, bool aNotify)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ public:
|
|||
}
|
||||
bool Async();
|
||||
void SetAsync(bool aValue, ErrorResult& rv);
|
||||
bool NoModule();
|
||||
void SetNoModule(bool aValue, ErrorResult& rv);
|
||||
|
||||
protected:
|
||||
virtual ~HTMLScriptElement();
|
||||
|
|
|
|||
42
dom/html/test/file_script_module.html
Normal file
42
dom/html/test/file_script_module.html
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
// Helper methods.
|
||||
function ok(a, msg) {
|
||||
parent.postMessage({ check: !!a, msg }, "*")
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
ok(a === b, msg);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
parent.postMessage({ done: true }, "*");
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="a" nomodule>42</script>
|
||||
<script id="b">42</script>
|
||||
<script>
|
||||
// Let's test the behavior of nomodule attribute and noModule getter/setter.
|
||||
var a = document.getElementById("a");
|
||||
is(a.noModule, true, "HTMLScriptElement with nomodule attribute has noModule set to true");
|
||||
a.removeAttribute("nomodule");
|
||||
is(a.noModule, false, "HTMLScriptElement without nomodule attribute has noModule set to false");
|
||||
a.noModule = true;
|
||||
ok(a.hasAttribute('nomodule'), "HTMLScriptElement.noModule = true add the nomodule attribute");
|
||||
|
||||
var b = document.getElementById("b");
|
||||
is(b.noModule, false, "HTMLScriptElement without nomodule attribute has noModule set to false");
|
||||
b.noModule = true;
|
||||
ok(b.hasAttribute('nomodule'), "HTMLScriptElement.noModule = true add the nomodule attribute");
|
||||
</script>
|
||||
|
||||
<script>var foo = 42;</script>
|
||||
<script nomodule>foo = 43;</script>
|
||||
<script>
|
||||
is(foo, 42, "nomodule HTMLScriptElements should not be executed in modern browsers");
|
||||
finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
32
dom/html/test/file_script_nomodule.html
Normal file
32
dom/html/test/file_script_nomodule.html
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<html>
|
||||
<body>
|
||||
<script>
|
||||
// Helper methods.
|
||||
function ok(a, msg) {
|
||||
parent.postMessage({ check: !!a, msg }, "*")
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
ok(a === b, msg);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
parent.postMessage({ done: true }, "*");
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="a" nomodule>42</script>
|
||||
<script>
|
||||
// Let's test the behavior of nomodule attribute and noModule getter/setter.
|
||||
var a = document.getElementById("a");
|
||||
ok(!("noModule" in a), "When modules are disabled HTMLScriptElement.noModule is not defined");
|
||||
</script>
|
||||
|
||||
<script>var foo = 42;</script>
|
||||
<script nomodule>foo = 43;</script>
|
||||
<script>
|
||||
is(foo, 43, "nomodule attribute is ignored when modules are disabled");
|
||||
finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -605,3 +605,7 @@ skip-if = os == "android" # up/down arrow keys not supported on android
|
|||
[test_bug1295719_event_sequence_for_number_keys.html]
|
||||
[test_bug1310865.html]
|
||||
[test_bug1315146.html]
|
||||
+[test_script_module.html]
|
||||
+support-files =
|
||||
+ file_script_module.html
|
||||
+ file_script_nomodule.html
|
||||
56
dom/html/test/test_script_module.html
Normal file
56
dom/html/test/test_script_module.html
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for HTMLScriptElement with nomodule attribute</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
onmessage = (e) => {
|
||||
if ("done" in e.data) {
|
||||
next();
|
||||
} else if ("check" in e.data) {
|
||||
ok(e.data.check, e.data.msg);
|
||||
} else {
|
||||
ok(false, "Unknown message");
|
||||
}
|
||||
}
|
||||
|
||||
var tests = [
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set":[["dom.moduleScripts.enabled", true]]})
|
||||
.then(() => {
|
||||
var ifr = document.createElement('iframe');
|
||||
ifr.src = "file_script_module.html";
|
||||
document.body.appendChild(ifr);
|
||||
});
|
||||
},
|
||||
|
||||
function() {
|
||||
SpecialPowers.pushPrefEnv({"set":[["dom.moduleScripts.enabled", false]]})
|
||||
.then(() => {
|
||||
var ifr = document.createElement('iframe');
|
||||
ifr.src = "file_script_nomodule.html";
|
||||
document.body.appendChild(ifr);
|
||||
});
|
||||
},
|
||||
];
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
next();
|
||||
|
||||
function next() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -13,6 +13,8 @@ interface HTMLScriptElement : HTMLElement {
|
|||
attribute DOMString src;
|
||||
[SetterThrows]
|
||||
attribute DOMString type;
|
||||
[SetterThrows, Pref="dom.moduleScripts.enabled"]
|
||||
attribute boolean noModule;
|
||||
[SetterThrows]
|
||||
attribute DOMString charset;
|
||||
[SetterThrows]
|
||||
|
|
|
|||
|
|
@ -84,44 +84,3 @@ function LegacyIteratorShim() {
|
|||
function LegacyGeneratorIteratorShim() {
|
||||
return NewLegacyIterator(ToObject(this), LegacyGeneratorIterator);
|
||||
}
|
||||
|
||||
// 7.4.8 CreateListIterator()
|
||||
function CreateListIterator(array) {
|
||||
let iterator = NewListIterator();
|
||||
UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, array);
|
||||
UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, 0);
|
||||
|
||||
// 7.4.8.1 ListIterator next()
|
||||
// The spec requires that we use a new next function per iterator object.
|
||||
let next = function() {
|
||||
if (!IsObject(this) || !IsListIterator(this))
|
||||
return callFunction(CallListIteratorMethodIfWrapped, this, "ListIteratorNext");
|
||||
|
||||
if (ActiveFunction() !== UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_METHOD))
|
||||
ThrowTypeError(JSMSG_INCOMPATIBLE_METHOD, "next", "method", ToString(this));
|
||||
|
||||
let array = UnsafeGetObjectFromReservedSlot(this, ITERATOR_SLOT_TARGET);
|
||||
let index = UnsafeGetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX);
|
||||
|
||||
if (index >= ToLength(array.length)) {
|
||||
UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, 1/0);
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
|
||||
UnsafeSetReservedSlot(this, ITERATOR_SLOT_NEXT_INDEX, index + 1);
|
||||
return { value: array[index], done: false };
|
||||
};
|
||||
|
||||
UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_METHOD, next);
|
||||
iterator.next = next;
|
||||
|
||||
iterator[std_iterator] = ListIteratorIdentity;
|
||||
return iterator;
|
||||
}
|
||||
|
||||
function ListIteratorIdentity() {
|
||||
if (!IsObject(this) || !IsListIterator(this))
|
||||
return callFunction(CallListIteratorMethodIfWrapped, this, "ListIteratorIdentity");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,12 +65,12 @@ function ModuleGetExportedNames(exportStarSet = [])
|
|||
return exportedNames;
|
||||
}
|
||||
|
||||
// 15.2.1.16.3 ResolveExport(exportName, resolveSet, exportStarSet)
|
||||
function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
|
||||
// 15.2.1.16.3 ResolveExport(exportName, resolveSet)
|
||||
function ModuleResolveExport(exportName, resolveSet = [])
|
||||
{
|
||||
if (!IsObject(this) || !IsModule(this)) {
|
||||
return callFunction(CallModuleMethodIfWrapped, this, exportName, resolveSet,
|
||||
exportStarSet, "ModuleResolveExport");
|
||||
"ModuleResolveExport");
|
||||
}
|
||||
|
||||
// Step 1
|
||||
|
|
@ -100,38 +100,29 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
|
|||
let e = indirectExportEntries[i];
|
||||
if (exportName === e.exportName) {
|
||||
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
|
||||
MODULE_STATE_INSTANTIATED);
|
||||
let indirectResolution = callFunction(importedModule.resolveExport, importedModule,
|
||||
e.importName, resolveSet, exportStarSet);
|
||||
if (indirectResolution !== null)
|
||||
return indirectResolution;
|
||||
MODULE_STATE_PARSED);
|
||||
return callFunction(importedModule.resolveExport, importedModule, e.importName,
|
||||
resolveSet);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6
|
||||
if (exportName === "default") {
|
||||
// A default export cannot be provided by an export *.
|
||||
ThrowSyntaxError(JSMSG_BAD_DEFAULT_EXPORT);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
if (callFunction(ArrayIncludes, exportStarSet, module))
|
||||
return null;
|
||||
|
||||
// Step 8
|
||||
_DefineDataProperty(exportStarSet, exportStarSet.length, module);
|
||||
|
||||
// Step 9
|
||||
let starResolution = null;
|
||||
|
||||
// Step 10
|
||||
// Step 8
|
||||
let starExportEntries = module.starExportEntries;
|
||||
for (let i = 0; i < starExportEntries.length; i++) {
|
||||
let e = starExportEntries[i];
|
||||
let importedModule = CallModuleResolveHook(module, e.moduleRequest,
|
||||
MODULE_STATE_INSTANTIATED);
|
||||
MODULE_STATE_PARSED);
|
||||
let resolution = callFunction(importedModule.resolveExport, importedModule,
|
||||
exportName, resolveSet, exportStarSet);
|
||||
exportName, resolveSet);
|
||||
if (resolution === "ambiguous")
|
||||
return resolution;
|
||||
|
||||
|
|
@ -148,6 +139,7 @@ function ModuleResolveExport(exportName, resolveSet = [], exportStarSet = [])
|
|||
}
|
||||
}
|
||||
|
||||
// Step 9
|
||||
return starResolution;
|
||||
}
|
||||
|
||||
|
|
@ -213,8 +205,8 @@ function GetModuleEnvironment(module)
|
|||
|
||||
function RecordInstantationFailure(module)
|
||||
{
|
||||
// Set the module's environment slot to 'null' to indicate a failed module
|
||||
// instantiation.
|
||||
// Set the module's state to 'failed' to indicate a failed module
|
||||
// instantiation and reset the environment slot to 'undefined'.
|
||||
assert(IsModule(module), "Non-module passed to RecordInstantationFailure");
|
||||
SetModuleState(module, MODULE_STATE_FAILED);
|
||||
UnsafeSetReservedSlot(module, MODULE_OBJECT_ENVIRONMENT_SLOT, undefined);
|
||||
|
|
@ -275,11 +267,13 @@ function ModuleDeclarationInstantiation()
|
|||
ThrowSyntaxError(JSMSG_MISSING_IMPORT, imp.importName);
|
||||
if (resolution === "ambiguous")
|
||||
ThrowSyntaxError(JSMSG_AMBIGUOUS_IMPORT, imp.importName);
|
||||
if (resolution.module.state < MODULE_STATE_INSTANTIATED)
|
||||
ThrowInternalError(JSMSG_BAD_MODULE_STATE);
|
||||
CreateImportBinding(env, imp.localName, resolution.module, resolution.bindingName);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 16.iv
|
||||
// Step 17.a.iii
|
||||
InstantiateModuleFunctionDeclarations(module);
|
||||
} catch (e) {
|
||||
RecordInstantationFailure(module);
|
||||
|
|
@ -318,11 +312,3 @@ function ModuleEvaluation()
|
|||
return EvaluateModule(module);
|
||||
}
|
||||
_SetCanonicalName(ModuleEvaluation, "ModuleEvaluation");
|
||||
|
||||
function ModuleNamespaceEnumerate()
|
||||
{
|
||||
if (!IsObject(this) || !IsModuleNamespace(this))
|
||||
return callFunction(CallModuleMethodIfWrapped, this, "ModuleNamespaceEnumerate");
|
||||
|
||||
return CreateListIterator(ModuleNamespaceExports(this));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ DEFINE_GETTER_FUNCTIONS(ExportEntryObject, moduleRequest, ModuleRequestSlot)
|
|||
DEFINE_GETTER_FUNCTIONS(ExportEntryObject, importName, ImportNameSlot)
|
||||
DEFINE_GETTER_FUNCTIONS(ExportEntryObject, localName, LocalNameSlot)
|
||||
|
||||
DEFINE_ATOM_ACCESSOR_METHOD(ExportEntryObject, exportName)
|
||||
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, exportName)
|
||||
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, moduleRequest)
|
||||
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, importName)
|
||||
DEFINE_ATOM_OR_NULL_ACCESSOR_METHOD(ExportEntryObject, localName)
|
||||
|
|
@ -289,14 +289,6 @@ ModuleNamespaceObject::create(JSContext* cx, HandleModuleObject module)
|
|||
if (!object)
|
||||
return nullptr;
|
||||
|
||||
RootedId funName(cx, INTERNED_STRING_TO_JSID(cx, cx->names().Symbol_iterator_fun));
|
||||
RootedFunction enumerateFun(cx);
|
||||
enumerateFun = JS::GetSelfHostedFunction(cx, "ModuleNamespaceEnumerate", funName, 0);
|
||||
if (!enumerateFun)
|
||||
return nullptr;
|
||||
|
||||
SetProxyExtra(object, ProxyHandler::EnumerateFunctionSlot, ObjectValue(*enumerateFun));
|
||||
|
||||
return &object->as<ModuleNamespaceObject>();
|
||||
}
|
||||
|
||||
|
|
@ -338,14 +330,9 @@ ModuleNamespaceObject::addBinding(JSContext* cx, HandleAtom exportedName,
|
|||
const char ModuleNamespaceObject::ProxyHandler::family = 0;
|
||||
|
||||
ModuleNamespaceObject::ProxyHandler::ProxyHandler()
|
||||
: BaseProxyHandler(&family, true)
|
||||
: BaseProxyHandler(&family, false)
|
||||
{}
|
||||
|
||||
JS::Value ModuleNamespaceObject::ProxyHandler::getEnumerateFunction(HandleObject proxy) const
|
||||
{
|
||||
return GetProxyExtra(proxy, EnumerateFunctionSlot);
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleNamespaceObject::ProxyHandler::getPrototype(JSContext* cx, HandleObject proxy,
|
||||
MutableHandleObject protop) const
|
||||
|
|
@ -358,6 +345,8 @@ bool
|
|||
ModuleNamespaceObject::ProxyHandler::setPrototype(JSContext* cx, HandleObject proxy,
|
||||
HandleObject proto, ObjectOpResult& result) const
|
||||
{
|
||||
if (!proto)
|
||||
return result.succeed();
|
||||
return result.failCantSetProto();
|
||||
}
|
||||
|
||||
|
|
@ -402,21 +391,12 @@ ModuleNamespaceObject::ProxyHandler::getOwnPropertyDescriptor(JSContext* cx, Han
|
|||
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
|
||||
if (JSID_IS_SYMBOL(id)) {
|
||||
Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id));
|
||||
if (symbol == cx->wellKnownSymbols().iterator) {
|
||||
RootedValue enumerateFun(cx, getEnumerateFunction(proxy));
|
||||
desc.object().set(proxy);
|
||||
desc.setConfigurable(false);
|
||||
desc.setEnumerable(false);
|
||||
desc.setValue(enumerateFun);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (symbol == cx->wellKnownSymbols().toStringTag) {
|
||||
RootedValue value(cx, StringValue(cx->names().Module));
|
||||
desc.object().set(proxy);
|
||||
desc.setWritable(false);
|
||||
desc.setEnumerable(false);
|
||||
desc.setConfigurable(true);
|
||||
desc.setConfigurable(false);
|
||||
desc.setValue(value);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -458,8 +438,8 @@ ModuleNamespaceObject::ProxyHandler::has(JSContext* cx, HandleObject proxy, Hand
|
|||
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
|
||||
if (JSID_IS_SYMBOL(id)) {
|
||||
Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id));
|
||||
return symbol == cx->wellKnownSymbols().iterator ||
|
||||
symbol == cx->wellKnownSymbols().toStringTag;
|
||||
*bp = symbol == cx->wellKnownSymbols().toStringTag;
|
||||
return true;
|
||||
}
|
||||
|
||||
*bp = ns->bindings().has(id);
|
||||
|
|
@ -473,23 +453,21 @@ ModuleNamespaceObject::ProxyHandler::get(JSContext* cx, HandleObject proxy, Hand
|
|||
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
|
||||
if (JSID_IS_SYMBOL(id)) {
|
||||
Rooted<JS::Symbol*> symbol(cx, JSID_TO_SYMBOL(id));
|
||||
if (symbol == cx->wellKnownSymbols().iterator) {
|
||||
vp.set(getEnumerateFunction(proxy));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (symbol == cx->wellKnownSymbols().toStringTag) {
|
||||
vp.setString(cx->names().Module);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
vp.setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
ModuleEnvironmentObject* env;
|
||||
Shape* shape;
|
||||
if (!ns->bindings().lookup(id, &env, &shape))
|
||||
return false;
|
||||
if (!ns->bindings().lookup(id, &env, &shape)) {
|
||||
vp.setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedValue value(cx, env->getSlot(shape->slot()));
|
||||
if (value.isMagic(JS_UNINITIALIZED_LEXICAL)) {
|
||||
|
|
@ -526,7 +504,7 @@ ModuleNamespaceObject::ProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject
|
|||
Rooted<ModuleNamespaceObject*> ns(cx, &proxy->as<ModuleNamespaceObject>());
|
||||
RootedObject exports(cx, &ns->exports());
|
||||
uint32_t count;
|
||||
if (!GetLengthProperty(cx, exports, &count) || !props.reserve(props.length() + count))
|
||||
if (!GetLengthProperty(cx, exports, &count) || !props.reserve(props.length() + count + 1))
|
||||
return false;
|
||||
|
||||
Rooted<ValueVector> names(cx, ValueVector(cx));
|
||||
|
|
@ -536,6 +514,8 @@ ModuleNamespaceObject::ProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject
|
|||
for (uint32_t i = 0; i < count; i++)
|
||||
props.infallibleAppend(AtomToId(&names[i].toString()->asAtom()));
|
||||
|
||||
props.infallibleAppend(SYMBOL_TO_JSID(cx->wellKnownSymbols().toStringTag));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1014,7 +994,7 @@ GlobalObject::initModuleProto(JSContext* cx, Handle<GlobalObject*> global)
|
|||
|
||||
static const JSFunctionSpec protoFunctions[] = {
|
||||
JS_SELF_HOSTED_FN("getExportedNames", "ModuleGetExportedNames", 1, 0),
|
||||
JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 3, 0),
|
||||
JS_SELF_HOSTED_FN("resolveExport", "ModuleResolveExport", 2, 0),
|
||||
JS_SELF_HOSTED_FN("declarationInstantiation", "ModuleDeclarationInstantiation", 0, 0),
|
||||
JS_SELF_HOSTED_FN("evaluation", "ModuleEvaluation", 0, 0),
|
||||
JS_FS_END
|
||||
|
|
@ -1164,6 +1144,13 @@ ModuleBuilder::processExport(frontend::ParseNode* pn)
|
|||
bool isDefault = pn->getKind() == PNK_EXPORT_DEFAULT;
|
||||
ParseNode* kid = isDefault ? pn->pn_left : pn->pn_kid;
|
||||
|
||||
if (isDefault && pn->pn_right) {
|
||||
// This is an export default containing an expression.
|
||||
RootedAtom localName(cx_, cx_->names().starDefaultStar);
|
||||
RootedAtom exportName(cx_, cx_->names().default_);
|
||||
return appendExportEntry(exportName, localName);
|
||||
}
|
||||
|
||||
switch (kid->getKind()) {
|
||||
case PNK_EXPORT_SPEC_LIST:
|
||||
MOZ_ASSERT(!isDefault);
|
||||
|
|
@ -1177,53 +1164,46 @@ ModuleBuilder::processExport(frontend::ParseNode* pn)
|
|||
break;
|
||||
|
||||
case PNK_CLASS: {
|
||||
const ClassNode& cls = kid->as<ClassNode>();
|
||||
MOZ_ASSERT(cls.names());
|
||||
RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom);
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
break;
|
||||
const ClassNode& cls = kid->as<ClassNode>();
|
||||
MOZ_ASSERT(cls.names());
|
||||
RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom);
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNK_VAR:
|
||||
case PNK_CONST:
|
||||
case PNK_LET: {
|
||||
MOZ_ASSERT(kid->isArity(PN_LIST));
|
||||
for (ParseNode* var = kid->pn_head; var; var = var->pn_next) {
|
||||
if (var->isKind(PNK_ASSIGN))
|
||||
var = var->pn_left;
|
||||
MOZ_ASSERT(var->isKind(PNK_NAME));
|
||||
RootedAtom localName(cx_, var->pn_atom);
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
MOZ_ASSERT(kid->isArity(PN_LIST));
|
||||
for (ParseNode* var = kid->pn_head; var; var = var->pn_next) {
|
||||
if (var->isKind(PNK_ASSIGN))
|
||||
var = var->pn_left;
|
||||
MOZ_ASSERT(var->isKind(PNK_NAME));
|
||||
RootedAtom localName(cx_, var->pn_atom);
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PNK_FUNCTION: {
|
||||
RootedFunction func(cx_, kid->pn_funbox->function());
|
||||
if (!func->isArrow()) {
|
||||
RootedAtom localName(cx_, func->explicitName());
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
MOZ_ASSERT_IF(isDefault, localName);
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_FALLTHROUGH; // Arrow functions are handled below.
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(isDefault);
|
||||
RootedAtom localName(cx_, cx_->names().starDefaultStar);
|
||||
RootedAtom exportName(cx_, cx_->names().default_);
|
||||
RootedFunction func(cx_, kid->pn_funbox->function());
|
||||
MOZ_ASSERT(!func->isArrow());
|
||||
RootedAtom localName(cx_, func->explicitName());
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
MOZ_ASSERT_IF(isDefault, localName);
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unexpected parse node");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -142,15 +142,8 @@ class ModuleNamespaceObject : public ProxyObject
|
|||
private:
|
||||
struct ProxyHandler : public BaseProxyHandler
|
||||
{
|
||||
enum
|
||||
{
|
||||
EnumerateFunctionSlot = 0
|
||||
};
|
||||
|
||||
ProxyHandler();
|
||||
|
||||
JS::Value getEnumerateFunction(HandleObject proxy) const;
|
||||
|
||||
bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override;
|
||||
bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
|
|
|||
|
|
@ -71,8 +71,6 @@
|
|||
// Used for list, i.e. Array and String, iterators.
|
||||
#define ITERATOR_SLOT_NEXT_INDEX 1
|
||||
#define ITERATOR_SLOT_ITEM_KIND 2
|
||||
// Used for ListIterator.
|
||||
#define ITERATOR_SLOT_NEXT_METHOD 2
|
||||
|
||||
#define ITEM_KIND_KEY 0
|
||||
#define ITEM_KIND_VALUE 1
|
||||
|
|
|
|||
1
js/src/jit-test/modules/empty.js
Normal file
1
js/src/jit-test/modules/empty.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
// Intentionally empty.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import "export-circular-nonexisting-binding-2.js";
|
||||
|
||||
export* from "empty.js";
|
||||
export {x} from "empty.js";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export {x} from "export-circular-nonexisting-binding-1.js";
|
||||
1
js/src/jit-test/modules/export-star-circular-1.js
Normal file
1
js/src/jit-test/modules/export-star-circular-1.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
export* from "export-star-circular-2.js";
|
||||
3
js/src/jit-test/modules/export-star-circular-2.js
Normal file
3
js/src/jit-test/modules/export-star-circular-2.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export {y as x} from "export-star-circular-1.js";
|
||||
|
||||
export var y = "pass";
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
iter = getSelfHostedValue("CreateListIterator")([]);
|
||||
iter.next();
|
||||
iter.next();
|
||||
2
js/src/jit-test/tests/modules/bug-1320993.js
Normal file
2
js/src/jit-test/tests/modules/bug-1320993.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
parseModule("export default (class {})");
|
||||
parseModule("export default (class A {})");
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// |jit-test| module; error:SyntaxError
|
||||
|
||||
import "export-circular-nonexisting-binding-1.js";
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// |jit-test| module; error:SyntaxError
|
||||
|
||||
export { a } from "empty.js";
|
||||
export* from "module1.js";
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
// |jit-test| module
|
||||
|
||||
import { x, y } from "export-star-circular-1.js";
|
||||
|
||||
assertEq(x, "pass");
|
||||
assertEq(y, "pass");
|
||||
|
|
@ -19,9 +19,19 @@ function testHasNames(names, expected) {
|
|||
});
|
||||
}
|
||||
|
||||
function testEqualArrays(actual, expected) {
|
||||
assertEq(Array.isArray(actual), true);
|
||||
assertEq(Array.isArray(expected), true);
|
||||
assertEq(actual.length, expected.length);
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
assertEq(actual[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
let a = moduleRepo['a'] = parseModule(
|
||||
`export var a = 1;
|
||||
export var b = 2;`
|
||||
`// Reflection methods should return these exports alphabetically sorted.
|
||||
export var b = 2;
|
||||
export var a = 1;`
|
||||
);
|
||||
|
||||
let b = moduleRepo['b'] = parseModule(
|
||||
|
|
@ -35,11 +45,16 @@ b.evaluation();
|
|||
testHasNames(getModuleEnvironmentNames(b), ["ns", "x"]);
|
||||
let ns = getModuleEnvironmentValue(b, "ns");
|
||||
testHasNames(Object.keys(ns), ["a", "b"]);
|
||||
assertEq(ns.a, 1);
|
||||
assertEq(ns.b, 2);
|
||||
assertEq(ns.c, undefined);
|
||||
assertEq(getModuleEnvironmentValue(b, "x"), 3);
|
||||
|
||||
// Test module namespace internal methods as defined in 9.4.6
|
||||
assertEq(Object.getPrototypeOf(ns), null);
|
||||
assertThrowsInstanceOf(() => Object.setPrototypeOf(ns, null), TypeError);
|
||||
assertEq(Reflect.setPrototypeOf(ns, null), true);
|
||||
assertEq(Reflect.setPrototypeOf(ns, Object.prototype), false);
|
||||
assertThrowsInstanceOf(() => Object.setPrototypeOf(ns, {}), TypeError);
|
||||
assertThrowsInstanceOf(function() { ns.foo = 1; }, TypeError);
|
||||
assertEq(Object.isExtensible(ns), false);
|
||||
Object.preventExtensions(ns);
|
||||
|
|
@ -59,29 +74,15 @@ desc = Object.getOwnPropertyDescriptor(ns, Symbol.toStringTag);
|
|||
assertEq(desc.value, "Module");
|
||||
assertEq(desc.writable, false);
|
||||
assertEq(desc.enumerable, false);
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.configurable, false);
|
||||
assertEq(typeof desc.get, "undefined");
|
||||
assertEq(typeof desc.set, "undefined");
|
||||
assertEq(Object.prototype.toString.call(ns), "[object Module]");
|
||||
|
||||
// Test @@iterator method.
|
||||
let iteratorFun = ns[Symbol.iterator];
|
||||
assertEq(iteratorFun.name, "[Symbol.iterator]");
|
||||
|
||||
let iterator = ns[Symbol.iterator]();
|
||||
assertEq(iterator[Symbol.iterator](), iterator);
|
||||
assertIteratorNext(iterator, "a");
|
||||
assertIteratorNext(iterator, "b");
|
||||
assertIteratorDone(iterator);
|
||||
|
||||
// The iterator's next method can only be called on the object it was originally
|
||||
// associated with.
|
||||
iterator = ns[Symbol.iterator]();
|
||||
let iterator2 = ns[Symbol.iterator]();
|
||||
assertThrowsInstanceOf(() => iterator.next.call({}), TypeError);
|
||||
assertThrowsInstanceOf(() => iterator.next.call(iterator2), TypeError);
|
||||
assertEq(iterator.next.call(iterator).value, "a");
|
||||
assertEq(iterator2.next.call(iterator2).value, "a");
|
||||
// Test [[OwnPropertyKeys]] internal method.
|
||||
testEqualArrays(Reflect.ownKeys(ns), ["a", "b", Symbol.toStringTag]);
|
||||
testEqualArrays(Object.getOwnPropertyNames(ns), ["a", "b"]);
|
||||
testEqualArrays(Object.getOwnPropertySymbols(ns), [Symbol.toStringTag]);
|
||||
|
||||
// Test cyclic namespace import and access in module evaluation.
|
||||
let c = moduleRepo['c'] =
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@
|
|||
_(IntrinsicGuardToArrayIterator) \
|
||||
_(IntrinsicGuardToMapIterator) \
|
||||
_(IntrinsicGuardToSetIterator) \
|
||||
_(IntrinsicIsListIterator) \
|
||||
_(IntrinsicGuardToStringIterator) \
|
||||
\
|
||||
_(IntrinsicGuardToMapObject) \
|
||||
|
|
|
|||
|
|
@ -285,8 +285,6 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
|
|||
return inlineGuardToClass(callInfo, &SetIteratorObject::class_);
|
||||
case InlinableNative::IntrinsicGuardToStringIterator:
|
||||
return inlineGuardToClass(callInfo, &StringIteratorObject::class_);
|
||||
case InlinableNative::IntrinsicIsListIterator:
|
||||
return inlineHasClass(callInfo, &ListIteratorObject::class_);
|
||||
case InlinableNative::IntrinsicDefineDataProperty:
|
||||
return inlineDefineDataProperty(callInfo);
|
||||
case InlinableNative::IntrinsicObjectHasPrototype:
|
||||
|
|
|
|||
|
|
@ -1135,18 +1135,6 @@ static const JSFunctionSpec string_iterator_methods[] = {
|
|||
JS_FS_END
|
||||
};
|
||||
|
||||
enum {
|
||||
ListIteratorSlotIteratedObject,
|
||||
ListIteratorSlotNextIndex,
|
||||
ListIteratorSlotNextMethod,
|
||||
ListIteratorSlotCount
|
||||
};
|
||||
|
||||
const Class ListIteratorObject::class_ = {
|
||||
"List Iterator",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ListIteratorSlotCount)
|
||||
};
|
||||
|
||||
JSObject*
|
||||
js::ValueToIterator(JSContext* cx, unsigned flags, HandleValue vp)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,12 +151,6 @@ class StringIteratorObject : public JSObject
|
|||
static const Class class_;
|
||||
};
|
||||
|
||||
class ListIteratorObject : public JSObject
|
||||
{
|
||||
public:
|
||||
static const Class class_;
|
||||
};
|
||||
|
||||
bool
|
||||
GetIterator(JSContext* cx, HandleObject obj, unsigned flags, MutableHandleObject objp);
|
||||
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ ModuleEnvironmentObject::createImportBinding(JSContext* cx, HandleAtom importNam
|
|||
{
|
||||
RootedId importNameId(cx, AtomToId(importName));
|
||||
RootedId localNameId(cx, AtomToId(localName));
|
||||
RootedModuleEnvironmentObject env(cx, module->environment());
|
||||
RootedModuleEnvironmentObject env(cx, &module->initialEnvironment());
|
||||
if (!importBindings().putNew(cx, importNameId, env, localNameId)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -856,37 +856,6 @@ intrinsic_NewStringIterator(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_NewListIterator(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 0);
|
||||
|
||||
RootedObject proto(cx, GlobalObject::getOrCreateIteratorPrototype(cx, cx->global()));
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
RootedObject iterator(cx);
|
||||
iterator = NewObjectWithGivenProto(cx, &ListIteratorObject::class_, proto);
|
||||
if (!iterator)
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*iterator);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_ActiveFunction(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 0);
|
||||
|
||||
ScriptFrameIter iter(cx);
|
||||
MOZ_ASSERT(iter.isFunctionFrame());
|
||||
args.rval().setObject(*iter.callee(cx));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_SetCanonicalName(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
|
@ -2290,11 +2259,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||
JS_FN("CallArrayIteratorMethodIfWrapped",
|
||||
CallNonGenericSelfhostedMethod<Is<ArrayIteratorObject>>, 2,0),
|
||||
|
||||
JS_FN("NewListIterator", intrinsic_NewListIterator, 0,0),
|
||||
JS_FN("CallListIteratorMethodIfWrapped",
|
||||
CallNonGenericSelfhostedMethod<Is<ListIteratorObject>>, 2,0),
|
||||
JS_FN("ActiveFunction", intrinsic_ActiveFunction, 0,0),
|
||||
|
||||
JS_FN("_SetCanonicalName", intrinsic_SetCanonicalName, 2,0),
|
||||
|
||||
JS_INLINABLE_FN("GuardToArrayIterator",
|
||||
|
|
@ -2309,9 +2273,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||
JS_INLINABLE_FN("GuardToStringIterator",
|
||||
intrinsic_GuardToBuiltin<StringIteratorObject>, 1,0,
|
||||
IntrinsicGuardToStringIterator),
|
||||
JS_INLINABLE_FN("IsListIterator",
|
||||
intrinsic_IsInstanceOfBuiltin<ListIteratorObject>, 1,0,
|
||||
IntrinsicIsListIterator),
|
||||
|
||||
JS_FN("_CreateMapIterationResultPair", intrinsic_CreateMapIterationResultPair, 0, 0),
|
||||
JS_INLINABLE_FN("_GetNextMapEntryForIterator", intrinsic_GetNextMapEntryForIterator, 2,0,
|
||||
|
|
@ -2533,7 +2494,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||
intrinsic_InstantiateModuleFunctionDeclarations, 1, 0),
|
||||
JS_FN("SetModuleState", intrinsic_SetModuleState, 1, 0),
|
||||
JS_FN("EvaluateModule", intrinsic_EvaluateModule, 1, 0),
|
||||
JS_FN("IsModuleNamespace", intrinsic_IsInstanceOfBuiltin<ModuleNamespaceObject>, 1, 0),
|
||||
JS_FN("NewModuleNamespace", intrinsic_NewModuleNamespace, 2, 0),
|
||||
JS_FN("AddModuleNamespaceBinding", intrinsic_AddModuleNamespaceBinding, 4, 0),
|
||||
JS_FN("ModuleNamespaceExports", intrinsic_ModuleNamespaceExports, 1, 0),
|
||||
|
|
|
|||
|
|
@ -5494,3 +5494,7 @@ pref("dom.storageManager.enabled", false);
|
|||
// >0 = suppress further prompts after the user has canceled the dialog n times
|
||||
// See application preferences for appropriate defaults.
|
||||
pref("prompts.authentication_dialog_abuse_limit", 0);
|
||||
|
||||
// Whether module scripts (<script type="module">) are enabled for content.
|
||||
pref("dom.moduleScripts.enabled", true);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
[create-module-script.html]
|
||||
prefs: [dom.moduleScripts.enabled:true]
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Insert non-async module script</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script>
|
||||
var test = async_test("Create module script")
|
||||
var moduleRan = false;
|
||||
function loadModule() {
|
||||
var script = document.createElement("script");
|
||||
script.onerror = function() {
|
||||
test.step(() => assert_unreached("Should not get an error"));
|
||||
test.done();
|
||||
};
|
||||
script.onload = function() {
|
||||
test.step(() => assert_equals(moduleRan, true));
|
||||
test.done();
|
||||
};
|
||||
script.type = "module";
|
||||
script.src = "support/module.js";
|
||||
script.async = false;
|
||||
document.documentElement.appendChild(script);
|
||||
}
|
||||
</script>
|
||||
<body onload='loadModule()'></body>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export default 42;
|
||||
moduleRan = true;
|
||||
Loading…
Add table
Add a link
Reference in a new issue