Bug 1839316: part 4) Add `RequestPriority` to `ScriptFetchOptions` and `ScriptLoadRequest`. r=smaug

The request priority isn't propagated from `ScriptFetchOptions`, so
setting it has no effect for end-users. That will be implemented in a
following part.

Differential Revision: https://phabricator.services.mozilla.com/D183483
This commit is contained in:
Mirko Brodesser 2023-08-09 13:50:28 +00:00
Родитель 6ff4895cb7
Коммит 5cade38f47
23 изменённых файлов: 231 добавлений и 66 удалений

Просмотреть файл

@ -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<JS::loader::ScriptFetchOptions> 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<JS::loader::EventScript> eventScript =

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
}
// <https://html.spec.whatwg.org/#fetch-priority-attribute>.
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

Просмотреть файл

@ -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<ModuleLoadRequest> 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();
}

Просмотреть файл

@ -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<ScriptLoadRequest> 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<Element> domElement = do_QueryInterface(aElement);
RefPtr<ScriptFetchOptions> fetchOptions =
new ScriptFetchOptions(aCORSMode, aReferrerPolicy, aNonce,
aParserMetadata, aTriggeringPrincipal, domElement);
RefPtr<ScriptFetchOptions> fetchOptions = new ScriptFetchOptions(
aCORSMode, aReferrerPolicy, aNonce, aRequestPriority, aParserMetadata,
aTriggeringPrincipal, domElement);
RefPtr<ScriptLoadContext> 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();
}
// <https://html.spec.whatwg.org/multipage/scripting.html#prepare-the-script-element>
// 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<ScriptLoadRequest> 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<ScriptLoadRequest> 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;

Просмотреть файл

@ -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
* <https://html.spec.whatwg.org/#the-script-element:attr-script-fetchpriority>.
* @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<ScriptLoadRequest> 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);
/**

Просмотреть файл

@ -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
*/

Просмотреть файл

@ -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 {
// <https://github.com/w3c/svgwg/issues/916>.
return FetchPriority::Auto;
}
} // namespace mozilla::dom

Просмотреть файл

@ -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;

Просмотреть файл

@ -9,6 +9,7 @@
#include <algorithm>
#include <type_traits>
#include "mozilla/dom/RequestBinding.h"
#include "nsIChannel.h"
#include "nsIContentPolicy.h"
#include "nsIContentSecurityPolicy.h"
@ -653,7 +654,7 @@ already_AddRefed<ScriptLoadRequest> WorkerScriptLoader::CreateScriptLoadRequest(
// policy is the empty string, and fetch priority is "auto".
RefPtr<ScriptFetchOptions> fetchOptions = new ScriptFetchOptions(
CORSMode::CORS_NONE, referrerPolicy, /* aNonce = */ u""_ns,
ParserMetadata::NotParserInserted, nullptr);
RequestPriority::Auto, ParserMetadata::NotParserInserted, nullptr);
RefPtr<ScriptLoadRequest> request = nullptr;
// Bug 1817259 - For now the debugger scripts are always loaded a Classic.

Просмотреть файл

@ -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<ModuleLoadRequest> 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();
}

Просмотреть файл

@ -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<ScriptFetchOptions> fetchOptions = new ScriptFetchOptions(
CORSMode::CORS_NONE, ReferrerPolicy::_empty, /* aNonce = */ u""_ns,
ParserMetadata::NotParserInserted,
RequestPriority::Auto, ParserMetadata::NotParserInserted,
/*triggeringPrincipal*/ nullptr);
WorkletModuleLoader* moduleLoader =

Просмотреть файл

@ -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) {}

Просмотреть файл

@ -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;
/*
* <https://html.spec.whatwg.org/multipage/webappapis.html#script-fetch-options>.
*/
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<Utf8Unit>().clearAndFree();
}
mozilla::dom::RequestPriority FetchPriority() const {
return mFetchOptions->mFetchPriority;
}
enum mozilla::dom::ReferrerPolicy ReferrerPolicy() const {
return mFetchOptions->mReferrerPolicy;
}

Просмотреть файл

