diff options
author | Moonchild <moonchild@palemoon.org> | 2020-08-25 05:52:40 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-08-30 09:48:07 +0000 |
commit | e854d58633a2c877778410393914146f7a137495 (patch) | |
tree | a9d1a7e502e515784232af20042ff5fa6db68671 /dom/script/ScriptLoader.cpp | |
parent | d58cb8e11b15c054f0773918cd7fd89ce2a7464e (diff) | |
download | UXP-e854d58633a2c877778410393914146f7a137495.tar UXP-e854d58633a2c877778410393914146f7a137495.tar.gz UXP-e854d58633a2c877778410393914146f7a137495.tar.lz UXP-e854d58633a2c877778410393914146f7a137495.tar.xz UXP-e854d58633a2c877778410393914146f7a137495.zip |
Issue #618 - (async) Keep track of script modes in a single mode state.
This simplifies handling of combinations of async/defer by assigning one and
only one state to scripts.
If async then always async > if defer or module then defer > otherwise blocking.
Diffstat (limited to 'dom/script/ScriptLoader.cpp')
-rw-r--r-- | dom/script/ScriptLoader.cpp | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index 9216be835..59c4ecae4 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -140,6 +140,18 @@ ScriptLoadRequest::AsModuleRequest() return static_cast<ModuleLoadRequest*>(this); } +void +ScriptLoadRequest::SetScriptMode(bool aDeferAttr, bool aAsyncAttr) +{ + if (aAsyncAttr) { + mScriptMode = ScriptMode::eAsync; + } else if (aDeferAttr || IsModuleRequest()) { + mScriptMode = ScriptMode::eDeferred; + } else { + mScriptMode = ScriptMode::eBlocking; + } +} + ////////////////////////////////////////////////////////////// // ScriptLoadRequestList @@ -1049,18 +1061,14 @@ ScriptLoader::StartLoad(ScriptLoadRequest *aRequest, const nsAString &aType, NS_ENSURE_SUCCESS(rv, rv); - nsIScriptElement *script = aRequest->mElement; - bool async = script ? script->GetScriptAsync() : aRequest->mPreloadAsAsync; - bool defer = script ? script->GetScriptDeferred() : aRequest->mPreloadAsDefer; - nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(channel)); if (cos) { - if (aScriptFromHead && !async && !defer) { + if (aScriptFromHead && aRequest->IsBlockingScript()) { // synchronous head scripts block lading of most other non js/css // content such as images cos->AddClassFlags(nsIClassOfService::Leader); - } else if (!defer) { + } else if (!aRequest->IsDeferredScript()) { // other scripts are neither blocked nor prioritized unless marked deferred cos->AddClassFlags(nsIClassOfService::Unblocked); } @@ -1315,8 +1323,15 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) } } - if (!request) { - // no usable preload + if (request) { + // Use a preload request. + + // It's possible these attributes changed since we started the preload, so + // update them here. + request->SetScriptMode(aElement->GetScriptDeferred(), + aElement->GetScriptAsync()); + } else { + // No usable preload found. SRIMetadata sriMetadata; { @@ -1340,8 +1355,10 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) version, ourCORSMode, sriMetadata, ourRefPolicy); request->mIsInline = false; + request->SetScriptMode(aElement->GetScriptDeferred(), + aElement->GetScriptAsync()); - // set aScriptFromHead to false so we don't treat non preloaded scripts as + // Set aScriptFromHead to false so we don't treat non-preloaded scripts as // blockers for full page load. See bug 792438. rv = StartLoad(request, type, false); if (NS_FAILED(rv)) { @@ -1359,7 +1376,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) request->mJSVersion = version; - if (aElement->GetScriptAsync()) { + if (request->IsAsyncScript()) { AddAsyncRequest(request); if (request->IsReadyToRun()) { // The script is available already. Run it ASAP when the event @@ -1386,7 +1403,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) } // we now have a parser-inserted request that may or may not be still // loading - if (aElement->GetScriptDeferred() || request->IsModuleRequest()) { + if (request->IsDeferredScript()) { // We don't want to run this yet. // If we come here, the script is a parser-created script and it has // the defer attribute but not the async attribute. Since a @@ -2605,8 +2622,7 @@ ScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset, Element::StringToCORSMode(aCrossOrigin), sriMetadata, aReferrerPolicy); request->mIsInline = false; - request->mPreloadAsAsync = aAsync; - request->mPreloadAsDefer = aDefer; + request->SetScriptMode(aDefer, aAsync); nsresult rv = StartLoad(request, aType, aScriptFromHead); if (NS_FAILED(rv)) { @@ -2621,6 +2637,9 @@ ScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset, void ScriptLoader::AddDeferRequest(ScriptLoadRequest* aRequest) { + MOZ_ASSERT(aRequest->IsDeferredScript()); + MOZ_ASSERT(!aRequest->mInDeferList && !aRequest->mInAsyncList); + aRequest->mInDeferList = true; mDeferRequests.AppendElement(aRequest); if (mDeferEnabled && aRequest == mDeferRequests.getFirst() && @@ -2634,6 +2653,9 @@ ScriptLoader::AddDeferRequest(ScriptLoadRequest* aRequest) void ScriptLoader::AddAsyncRequest(ScriptLoadRequest* aRequest) { + MOZ_ASSERT(aRequest->IsAsyncScript()); + MOZ_ASSERT(!aRequest->mInDeferList && !aRequest->mInAsyncList); + aRequest->mInAsyncList = true; if (aRequest->IsReadyToRun()) { mLoadedAsyncRequests.AppendElement(aRequest); |