summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-08-25 07:06:43 +0000
committerMoonchild <moonchild@palemoon.org>2020-08-30 09:51:18 +0000
commit77e8ba7eaf3ca00f25d0507cf17de2f50741f335 (patch)
treeb9025ffd0f46746481cd809598cd62142764f225
parente854d58633a2c877778410393914146f7a137495 (diff)
downloadUXP-77e8ba7eaf3ca00f25d0507cf17de2f50741f335.tar
UXP-77e8ba7eaf3ca00f25d0507cf17de2f50741f335.tar.gz
UXP-77e8ba7eaf3ca00f25d0507cf17de2f50741f335.tar.lz
UXP-77e8ba7eaf3ca00f25d0507cf17de2f50741f335.tar.xz
UXP-77e8ba7eaf3ca00f25d0507cf17de2f50741f335.zip
Issue #618 - Implement async attribute for inline module scripts. (uplift)
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.cpp13
-rw-r--r--dom/base/nsIDocument.h2
-rw-r--r--dom/html/HTMLScriptElement.cpp23
-rw-r--r--dom/html/HTMLScriptElement.h2
-rw-r--r--dom/script/ScriptElement.cpp4
-rw-r--r--dom/script/ScriptLoader.cpp33
-rw-r--r--dom/script/ScriptLoader.h2
-rw-r--r--dom/script/nsIScriptElement.h29
-rw-r--r--dom/svg/SVGScriptElement.cpp2
-rw-r--r--dom/svg/SVGScriptElement.h2
-rw-r--r--parser/html/nsHtml5TreeOperation.cpp2
11 files changed, 73 insertions, 41 deletions
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index d0634b0f9..de793bfab 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12745,3 +12745,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 506acc7e4..29afa5439 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2872,6 +2872,8 @@ public:
virtual void ScheduleIntersectionObserverNotification() = 0;
virtual void NotifyIntersectionObservers() = 0;
+ bool ModuleScriptsEnabled();
+
protected:
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
diff --git a/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp
index ddeb925eb..6b0b4be59 100644
--- a/dom/html/HTMLScriptElement.cpp
+++ b/dom/html/HTMLScriptElement.cpp
@@ -279,12 +279,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 "".
@@ -299,14 +307,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 073cf7faf..ffe9d3fbd 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 9cb239c66..eb20dbf32 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 59c4ecae4..989301b91 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 e9b663acd..ed1e6acbc 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 470d51c94..e3e1bc49a 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 f2fb3ff5c..1e0647104 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 9f098e047..d89f860fb 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 3877e01b8..02cb3caac 100644
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -833,7 +833,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: {