@ -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 <cstdarg>
#include "mozilla/Logging.h"
#include "mozilla/dom/RequestBinding.h"
#ifdef ANDROID
# include <android/log.h>
#endif
@ -1804,9 +1806,10 @@ nsresult mozJSModuleLoader::ImportESModule(
mModuleLoader->GetGlobalObject()->PrincipalOrNull();
MOZ_ASSERT(principal);
RefPtr<ScriptFetchOptions> options = new ScriptFetchOptions(
CORS_NONE, dom::ReferrerPolicy::No_referrer,
/* aNonce = */ u""_ns, ParserMetadata::NotParserInserted, principal);
RefPtr<ScriptFetchOptions> options =
new ScriptFetchOptions(CORS_NONE, dom::ReferrerPolicy::No_referrer,
/* aNonce = */ u""_ns, dom::RequestPriority::Auto,
ParserMetadata::NotParserInserted, principal);
RefPtr<ComponentLoadContext> context = new ComponentLoadContext();
context->mSkipCheck = aSkipCheck;

Просмотреть файл

@ -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,

Просмотреть файл

@ -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(

Просмотреть файл

@ -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

Просмотреть файл

@ -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 `<script>` element doesn't support
// `fetchpriority` yet.
// 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, nullptr, type, crossOrigin, /* aMedia = */ nullptr, nonce,
integrity, referrerPolicy, mode == nsHtml5TreeBuilder::IN_HEAD,
false, false, false, false);
fetchPriority, integrity, referrerPolicy,
mode == nsHtml5TreeBuilder::IN_HEAD, false, false, false,
false);
}
} else if (nsGkAtoms::style == aName) {
mImportScanner.Start();

Просмотреть файл

@ -1205,9 +1205,10 @@ dom::ReferrerPolicy nsHtml5TreeOpExecutor::GetPreloadReferrerPolicy(
void nsHtml5TreeOpExecutor::PreloadScript(
const nsAString& aURL, const nsAString& aCharset, const nsAString& aType,
const nsAString& aCrossOrigin, const nsAString& aMedia,
const nsAString& aNonce, const nsAString& aIntegrity,
dom::ReferrerPolicy aReferrerPolicy, bool aScriptFromHead, bool aAsync,
bool aDefer, bool aNoModule, bool aLinkPreload) {
const nsAString& aNonce, const nsAString& aFetchPriority,
const nsAString& aIntegrity, dom::ReferrerPolicy aReferrerPolicy,
bool aScriptFromHead, bool aAsync, bool aDefer, bool aNoModule,
bool aLinkPreload) {
nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYetAndMediaApplies(aURL, aMedia);
if (!uri) {
return;
@ -1217,8 +1218,8 @@ void nsHtml5TreeOpExecutor::PreloadScript(
return;
}
mDocument->ScriptLoader()->PreloadURI(
uri, aCharset, aType, aCrossOrigin, aNonce, aIntegrity, aScriptFromHead,
aAsync, aDefer, aNoModule, aLinkPreload,
uri, aCharset, aType, aCrossOrigin, aNonce, aFetchPriority, aIntegrity,
aScriptFromHead, aAsync, aDefer, aNoModule, aLinkPreload,
GetPreloadReferrerPolicy(aReferrerPolicy), 0);
}

Просмотреть файл

@ -246,6 +246,7 @@ class nsHtml5TreeOpExecutor final
void PreloadScript(const nsAString& aURL, const nsAString& aCharset,
const nsAString& aType, const nsAString& aCrossOrigin,
const nsAString& aMedia, const nsAString& aNonce,
const nsAString& aFetchPriority,
const nsAString& aIntegrity,
ReferrerPolicy aReferrerPolicy, bool aScriptFromHead,
bool aAsync, bool aDefer, bool aNoModule,

Просмотреть файл

@ -8,6 +8,7 @@
#include "FetchPreloader.h"
#include "PreloaderBase.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/dom/FetchPriority.h"
#include "mozilla/dom/HTMLLinkElement.h"
#include "mozilla/dom/ScriptLoader.h"
#include "mozilla/dom/ReferrerInfo.h"
@ -72,8 +73,8 @@ already_AddRefed<PreloaderBase> PreloadService::PreloadLinkElement(
return nullptr;
}
nsAutoString as, charset, crossOrigin, integrity, referrerPolicy, rel, srcset,
sizes, type, url;
nsAutoString as, charset, crossOrigin, integrity, referrerPolicy,
fetchPriority, rel, srcset, sizes, type, url;
nsCOMPtr<nsIURI> uri = aLinkElement->GetURI();
aLinkElement->GetCharset(charset);
@ -83,6 +84,8 @@ already_AddRefed<PreloaderBase> PreloadService::PreloadLinkElement(
aLinkElement->GetCrossOrigin(crossOrigin);
aLinkElement->GetIntegrity(integrity);
aLinkElement->GetReferrerPolicy(referrerPolicy);
// Bug 1839315: get "fetchpriority"'s value from the link element instead,
fetchPriority = NS_ConvertUTF8toUTF16(dom::kFetchPriorityAttributeValueAuto);
aLinkElement->GetRel(rel);
nsAutoString nonce;
@ -101,7 +104,8 @@ already_AddRefed<PreloaderBase> PreloadService::PreloadLinkElement(
auto result = PreloadOrCoalesce(uri, url, aPolicyType, as, type, charset,
srcset, sizes, nonce, integrity, crossOrigin,
referrerPolicy, /* aFromHeader = */ false, 0);
referrerPolicy, fetchPriority,
/* aFromHeader = */ false, 0);
if (!result.mPreloader) {
NotifyNodeEvent(aLinkElement, result.mAlreadyComplete);
@ -127,8 +131,12 @@ void PreloadService::PreloadLinkHeader(
return;
}
// Bug 1839315: which fetch priority to use here?
const nsAutoString fetchPriority =
NS_ConvertUTF8toUTF16(dom::kFetchPriorityAttributeValueAuto);
PreloadOrCoalesce(aURI, aURL, aPolicyType, aAs, aType, u""_ns, aSrcset,
aSizes, aNonce, aIntegrity, aCORS, aReferrerPolicy,
fetchPriority,
/* aFromHeader = */ true, aEarlyHintPreloaderId);
}
@ -137,8 +145,8 @@ PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce(
const nsAString& aAs, const nsAString& aType, const nsAString& aCharset,
const nsAString& aSrcset, const nsAString& aSizes, const nsAString& aNonce,
const nsAString& aIntegrity, const nsAString& aCORS,
const nsAString& aReferrerPolicy, bool aFromHeader,
uint64_t aEarlyHintPreloaderId) {
const nsAString& aReferrerPolicy, const nsAString& aFetchPriority,
bool aFromHeader, uint64_t aEarlyHintPreloaderId) {
if (!aURI) {
MOZ_ASSERT_UNREACHABLE("Should not pass null nsIURI");
return {nullptr, false};
@ -179,7 +187,7 @@ PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce(
if (aAs.LowerCaseEqualsASCII("script")) {
PreloadScript(uri, aType, aCharset, aCORS, aReferrerPolicy, aNonce,
aIntegrity, true /* isInHead - TODO */,
aFetchPriority, aIntegrity, true /* isInHead - TODO */,
aEarlyHintPreloaderId);
} else if (aAs.LowerCaseEqualsASCII("style")) {
auto status = mDocument->PreloadStyle(
@ -214,12 +222,13 @@ PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce(
void PreloadService::PreloadScript(
nsIURI* aURI, const nsAString& aType, const nsAString& aCharset,
const nsAString& aCrossOrigin, const nsAString& aReferrerPolicy,
const nsAString& aNonce, const nsAString& aIntegrity, bool aScriptFromHead,
const nsAString& aNonce, const nsAString& aFetchPriority,
const nsAString& aIntegrity, bool aScriptFromHead,
uint64_t aEarlyHintPreloaderId) {
mDocument->ScriptLoader()->PreloadURI(
aURI, aCharset, aType, aCrossOrigin, aNonce, aIntegrity, aScriptFromHead,
false, false, false, true, PreloadReferrerPolicy(aReferrerPolicy),
aEarlyHintPreloaderId);
aURI, aCharset, aType, aCrossOrigin, aNonce, aFetchPriority, aIntegrity,
aScriptFromHead, false, false, false, true,
PreloadReferrerPolicy(aReferrerPolicy), aEarlyHintPreloaderId);
}
void PreloadService::PreloadImage(nsIURI* aURI, const nsAString& aCrossOrigin,

Просмотреть файл

@ -81,6 +81,7 @@ class PreloadService {
void PreloadScript(nsIURI* aURI, const nsAString& aType,
const nsAString& aCharset, const nsAString& aCrossOrigin,
const nsAString& aReferrerPolicy, const nsAString& aNonce,
const nsAString& aFetchPriority,
const nsAString& aIntegrity, bool aScriptFromHead,
uint64_t aEarlyHintPreloaderId);
@ -116,7 +117,8 @@ class PreloadService {
const nsAString& aSrcset, const nsAString& aSizes,
const nsAString& aNonce, const nsAString& aIntegrity,
const nsAString& aCORS, const nsAString& aReferrerPolicy,
bool aFromHeader, uint64_t aEarlyHintPreloaderId);
const nsAString& aFetchPriority, bool aFromHeader,
uint64_t aEarlyHintPreloaderId);
private:
nsRefPtrHashtable<PreloadHashKey, PreloaderBase> mPreloads;