Bug 1342012 - Initial browser support for dynamic import from module scripts r=smaug
This commit is contained in:
@@ -113,9 +113,9 @@ NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(ScriptLoader, mNonAsyncExternalScriptInsertedRequests,
|
||||
mLoadingAsyncRequests, mLoadedAsyncRequests,
|
||||
mDeferRequests, mXSLTRequests, mParserBlockingRequest,
|
||||
mBytecodeEncodingQueue, mPreloads,
|
||||
mPendingChildLoaders, mFetchedModules)
|
||||
mDeferRequests, mXSLTRequests, mDynamicImportRequests,
|
||||
mParserBlockingRequest, mBytecodeEncodingQueue,
|
||||
mPreloads, mPendingChildLoaders, mFetchedModules)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptLoader)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptLoader)
|
||||
@@ -133,6 +133,7 @@ ScriptLoader::ScriptLoader(nsIDocument* aDocument)
|
||||
mGiveUpEncoding(false),
|
||||
mReporter(new ConsoleReportCollector()) {
|
||||
LOG(("ScriptLoader::ScriptLoader %p", this));
|
||||
EnsureModuleHooksInitialized();
|
||||
}
|
||||
|
||||
ScriptLoader::~ScriptLoader() {
|
||||
@@ -164,6 +165,11 @@ ScriptLoader::~ScriptLoader() {
|
||||
req->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req = mDynamicImportRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
FinishDynamicImport(req->AsModuleRequest(), NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
for (ScriptLoadRequest* req =
|
||||
mNonAsyncExternalScriptInsertedRequests.getFirst();
|
||||
req; req = req->getNext()) {
|
||||
@@ -471,7 +477,7 @@ nsresult ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr));
|
||||
|
||||
RefPtr<ModuleScript> moduleScript =
|
||||
new ModuleScript(this, aRequest->mBaseURL);
|
||||
new ModuleScript(this, aRequest->mFetchOptions, aRequest->mBaseURL);
|
||||
aRequest->mModuleScript = moduleScript;
|
||||
|
||||
if (!module) {
|
||||
@@ -689,7 +695,8 @@ RefPtr<GenericPromise> ScriptLoader::StartFetchingModuleAndDependencies(
|
||||
ModuleLoadRequest* aParent, nsIURI* aURI) {
|
||||
MOZ_ASSERT(aURI);
|
||||
|
||||
RefPtr<ModuleLoadRequest> childRequest = new ModuleLoadRequest(aURI, aParent);
|
||||
RefPtr<ModuleLoadRequest> childRequest =
|
||||
ModuleLoadRequest::CreateStaticImport(aURI, aParent);
|
||||
|
||||
aParent->mImports.AppendElement(childRequest);
|
||||
|
||||
@@ -725,6 +732,12 @@ JSObject* HostResolveImportedModule(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
JS::Handle<JSString*> aSpecifier) {
|
||||
// Let referencing module script be referencingModule.[[HostDefined]].
|
||||
if (aReferencingPrivate.isUndefined()) {
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
||||
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) ==
|
||||
aReferencingPrivate);
|
||||
@@ -774,14 +787,114 @@ bool HostPopulateImportMeta(JSContext* aCx,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
static void EnsureModuleResolveHook(JSContext* aCx) {
|
||||
JSRuntime* rt = JS_GetRuntime(aCx);
|
||||
bool HostImportModuleDynamically(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
JS::Handle<JSString*> aSpecifier,
|
||||
JS::Handle<JSObject*> aPromise) {
|
||||
if (aReferencingPrivate.isUndefined()) {
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
||||
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) ==
|
||||
aReferencingPrivate);
|
||||
|
||||
// Attempt to resolve the module specifier.
|
||||
nsAutoJSString string;
|
||||
if (!string.init(aCx, aSpecifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(script, string);
|
||||
if (!uri) {
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_BAD_MODULE_SPECIFIER, string.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a new top-level load request.
|
||||
RefPtr<ModuleLoadRequest> request = ModuleLoadRequest::CreateDynamicImport(
|
||||
uri, script, aReferencingPrivate, aSpecifier, aPromise);
|
||||
|
||||
script->Loader()->StartDynamicImport(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptLoader::StartDynamicImport(ModuleLoadRequest* aRequest) {
|
||||
LOG(("ScriptLoadRequest (%p): Start dynamic import", aRequest));
|
||||
|
||||
mDynamicImportRequests.AppendElement(aRequest);
|
||||
|
||||
nsresult rv = StartLoad(aRequest);
|
||||
if (NS_FAILED(rv)) {
|
||||
FinishDynamicImport(aRequest, rv);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptLoader::FinishDynamicImport(ModuleLoadRequest* aRequest,
|
||||
nsresult aResult) {
|
||||
AutoJSAPI jsapi;
|
||||
MOZ_ALWAYS_TRUE(jsapi.Init(aRequest->mDynamicPromise));
|
||||
FinishDynamicImport(jsapi.cx(), aRequest, aResult);
|
||||
}
|
||||
|
||||
void ScriptLoader::FinishDynamicImport(JSContext* aCx,
|
||||
ModuleLoadRequest* aRequest,
|
||||
nsresult aResult) {
|
||||
LOG(("ScriptLoadRequest (%p): Finish dynamic import %d %d", aRequest,
|
||||
unsigned(aResult), JS_IsExceptionPending(aCx)));
|
||||
|
||||
// Complete the dynamic import, report failures indicated by aResult or as a
|
||||
// pending exception on the context.
|
||||
|
||||
if (NS_FAILED(aResult)) {
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
JS_ReportErrorNumberUC(aCx, js::GetErrorMessage, nullptr,
|
||||
JSMSG_IMPORT_SCRIPT_NOT_FOUND);
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> referencingScript(aCx,
|
||||
aRequest->mDynamicReferencingPrivate);
|
||||
JS::Rooted<JSString*> specifier(aCx, aRequest->mDynamicSpecifier);
|
||||
JS::Rooted<JSObject*> promise(aCx, aRequest->mDynamicPromise);
|
||||
|
||||
JS::FinishDynamicModuleImport(aCx, referencingScript, specifier, promise);
|
||||
|
||||
// FinishDynamicModuleImport clears any pending exception.
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(aCx));
|
||||
|
||||
aRequest->ClearDynamicImport();
|
||||
}
|
||||
|
||||
static void DynamicImportPrefChangedCallback(const char* aPrefName,
|
||||
void* aClosure) {
|
||||
bool enabled = Preferences::GetBool(aPrefName);
|
||||
JS::ModuleDynamicImportHook hook =
|
||||
enabled ? HostImportModuleDynamically : nullptr;
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSRuntime* rt = JS_GetRuntime(jsapi.cx());
|
||||
JS::SetModuleDynamicImportHook(rt, hook);
|
||||
}
|
||||
|
||||
void ScriptLoader::EnsureModuleHooksInitialized() {
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSRuntime* rt = JS_GetRuntime(jsapi.cx());
|
||||
if (JS::GetModuleResolveHook(rt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JS::SetModuleResolveHook(rt, HostResolveImportedModule);
|
||||
JS::SetModuleMetadataHook(rt, HostPopulateImportMeta);
|
||||
JS::SetScriptPrivateFinalizeHook(rt, HostFinalizeTopLevelScript);
|
||||
|
||||
Preferences::RegisterCallbackAndCall(DynamicImportPrefChangedCallback,
|
||||
"javascript.options.dynamicImport",
|
||||
(void*)nullptr);
|
||||
}
|
||||
|
||||
void ScriptLoader::CheckModuleDependenciesLoaded(ModuleLoadRequest* aRequest) {
|
||||
@@ -815,18 +928,34 @@ class ScriptRequestProcessor : public Runnable {
|
||||
: Runnable("dom::ScriptRequestProcessor"),
|
||||
mLoader(aLoader),
|
||||
mRequest(aRequest) {}
|
||||
NS_IMETHOD Run() override { return mLoader->ProcessRequest(mRequest); }
|
||||
NS_IMETHOD Run() override {
|
||||
if (mRequest->IsModuleRequest() &&
|
||||
mRequest->AsModuleRequest()->IsDynamicImport()) {
|
||||
mLoader->ProcessDynamicImport(mRequest->AsModuleRequest());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return mLoader->ProcessRequest(mRequest);
|
||||
}
|
||||
};
|
||||
|
||||
void ScriptLoader::RunScriptWhenSafe(ScriptLoadRequest* aRequest) {
|
||||
auto runnable = new ScriptRequestProcessor(this, aRequest);
|
||||
nsContentUtils::AddScriptRunner(runnable);
|
||||
}
|
||||
|
||||
void ScriptLoader::ProcessLoadedModuleTree(ModuleLoadRequest* aRequest) {
|
||||
MOZ_ASSERT(aRequest->IsReadyToRun());
|
||||
|
||||
if (aRequest->IsTopLevel()) {
|
||||
if (aRequest->mIsInline &&
|
||||
aRequest->Element()->GetParserCreated() == NOT_FROM_PARSER) {
|
||||
if (aRequest->IsDynamicImport()) {
|
||||
MOZ_ASSERT(aRequest->isInList());
|
||||
RefPtr<ScriptLoadRequest> req = mDynamicImportRequests.Steal(aRequest);
|
||||
RunScriptWhenSafe(req);
|
||||
} else if (aRequest->mIsInline &&
|
||||
aRequest->Element()->GetParserCreated() == NOT_FROM_PARSER) {
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new ScriptRequestProcessor(this, aRequest));
|
||||
RunScriptWhenSafe(aRequest);
|
||||
} else {
|
||||
MaybeMoveToLoadedList(aRequest);
|
||||
ProcessPendingRequests();
|
||||
@@ -884,8 +1013,6 @@ bool ScriptLoader::InstantiateModuleTree(ModuleLoadRequest* aRequest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EnsureModuleResolveHook(jsapi.cx());
|
||||
|
||||
JS::Rooted<JSObject*> module(jsapi.cx(), moduleScript->ModuleRecord());
|
||||
bool ok = NS_SUCCEEDED(nsJSUtils::ModuleInstantiate(jsapi.cx(), module));
|
||||
|
||||
@@ -1210,7 +1337,8 @@ ScriptLoadRequest* ScriptLoader::CreateLoadRequest(
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aKind == ScriptKind::eModule);
|
||||
return new ModuleLoadRequest(aURI, fetchOptions, aIntegrity, referrer, this);
|
||||
return ModuleLoadRequest::CreateTopLevel(aURI, fetchOptions, aIntegrity,
|
||||
referrer, this);
|
||||
}
|
||||
|
||||
bool ScriptLoader::ProcessScriptElement(nsIScriptElement* aElement) {
|
||||
@@ -1538,7 +1666,7 @@ bool ScriptLoader::ProcessInlineScript(nsIScriptElement* aElement,
|
||||
NS_ASSERTION(
|
||||
!nsContentUtils::IsSafeToRunScript(),
|
||||
"A script-inserted script is inserted without an update batch?");
|
||||
nsContentUtils::AddScriptRunner(new ScriptRequestProcessor(this, request));
|
||||
RunScriptWhenSafe(request);
|
||||
return false;
|
||||
}
|
||||
if (aElement->GetParserCreated() == FROM_PARSER_NETWORK &&
|
||||
@@ -1915,8 +2043,7 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
if (request->mModuleScript &&
|
||||
!request->mModuleScript->HasErrorToRethrow()) {
|
||||
if (request->mModuleScript) {
|
||||
if (!InstantiateModuleTree(request)) {
|
||||
request->mModuleScript = nullptr;
|
||||
}
|
||||
@@ -2018,6 +2145,25 @@ nsresult ScriptLoader::ProcessRequest(ScriptLoadRequest* aRequest) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
void ScriptLoader::ProcessDynamicImport(ModuleLoadRequest* aRequest) {
|
||||
if (aRequest->mModuleScript) {
|
||||
if (!InstantiateModuleTree(aRequest)) {
|
||||
aRequest->mModuleScript = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (aRequest->mModuleScript) {
|
||||
rv = EvaluateScript(aRequest);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
FinishDynamicImport(aRequest, rv);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ScriptLoader::FireScriptAvailable(nsresult aResult,
|
||||
ScriptLoadRequest* aRequest) {
|
||||
for (int32_t i = 0; i < mObservers.Count(); i++) {
|
||||
@@ -2062,7 +2208,7 @@ already_AddRefed<nsIScriptGlobalObject> ScriptLoader::GetScriptGlobalObject() {
|
||||
}
|
||||
|
||||
nsresult ScriptLoader::FillCompileOptionsForRequest(
|
||||
const AutoJSAPI& jsapi, ScriptLoadRequest* aRequest,
|
||||
const mozilla::dom::AutoJSAPI& jsapi, ScriptLoadRequest* aRequest,
|
||||
JS::Handle<JSObject*> aScopeChain, JS::CompileOptions* aOptions) {
|
||||
// It's very important to use aRequest->mURI, not the final URI of the channel
|
||||
// aRequest ended up getting script data from, as the script filename.
|
||||
@@ -2203,6 +2349,19 @@ nsresult ScriptLoader::FillCompileOptionsForRequest(
|
||||
return true;
|
||||
}
|
||||
|
||||
class MOZ_RAII AutoSetProcessingScriptTag {
|
||||
nsCOMPtr<nsIScriptContext> mContext;
|
||||
bool mOldTag;
|
||||
|
||||
public:
|
||||
explicit AutoSetProcessingScriptTag(nsIScriptContext* aContext)
|
||||
: mContext(aContext), mOldTag(mContext->GetProcessingScriptTag()) {
|
||||
mContext->SetProcessingScriptTag(true);
|
||||
}
|
||||
|
||||
~AutoSetProcessingScriptTag() { mContext->SetProcessingScriptTag(mOldTag); }
|
||||
};
|
||||
|
||||
nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
using namespace mozilla::Telemetry;
|
||||
MOZ_ASSERT(aRequest->IsReadyToRun());
|
||||
@@ -2242,8 +2401,8 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
JSContext* cx = aes.cx();
|
||||
JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject());
|
||||
|
||||
bool oldProcessingScriptTag = context->GetProcessingScriptTag();
|
||||
context->SetProcessingScriptTag(true);
|
||||
AutoSetProcessingScriptTag setProcessingScriptTag(context);
|
||||
|
||||
nsresult rv;
|
||||
{
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
@@ -2255,8 +2414,6 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
// currentScript is set to null for modules.
|
||||
AutoCurrentScriptUpdater scriptUpdater(this, nullptr);
|
||||
|
||||
EnsureModuleResolveHook(cx);
|
||||
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
MOZ_ASSERT(request->mModuleScript);
|
||||
MOZ_ASSERT(!request->mOffThreadToken);
|
||||
@@ -2267,7 +2424,13 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
aRequest));
|
||||
JS::Rooted<JS::Value> error(cx, moduleScript->ErrorToRethrow());
|
||||
JS_SetPendingException(cx, error);
|
||||
return NS_OK; // An error is reported by AutoEntryScript.
|
||||
|
||||
// For a dynamic import, the promise is rejected. Otherwise an error is
|
||||
// either reported by AutoEntryScript.
|
||||
if (request->IsDynamicImport()) {
|
||||
FinishDynamicImport(cx, request, NS_OK);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> module(cx, moduleScript->ModuleRecord());
|
||||
@@ -2280,9 +2443,16 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
|
||||
rv = nsJSUtils::ModuleEvaluate(cx, module);
|
||||
MOZ_ASSERT(NS_FAILED(rv) == aes.HasException());
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("ScriptLoadRequest (%p): evaluation failed", aRequest));
|
||||
rv = NS_OK; // An error is reported by AutoEntryScript.
|
||||
// For a dynamic import, the promise is rejected. Otherwise an error is
|
||||
// either reported by AutoEntryScript.
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
if (request->IsDynamicImport()) {
|
||||
FinishDynamicImport(cx, request, rv);
|
||||
}
|
||||
|
||||
aRequest->mCacheInfo = nullptr;
|
||||
@@ -2354,8 +2524,7 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
|
||||
// Queue the current script load request to later save the bytecode.
|
||||
if (script && encodeBytecode) {
|
||||
aRequest->mScript = script;
|
||||
HoldJSObjects(aRequest);
|
||||
aRequest->SetScript(script);
|
||||
TRACE_FOR_TEST(aRequest->Element(), "scriptloader_encode");
|
||||
MOZ_ASSERT(aRequest->mBytecodeOffset ==
|
||||
aRequest->mScriptBytecode.length());
|
||||
@@ -2379,7 +2548,6 @@ nsresult ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest) {
|
||||
MaybeTriggerBytecodeEncoding();
|
||||
}
|
||||
|
||||
context->SetProcessingScriptTag(oldProcessingScriptTag);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -2567,7 +2735,8 @@ bool ScriptLoader::HasPendingRequests() {
|
||||
return mParserBlockingRequest || !mXSLTRequests.isEmpty() ||
|
||||
!mLoadedAsyncRequests.isEmpty() ||
|
||||
!mNonAsyncExternalScriptInsertedRequests.isEmpty() ||
|
||||
!mDeferRequests.isEmpty() || !mPendingChildLoaders.IsEmpty();
|
||||
!mDeferRequests.isEmpty() || !mDynamicImportRequests.isEmpty() ||
|
||||
!mPendingChildLoaders.IsEmpty();
|
||||
}
|
||||
|
||||
void ScriptLoader::ProcessPendingRequestsAsync() {
|
||||
@@ -2980,12 +3149,31 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
||||
RefPtr<ScriptLoadRequest> req = mXSLTRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->IsModuleRequest() && !aRequest->IsPreload()) {
|
||||
} else if (aRequest->IsPreload()) {
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
aRequest->Cancel();
|
||||
}
|
||||
if (aRequest->IsTopLevel()) {
|
||||
MOZ_ALWAYS_TRUE(
|
||||
mPreloads.RemoveElement(aRequest, PreloadRequestComparator()));
|
||||
}
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_PRELOAD_RESULT::LoadError);
|
||||
} else if (aRequest->IsModuleRequest()) {
|
||||
ModuleLoadRequest* modReq = aRequest->AsModuleRequest();
|
||||
MOZ_ASSERT(!modReq->IsTopLevel());
|
||||
MOZ_ASSERT(!modReq->isInList());
|
||||
modReq->Cancel();
|
||||
// A single error is fired for the top level module.
|
||||
if (modReq->IsDynamicImport()) {
|
||||
MOZ_ASSERT(modReq->IsTopLevel());
|
||||
if (aRequest->isInList()) {
|
||||
RefPtr<ScriptLoadRequest> req = mDynamicImportRequests.Steal(aRequest);
|
||||
modReq->Cancel();
|
||||
FinishDynamicImport(modReq, aResult);
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!modReq->IsTopLevel());
|
||||
MOZ_ASSERT(!modReq->isInList());
|
||||
modReq->Cancel();
|
||||
// The error is handled for the top level module.
|
||||
}
|
||||
} else if (mParserBlockingRequest == aRequest) {
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
mParserBlockingRequest = nullptr;
|
||||
@@ -3000,16 +3188,6 @@ void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
|
||||
FireScriptAvailable(aResult, aRequest);
|
||||
ContinueParserAsync(aRequest);
|
||||
mCurrentParserInsertedScript = oldParserInsertedScript;
|
||||
} else if (aRequest->IsPreload()) {
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
aRequest->Cancel();
|
||||
}
|
||||
if (aRequest->IsTopLevel()) {
|
||||
MOZ_ALWAYS_TRUE(
|
||||
mPreloads.RemoveElement(aRequest, PreloadRequestComparator()));
|
||||
}
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
AccumulateCategorical(LABELS_DOM_SCRIPT_PRELOAD_RESULT::LoadError);
|
||||
} else {
|
||||
// This happens for blocking requests cancelled by ParsingComplete().
|
||||
MOZ_ASSERT(aRequest->IsCanceled());
|
||||
@@ -3110,11 +3288,12 @@ nsresult ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
|
||||
mLoadingAsyncRequests.Contains(aRequest) ||
|
||||
mNonAsyncExternalScriptInsertedRequests.Contains(aRequest) ||
|
||||
mXSLTRequests.Contains(aRequest) ||
|
||||
mDynamicImportRequests.Contains(aRequest) ||
|
||||
(aRequest->IsModuleRequest() &&
|
||||
!aRequest->AsModuleRequest()->IsTopLevel() &&
|
||||
!aRequest->isInList()) ||
|
||||
mPreloads.Contains(aRequest, PreloadRequestComparator()) ||
|
||||
mParserBlockingRequest,
|
||||
mParserBlockingRequest == aRequest,
|
||||
"aRequest should be pending!");
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
@@ -3191,6 +3370,13 @@ void ScriptLoader::ParsingComplete(bool aTerminated) {
|
||||
mLoadedAsyncRequests.Clear();
|
||||
mNonAsyncExternalScriptInsertedRequests.Clear();
|
||||
mXSLTRequests.Clear();
|
||||
|
||||
for (ScriptLoadRequest* req = mDynamicImportRequests.getFirst(); req;
|
||||
req = req->getNext()) {
|
||||
req->Cancel();
|
||||
FinishDynamicImport(req->AsModuleRequest(), NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
if (mParserBlockingRequest) {
|
||||
mParserBlockingRequest->Cancel();
|
||||
mParserBlockingRequest = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user