diff options
author | Moonchild <moonchild@palemoon.org> | 2020-08-25 07:06:43 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-08-25 07:06:43 +0000 |
commit | b78f53ffb09a6aae6dbdc069c7cdd42d11b5eed2 (patch) | |
tree | e4c6248559f4fe559cfe32df5ccf81a3bdcb47ab | |
parent | 8b397a63af13f7dfc127b1105f33cd652b2f1f6d (diff) | |
download | uxp-b78f53ffb09a6aae6dbdc069c7cdd42d11b5eed2.tar.gz |
Issue #618 - (async) Implement async attribute for inline module scripts.
This commit does several things:
- Moves the pref check from ScriptLoader to ns[I]Document so it can be called on
the document.
- Changes the atrribute freezing function to a better name that takes the
document as a parameter.
- Sets the proper async/defer attributes on HTML script elements based on
keywords and whether they are module scripts or not.
-rw-r--r-- | dom/base/nsDocument.cpp | 13 | ||||
-rw-r--r-- | dom/base/nsIDocument.h | 2 | ||||
-rw-r--r-- | dom/html/HTMLScriptElement.cpp | 23 | ||||
-rw-r--r-- | dom/html/HTMLScriptElement.h | 2 | ||||
-rw-r--r-- | dom/script/ScriptElement.cpp | 4 | ||||
-rw-r--r-- | dom/script/ScriptLoader.cpp | 33 | ||||
-rw-r--r-- | dom/script/ScriptLoader.h | 2 | ||||
-rw-r--r-- | dom/script/nsIScriptElement.h | 29 | ||||
-rw-r--r-- | dom/svg/SVGScriptElement.cpp | 2 | ||||
-rw-r--r-- | dom/svg/SVGScriptElement.h | 2 | ||||
-rw-r--r-- | parser/html/nsHtml5TreeOperation.cpp | 2 |
11 files changed, 73 insertions, 41 deletions
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index dc4b23f2ce..76490e6b44 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -12446,3 +12446,16 @@ nsIDocument::GetSelection(ErrorResult& aRv) return nsGlobalWindow::Cast(window)->GetSelection(aRv); } + +bool +nsIDocument::ModuleScriptsEnabled() +{ + static bool sEnabledForContent = false; + static bool sCachedPref = false; + if (!sCachedPref) { + sCachedPref = true; + Preferences::AddBoolVarCache(&sEnabledForContent, "dom.moduleScripts.enabled", false); + } + + return nsContentUtils::IsChromeDoc(this) || sEnabledForContent; +}
\ No newline at end of file diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 33aac3a3d6..21cd0aaf7c 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2851,6 +2851,8 @@ public: return mIsWebComponentsEnabled; } + bool ModuleScriptsEnabled(); + protected: bool GetUseCounter(mozilla::UseCounter aUseCounter) { diff --git a/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp index 5b727280f5..f1463d6aa4 100644 --- a/dom/html/HTMLScriptElement.cpp +++ b/dom/html/HTMLScriptElement.cpp @@ -280,12 +280,20 @@ HTMLScriptElement::GetScriptCharset(nsAString& charset) } void -HTMLScriptElement::FreezeUriAsyncDefer() +HTMLScriptElement::FreezeExecutionAttrs(nsIDocument* aOwnerDoc) { if (mFrozen) { return; } + MOZ_ASSERT(!mIsModule && !mAsync && !mDefer && !mExternal); + + // Determine whether this is a classic script or a module script. + nsAutoString type; + GetScriptType(type); + mIsModule = aOwnerDoc->ModuleScriptsEnabled() && + !type.IsEmpty() && type.LowerCaseEqualsASCII("module"); + // variation of this code in nsSVGScriptElement - check if changes // need to be transfered when modifying. Note that we don't use GetSrc here // because it will return the base URL when the attr value is "". @@ -300,14 +308,13 @@ HTMLScriptElement::FreezeUriAsyncDefer() // At this point mUri will be null for invalid URLs. mExternal = true; - - bool defer, async; - GetAsync(&async); - GetDefer(&defer); - - mDefer = !async && defer; - mAsync = async; } + + bool defer, async; + GetAsync(&async); + mAsync = (mExternal || mIsModule) && async; + GetDefer(&defer); + mDefer = mExternal && !async && defer; mFrozen = true; } diff --git a/dom/html/HTMLScriptElement.h b/dom/html/HTMLScriptElement.h index 6edeb98322..198df1ed0d 100644 --- a/dom/html/HTMLScriptElement.h +++ b/dom/html/HTMLScriptElement.h @@ -41,7 +41,7 @@ public: virtual bool GetScriptType(nsAString& type) override; virtual void GetScriptText(nsAString& text) override; virtual void GetScriptCharset(nsAString& charset) override; - virtual void FreezeUriAsyncDefer() override; + virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override; virtual CORSMode GetCORSMode() const override; // nsIContent diff --git a/dom/script/ScriptElement.cpp b/dom/script/ScriptElement.cpp index 9cb239c66c..eb20dbf32e 100644 --- a/dom/script/ScriptElement.cpp +++ b/dom/script/ScriptElement.cpp @@ -128,11 +128,11 @@ ScriptElement::MaybeProcessScript() return false; } - FreezeUriAsyncDefer(); + nsIDocument* ownerDoc = cont->OwnerDoc(); + FreezeExecutionAttrs(ownerDoc); mAlreadyStarted = true; - nsIDocument* ownerDoc = cont->OwnerDoc(); nsCOMPtr<nsIParser> parser = ((nsIScriptElement*) this)->GetCreatorParser(); if (parser) { nsCOMPtr<nsIContentSink> sink = parser->GetContentSink(); diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index 59c4ecae46..989301b919 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -391,19 +391,6 @@ ScriptLoader::CheckContentPolicy(nsIDocument* aDocument, } bool -ScriptLoader::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 ScriptLoader::ModuleMapContainsURL(nsIURI* aURL) const { // Returns whether we have fetched, or are currently fetching, a module script @@ -1227,14 +1214,12 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) nsCOMPtr<nsIContent> scriptContent = do_QueryInterface(aElement); - // Determine whether this is a classic script or a module script. nsAutoString type; bool hasType = aElement->GetScriptType(type); - ScriptKind scriptKind = ScriptKind::Classic; - if (ModuleScriptsEnabled() && - !type.IsEmpty() && type.LowerCaseEqualsASCII("module")) { - scriptKind = ScriptKind::Module; - } + + ScriptKind scriptKind = aElement->GetScriptIsModule() ? + ScriptKind::Module : + ScriptKind::Classic; // Step 13. Check that the script is not an eventhandler if (IsScriptEventHandler(scriptKind, scriptContent)) { @@ -1268,7 +1253,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) // 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() && + if (mDocument->ModuleScriptsEnabled() && scriptKind == ScriptKind::Classic && scriptContent->IsHTMLElement() && scriptContent->HasAttr(kNameSpaceID_None, nsGkAtoms::nomodule)) { @@ -1480,6 +1465,12 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement *aElement) request->mIsInline = true; request->mLineNo = aElement->GetScriptLineNumber(); + // Only the 'async' attribute is heeded on an inline module script and + // inline classic scripts ignore both these attributes. + MOZ_ASSERT(!aElement->GetScriptDeferred()); + MOZ_ASSERT_IF(!request->IsModuleRequest(), !aElement->GetScriptAsync()); + request->SetScriptMode(false, aElement->GetScriptAsync()); + if (request->IsModuleRequest()) { ModuleLoadRequest* modReq = request->AsModuleRequest(); modReq->mBaseURL = mDocument->GetDocBaseURI(); @@ -2601,7 +2592,7 @@ ScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset, } // TODO: Preload module scripts. - if (ModuleScriptsEnabled() && aType.LowerCaseEqualsASCII("module")) { + if (mDocument->ModuleScriptsEnabled() && aType.LowerCaseEqualsASCII("module")) { return; } diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h index e9b663acd5..ed1e6acbc4 100644 --- a/dom/script/ScriptLoader.h +++ b/dom/script/ScriptLoader.h @@ -606,8 +606,6 @@ private: JS::SourceBufferHolder GetScriptSource(ScriptLoadRequest* aRequest, nsAutoString& inlineData); - bool ModuleScriptsEnabled(); - void SetModuleFetchStarted(ModuleLoadRequest *aRequest); void SetModuleFetchFinishedAndResumeWaitingRequests(ModuleLoadRequest *aRequest, nsresult aResult); diff --git a/dom/script/nsIScriptElement.h b/dom/script/nsIScriptElement.h index 470d51c948..e3e1bc49ae 100644 --- a/dom/script/nsIScriptElement.h +++ b/dom/script/nsIScriptElement.h @@ -13,6 +13,7 @@ #include "nsIScriptLoaderObserver.h" #include "nsWeakPtr.h" #include "nsIParser.h" +#include "nsIDocument.h" #include "nsContentCreatorFunctions.h" #include "nsIDOMHTMLScriptElement.h" #include "mozilla/CORSMode.h" @@ -37,6 +38,7 @@ public: mForceAsync(aFromParser == mozilla::dom::NOT_FROM_PARSER || aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT), mFrozen(false), + mIsModule(false), mDefer(false), mAsync(false), mExternal(false), @@ -73,11 +75,25 @@ public: virtual void GetScriptCharset(nsAString& charset) = 0; /** - * Freezes the return values of GetScriptDeferred(), GetScriptAsync() and - * GetScriptURI() so that subsequent modifications to the attributes don't - * change execution behavior. + * Freezes the return values of the following methods so that subsequent + * modifications to the attributes don't change execution behavior: + * - GetScriptIsModule() + * - GetScriptDeferred() + * - GetScriptAsync() + * - GetScriptURI() + * - GetScriptExternal() */ - virtual void FreezeUriAsyncDefer() = 0; + virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) = 0; + + /** + * Is the script a module script? + * Currently only supported by HTML scripts. + */ + bool GetScriptIsModule() + { + NS_PRECONDITION(mFrozen, "Execution attributes not yet frozen: Not ready for this call!"); + return mIsModule; + } /** * Is the script deferred. Currently only supported by HTML scripts. @@ -293,6 +309,11 @@ protected: bool mFrozen; /** + * The effective moduleness. + */ + bool mIsModule; + + /** * The effective deferredness. */ bool mDefer; diff --git a/dom/svg/SVGScriptElement.cpp b/dom/svg/SVGScriptElement.cpp index 7adce2f46b..9a4afb13a4 100644 --- a/dom/svg/SVGScriptElement.cpp +++ b/dom/svg/SVGScriptElement.cpp @@ -137,7 +137,7 @@ SVGScriptElement::GetScriptCharset(nsAString& charset) } void -SVGScriptElement::FreezeUriAsyncDefer() +SVGScriptElement::FreezeExecutionAttrs(nsIDocument* aOwnerDoc) { if (mFrozen) { return; diff --git a/dom/svg/SVGScriptElement.h b/dom/svg/SVGScriptElement.h index 79a3de70da..8ee94bf020 100644 --- a/dom/svg/SVGScriptElement.h +++ b/dom/svg/SVGScriptElement.h @@ -44,7 +44,7 @@ public: virtual bool GetScriptType(nsAString& type) override; virtual void GetScriptText(nsAString& text) override; virtual void GetScriptCharset(nsAString& charset) override; - virtual void FreezeUriAsyncDefer() override; + virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) override; virtual CORSMode GetCORSMode() const override; // ScriptElement diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp index 46907d3a4a..6444b96749 100644 --- a/parser/html/nsHtml5TreeOperation.cpp +++ b/parser/html/nsHtml5TreeOperation.cpp @@ -1076,7 +1076,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder, nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(node); NS_ASSERTION(sele, "Node didn't QI to script."); sele->SetScriptLineNumber(mFour.integer); - sele->FreezeUriAsyncDefer(); + sele->FreezeExecutionAttrs(node->OwnerDoc()); return NS_OK; } case eTreeOpSvgLoad: { |