summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-08-24 11:11:17 +0000
committerMoonchild <moonchild@palemoon.org>2020-08-30 09:47:49 +0000
commitd58cb8e11b15c054f0773918cd7fd89ce2a7464e (patch)
tree380d82f3b0ad12222da2338da83408b97b402634
parent429a7bdb93e443236f4a4b04afc9a12c78f54247 (diff)
downloadUXP-d58cb8e11b15c054f0773918cd7fd89ce2a7464e.tar
UXP-d58cb8e11b15c054f0773918cd7fd89ce2a7464e.tar.gz
UXP-d58cb8e11b15c054f0773918cd7fd89ce2a7464e.tar.lz
UXP-d58cb8e11b15c054f0773918cd7fd89ce2a7464e.tar.xz
UXP-d58cb8e11b15c054f0773918cd7fd89ce2a7464e.zip
Issue #618 - (async, preload) Correctly pass info about async/defer to parser.
This makes sure we don't block body-referred sub-resources by head-referenced defer and async scripts. This is important for all script loads, not just modules, but is added here because it was run into while implementing modules.
-rw-r--r--dom/script/ScriptLoader.cpp12
-rw-r--r--dom/script/ScriptLoader.h6
-rw-r--r--parser/html/nsHtml5SpeculativeLoad.cpp11
-rw-r--r--parser/html/nsHtml5SpeculativeLoad.h13
-rw-r--r--parser/html/nsHtml5TreeBuilderCppSupplement.h16
-rw-r--r--parser/html/nsHtml5TreeOpExecutor.cpp6
-rw-r--r--parser/html/nsHtml5TreeOpExecutor.h4
7 files changed, 53 insertions, 15 deletions
diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp
index 58f0c0bbe..9216be835 100644
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -1050,15 +1050,17 @@ 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 &&
- !(script && (script->GetScriptAsync() || script->GetScriptDeferred()))) {
+ if (aScriptFromHead && !async && !defer) {
// synchronous head scripts block lading of most other non js/css
// content such as images
cos->AddClassFlags(nsIClassOfService::Leader);
- } else if (!(script && script->GetScriptDeferred())) {
+ } else if (!defer) {
// other scripts are neither blocked nor prioritized unless marked deferred
cos->AddClassFlags(nsIClassOfService::Unblocked);
}
@@ -2571,6 +2573,8 @@ ScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead,
+ bool aAsync,
+ bool aDefer,
const mozilla::net::ReferrerPolicy aReferrerPolicy)
{
NS_ENSURE_TRUE_VOID(mDocument);
@@ -2601,6 +2605,8 @@ ScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
Element::StringToCORSMode(aCrossOrigin), sriMetadata,
aReferrerPolicy);
request->mIsInline = false;
+ request->mPreloadAsAsync = aAsync;
+ request->mPreloadAsDefer = aDefer;
nsresult rv = StartLoad(request, aType, aScriptFromHead);
if (NS_FAILED(rv)) {
diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h
index 61680a3ee..b7e20c7ee 100644
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -76,6 +76,8 @@ public:
mHasSourceMapURL(false),
mInDeferList(false),
mInAsyncList(false),
+ mPreloadAsAsync(false),
+ mPreloadAsDefer(false),
mIsNonAsyncScriptInserted(false),
mIsXSLT(false),
mIsCanceled(false),
@@ -161,6 +163,8 @@ public:
bool mHasSourceMapURL; // Does the HTTP header have a source map url?
bool mInDeferList; // True if we live in mDeferRequests.
bool mInAsyncList; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
+ bool mPreloadAsAsync; // True if this is a preload request and the script is async
+ bool mPreloadAsDefer; // True if this is a preload request and the script is defer
bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
bool mIsXSLT; // True if we live in mXSLTRequests.
bool mIsCanceled; // True if we have been explicitly canceled.
@@ -459,6 +463,8 @@ public:
const nsAString &aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead,
+ bool aAsync,
+ bool aDefer,
const mozilla::net::ReferrerPolicy aReferrerPolicy);
/**
diff --git a/parser/html/nsHtml5SpeculativeLoad.cpp b/parser/html/nsHtml5SpeculativeLoad.cpp
index 8ffc4d063..7bae0699f 100644
--- a/parser/html/nsHtml5SpeculativeLoad.cpp
+++ b/parser/html/nsHtml5SpeculativeLoad.cpp
@@ -6,9 +6,12 @@
#include "nsHtml5TreeOpExecutor.h"
nsHtml5SpeculativeLoad::nsHtml5SpeculativeLoad()
+ :
#ifdef DEBUG
- : mOpCode(eSpeculativeLoadUninitialized)
+ mOpCode(eSpeculativeLoadUninitialized),
#endif
+ mIsAsync(false),
+ mIsDefer(false)
{
MOZ_COUNT_CTOR(nsHtml5SpeculativeLoad);
}
@@ -48,11 +51,13 @@ nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
break;
case eSpeculativeLoadScript:
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
- mCrossOrigin, mIntegrity, false);
+ mCrossOrigin, mIntegrity, false,
+ mIsAsync, mIsDefer);
break;
case eSpeculativeLoadScriptFromHead:
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
- mCrossOrigin, mIntegrity, true);
+ mCrossOrigin, mIntegrity, true,
+ mIsAsync, mIsDefer);
break;
case eSpeculativeLoadStyle:
aExecutor->PreloadStyle(mUrl, mCharset, mCrossOrigin, mIntegrity);
diff --git a/parser/html/nsHtml5SpeculativeLoad.h b/parser/html/nsHtml5SpeculativeLoad.h
index 6f1365bcf..fcc84de4f 100644
--- a/parser/html/nsHtml5SpeculativeLoad.h
+++ b/parser/html/nsHtml5SpeculativeLoad.h
@@ -128,7 +128,9 @@ class nsHtml5SpeculativeLoad {
nsHtml5String aType,
nsHtml5String aCrossOrigin,
nsHtml5String aIntegrity,
- bool aParserInHead)
+ bool aParserInHead,
+ bool aAsync,
+ bool aDefer)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
@@ -139,6 +141,8 @@ class nsHtml5SpeculativeLoad {
aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
aCrossOrigin.ToString(mCrossOrigin);
aIntegrity.ToString(mIntegrity);
+ mIsAsync = aAsync;
+ mIsDefer = aDefer;
}
inline void InitStyle(nsHtml5String aUrl,
@@ -221,6 +225,13 @@ class nsHtml5SpeculativeLoad {
private:
eHtml5SpeculativeLoad mOpCode;
+
+ /**
+ * Whether the refering element has async and/or defer attributes.
+ */
+ bool mIsAsync;
+ bool mIsDefer;
+
nsString mUrl;
nsString mReferrerPolicy;
nsString mMetaCSP;
diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h
index aacc5a3e0..9709396c7 100644
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -167,16 +167,20 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
+ bool async =
+ aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC);
+ bool defer =
+ aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
mSpeculativeLoadQueue.AppendElement()->InitScript(
url,
charset,
type,
crossOrigin,
integrity,
- mode == NS_HTML5TREE_BUILDER_IN_HEAD);
- mCurrentHtmlScriptIsAsyncOrDefer =
- aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
- aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
+ mode == NS_HTML5TREE_BUILDER_IN_HEAD,
+ async,
+ defer);
+ mCurrentHtmlScriptIsAsyncOrDefer = async || defer;
}
} else if (nsHtml5Atoms::link == aName) {
nsHtml5String rel =
@@ -279,7 +283,9 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
type,
crossOrigin,
integrity,
- mode == NS_HTML5TREE_BUILDER_IN_HEAD);
+ mode == NS_HTML5TREE_BUILDER_IN_HEAD,
+ false /* async */,
+ false /* defer */);
}
} else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
index 3ed634d0c..9be7f3b0d 100644
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -921,14 +921,16 @@ nsHtml5TreeOpExecutor::PreloadScript(const nsAString& aURL,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity,
- bool aScriptFromHead)
+ bool aScriptFromHead,
+ bool aAsync,
+ bool aDefer)
{
nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
if (!uri) {
return;
}
mDocument->ScriptLoader()->PreloadURI(uri, aCharset, aType, aCrossOrigin,
- aIntegrity, aScriptFromHead,
+ aIntegrity, aScriptFromHead, aAsync, aDefer,
mSpeculationReferrerPolicy);
}
diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h
index c4b6a4594..64a5daa96 100644
--- a/parser/html/nsHtml5TreeOpExecutor.h
+++ b/parser/html/nsHtml5TreeOpExecutor.h
@@ -249,7 +249,9 @@ class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity,
- bool aScriptFromHead);
+ bool aScriptFromHead,
+ bool aAsync,
+ bool aDefer);
void PreloadStyle(const nsAString& aURL, const nsAString& aCharset,
const nsAString& aCrossOrigin,