diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index 491b7b8e7f93..b48a41c441fd 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -27,6 +27,7 @@ #include "mozilla/dom/Event.h" #include "mozilla/dom/EventTargetBinding.h" #include "mozilla/dom/PopupBlocker.h" +#include "mozilla/dom/RequestBinding.h" #include "mozilla/dom/ScriptLoader.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/TouchEvent.h" @@ -1174,7 +1175,8 @@ nsresult EventListenerManager::CompileEventHandlerInternal( RefPtr fetchOptions = new JS::loader::ScriptFetchOptions( CORS_NONE, aElement->OwnerDoc()->GetReferrerPolicy(), - /* aNonce = */ u""_ns, JS::loader::ParserMetadata::NotParserInserted, + /* aNonce = */ u""_ns, RequestPriority::Auto, + JS::loader::ParserMetadata::NotParserInserted, aElement->OwnerDoc()->NodePrincipal()); RefPtr eventScript = diff --git a/dom/html/HTMLScriptElement.cpp b/dom/html/HTMLScriptElement.cpp index 4f0593fa4f66..a1390c2f60f1 100644 --- a/dom/html/HTMLScriptElement.cpp +++ b/dom/html/HTMLScriptElement.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsAttrValue.h" +#include "nsAttrValueOrString.h" +#include "nsGenericHTMLElement.h" #include "nsGkAtoms.h" #include "nsStyleConsts.h" #include "mozilla/dom/Document.h" @@ -22,6 +24,7 @@ #include "mozilla/dom/FetchPriority.h" #include "mozilla/dom/HTMLScriptElement.h" #include "mozilla/dom/HTMLScriptElementBinding.h" +#include "mozilla/Assertions.h" #include "mozilla/StaticPrefs_dom.h" NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Script) @@ -89,9 +92,7 @@ bool HTMLScriptElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, } if (aAttribute == nsGkAtoms::fetchpriority) { - aResult.ParseEnumValue(aValue, kFetchPriorityEnumTable, - false /* aCaseSensitive */, - kFetchPriorityEnumTableInvalidValueDefault); + HTMLScriptElement::ParseFetchPriority(aValue, aResult); return true; } } @@ -224,6 +225,17 @@ CORSMode HTMLScriptElement::GetCORSMode() const { return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); } +FetchPriority HTMLScriptElement::GetFetchPriority() const { + const nsAttrValue* fetchpriorityAttribute = + GetParsedAttr(nsGkAtoms::fetchpriority); + if (fetchpriorityAttribute) { + MOZ_ASSERT(fetchpriorityAttribute->Type() == nsAttrValue::eEnum); + return FetchPriority(fetchpriorityAttribute->GetEnumValue()); + } + + return FetchPriority::Auto; +} + mozilla::dom::ReferrerPolicy HTMLScriptElement::GetReferrerPolicy() { return GetReferrerPolicyAsEnum(); } @@ -239,6 +251,14 @@ void HTMLScriptElement::GetFetchPriority(nsAString& aFetchPriority) const { aFetchPriority); } +/* static */ +FetchPriority HTMLScriptElement::ToFetchPriority(const nsAString& aValue) { + nsAttrValue attrValue; + HTMLScriptElement::ParseFetchPriority(aValue, attrValue); + MOZ_ASSERT(attrValue.Type() == nsAttrValue::eEnum); + return FetchPriority(attrValue.GetEnumValue()); +} + // https://html.spec.whatwg.org/multipage/scripting.html#dom-script-supports /* static */ bool HTMLScriptElement::Supports(const GlobalObject& aGlobal, @@ -249,4 +269,12 @@ bool HTMLScriptElement::Supports(const GlobalObject& aGlobal, aType.EqualsLiteral("importmap")); } +/* static */ +void HTMLScriptElement::ParseFetchPriority(const nsAString& aValue, + nsAttrValue& aResult) { + aResult.ParseEnumValue(aValue, kFetchPriorityEnumTable, + false /* aCaseSensitive */, + kFetchPriorityEnumTableInvalidValueDefault); +} + } // namespace mozilla::dom diff --git a/dom/html/HTMLScriptElement.h b/dom/html/HTMLScriptElement.h index 9397a1f323f2..b2e462f40214 100644 --- a/dom/html/HTMLScriptElement.h +++ b/dom/html/HTMLScriptElement.h @@ -7,9 +7,11 @@ #ifndef mozilla_dom_HTMLScriptElement_h #define mozilla_dom_HTMLScriptElement_h +#include "mozilla/dom/FetchPriority.h" #include "nsGenericHTMLElement.h" #include "mozilla/Attributes.h" #include "mozilla/dom/ScriptElement.h" +#include "nsStringFwd.h" namespace mozilla::dom { @@ -34,6 +36,7 @@ class HTMLScriptElement final : public nsGenericHTMLElement, virtual void GetScriptCharset(nsAString& charset) override; virtual void FreezeExecutionAttrs(const Document* aOwnerDoc) override; virtual CORSMode GetCORSMode() const override; + virtual FetchPriority GetFetchPriority() const override; virtual mozilla::dom::ReferrerPolicy GetReferrerPolicy() override; // nsIContent @@ -134,6 +137,9 @@ class HTMLScriptElement final : public nsGenericHTMLElement, SetHTMLAttr(nsGkAtoms::fetchpriority, aFetchPriority); } + // . + static FetchPriority ToFetchPriority(const nsAString& aValue); + [[nodiscard]] static bool Supports(const GlobalObject& aGlobal, const nsAString& aType); @@ -150,6 +156,9 @@ class HTMLScriptElement final : public nsGenericHTMLElement, // ScriptElement virtual bool HasScriptContent() override; + + private: + static void ParseFetchPriority(const nsAString& aValue, nsAttrValue& aResult); }; } // namespace mozilla::dom diff --git a/dom/script/ModuleLoader.cpp b/dom/script/ModuleLoader.cpp index 3e2e53e02470..b9f4543ff776 100644 --- a/dom/script/ModuleLoader.cpp +++ b/dom/script/ModuleLoader.cpp @@ -21,6 +21,7 @@ #include "js/loader/ScriptLoadRequest.h" #include "js/loader/ModuleLoaderBase.h" #include "js/loader/ModuleLoadRequest.h" +#include "mozilla/dom/RequestBinding.h" #include "xpcpublic.h" #include "GeckoProfiler.h" #include "nsContentSecurityManager.h" @@ -298,8 +299,8 @@ already_AddRefed ModuleLoader::CreateDynamicImport( // "auto". options = new ScriptFetchOptions( mozilla::CORS_NONE, document->GetReferrerPolicy(), - /* aNonce = */ u""_ns, ParserMetadata::NotParserInserted, principal, - nullptr); + /* aNonce = */ u""_ns, RequestPriority::Auto, + ParserMetadata::NotParserInserted, principal, nullptr); baseURL = document->GetDocBaseURI(); } diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index ebab1034e1f6..292c3d9d8dcd 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -9,6 +9,10 @@ #include "ScriptTrace.h" #include "ModuleLoader.h" +#include "mozilla/Assertions.h" +#include "mozilla/dom/FetchPriority.h" +#include "mozilla/dom/HTMLScriptElement.h" +#include "mozilla/dom/RequestBinding.h" #include "nsIChildChannel.h" #include "zlib.h" @@ -835,16 +839,31 @@ static bool CSPAllowsInlineScript(nsIScriptElement* aElement, return NS_SUCCEEDED(rv) && allowInlineScript; } +namespace { +constexpr RequestPriority FetchPriorityToRequestPriority( + const FetchPriority aFetchPriority) { + switch (aFetchPriority) { + case FetchPriority::High: + return RequestPriority::High; + case FetchPriority::Low: + return RequestPriority::Low; + case FetchPriority::Auto: + return RequestPriority::Auto; + } +} +} // namespace + already_AddRefed ScriptLoader::CreateLoadRequest( ScriptKind aKind, nsIURI* aURI, nsIScriptElement* aElement, nsIPrincipal* aTriggeringPrincipal, CORSMode aCORSMode, - const nsAString& aNonce, const SRIMetadata& aIntegrity, - ReferrerPolicy aReferrerPolicy, ParserMetadata aParserMetadata) { + const nsAString& aNonce, RequestPriority aRequestPriority, + const SRIMetadata& aIntegrity, ReferrerPolicy aReferrerPolicy, + ParserMetadata aParserMetadata) { nsIURI* referrer = mDocument->GetDocumentURIAsReferrer(); nsCOMPtr domElement = do_QueryInterface(aElement); - RefPtr fetchOptions = - new ScriptFetchOptions(aCORSMode, aReferrerPolicy, aNonce, - aParserMetadata, aTriggeringPrincipal, domElement); + RefPtr fetchOptions = new ScriptFetchOptions( + aCORSMode, aReferrerPolicy, aNonce, aRequestPriority, aParserMetadata, + aTriggeringPrincipal, domElement); RefPtr context = new ScriptLoadContext(); if (aKind == ScriptKind::eClassic || aKind == ScriptKind::eImportMap) { @@ -1019,12 +1038,14 @@ bool ScriptLoader::ProcessExternalScript(nsIScriptElement* aElement, } CORSMode ourCORSMode = aElement->GetCORSMode(); + const FetchPriority fetchPriority = aElement->GetFetchPriority(); ReferrerPolicy referrerPolicy = GetReferrerPolicy(aElement); ParserMetadata parserMetadata = GetParserMetadata(aElement); request = CreateLoadRequest(aScriptKind, scriptURI, aElement, principal, - ourCORSMode, nonce, sriMetadata, referrerPolicy, - parserMetadata); + ourCORSMode, nonce, + FetchPriorityToRequestPriority(fetchPriority), + sriMetadata, referrerPolicy, parserMetadata); request->GetScriptLoadContext()->mIsInline = false; request->GetScriptLoadContext()->SetScriptMode( aElement->GetScriptDeferred(), aElement->GetScriptAsync(), false); @@ -1191,12 +1212,18 @@ bool ScriptLoader::ProcessInlineScript(nsIScriptElement* aElement, if (aScriptKind == ScriptKind::eModule) { corsMode = aElement->GetCORSMode(); } + // + // step 29 specifies to use the fetch priority. Presumably it has no effect + // for inline scripts. + const auto fetchPriority = aElement->GetFetchPriority(); + ReferrerPolicy referrerPolicy = GetReferrerPolicy(aElement); ParserMetadata parserMetadata = GetParserMetadata(aElement); RefPtr request = CreateLoadRequest(aScriptKind, mDocument->GetDocumentURI(), aElement, mDocument->NodePrincipal(), corsMode, nonce, + FetchPriorityToRequestPriority(fetchPriority), SRIMetadata(), // SRI doesn't apply referrerPolicy, parserMetadata); request->GetScriptLoadContext()->mIsInline = true; @@ -3544,8 +3571,9 @@ void ScriptLoader::ParsingComplete(bool aTerminated) { void ScriptLoader::PreloadURI( nsIURI* aURI, const nsAString& aCharset, const nsAString& aType, const nsAString& aCrossOrigin, const nsAString& aNonce, - const nsAString& aIntegrity, bool aScriptFromHead, bool aAsync, bool aDefer, - bool aNoModule, bool aLinkPreload, const ReferrerPolicy aReferrerPolicy, + const nsAString& aFetchPriority, const nsAString& aIntegrity, + bool aScriptFromHead, bool aAsync, bool aDefer, bool aNoModule, + bool aLinkPreload, const ReferrerPolicy aReferrerPolicy, uint64_t aEarlyHintPreloaderId) { NS_ENSURE_TRUE_VOID(mDocument); // Check to see if scripts has been turned off. @@ -3577,6 +3605,9 @@ void ScriptLoader::PreloadURI( SRIMetadata sriMetadata; GetSRIMetadata(aIntegrity, &sriMetadata); + const auto requestPriority = FetchPriorityToRequestPriority( + HTMLScriptElement::ToFetchPriority(aFetchPriority)); + // For link type "modulepreload": // https://html.spec.whatwg.org/multipage/links.html#link-type-modulepreload // Step 11. Let options be a script fetch options whose cryptographic nonce is @@ -3590,7 +3621,7 @@ void ScriptLoader::PreloadURI( RefPtr request = CreateLoadRequest(scriptKind, aURI, nullptr, mDocument->NodePrincipal(), Element::StringToCORSMode(aCrossOrigin), aNonce, - sriMetadata, aReferrerPolicy, + requestPriority, sriMetadata, aReferrerPolicy, aLinkPreload ? ParserMetadata::NotParserInserted : ParserMetadata::ParserInserted); request->GetScriptLoadContext()->mIsInline = false; diff --git a/dom/script/ScriptLoader.h b/dom/script/ScriptLoader.h index 3618bcce4dd5..2fadd7094a44 100644 --- a/dom/script/ScriptLoader.h +++ b/dom/script/ScriptLoader.h @@ -79,6 +79,7 @@ class ScriptLoader; class ScriptRequestProcessor; enum class ReferrerPolicy : uint8_t; +enum class RequestPriority : uint8_t; class AsyncCompileShutdownObserver final : public nsIObserver { ~AsyncCompileShutdownObserver() { Unregister(); } @@ -373,14 +374,19 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface { * @param aType The type parameter for the script. * @param aCrossOrigin The crossorigin attribute for the script. * Void if not present. + * @param aFetchPriority + * . * @param aIntegrity The expect hash url, if avail, of the request + * @param aScriptFromHead Whether or not the script was a child of head */ virtual void PreloadURI(nsIURI* aURI, const nsAString& aCharset, const nsAString& aType, const nsAString& aCrossOrigin, - const nsAString& aNonce, const nsAString& aIntegrity, - bool aScriptFromHead, bool aAsync, bool aDefer, - bool aNoModule, bool aLinkPreload, + const nsAString& aNonce, + const nsAString& aFetchPriority, + const nsAString& aIntegrity, bool aScriptFromHead, + bool aAsync, bool aDefer, bool aNoModule, + bool aLinkPreload, const ReferrerPolicy aReferrerPolicy, uint64_t aEarlyHintPreloaderId); @@ -429,8 +435,8 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface { already_AddRefed CreateLoadRequest( ScriptKind aKind, nsIURI* aURI, nsIScriptElement* aElement, nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode aCORSMode, - const nsAString& aNonce, const SRIMetadata& aIntegrity, - ReferrerPolicy aReferrerPolicy, + const nsAString& aNonce, RequestPriority aRequestPriority, + const SRIMetadata& aIntegrity, ReferrerPolicy aReferrerPolicy, JS::loader::ParserMetadata aParserMetadata); /** diff --git a/dom/script/nsIScriptElement.h b/dom/script/nsIScriptElement.h index 7035af9d4dac..074f6ae6fd25 100644 --- a/dom/script/nsIScriptElement.h +++ b/dom/script/nsIScriptElement.h @@ -29,6 +29,7 @@ class nsIURI; namespace mozilla::dom { class Document; +enum class FetchPriority : uint8_t; enum class ReferrerPolicy : uint8_t; } // namespace mozilla::dom @@ -236,6 +237,13 @@ class nsIScriptElement : public nsIScriptLoaderObserver { return mozilla::CORS_NONE; } + /** + * Get the fetch priority + * (https://html.spec.whatwg.org/multipage/scripting.html#attr-script-fetchpriority) + * of the script element. + */ + virtual mozilla::dom::FetchPriority GetFetchPriority() const = 0; + /** * Get referrer policy of the script element */ diff --git a/dom/svg/SVGScriptElement.cpp b/dom/svg/SVGScriptElement.cpp index fa19460e01c9..4fe7d234c61e 100644 --- a/dom/svg/SVGScriptElement.cpp +++ b/dom/svg/SVGScriptElement.cpp @@ -6,6 +6,7 @@ #include "mozilla/dom/SVGScriptElement.h" +#include "mozilla/dom/FetchPriority.h" #include "nsGkAtoms.h" #include "nsNetUtil.h" #include "nsContentUtils.h" @@ -214,4 +215,9 @@ CORSMode SVGScriptElement::GetCORSMode() const { return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); } +FetchPriority SVGScriptElement::GetFetchPriority() const { + // . + return FetchPriority::Auto; +} + } // namespace mozilla::dom diff --git a/dom/svg/SVGScriptElement.h b/dom/svg/SVGScriptElement.h index 129a652427b8..5f318eb0a519 100644 --- a/dom/svg/SVGScriptElement.h +++ b/dom/svg/SVGScriptElement.h @@ -43,6 +43,7 @@ class SVGScriptElement final : public SVGScriptElementBase, void GetScriptCharset(nsAString& charset) override; void FreezeExecutionAttrs(const Document* aOwnerDoc) override; CORSMode GetCORSMode() const override; + FetchPriority GetFetchPriority() const override; // ScriptElement bool HasScriptContent() override; diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index d02f0171b8fd..b7abd0e741c7 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -9,6 +9,7 @@ #include #include +#include "mozilla/dom/RequestBinding.h" #include "nsIChannel.h" #include "nsIContentPolicy.h" #include "nsIContentSecurityPolicy.h" @@ -653,7 +654,7 @@ already_AddRefed WorkerScriptLoader::CreateScriptLoadRequest( // policy is the empty string, and fetch priority is "auto". RefPtr fetchOptions = new ScriptFetchOptions( CORSMode::CORS_NONE, referrerPolicy, /* aNonce = */ u""_ns, - ParserMetadata::NotParserInserted, nullptr); + RequestPriority::Auto, ParserMetadata::NotParserInserted, nullptr); RefPtr request = nullptr; // Bug 1817259 - For now the debugger scripts are always loaded a Classic. diff --git a/dom/workers/loader/WorkerModuleLoader.cpp b/dom/workers/loader/WorkerModuleLoader.cpp index 79f252c7a063..84cf9f9c07c1 100644 --- a/dom/workers/loader/WorkerModuleLoader.cpp +++ b/dom/workers/loader/WorkerModuleLoader.cpp @@ -6,6 +6,7 @@ #include "js/experimental/JSStencil.h" // JS::Stencil, JS::CompileModuleScriptToStencil, JS::InstantiateModuleStencil #include "js/loader/ModuleLoadRequest.h" +#include "mozilla/dom/RequestBinding.h" #include "mozilla/dom/WorkerLoadContext.h" #include "mozilla/dom/WorkerPrivate.h" #include "mozilla/dom/workerinternals/ScriptLoader.h" @@ -117,8 +118,8 @@ already_AddRefed WorkerModuleLoader::CreateDynamicImport( ReferrerPolicy referrerPolicy = workerPrivate->GetReferrerPolicy(); options = new ScriptFetchOptions( CORSMode::CORS_NONE, referrerPolicy, - /* aNonce = */ u""_ns, JS::loader::ParserMetadata::NotParserInserted, - nullptr); + /* aNonce = */ u""_ns, RequestPriority::Auto, + JS::loader::ParserMetadata::NotParserInserted, nullptr); baseURL = GetBaseURI(); } diff --git a/dom/worklet/WorkletFetchHandler.cpp b/dom/worklet/WorkletFetchHandler.cpp index 620d5e85660c..299f71f62cd4 100644 --- a/dom/worklet/WorkletFetchHandler.cpp +++ b/dom/worklet/WorkletFetchHandler.cpp @@ -9,6 +9,7 @@ #include "mozilla/dom/Document.h" #include "mozilla/dom/Fetch.h" #include "mozilla/dom/Request.h" +#include "mozilla/dom/RequestBinding.h" #include "mozilla/dom/Response.h" #include "mozilla/dom/RootedDictionary.h" #include "mozilla/dom/ScriptLoader.h" @@ -94,7 +95,7 @@ NS_IMETHODIMP StartModuleLoadRunnable::RunOnWorkletThread() { // policy is the empty string, and fetch priority is "auto". RefPtr fetchOptions = new ScriptFetchOptions( CORSMode::CORS_NONE, ReferrerPolicy::_empty, /* aNonce = */ u""_ns, - ParserMetadata::NotParserInserted, + RequestPriority::Auto, ParserMetadata::NotParserInserted, /*triggeringPrincipal*/ nullptr); WorkletModuleLoader* moduleLoader = diff --git a/js/loader/ScriptLoadRequest.cpp b/js/loader/ScriptLoadRequest.cpp index f3bab584096b..0965d20d3298 100644 --- a/js/loader/ScriptLoadRequest.cpp +++ b/js/loader/ScriptLoadRequest.cpp @@ -37,11 +37,13 @@ NS_IMPL_CYCLE_COLLECTION(ScriptFetchOptions, mTriggeringPrincipal, mElement) ScriptFetchOptions::ScriptFetchOptions( mozilla::CORSMode aCORSMode, mozilla::dom::ReferrerPolicy aReferrerPolicy, - const nsAString& aNonce, const ParserMetadata aParserMetadata, - nsIPrincipal* aTriggeringPrincipal, mozilla::dom::Element* aElement) + const nsAString& aNonce, mozilla::dom::RequestPriority aFetchPriority, + const ParserMetadata aParserMetadata, nsIPrincipal* aTriggeringPrincipal, + mozilla::dom::Element* aElement) : mCORSMode(aCORSMode), mReferrerPolicy(aReferrerPolicy), mNonce(aNonce), + mFetchPriority(aFetchPriority), mParserMetadata(aParserMetadata), mTriggeringPrincipal(aTriggeringPrincipal), mElement(aElement) {} diff --git a/js/loader/ScriptLoadRequest.h b/js/loader/ScriptLoadRequest.h index 56a08ecce303..069ddb57fb9f 100644 --- a/js/loader/ScriptLoadRequest.h +++ b/js/loader/ScriptLoadRequest.h @@ -37,6 +37,7 @@ namespace mozilla::dom { class ScriptLoadContext; class WorkerLoadContext; class WorkletLoadContext; +enum class RequestPriority : uint8_t; } // namespace mozilla::dom @@ -88,6 +89,7 @@ class ScriptFetchOptions { ScriptFetchOptions(mozilla::CORSMode aCORSMode, enum mozilla::dom::ReferrerPolicy aReferrerPolicy, const nsAString& aNonce, + mozilla::dom::RequestPriority aFetchPriority, const ParserMetadata aParserMetadata, nsIPrincipal* aTriggeringPrincipal, mozilla::dom::Element* aElement = nullptr); @@ -111,6 +113,11 @@ class ScriptFetchOptions { */ const nsString mNonce; + /* + * . + */ + const mozilla::dom::RequestPriority mFetchPriority; + /* * The parser metadata used for the initial fetch and for fetching any * imported modules @@ -294,6 +301,10 @@ class ScriptLoadRequest : ScriptText().clearAndFree(); } + mozilla::dom::RequestPriority FetchPriority() const { + return mFetchOptions->mFetchPriority; + } + enum mozilla::dom::ReferrerPolicy ReferrerPolicy() const { return mFetchOptions->mReferrerPolicy; } diff --git a/js/xpconnect/loader/mozJSModuleLoader.cpp b/js/xpconnect/loader/mozJSModuleLoader.cpp index 7ef554940b98..b20046accbed 100644 --- a/js/xpconnect/loader/mozJSModuleLoader.cpp +++ b/js/xpconnect/loader/mozJSModuleLoader.cpp @@ -4,6 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "ScriptLoadRequest.h" #include "mozilla/Attributes.h" #include "mozilla/ArrayUtils.h" // mozilla::ArrayLength #include "mozilla/Utf8.h" // mozilla::Utf8Unit @@ -11,6 +12,7 @@ #include #include "mozilla/Logging.h" +#include "mozilla/dom/RequestBinding.h" #ifdef ANDROID # include #endif @@ -1804,9 +1806,10 @@ nsresult mozJSModuleLoader::ImportESModule( mModuleLoader->GetGlobalObject()->PrincipalOrNull(); MOZ_ASSERT(principal); - RefPtr options = new ScriptFetchOptions( - CORS_NONE, dom::ReferrerPolicy::No_referrer, - /* aNonce = */ u""_ns, ParserMetadata::NotParserInserted, principal); + RefPtr options = + new ScriptFetchOptions(CORS_NONE, dom::ReferrerPolicy::No_referrer, + /* aNonce = */ u""_ns, dom::RequestPriority::Auto, + ParserMetadata::NotParserInserted, principal); RefPtr context = new ComponentLoadContext(); context->mSkipCheck = aSkipCheck; diff --git a/js/xpconnect/loader/mozJSModuleLoader.h b/js/xpconnect/loader/mozJSModuleLoader.h index e5a114a193d5..445787736bea 100644 --- a/js/xpconnect/loader/mozJSModuleLoader.h +++ b/js/xpconnect/loader/mozJSModuleLoader.h @@ -78,7 +78,7 @@ class mozJSModuleLoader final : public nsIMemoryReporter { JS::MutableHandleObject aModuleExports, bool aIgnoreExports = false); - // Load an ES6 module and all its dependencies. + // Synchronously load an ES6 module and all its dependencies. nsresult ImportESModule( JSContext* aCx, const nsACString& aResourceURI, JS::MutableHandleObject aModuleNamespace, diff --git a/parser/html/nsHtml5SpeculativeLoad.cpp b/parser/html/nsHtml5SpeculativeLoad.cpp index b969d99aee62..861c30cd14be 100644 --- a/parser/html/nsHtml5SpeculativeLoad.cpp +++ b/parser/html/nsHtml5SpeculativeLoad.cpp @@ -63,33 +63,33 @@ void nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor) { aExecutor->PreloadScript( mUrlOrSizes, mCharsetOrSrcset, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, - mCrossOrigin, mMedia, mNonce, mReferrerPolicyOrIntegrity, - mScriptReferrerPolicy, false, mIsAsync, mIsDefer, false, - mIsLinkPreload); + mCrossOrigin, mMedia, mNonce, mFetchPriority, + mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, false, mIsAsync, + mIsDefer, false, mIsLinkPreload); break; case eSpeculativeLoadScriptFromHead: aExecutor->PreloadScript( mUrlOrSizes, mCharsetOrSrcset, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, - mCrossOrigin, mMedia, mNonce, mReferrerPolicyOrIntegrity, - mScriptReferrerPolicy, true, mIsAsync, mIsDefer, false, - mIsLinkPreload); + mCrossOrigin, mMedia, mNonce, mFetchPriority, + mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, true, mIsAsync, + mIsDefer, false, mIsLinkPreload); break; case eSpeculativeLoadNoModuleScript: aExecutor->PreloadScript( mUrlOrSizes, mCharsetOrSrcset, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, - mCrossOrigin, mMedia, mNonce, mReferrerPolicyOrIntegrity, - mScriptReferrerPolicy, false, mIsAsync, mIsDefer, true, - mIsLinkPreload); + mCrossOrigin, mMedia, mNonce, mFetchPriority, + mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, false, mIsAsync, + mIsDefer, true, mIsLinkPreload); break; case eSpeculativeLoadNoModuleScriptFromHead: aExecutor->PreloadScript( mUrlOrSizes, mCharsetOrSrcset, mTypeOrCharsetSourceOrDocumentModeOrMetaCSPOrSizesOrIntegrity, - mCrossOrigin, mMedia, mNonce, mReferrerPolicyOrIntegrity, - mScriptReferrerPolicy, true, mIsAsync, mIsDefer, true, - mIsLinkPreload); + mCrossOrigin, mMedia, mNonce, mFetchPriority, + mReferrerPolicyOrIntegrity, mScriptReferrerPolicy, true, mIsAsync, + mIsDefer, true, mIsLinkPreload); break; case eSpeculativeLoadStyle: aExecutor->PreloadStyle( diff --git a/parser/html/nsHtml5SpeculativeLoad.h b/parser/html/nsHtml5SpeculativeLoad.h index 71339b0659fb..8f1ad1642b91 100644 --- a/parser/html/nsHtml5SpeculativeLoad.h +++ b/parser/html/nsHtml5SpeculativeLoad.h @@ -169,7 +169,7 @@ class nsHtml5SpeculativeLoad { inline void InitScript(nsHtml5String aUrl, nsHtml5String aCharset, nsHtml5String aType, nsHtml5String aCrossOrigin, nsHtml5String aMedia, nsHtml5String aNonce, - nsHtml5String aIntegrity, + nsHtml5String aFetchPriority, nsHtml5String aIntegrity, nsHtml5String aReferrerPolicy, bool aParserInHead, bool aAsync, bool aDefer, bool aNoModule, bool aLinkPreload) { @@ -189,6 +189,7 @@ class nsHtml5SpeculativeLoad { aCrossOrigin.ToString(mCrossOrigin); aMedia.ToString(mMedia); aNonce.ToString(mNonce); + aFetchPriority.ToString(mFetchPriority); aIntegrity.ToString(mReferrerPolicyOrIntegrity); nsAutoString referrerPolicy; aReferrerPolicy.ToString(referrerPolicy); @@ -415,6 +416,12 @@ class nsHtml5SpeculativeLoad { * of the "nonce" attribute. */ nsString mNonce; + /** + * If mOpCode is eSpeculativeLoadNoModuleScript[FromHead] or + * eSpeculativeLoadScript[FromHead] this represents the value of the + * "fetchpriority" attribute. + */ + nsString mFetchPriority; /** * If mOpCode is eSpeculativeLoadScript[FromHead] this represents the value * of the "referrerpolicy" attribute. This field holds one of the values diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h index f78f254b9779..4e557775ebca 100644 --- a/parser/html/nsHtml5TreeBuilderCppSupplement.h +++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h @@ -6,7 +6,10 @@ #include "ErrorList.h" #include "nsError.h" +#include "nsHtml5AttributeName.h" +#include "nsHtml5String.h" #include "nsNetUtil.h" +#include "mozilla/dom/FetchPriority.h" #include "mozilla/CheckedInt.h" #include "mozilla/Likely.h" #include "mozilla/StaticPrefs_dom.h" @@ -251,6 +254,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); nsHtml5String nonce = aAttributes->getValue(nsHtml5AttributeName::ATTR_NONCE); + nsHtml5String fetchPriority = + aAttributes->getValue(nsHtml5AttributeName::ATTR_FETCHPRIORITY); nsHtml5String integrity = aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); nsHtml5String referrerPolicy = aAttributes->getValue( @@ -263,8 +268,9 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( aAttributes->contains(nsHtml5AttributeName::ATTR_NOMODULE); mSpeculativeLoadQueue.AppendElement()->InitScript( url, charset, type, crossOrigin, /* aMedia = */ nullptr, nonce, - integrity, referrerPolicy, mode == nsHtml5TreeBuilder::IN_HEAD, - async, defer, noModule, false); + fetchPriority, integrity, referrerPolicy, + mode == nsHtml5TreeBuilder::IN_HEAD, async, defer, noModule, + false); mCurrentHtmlScriptIsAsyncOrDefer = async || defer; } } else if (nsGkAtoms::link == aName) { @@ -332,8 +338,17 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( if (as.LowerCaseEqualsASCII("script")) { nsHtml5String type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE); + + // Bug 1839315: get the attribute's value instead. + // Use the empty string and rely on the + // "invalid value default" state being used later. + // Compared to using a non-empty string, this doesn't + // require calling `Release()` for the string. + nsHtml5String fetchPriority = nsHtml5String::EmptyString(); + mSpeculativeLoadQueue.AppendElement()->InitScript( - url, charset, type, crossOrigin, media, nonce, integrity, + url, charset, type, crossOrigin, media, nonce, + /* aFetchPriority */ fetchPriority, integrity, referrerPolicy, mode == nsHtml5TreeBuilder::IN_HEAD, false, false, false, true); } else if (as.LowerCaseEqualsASCII("style")) { @@ -383,8 +398,17 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( nsHtml5AttributeName::ATTR_INTEGRITY); nsHtml5String referrerPolicy = aAttributes->getValue( nsHtml5AttributeName::ATTR_REFERRERPOLICY); + + // Bug 1839315: get the attribute's value instead. + // Use the empty string and rely on the + // "invalid value default" state being used later. + // Compared to using a non-empty string, this doesn't + // require calling `Release()` for the string. + nsHtml5String fetchPriority = nsHtml5String::EmptyString(); + mSpeculativeLoadQueue.AppendElement()->InitScript( - url, charset, type, crossOrigin, media, nonce, integrity, + url, charset, type, crossOrigin, media, nonce, + /* aFetchPriority */ fetchPriority, integrity, referrerPolicy, mode == nsHtml5TreeBuilder::IN_HEAD, false, false, false, true); } @@ -483,10 +507,20 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement( aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); nsHtml5String referrerPolicy = aAttributes->getValue( nsHtml5AttributeName::ATTR_REFERRERPOLICY); + + // Bug 1847712: SVG's `