Bug 1342416 - Preload module scripts r=baku
This commit is contained in:
@@ -511,6 +511,7 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv) == (module != nullptr));
|
||||
|
||||
RefPtr<ModuleScript> moduleScript = new ModuleScript(this, aRequest->mBaseURL);
|
||||
aRequest->mModuleScript = moduleScript;
|
||||
|
||||
@@ -999,7 +1000,7 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// Check whether the module has been fetched or is currently being fetched,
|
||||
// and if so wait for it.
|
||||
// and if so wait for it rather than starting a new fetch.
|
||||
ModuleLoadRequest* request = aRequest->AsModuleRequest();
|
||||
if (ModuleMapContainsURL(request->mURI)) {
|
||||
LOG(("ScriptLoadRequest (%p): Waiting for module fetch", aRequest));
|
||||
@@ -1009,10 +1010,6 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
||||
&ModuleLoadRequest::LoadFailed);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Otherwise put the URL in the module map and mark it as fetching.
|
||||
SetModuleFetchStarted(request);
|
||||
LOG(("ScriptLoadRequest (%p): Start fetching module", aRequest));
|
||||
}
|
||||
|
||||
nsContentPolicyType contentPolicyType = aRequest->IsPreload()
|
||||
@@ -1175,7 +1172,17 @@ ScriptLoader::StartLoad(ScriptLoadRequest* aRequest)
|
||||
rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), handler);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return channel->AsyncOpen2(loader);
|
||||
rv = channel->AsyncOpen2(loader);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aRequest->IsModuleRequest()) {
|
||||
// We successfully started fetching a module so put its URL in the module
|
||||
// map and mark it as fetching.
|
||||
SetModuleFetchStarted(aRequest->AsModuleRequest());
|
||||
LOG(("ScriptLoadRequest (%p): Start fetching module", aRequest));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1226,12 +1233,8 @@ ScriptLoader::CreateLoadRequest(ScriptKind aKind,
|
||||
nsIURI* referrer = mDocument->GetDocumentURI();
|
||||
|
||||
if (aKind == ScriptKind::eClassic) {
|
||||
ScriptLoadRequest* slr = new ScriptLoadRequest(aKind, aURI, aElement,
|
||||
aCORSMode, aIntegrity,
|
||||
referrer, aReferrerPolicy);
|
||||
|
||||
LOG(("ScriptLoader %p creates ScriptLoadRequest %p", this, slr));
|
||||
return slr;
|
||||
return new ScriptLoadRequest(aKind, aURI, aElement, aCORSMode, aIntegrity,
|
||||
referrer, aReferrerPolicy);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aKind == ScriptKind::eModule);
|
||||
@@ -1313,6 +1316,9 @@ ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
nsAutoString aTypeAttr,
|
||||
nsIContent* aScriptContent)
|
||||
{
|
||||
LOG(("ScriptLoader (%p): Process external script for element %p",
|
||||
this, aElement));
|
||||
|
||||
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
|
||||
if (!scriptURI) {
|
||||
// Asynchronously report the failure to create a URI object
|
||||
@@ -1327,6 +1333,8 @@ ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
|
||||
if (request && NS_FAILED(CheckContentPolicy(mDocument, aElement, request->mURI,
|
||||
aTypeAttr, false))) {
|
||||
LOG(("ScriptLoader (%p): content policy check failed for preload", this));
|
||||
|
||||
// Probably plans have changed; even though the preload was allowed seems
|
||||
// like the actual load is not; let's cancel the preload request.
|
||||
request->Cancel();
|
||||
@@ -1337,6 +1345,8 @@ ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
if (request) {
|
||||
// Use the preload request.
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Using preload request", request.get()));
|
||||
|
||||
// It's possible these attributes changed since we started the preload so
|
||||
// update them here.
|
||||
request->SetScriptMode(aElement->GetScriptDeferred(),
|
||||
@@ -1371,6 +1381,9 @@ ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
// keep request->mScriptFromHead to false so we don't treat non preloaded
|
||||
// scripts as blockers for full page load. See bug 792438.
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Created request for external script",
|
||||
request.get()));
|
||||
|
||||
nsresult rv = StartLoad(request);
|
||||
if (NS_FAILED(rv)) {
|
||||
ReportErrorToConsole(request, rv);
|
||||
@@ -1389,8 +1402,9 @@ ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement,
|
||||
}
|
||||
}
|
||||
|
||||
// Should still be in loading stage of script.
|
||||
NS_ASSERTION(!request->InCompilingStage(),
|
||||
// We should still be in loading stage of script unless we're loading a
|
||||
// module.
|
||||
NS_ASSERTION(!request->InCompilingStage() || request->IsModuleRequest(),
|
||||
"Request should not yet be in compiling stage.");
|
||||
|
||||
if (request->IsAsyncScript()) {
|
||||
@@ -1581,6 +1595,8 @@ ScriptLoadRequest*
|
||||
ScriptLoader::LookupPreloadRequest(nsIScriptElement* aElement,
|
||||
ScriptKind aScriptKind)
|
||||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
nsTArray<PreloadInfo>::index_type i =
|
||||
mPreloads.IndexOf(aElement->GetScriptURI(), 0, PreloadURIComparator());
|
||||
if (i == nsTArray<PreloadInfo>::NoIndex) {
|
||||
@@ -2058,14 +2074,16 @@ ScriptLoader::FillCompileOptionsForRequest(const AutoJSAPI&jsapi,
|
||||
aOptions->setMutedErrors(!subsumes);
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> elementVal(cx);
|
||||
MOZ_ASSERT(aRequest->mElement);
|
||||
if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, aRequest->mElement,
|
||||
&elementVal,
|
||||
/* aAllowWrapping = */ true))) {
|
||||
MOZ_ASSERT(elementVal.isObject());
|
||||
aOptions->setElement(&elementVal.toObject());
|
||||
if (!aRequest->IsModuleRequest()) {
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> elementVal(cx);
|
||||
MOZ_ASSERT(aRequest->mElement);
|
||||
if (NS_SUCCEEDED(nsContentUtils::WrapNative(cx, aRequest->mElement,
|
||||
&elementVal,
|
||||
/* aAllowWrapping = */ true))) {
|
||||
MOZ_ASSERT(elementVal.isObject());
|
||||
aOptions->setElement(&elementVal.toObject());
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -2223,6 +2241,12 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
|
||||
JS::Rooted<JSObject*> module(cx, moduleScript->ModuleRecord());
|
||||
MOZ_ASSERT(module);
|
||||
|
||||
if (!moduleScript->SourceElementAssociated()) {
|
||||
rv = nsJSUtils::InitModuleSourceElement(cx, module, aRequest->mElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
moduleScript->SetSourceElementAssociated();
|
||||
}
|
||||
|
||||
rv = nsJSUtils::ModuleEvaluate(cx, module);
|
||||
MOZ_ASSERT(NS_FAILED(rv) == aes.HasException());
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -2958,7 +2982,7 @@ ScriptLoader::HandleLoadError(ScriptLoadRequest *aRequest, nsresult aResult)
|
||||
RefPtr<ScriptLoadRequest> req = mXSLTRequests.Steal(aRequest);
|
||||
FireScriptAvailable(aResult, req);
|
||||
}
|
||||
} else if (aRequest->IsModuleRequest()) {
|
||||
} else if (aRequest->IsModuleRequest() && !aRequest->IsPreload()) {
|
||||
ModuleLoadRequest* modReq = aRequest->AsModuleRequest();
|
||||
MOZ_ASSERT(!modReq->IsTopLevel());
|
||||
MOZ_ASSERT(!modReq->isInList());
|
||||
@@ -2978,9 +3002,19 @@ ScriptLoader::HandleLoadError(ScriptLoadRequest *aRequest, nsresult aResult)
|
||||
FireScriptAvailable(aResult, aRequest);
|
||||
ContinueParserAsync(aRequest);
|
||||
mCurrentParserInsertedScript = oldParserInsertedScript;
|
||||
} else {
|
||||
mPreloads.RemoveElement(aRequest, PreloadRequestComparator());
|
||||
} 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());
|
||||
MOZ_ASSERT(!aRequest->isInList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3186,19 +3220,26 @@ ScriptLoader::PreloadURI(nsIURI* aURI,
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptKind scriptKind = ScriptKind::eClassic;
|
||||
|
||||
if (mDocument->ModuleScriptsEnabled()) {
|
||||
// Don't load nomodule scripts.
|
||||
if (aNoModule) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Preload module scripts.
|
||||
if (aType.LowerCaseEqualsASCII("module")) {
|
||||
return;
|
||||
static const char kASCIIWhitespace[] = "\t\n\f\r ";
|
||||
|
||||
nsAutoString type(aType);
|
||||
type.Trim(kASCIIWhitespace);
|
||||
if (type.LowerCaseEqualsASCII("module")) {
|
||||
scriptKind = ScriptKind::eModule;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aType.IsEmpty() && !nsContentUtils::IsJavascriptMIMEType(aType)) {
|
||||
if (scriptKind == ScriptKind::eClassic &&
|
||||
!aType.IsEmpty() && !nsContentUtils::IsJavascriptMIMEType(aType))
|
||||
{
|
||||
// Unknown type. Don't load it.
|
||||
return;
|
||||
}
|
||||
@@ -3207,7 +3248,7 @@ ScriptLoader::PreloadURI(nsIURI* aURI,
|
||||
GetSRIMetadata(aIntegrity, &sriMetadata);
|
||||
|
||||
RefPtr<ScriptLoadRequest> request =
|
||||
CreateLoadRequest(ScriptKind::eClassic, aURI, nullptr,
|
||||
CreateLoadRequest(scriptKind, aURI, nullptr,
|
||||
Element::StringToCORSMode(aCrossOrigin), sriMetadata,
|
||||
aReferrerPolicy);
|
||||
request->mTriggeringPrincipal = mDocument->NodePrincipal();
|
||||
@@ -3215,6 +3256,13 @@ ScriptLoader::PreloadURI(nsIURI* aURI,
|
||||
request->mScriptFromHead = aScriptFromHead;
|
||||
request->SetScriptMode(aDefer, aAsync);
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString url;
|
||||
aURI->GetAsciiSpec(url);
|
||||
LOG(("ScriptLoadRequest (%p): Created preload request for %s",
|
||||
request.get(), url.get()));
|
||||
}
|
||||
|
||||
nsresult rv = StartLoad(request);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user