Bug 1637651 - Assume non-quirks mode for style Link header preloads. r=smaug

This is an issue I found while going through this code and
writing/debugging a test for the bug at hand. Without this, the test in
the actual fix for this bug will fail to actually reuse the preloaded
stylesheet.

It seems reasonable to assume that the intersection of quirks mode
documents using link preload headers is small (and in that case we'd
parse the sheet twice, but oh well).

Differential Revision: https://phabricator.services.mozilla.com/D103567
This commit is contained in:
Emilio Cobos Álvarez 2021-02-01 23:23:50 +00:00
Родитель 6a81495553
Коммит fe36177806
12 изменённых файлов: 147 добавлений и 99 удалений

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

@ -11918,19 +11918,18 @@ NS_IMPL_ISUPPORTS(StubCSSLoaderObserver, nsICSSLoaderObserver)
SheetPreloadStatus Document::PreloadStyle( SheetPreloadStatus Document::PreloadStyle(
nsIURI* uri, const Encoding* aEncoding, const nsAString& aCrossOriginAttr, nsIURI* uri, const Encoding* aEncoding, const nsAString& aCrossOriginAttr,
const enum ReferrerPolicy aReferrerPolicy, const nsAString& aIntegrity, const enum ReferrerPolicy aReferrerPolicy, const nsAString& aIntegrity,
bool aIsLinkPreload) { css::StylePreloadKind aKind) {
MOZ_ASSERT(aKind != css::StylePreloadKind::None);
// The CSSLoader will retain this object after we return. // The CSSLoader will retain this object after we return.
nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver(); nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver();
nsCOMPtr<nsIReferrerInfo> referrerInfo = nsCOMPtr<nsIReferrerInfo> referrerInfo =
ReferrerInfo::CreateFromDocumentAndPolicyOverride(this, aReferrerPolicy); ReferrerInfo::CreateFromDocumentAndPolicyOverride(this, aReferrerPolicy);
auto preloadType = aIsLinkPreload ? css::Loader::IsPreload::FromLink
: css::Loader::IsPreload::FromParser;
// Charset names are always ASCII. // Charset names are always ASCII.
auto result = CSSLoader()->LoadSheet( auto result = CSSLoader()->LoadSheet(
uri, preloadType, aEncoding, referrerInfo, obs, uri, aKind, aEncoding, referrerInfo, obs,
Element::StringToCORSMode(aCrossOriginAttr), aIntegrity); Element::StringToCORSMode(aCrossOriginAttr), aIntegrity);
if (result.isErr()) { if (result.isErr()) {
return SheetPreloadStatus::Errored; return SheetPreloadStatus::Errored;

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

@ -44,6 +44,7 @@
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/UseCounter.h" #include "mozilla/UseCounter.h"
#include "mozilla/WeakPtr.h" #include "mozilla/WeakPtr.h"
#include "mozilla/css/StylePreloadKind.h"
#include "mozilla/dom/DispatcherTrait.h" #include "mozilla/dom/DispatcherTrait.h"
#include "mozilla/dom/DocumentOrShadowRoot.h" #include "mozilla/dom/DocumentOrShadowRoot.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
@ -2951,14 +2952,14 @@ class Document : public nsINode,
void ForgetImagePreload(nsIURI* aURI); void ForgetImagePreload(nsIURI* aURI);
/** /**
* Called by nsParser to preload style sheets. aCrossOriginAttr should be a * Called by the parser or the preload service to preload style sheets.
* void string if the attr is not present. * aCrossOriginAttr should be a void string if the attr is not present.
*/ */
SheetPreloadStatus PreloadStyle(nsIURI* aURI, const Encoding* aEncoding, SheetPreloadStatus PreloadStyle(nsIURI* aURI, const Encoding* aEncoding,
const nsAString& aCrossOriginAttr, const nsAString& aCrossOriginAttr,
ReferrerPolicyEnum aReferrerPolicy, ReferrerPolicyEnum aReferrerPolicy,
const nsAString& aIntegrity, const nsAString& aIntegrity,
bool aIsLinkPreload); css::StylePreloadKind);
/** /**
* Called by the chrome registry to load style sheets. * Called by the chrome registry to load style sheets.

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

@ -144,7 +144,7 @@ SheetLoadDataHashKey::SheetLoadDataHashKey(const css::SheetLoadData& aLoadData)
mCORSMode(aLoadData.mSheet->GetCORSMode()), mCORSMode(aLoadData.mSheet->GetCORSMode()),
mParsingMode(aLoadData.mSheet->ParsingMode()), mParsingMode(aLoadData.mSheet->ParsingMode()),
mCompatMode(aLoadData.mCompatMode), mCompatMode(aLoadData.mCompatMode),
mIsLinkPreload(aLoadData.IsLinkPreload()) { mIsLinkRelPreload(aLoadData.IsLinkRelPreload()) {
MOZ_COUNT_CTOR(SheetLoadDataHashKey); MOZ_COUNT_CTOR(SheetLoadDataHashKey);
MOZ_ASSERT(mURI); MOZ_ASSERT(mURI);
MOZ_ASSERT(mPrincipal); MOZ_ASSERT(mPrincipal);
@ -209,11 +209,11 @@ bool SheetLoadDataHashKey::KeyEquals(const SheetLoadDataHashKey& aKey) const {
// check makes sure that regular loads will never find such a weaker preload // check makes sure that regular loads will never find such a weaker preload
// and rather start a new, independent load with new, stronger SRI checker // and rather start a new, independent load with new, stronger SRI checker
// set up, so that integrity is ensured. // set up, so that integrity is ensured.
if (mIsLinkPreload != aKey.mIsLinkPreload) { if (mIsLinkRelPreload != aKey.mIsLinkRelPreload) {
const auto& linkPreloadMetadata = const auto& linkPreloadMetadata =
mIsLinkPreload ? mSRIMetadata : aKey.mSRIMetadata; mIsLinkRelPreload ? mSRIMetadata : aKey.mSRIMetadata;
const auto& consumerPreloadMetadata = const auto& consumerPreloadMetadata =
mIsLinkPreload ? aKey.mSRIMetadata : mSRIMetadata; mIsLinkRelPreload ? aKey.mSRIMetadata : mSRIMetadata;
if (!consumerPreloadMetadata.CanTrustBeDelegatedTo(linkPreloadMetadata)) { if (!consumerPreloadMetadata.CanTrustBeDelegatedTo(linkPreloadMetadata)) {
LOG((" > Preload SRI metadata mismatch\n")); LOG((" > Preload SRI metadata mismatch\n"));
@ -262,7 +262,7 @@ NS_IMPL_ISUPPORTS(SheetLoadData, nsIRunnable, nsIThreadObserver)
SheetLoadData::SheetLoadData(Loader* aLoader, const nsAString& aTitle, SheetLoadData::SheetLoadData(Loader* aLoader, const nsAString& aTitle,
nsIURI* aURI, StyleSheet* aSheet, bool aSyncLoad, nsIURI* aURI, StyleSheet* aSheet, bool aSyncLoad,
nsINode* aOwningNode, IsAlternate aIsAlternate, nsINode* aOwningNode, IsAlternate aIsAlternate,
MediaMatched aMediaMatches, IsPreload aIsPreload, MediaMatched aMediaMatches, StylePreloadKind aPreloadKind,
nsICSSLoaderObserver* aObserver, nsICSSLoaderObserver* aObserver,
nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aTriggeringPrincipal,
nsIReferrerInfo* aReferrerInfo, nsIReferrerInfo* aReferrerInfo,
@ -289,14 +289,14 @@ SheetLoadData::SheetLoadData(Loader* aLoader, const nsAString& aTitle,
mIsCrossOriginNoCORS(false), mIsCrossOriginNoCORS(false),
mBlockResourceTiming(false), mBlockResourceTiming(false),
mLoadFailed(false), mLoadFailed(false),
mIsPreload(aIsPreload), mPreloadKind(aPreloadKind),
mOwningNode(aOwningNode), mOwningNode(aOwningNode),
mObserver(aObserver), mObserver(aObserver),
mTriggeringPrincipal(aTriggeringPrincipal), mTriggeringPrincipal(aTriggeringPrincipal),
mReferrerInfo(aReferrerInfo), mReferrerInfo(aReferrerInfo),
mRequestingNode(aRequestingNode), mRequestingNode(aRequestingNode),
mGuessedEncoding(GetFallbackEncoding(*aLoader, aOwningNode, nullptr)), mGuessedEncoding(GetFallbackEncoding(*aLoader, aOwningNode, nullptr)),
mCompatMode(aLoader->mCompatMode) { mCompatMode(aLoader->CompatMode(aPreloadKind)) {
MOZ_ASSERT(!mOwningNode || dom::LinkStyle::FromNode(*mOwningNode), MOZ_ASSERT(!mOwningNode || dom::LinkStyle::FromNode(*mOwningNode),
"Must implement LinkStyle"); "Must implement LinkStyle");
MOZ_ASSERT(mTriggeringPrincipal); MOZ_ASSERT(mTriggeringPrincipal);
@ -331,7 +331,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet,
mIsCrossOriginNoCORS(false), mIsCrossOriginNoCORS(false),
mBlockResourceTiming(false), mBlockResourceTiming(false),
mLoadFailed(false), mLoadFailed(false),
mIsPreload(IsPreload::No), mPreloadKind(StylePreloadKind::None),
mOwningNode(nullptr), mOwningNode(nullptr),
mObserver(aObserver), mObserver(aObserver),
mTriggeringPrincipal(aTriggeringPrincipal), mTriggeringPrincipal(aTriggeringPrincipal),
@ -339,7 +339,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet,
mRequestingNode(aRequestingNode), mRequestingNode(aRequestingNode),
mGuessedEncoding(GetFallbackEncoding( mGuessedEncoding(GetFallbackEncoding(
*aLoader, nullptr, aParentData ? aParentData->mEncoding : nullptr)), *aLoader, nullptr, aParentData ? aParentData->mEncoding : nullptr)),
mCompatMode(aLoader->mCompatMode) { mCompatMode(aLoader->CompatMode(mPreloadKind)) {
MOZ_ASSERT(mLoader, "Must have a loader!"); MOZ_ASSERT(mLoader, "Must have a loader!");
MOZ_ASSERT(mTriggeringPrincipal); MOZ_ASSERT(mTriggeringPrincipal);
MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad, MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad,
@ -349,7 +349,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet,
SheetLoadData::SheetLoadData( SheetLoadData::SheetLoadData(
Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet, bool aSyncLoad, Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet, bool aSyncLoad,
UseSystemPrincipal aUseSystemPrincipal, IsPreload aIsPreload, UseSystemPrincipal aUseSystemPrincipal, StylePreloadKind aPreloadKind,
const Encoding* aPreloadEncoding, nsICSSLoaderObserver* aObserver, const Encoding* aPreloadEncoding, nsICSSLoaderObserver* aObserver,
nsIPrincipal* aTriggeringPrincipal, nsIReferrerInfo* aReferrerInfo, nsIPrincipal* aTriggeringPrincipal, nsIReferrerInfo* aReferrerInfo,
nsINode* aRequestingNode) nsINode* aRequestingNode)
@ -374,7 +374,7 @@ SheetLoadData::SheetLoadData(
mIsCrossOriginNoCORS(false), mIsCrossOriginNoCORS(false),
mBlockResourceTiming(false), mBlockResourceTiming(false),
mLoadFailed(false), mLoadFailed(false),
mIsPreload(aIsPreload), mPreloadKind(aPreloadKind),
mOwningNode(nullptr), mOwningNode(nullptr),
mObserver(aObserver), mObserver(aObserver),
mTriggeringPrincipal(aTriggeringPrincipal), mTriggeringPrincipal(aTriggeringPrincipal),
@ -382,7 +382,7 @@ SheetLoadData::SheetLoadData(
mRequestingNode(aRequestingNode), mRequestingNode(aRequestingNode),
mGuessedEncoding( mGuessedEncoding(
GetFallbackEncoding(*aLoader, nullptr, aPreloadEncoding)), GetFallbackEncoding(*aLoader, nullptr, aPreloadEncoding)),
mCompatMode(aLoader->mCompatMode) { mCompatMode(aLoader->CompatMode(aPreloadKind)) {
MOZ_ASSERT(mTriggeringPrincipal); MOZ_ASSERT(mTriggeringPrincipal);
MOZ_ASSERT(mLoader, "Must have a loader!"); MOZ_ASSERT(mLoader, "Must have a loader!");
MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad, MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad,
@ -501,7 +501,7 @@ bool LoaderReusableStyleSheets::FindReusableStyleSheet(
Loader::Loader() Loader::Loader()
: mDocument(nullptr), : mDocument(nullptr),
mCompatMode(eCompatibility_FullStandards), mDocumentCompatMode(eCompatibility_FullStandards),
mReporter(new ConsoleReportCollector()) {} mReporter(new ConsoleReportCollector()) {}
Loader::Loader(DocGroup* aDocGroup) : Loader() { mDocGroup = aDocGroup; } Loader::Loader(DocGroup* aDocGroup) : Loader() { mDocGroup = aDocGroup; }
@ -509,7 +509,7 @@ Loader::Loader(DocGroup* aDocGroup) : Loader() { mDocGroup = aDocGroup; }
Loader::Loader(Document* aDocument) : Loader() { Loader::Loader(Document* aDocument) : Loader() {
MOZ_ASSERT(aDocument, "We should get a valid document from the caller!"); MOZ_ASSERT(aDocument, "We should get a valid document from the caller!");
mDocument = aDocument; mDocument = aDocument;
mCompatMode = aDocument->GetCompatibilityMode(); mDocumentCompatMode = aDocument->GetCompatibilityMode();
mSheets = SharedStyleSheetCache::Get(); mSheets = SharedStyleSheetCache::Get();
RegisterInSheetCache(); RegisterInSheetCache();
} }
@ -783,7 +783,7 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus,
sameOrigin = false; sameOrigin = false;
} }
if (sameOrigin && mLoader->mCompatMode == eCompatibility_NavQuirks) { if (sameOrigin && mCompatMode == eCompatibility_NavQuirks) {
errorMessage = "MimeNotCssWarn"; errorMessage = "MimeNotCssWarn";
errorFlag = nsIScriptError::warningFlag; errorFlag = nsIScriptError::warningFlag;
} else { } else {
@ -884,14 +884,14 @@ nsresult Loader::CheckContentPolicy(nsIPrincipal* aLoadingPrincipal,
nsIURI* aTargetURI, nsIURI* aTargetURI,
nsINode* aRequestingNode, nsINode* aRequestingNode,
const nsAString& aNonce, const nsAString& aNonce,
IsPreload aIsPreload) { StylePreloadKind aPreloadKind) {
// When performing a system load don't consult content policies. // When performing a system load don't consult content policies.
if (!mDocument) { if (!mDocument) {
return NS_OK; return NS_OK;
} }
nsContentPolicyType contentPolicyType = nsContentPolicyType contentPolicyType =
aIsPreload == IsPreload::No aPreloadKind == StylePreloadKind::None
? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET
: nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD; : nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD;
@ -902,7 +902,7 @@ nsresult Loader::CheckContentPolicy(nsIPrincipal* aLoadingPrincipal,
// snapshot the nonce at load start time for performing CSP checks // snapshot the nonce at load start time for performing CSP checks
if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET) { if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET) {
secCheckLoadInfo->SetCspNonce(aNonce); secCheckLoadInfo->SetCspNonce(aNonce);
MOZ_ASSERT_IF(aIsPreload != IsPreload::No, aNonce.IsEmpty()); MOZ_ASSERT_IF(aPreloadKind != StylePreloadKind::None, aNonce.IsEmpty());
} }
int16_t shouldLoad = nsIContentPolicy::ACCEPT; int16_t shouldLoad = nsIContentPolicy::ACCEPT;
@ -948,7 +948,7 @@ std::tuple<RefPtr<StyleSheet>, Loader::SheetState> Loader::CreateSheet(
nsIURI* aURI, nsIContent* aLinkingContent, nsIURI* aURI, nsIContent* aLinkingContent,
nsIPrincipal* aTriggeringPrincipal, css::SheetParsingMode aParsingMode, nsIPrincipal* aTriggeringPrincipal, css::SheetParsingMode aParsingMode,
CORSMode aCORSMode, const Encoding* aPreloadOrParentDataEncoding, CORSMode aCORSMode, const Encoding* aPreloadOrParentDataEncoding,
const nsAString& aIntegrity, bool aSyncLoad, IsPreload aIsPreload) { const nsAString& aIntegrity, bool aSyncLoad, StylePreloadKind aPreloadKind) {
MOZ_ASSERT(aURI, "This path is not taken for inline stylesheets"); MOZ_ASSERT(aURI, "This path is not taken for inline stylesheets");
LOG(("css::Loader::CreateSheet(%s)", aURI->GetSpecOrDefault().get())); LOG(("css::Loader::CreateSheet(%s)", aURI->GetSpecOrDefault().get()));
@ -965,11 +965,12 @@ std::tuple<RefPtr<StyleSheet>, Loader::SheetState> Loader::CreateSheet(
} }
if (mSheets) { if (mSheets) {
SheetLoadDataHashKey key( SheetLoadDataHashKey key(aURI, aTriggeringPrincipal, LoaderPrincipal(),
aURI, aTriggeringPrincipal, LoaderPrincipal(), PartitionedPrincipal(), PartitionedPrincipal(),
GetFallbackEncoding(*this, aLinkingContent, GetFallbackEncoding(*this, aLinkingContent,
aPreloadOrParentDataEncoding), aPreloadOrParentDataEncoding),
aCORSMode, aParsingMode, mCompatMode, sriMetadata, aIsPreload); aCORSMode, aParsingMode, CompatMode(aPreloadKind),
sriMetadata, aPreloadKind);
auto cacheResult = mSheets->Lookup(*this, key, aSyncLoad); auto cacheResult = mSheets->Lookup(*this, key, aSyncLoad);
if (const auto& [styleSheet, sheetState] = cacheResult; styleSheet) { if (const auto& [styleSheet, sheetState] = cacheResult; styleSheet) {
LOG((" Hit cache with state: %s", gStateStrings[size_t(sheetState)])); LOG((" Hit cache with state: %s", gStateStrings[size_t(sheetState)]));
@ -1196,7 +1197,7 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState,
nsILoadInfo::SEC_ALLOW_CHROME; nsILoadInfo::SEC_ALLOW_CHROME;
nsContentPolicyType contentPolicyType = nsContentPolicyType contentPolicyType =
aLoadData.mIsPreload == IsPreload::No aLoadData.mPreloadKind == StylePreloadKind::None
? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET
: nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD; : nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD;
@ -1295,8 +1296,7 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState,
} }
} }
aLoadData.NotifyOpen(preloadKey, mDocument, aLoadData.NotifyOpen(preloadKey, mDocument, aLoadData.IsLinkRelPreload());
aLoadData.mIsPreload == IsPreload::FromLink);
if (coalescedLoad) { if (coalescedLoad) {
// All done here; once the load completes we'll be marked complete // All done here; once the load completes we'll be marked complete
// automatically. // automatically.
@ -1336,7 +1336,7 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState,
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME; securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
nsContentPolicyType contentPolicyType = nsContentPolicyType contentPolicyType =
aLoadData.mIsPreload == IsPreload::No aLoadData.mPreloadKind == StylePreloadKind::None
? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET ? nsIContentPolicy::TYPE_INTERNAL_STYLESHEET
: nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD; : nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD;
@ -1381,7 +1381,7 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState,
if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel)) { if (nsCOMPtr<nsIClassOfService> cos = do_QueryInterface(channel)) {
cos->AddClassFlags(nsIClassOfService::Leader); cos->AddClassFlags(nsIClassOfService::Leader);
} }
if (aLoadData.mIsPreload == IsPreload::FromLink) { if (aLoadData.IsLinkRelPreload()) {
SheetLoadData::PrioritizeAsPreload(channel); SheetLoadData::PrioritizeAsPreload(channel);
SheetLoadData::AddLoadBackgroundFlag(channel); SheetLoadData::AddLoadBackgroundFlag(channel);
} }
@ -1713,7 +1713,7 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle(
} else { } else {
auto data = MakeRefPtr<SheetLoadData>( auto data = MakeRefPtr<SheetLoadData>(
this, aInfo.mTitle, nullptr, sheet, false, aInfo.mContent, isAlternate, this, aInfo.mTitle, nullptr, sheet, false, aInfo.mContent, isAlternate,
matched, IsPreload::No, aObserver, principal, aInfo.mReferrerInfo, matched, StylePreloadKind::None, aObserver, principal, aInfo.mReferrerInfo,
aInfo.mContent); aInfo.mContent);
data->mLineNumber = aLineNumber; data->mLineNumber = aLineNumber;
@ -1773,7 +1773,7 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadStyleLink(
MOZ_ASSERT_IF(syncLoad, !aObserver); MOZ_ASSERT_IF(syncLoad, !aObserver);
nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aInfo.mURI, nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aInfo.mURI,
context, aInfo.mNonce, IsPreload::No); context, aInfo.mNonce, StylePreloadKind::None);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
// Don't fire the error event if our document is loaded as data. We're // Don't fire the error event if our document is loaded as data. We're
// supposed to not even try to do loads in that case... Unfortunately, we // supposed to not even try to do loads in that case... Unfortunately, we
@ -1795,7 +1795,7 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadStyleLink(
// pending sheets go to the non-pending state. // pending sheets go to the non-pending state.
auto isAlternate = IsAlternateSheet(aInfo.mTitle, aInfo.mHasAlternateRel); auto isAlternate = IsAlternateSheet(aInfo.mTitle, aInfo.mHasAlternateRel);
auto [sheet, state] = auto [sheet, state] =
CreateSheet(aInfo, eAuthorSheetFeatures, syncLoad, IsPreload::No); CreateSheet(aInfo, eAuthorSheetFeatures, syncLoad, StylePreloadKind::None);
LOG((" Sheet is alternate: %d", static_cast<int>(isAlternate))); LOG((" Sheet is alternate: %d", static_cast<int>(isAlternate)));
@ -1814,7 +1814,7 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadStyleLink(
"If there is any node, it should be a LinkStyle"); "If there is any node, it should be a LinkStyle");
auto data = MakeRefPtr<SheetLoadData>( auto data = MakeRefPtr<SheetLoadData>(
this, aInfo.mTitle, aInfo.mURI, sheet, syncLoad, aInfo.mContent, this, aInfo.mTitle, aInfo.mURI, sheet, syncLoad, aInfo.mContent,
isAlternate, matched, IsPreload::No, aObserver, principal, isAlternate, matched, StylePreloadKind::None, aObserver, principal,
aInfo.mReferrerInfo, context); aInfo.mReferrerInfo, context);
MaybeNotifyPreloadUsed(*data); MaybeNotifyPreloadUsed(*data);
@ -1920,7 +1920,7 @@ nsresult Loader::LoadChildSheet(StyleSheet& aParentSheet,
nsIPrincipal* principal = aParentSheet.Principal(); nsIPrincipal* principal = aParentSheet.Principal();
nsresult rv = CheckContentPolicy(LoaderPrincipal(), principal, aURL, context, nsresult rv = CheckContentPolicy(LoaderPrincipal(), principal, aURL, context,
u""_ns, IsPreload::No); u""_ns, StylePreloadKind::None);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
if (aParentData) { if (aParentData) {
MarkLoadTreeFailed(*aParentData); MarkLoadTreeFailed(*aParentData);
@ -1961,7 +1961,7 @@ nsresult Loader::LoadChildSheet(StyleSheet& aParentSheet,
CreateSheet(aURL, nullptr, principal, aParentSheet.ParsingMode(), CreateSheet(aURL, nullptr, principal, aParentSheet.ParsingMode(),
CORS_NONE, aParentData ? aParentData->mEncoding : nullptr, CORS_NONE, aParentData ? aParentData->mEncoding : nullptr,
u""_ns, // integrity is only checked on main sheet u""_ns, // integrity is only checked on main sheet
aParentData && aParentData->mSyncLoad, IsPreload::No); aParentData && aParentData->mSyncLoad, StylePreloadKind::None);
PrepareSheet(*sheet, u""_ns, u""_ns, aMedia, IsAlternate::No, PrepareSheet(*sheet, u""_ns, u""_ns, aMedia, IsAlternate::No,
IsExplicitlyEnabled::No); IsExplicitlyEnabled::No);
} }
@ -2003,7 +2003,7 @@ Result<RefPtr<StyleSheet>, nsresult> Loader::LoadSheetSync(
UseSystemPrincipal aUseSystemPrincipal) { UseSystemPrincipal aUseSystemPrincipal) {
LOG(("css::Loader::LoadSheetSync")); LOG(("css::Loader::LoadSheetSync"));
nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo(nullptr); nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo(nullptr);
return InternalLoadNonDocumentSheet(aURL, IsPreload::No, aParsingMode, return InternalLoadNonDocumentSheet(aURL, StylePreloadKind::None, aParsingMode,
aUseSystemPrincipal, nullptr, aUseSystemPrincipal, nullptr,
referrerInfo, nullptr, CORS_NONE, u""_ns); referrerInfo, nullptr, CORS_NONE, u""_ns);
} }
@ -2013,22 +2013,22 @@ Result<RefPtr<StyleSheet>, nsresult> Loader::LoadSheet(
UseSystemPrincipal aUseSystemPrincipal, nsICSSLoaderObserver* aObserver) { UseSystemPrincipal aUseSystemPrincipal, nsICSSLoaderObserver* aObserver) {
nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo(nullptr); nsCOMPtr<nsIReferrerInfo> referrerInfo = new ReferrerInfo(nullptr);
return InternalLoadNonDocumentSheet( return InternalLoadNonDocumentSheet(
aURI, IsPreload::No, aParsingMode, aUseSystemPrincipal, nullptr, aURI, StylePreloadKind::None, aParsingMode, aUseSystemPrincipal, nullptr,
referrerInfo, aObserver, CORS_NONE, u""_ns); referrerInfo, aObserver, CORS_NONE, u""_ns);
} }
Result<RefPtr<StyleSheet>, nsresult> Loader::LoadSheet( Result<RefPtr<StyleSheet>, nsresult> Loader::LoadSheet(
nsIURI* aURL, IsPreload aIsPreload, const Encoding* aPreloadEncoding, nsIURI* aURL, StylePreloadKind aPreloadKind, const Encoding* aPreloadEncoding,
nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver, nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver,
CORSMode aCORSMode, const nsAString& aIntegrity) { CORSMode aCORSMode, const nsAString& aIntegrity) {
LOG(("css::Loader::LoadSheet(aURL, aObserver) api call")); LOG(("css::Loader::LoadSheet(aURL, aObserver) api call"));
return InternalLoadNonDocumentSheet( return InternalLoadNonDocumentSheet(
aURL, aIsPreload, eAuthorSheetFeatures, UseSystemPrincipal::No, aURL, aPreloadKind, eAuthorSheetFeatures, UseSystemPrincipal::No,
aPreloadEncoding, aReferrerInfo, aObserver, aCORSMode, aIntegrity); aPreloadEncoding, aReferrerInfo, aObserver, aCORSMode, aIntegrity);
} }
Result<RefPtr<StyleSheet>, nsresult> Loader::InternalLoadNonDocumentSheet( Result<RefPtr<StyleSheet>, nsresult> Loader::InternalLoadNonDocumentSheet(
nsIURI* aURL, IsPreload aIsPreload, SheetParsingMode aParsingMode, nsIURI* aURL, StylePreloadKind aPreloadKind, SheetParsingMode aParsingMode,
UseSystemPrincipal aUseSystemPrincipal, const Encoding* aPreloadEncoding, UseSystemPrincipal aUseSystemPrincipal, const Encoding* aPreloadEncoding,
nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver, nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver,
CORSMode aCORSMode, const nsAString& aIntegrity) { CORSMode aCORSMode, const nsAString& aIntegrity) {
@ -2047,7 +2047,7 @@ Result<RefPtr<StyleSheet>, nsresult> Loader::InternalLoadNonDocumentSheet(
nsIPrincipal* loadingPrincipal = LoaderPrincipal(); nsIPrincipal* loadingPrincipal = LoaderPrincipal();
nsIPrincipal* triggeringPrincipal = loadingPrincipal; nsIPrincipal* triggeringPrincipal = loadingPrincipal;
nsresult rv = CheckContentPolicy(loadingPrincipal, triggeringPrincipal, aURL, nsresult rv = CheckContentPolicy(loadingPrincipal, triggeringPrincipal, aURL,
mDocument, u""_ns, aIsPreload); mDocument, u""_ns, aPreloadKind);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return Err(rv); return Err(rv);
} }
@ -2055,13 +2055,13 @@ Result<RefPtr<StyleSheet>, nsresult> Loader::InternalLoadNonDocumentSheet(
bool syncLoad = !aObserver; bool syncLoad = !aObserver;
auto [sheet, state] = auto [sheet, state] =
CreateSheet(aURL, nullptr, triggeringPrincipal, aParsingMode, aCORSMode, CreateSheet(aURL, nullptr, triggeringPrincipal, aParsingMode, aCORSMode,
aPreloadEncoding, aIntegrity, syncLoad, aIsPreload); aPreloadEncoding, aIntegrity, syncLoad, aPreloadKind);
PrepareSheet(*sheet, u""_ns, u""_ns, nullptr, IsAlternate::No, PrepareSheet(*sheet, u""_ns, u""_ns, nullptr, IsAlternate::No,
IsExplicitlyEnabled::No); IsExplicitlyEnabled::No);
auto data = MakeRefPtr<SheetLoadData>( auto data = MakeRefPtr<SheetLoadData>(
this, aURL, sheet, syncLoad, aUseSystemPrincipal, aIsPreload, this, aURL, sheet, syncLoad, aUseSystemPrincipal, aPreloadKind,
aPreloadEncoding, aObserver, triggeringPrincipal, aReferrerInfo, aPreloadEncoding, aObserver, triggeringPrincipal, aReferrerInfo,
mDocument); mDocument);
if (state == SheetState::Complete) { if (state == SheetState::Complete) {

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

@ -14,6 +14,7 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/CORSMode.h" #include "mozilla/CORSMode.h"
#include "mozilla/css/StylePreloadKind.h"
#include "mozilla/dom/LinkStyle.h" #include "mozilla/dom/LinkStyle.h"
#include "mozilla/MemoryReporting.h" #include "mozilla/MemoryReporting.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
@ -47,16 +48,6 @@ class Element;
// This must contain all the state that affects CSS parsing. // This must contain all the state that affects CSS parsing.
class SheetLoadDataHashKey : public PLDHashEntryHdr { class SheetLoadDataHashKey : public PLDHashEntryHdr {
public: public:
enum class IsPreload : uint8_t {
No,
// This is a speculative load initiated by a <link rel=stylesheet> tag
// scanned by the parser, or @import rules found in a <style> tag.
FromParser,
// This is a speculative load as well, but initiated by
// <link rel="preload" as="style">
FromLink,
};
using KeyType = const SheetLoadDataHashKey&; using KeyType = const SheetLoadDataHashKey&;
using KeyTypePointer = const SheetLoadDataHashKey*; using KeyTypePointer = const SheetLoadDataHashKey*;
@ -70,7 +61,7 @@ class SheetLoadDataHashKey : public PLDHashEntryHdr {
mParsingMode(aKey->mParsingMode), mParsingMode(aKey->mParsingMode),
mCompatMode(aKey->mCompatMode), mCompatMode(aKey->mCompatMode),
mSRIMetadata(aKey->mSRIMetadata), mSRIMetadata(aKey->mSRIMetadata),
mIsLinkPreload(aKey->mIsLinkPreload) { mIsLinkRelPreload(aKey->mIsLinkRelPreload) {
MOZ_COUNT_CTOR(SheetLoadDataHashKey); MOZ_COUNT_CTOR(SheetLoadDataHashKey);
} }
@ -81,7 +72,7 @@ class SheetLoadDataHashKey : public PLDHashEntryHdr {
CORSMode aCORSMode, css::SheetParsingMode aParsingMode, CORSMode aCORSMode, css::SheetParsingMode aParsingMode,
nsCompatibility aCompatMode, nsCompatibility aCompatMode,
const dom::SRIMetadata& aSRIMetadata, const dom::SRIMetadata& aSRIMetadata,
IsPreload aIsPreload) css::StylePreloadKind aPreloadKind)
: mURI(aURI), : mURI(aURI),
mPrincipal(aPrincipal), mPrincipal(aPrincipal),
mLoaderPrincipal(aLoaderPrincipal), mLoaderPrincipal(aLoaderPrincipal),
@ -91,7 +82,7 @@ class SheetLoadDataHashKey : public PLDHashEntryHdr {
mParsingMode(aParsingMode), mParsingMode(aParsingMode),
mCompatMode(aCompatMode), mCompatMode(aCompatMode),
mSRIMetadata(aSRIMetadata), mSRIMetadata(aSRIMetadata),
mIsLinkPreload(aIsPreload == IsPreload::FromLink) { mIsLinkRelPreload(IsLinkRelPreload(aPreloadKind)) {
MOZ_ASSERT(aURI); MOZ_ASSERT(aURI);
MOZ_ASSERT(aPrincipal); MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aLoaderPrincipal); MOZ_ASSERT(aLoaderPrincipal);
@ -108,7 +99,7 @@ class SheetLoadDataHashKey : public PLDHashEntryHdr {
mParsingMode(std::move(toMove.mParsingMode)), mParsingMode(std::move(toMove.mParsingMode)),
mCompatMode(std::move(toMove.mCompatMode)), mCompatMode(std::move(toMove.mCompatMode)),
mSRIMetadata(std::move(toMove.mSRIMetadata)), mSRIMetadata(std::move(toMove.mSRIMetadata)),
mIsLinkPreload(std::move(toMove.mIsLinkPreload)) { mIsLinkRelPreload(std::move(toMove.mIsLinkRelPreload)) {
MOZ_COUNT_CTOR(SheetLoadDataHashKey); MOZ_COUNT_CTOR(SheetLoadDataHashKey);
} }
@ -156,7 +147,7 @@ class SheetLoadDataHashKey : public PLDHashEntryHdr {
const css::SheetParsingMode mParsingMode; const css::SheetParsingMode mParsingMode;
const nsCompatibility mCompatMode; const nsCompatibility mCompatMode;
dom::SRIMetadata mSRIMetadata; dom::SRIMetadata mSRIMetadata;
const bool mIsLinkPreload; const bool mIsLinkRelPreload;
}; };
namespace css { namespace css {
@ -237,9 +228,22 @@ class Loader final {
void RegisterInSheetCache(); void RegisterInSheetCache();
void SetCompatibilityMode(nsCompatibility aCompatMode) { void SetCompatibilityMode(nsCompatibility aCompatMode) {
mCompatMode = aCompatMode; mDocumentCompatMode = aCompatMode;
}
using StylePreloadKind = css::StylePreloadKind;
nsCompatibility CompatMode(StylePreloadKind aPreloadKind) const {
// For Link header preload, we guess non-quirks, because otherwise it is
// useless for modern pages.
//
// Link element preload is generally good because the speculative html
// parser deals with quirks mode properly.
if (aPreloadKind == StylePreloadKind::FromLinkRelPreloadHeader) {
return eCompatibility_FullStandards;
}
return mDocumentCompatMode;
} }
nsCompatibility GetCompatibilityMode() { return mCompatMode; }
// TODO(emilio): Is the complexity of this method and carrying the titles // TODO(emilio): Is the complexity of this method and carrying the titles
// around worth it? The alternate sheets will load anyhow eventually... // around worth it? The alternate sheets will load anyhow eventually...
@ -332,8 +336,6 @@ class Loader final {
nsIURI*, SheetParsingMode = eAuthorSheetFeatures, nsIURI*, SheetParsingMode = eAuthorSheetFeatures,
UseSystemPrincipal = UseSystemPrincipal::No); UseSystemPrincipal = UseSystemPrincipal::No);
using IsPreload = SheetLoadDataHashKey::IsPreload;
/** /**
* Asynchronously load the stylesheet at aURL. If a successful result is * Asynchronously load the stylesheet at aURL. If a successful result is
* returned, aObserver is guaranteed to be notified asynchronously once the * returned, aObserver is guaranteed to be notified asynchronously once the
@ -356,7 +358,7 @@ class Loader final {
* non-UTF8 sheets being treated as UTF-8 by this method. * non-UTF8 sheets being treated as UTF-8 by this method.
*/ */
Result<RefPtr<StyleSheet>, nsresult> LoadSheet( Result<RefPtr<StyleSheet>, nsresult> LoadSheet(
nsIURI* aURI, IsPreload, const Encoding* aPreloadEncoding, nsIURI* aURI, StylePreloadKind, const Encoding* aPreloadEncoding,
nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver, nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver,
CORSMode = CORS_NONE, const nsAString& aIntegrity = u""_ns); CORSMode = CORS_NONE, const nsAString& aIntegrity = u""_ns);
@ -483,18 +485,18 @@ class Loader final {
nsresult CheckContentPolicy(nsIPrincipal* aLoadingPrincipal, nsresult CheckContentPolicy(nsIPrincipal* aLoadingPrincipal,
nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aTriggeringPrincipal,
nsIURI* aTargetURI, nsINode* aRequestingNode, nsIURI* aTargetURI, nsINode* aRequestingNode,
const nsAString& aNonce, IsPreload); const nsAString& aNonce, StylePreloadKind);
std::tuple<RefPtr<StyleSheet>, SheetState> CreateSheet( std::tuple<RefPtr<StyleSheet>, SheetState> CreateSheet(
const SheetInfo& aInfo, css::SheetParsingMode aParsingMode, const SheetInfo& aInfo, css::SheetParsingMode aParsingMode,
bool aSyncLoad, IsPreload aIsPreload) { bool aSyncLoad, css::StylePreloadKind aPreloadKind) {
nsIPrincipal* triggeringPrincipal = aInfo.mTriggeringPrincipal nsIPrincipal* triggeringPrincipal = aInfo.mTriggeringPrincipal
? aInfo.mTriggeringPrincipal.get() ? aInfo.mTriggeringPrincipal.get()
: LoaderPrincipal(); : LoaderPrincipal();
return CreateSheet(aInfo.mURI, aInfo.mContent, triggeringPrincipal, return CreateSheet(aInfo.mURI, aInfo.mContent, triggeringPrincipal,
aParsingMode, aInfo.mCORSMode, aParsingMode, aInfo.mCORSMode,
/* aPreloadOrParentDataEncoding = */ nullptr, /* aPreloadOrParentDataEncoding = */ nullptr,
aInfo.mIntegrity, aSyncLoad, aIsPreload); aInfo.mIntegrity, aSyncLoad, aPreloadKind);
} }
// For inline style, the aURI param is null, but the aLinkingContent // For inline style, the aURI param is null, but the aLinkingContent
@ -504,7 +506,7 @@ class Loader final {
nsIURI* aURI, nsIContent* aLinkingContent, nsIURI* aURI, nsIContent* aLinkingContent,
nsIPrincipal* aTriggeringPrincipal, css::SheetParsingMode, CORSMode, nsIPrincipal* aTriggeringPrincipal, css::SheetParsingMode, CORSMode,
const Encoding* aPreloadOrParentDataEncoding, const nsAString& aIntegrity, const Encoding* aPreloadOrParentDataEncoding, const nsAString& aIntegrity,
bool aSyncLoad, IsPreload aIsPreload); bool aSyncLoad, StylePreloadKind);
// Pass in either a media string or the MediaList from the CSSParser. Don't // Pass in either a media string or the MediaList from the CSSParser. Don't
// pass both. // pass both.
@ -520,7 +522,7 @@ class Loader final {
void InsertChildSheet(StyleSheet& aSheet, StyleSheet& aParentSheet); void InsertChildSheet(StyleSheet& aSheet, StyleSheet& aParentSheet);
Result<RefPtr<StyleSheet>, nsresult> InternalLoadNonDocumentSheet( Result<RefPtr<StyleSheet>, nsresult> InternalLoadNonDocumentSheet(
nsIURI* aURL, IsPreload, SheetParsingMode aParsingMode, nsIURI* aURL, StylePreloadKind, SheetParsingMode aParsingMode,
UseSystemPrincipal, const Encoding* aPreloadEncoding, UseSystemPrincipal, const Encoding* aPreloadEncoding,
nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver, nsIReferrerInfo* aReferrerInfo, nsICSSLoaderObserver* aObserver,
CORSMode aCORSMode, const nsAString& aIntegrity); CORSMode aCORSMode, const nsAString& aIntegrity);
@ -601,7 +603,7 @@ class Loader final {
// For dispatching events via DocGroup::Dispatch() when mDocument is nullptr. // For dispatching events via DocGroup::Dispatch() when mDocument is nullptr.
RefPtr<dom::DocGroup> mDocGroup; RefPtr<dom::DocGroup> mDocGroup;
nsCompatibility mCompatMode; nsCompatibility mDocumentCompatMode;
nsCOMPtr<nsIConsoleReportCollector> mReporter; nsCOMPtr<nsIConsoleReportCollector> mReporter;

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

@ -346,7 +346,7 @@ void SharedStyleSheetCache::LoadCompletedInternal(
// Not a document load, nothing to do. // Not a document load, nothing to do.
return false; return false;
} }
if (data->mIsPreload != css::Loader::IsPreload::No) { if (data->IsPreload()) {
// Preloads are not supposed to be observable. // Preloads are not supposed to be observable.
return false; return false;
} }

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

@ -26,8 +26,7 @@ class nsIURI;
class nsIReferrerInfo; class nsIReferrerInfo;
struct StyleUseCounters; struct StyleUseCounters;
namespace mozilla { namespace mozilla::css {
namespace css {
/********************************************* /*********************************************
* Data needed to properly load a stylesheet * * Data needed to properly load a stylesheet *
@ -43,7 +42,6 @@ class SheetLoadData final : public PreloaderBase,
public nsIThreadObserver { public nsIThreadObserver {
using MediaMatched = dom::LinkStyle::MediaMatched; using MediaMatched = dom::LinkStyle::MediaMatched;
using IsAlternate = dom::LinkStyle::IsAlternate; using IsAlternate = dom::LinkStyle::IsAlternate;
using IsPreload = Loader::IsPreload;
using UseSystemPrincipal = Loader::UseSystemPrincipal; using UseSystemPrincipal = Loader::UseSystemPrincipal;
protected: protected:
@ -58,7 +56,7 @@ class SheetLoadData final : public PreloaderBase,
SheetLoadData(Loader* aLoader, const nsAString& aTitle, nsIURI* aURI, SheetLoadData(Loader* aLoader, const nsAString& aTitle, nsIURI* aURI,
StyleSheet* aSheet, bool aSyncLoad, nsINode* aOwningNode, StyleSheet* aSheet, bool aSyncLoad, nsINode* aOwningNode,
IsAlternate aIsAlternate, MediaMatched aMediaMatched, IsAlternate aIsAlternate, MediaMatched aMediaMatched,
IsPreload aIsPreload, nsICSSLoaderObserver* aObserver, StylePreloadKind aPreloadKind, nsICSSLoaderObserver* aObserver,
nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aTriggeringPrincipal,
nsIReferrerInfo* aReferrerInfo, nsINode* aRequestingNode); nsIReferrerInfo* aReferrerInfo, nsINode* aRequestingNode);
@ -70,7 +68,7 @@ class SheetLoadData final : public PreloaderBase,
// Data for loading a non-document sheet // Data for loading a non-document sheet
SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet, SheetLoadData(Loader* aLoader, nsIURI* aURI, StyleSheet* aSheet,
bool aSyncLoad, UseSystemPrincipal, IsPreload, bool aSyncLoad, UseSystemPrincipal, StylePreloadKind,
const Encoding* aPreloadEncoding, const Encoding* aPreloadEncoding,
nsICSSLoaderObserver* aObserver, nsICSSLoaderObserver* aObserver,
nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aTriggeringPrincipal,
@ -201,7 +199,7 @@ class SheetLoadData final : public PreloaderBase,
// TODO(emilio): This can become a bitfield once we build with a GCC version // TODO(emilio): This can become a bitfield once we build with a GCC version
// that has the fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414, // that has the fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414,
// which causes a false positive warning here. // which causes a false positive warning here.
const IsPreload mIsPreload; const StylePreloadKind mPreloadKind;
// This is the node that imported the sheet. Needed to get the charset set on // This is the node that imported the sheet. Needed to get the charset set on
// it, and to fire load/error events. Must implement LinkStyle. // it, and to fire load/error events. Must implement LinkStyle.
@ -250,9 +248,10 @@ class SheetLoadData final : public PreloaderBase,
} }
} }
bool IsLinkPreload() const { return mIsPreload == IsPreload::FromLink; } bool IsPreload() const { return mPreloadKind != StylePreloadKind::None; }
bool IsLinkRelPreload() const { return css::IsLinkRelPreload(mPreloadKind); }
bool BlocksLoadEvent() const { return !RootLoadData().IsLinkPreload(); } bool BlocksLoadEvent() const { return !RootLoadData().IsLinkRelPreload(); }
private: private:
const SheetLoadData& RootLoadData() const { const SheetLoadData& RootLoadData() const {
@ -268,8 +267,7 @@ class SheetLoadData final : public PreloaderBase,
using SheetLoadDataHolder = nsMainThreadPtrHolder<SheetLoadData>; using SheetLoadDataHolder = nsMainThreadPtrHolder<SheetLoadData>;
} // namespace css } // namespace mozilla::css
} // namespace mozilla
/** /**
* Casting SheetLoadData to nsISupports is ambiguous. * Casting SheetLoadData to nsISupports is ambiguous.

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

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#ifndef mozilla_css_StylePreloadKind_h
#define mozilla_css_StylePreloadKind_h
#include <stdint.h>
namespace mozilla::css {
enum class StylePreloadKind : uint8_t {
// Not a preload.
None,
// An speculative load from the parser for a <link rel="stylesheet"> or
// @import stylesheet.
FromParser,
// A preload (speculative or not) for a <link rel="preload" as="style">
// element.
FromLinkRelPreloadElement,
// A preload for a "Link" rel=preload response header.
FromLinkRelPreloadHeader,
};
inline bool IsLinkRelPreload(StylePreloadKind aKind) {
return aKind == StylePreloadKind::FromLinkRelPreloadElement ||
aKind == StylePreloadKind::FromLinkRelPreloadHeader;
}
} // namespace mozilla::css
#endif // mozilla_css_StylePreloadKind_h

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

@ -706,7 +706,7 @@ already_AddRefed<dom::Promise> StyleSheet::Replace(const nsACString& aText,
auto* loader = mConstructorDocument->CSSLoader(); auto* loader = mConstructorDocument->CSSLoader();
auto loadData = MakeRefPtr<css::SheetLoadData>( auto loadData = MakeRefPtr<css::SheetLoadData>(
loader, nullptr, this, /* aSyncLoad */ false, loader, nullptr, this, /* aSyncLoad */ false,
css::Loader::UseSystemPrincipal::No, css::Loader::IsPreload::No, css::Loader::UseSystemPrincipal::No, css::StylePreloadKind::None,
/* aPreloadEncoding */ nullptr, /* aPreloadEncoding */ nullptr,
/* aObserver */ nullptr, mConstructorDocument->NodePrincipal(), /* aObserver */ nullptr, mConstructorDocument->NodePrincipal(),
GetReferrerInfo(), GetReferrerInfo(),
@ -1216,8 +1216,15 @@ void StyleSheet::ParseSheetSync(
css::Loader* aLoader, const nsACString& aBytes, css::Loader* aLoader, const nsACString& aBytes,
css::SheetLoadData* aLoadData, uint32_t aLineNumber, css::SheetLoadData* aLoadData, uint32_t aLineNumber,
css::LoaderReusableStyleSheets* aReusableSheets) { css::LoaderReusableStyleSheets* aReusableSheets) {
nsCompatibility compatMode = const nsCompatibility compatMode = [&] {
aLoader ? aLoader->GetCompatibilityMode() : eCompatibility_FullStandards; if (aLoadData) {
return aLoadData->mCompatMode;
}
if (aLoader) {
return aLoader->CompatMode(css::StylePreloadKind::None);
}
return eCompatibility_FullStandards;
}();
const StyleUseCounters* useCounters = const StyleUseCounters* useCounters =
aLoader && aLoader->GetDocument() aLoader && aLoader->GetDocument()

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

@ -153,6 +153,7 @@ EXPORTS.mozilla.css += [
"SheetLoadData.h", "SheetLoadData.h",
"SheetParsingMode.h", "SheetParsingMode.h",
"StreamLoader.h", "StreamLoader.h",
"StylePreloadKind.h",
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [

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

@ -1141,7 +1141,9 @@ void nsHtml5TreeOpExecutor::PreloadStyle(const nsAString& aURL,
mDocument->PreloadStyle(uri, Encoding::ForLabel(aCharset), aCrossOrigin, mDocument->PreloadStyle(uri, Encoding::ForLabel(aCharset), aCrossOrigin,
GetPreloadReferrerPolicy(aReferrerPolicy), aIntegrity, GetPreloadReferrerPolicy(aReferrerPolicy), aIntegrity,
aLinkPreload); aLinkPreload
? css::StylePreloadKind::FromLinkRelPreloadElement
: css::StylePreloadKind::FromParser);
} }
void nsHtml5TreeOpExecutor::PreloadImage( void nsHtml5TreeOpExecutor::PreloadImage(

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

@ -93,9 +93,9 @@ already_AddRefed<PreloaderBase> PreloadService::PreloadLinkElement(
aLinkElement->GetReferrerPolicy(referrerPolicy); aLinkElement->GetReferrerPolicy(referrerPolicy);
aLinkElement->GetType(type); aLinkElement->GetType(type);
auto result = auto result = PreloadOrCoalesce(uri, url, aPolicyType, as, type, charset,
PreloadOrCoalesce(uri, url, aPolicyType, as, type, charset, srcset, sizes, srcset, sizes, integrity, crossOrigin,
integrity, crossOrigin, referrerPolicy); referrerPolicy, /* aFromHeader = */ false);
if (!result.mPreloader) { if (!result.mPreloader) {
NotifyNodeEvent(aLinkElement, result.mAlreadyComplete); NotifyNodeEvent(aLinkElement, result.mAlreadyComplete);
@ -129,7 +129,8 @@ void PreloadService::PreloadLinkHeader(
} }
PreloadOrCoalesce(aURI, aURL, aPolicyType, aAs, aType, u""_ns, aSrcset, PreloadOrCoalesce(aURI, aURL, aPolicyType, aAs, aType, u""_ns, aSrcset,
aSizes, aIntegrity, aCORS, aReferrerPolicy); aSizes, aIntegrity, aCORS, aReferrerPolicy,
/* aFromHeader = */ true);
} }
PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce( PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce(
@ -137,7 +138,7 @@ PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce(
const nsAString& aAs, const nsAString& aType, const nsAString& aCharset, const nsAString& aAs, const nsAString& aType, const nsAString& aCharset,
const nsAString& aSrcset, const nsAString& aSizes, const nsAString& aSrcset, const nsAString& aSizes,
const nsAString& aIntegrity, const nsAString& aCORS, const nsAString& aIntegrity, const nsAString& aCORS,
const nsAString& aReferrerPolicy) { const nsAString& aReferrerPolicy, bool aFromHeader) {
if (!aURI) { if (!aURI) {
MOZ_ASSERT_UNREACHABLE("Should not pass null nsIURI"); MOZ_ASSERT_UNREACHABLE("Should not pass null nsIURI");
return {nullptr, false}; return {nullptr, false};
@ -182,7 +183,9 @@ PreloadService::PreloadOrCoalesceResult PreloadService::PreloadOrCoalesce(
} else if (aAs.LowerCaseEqualsASCII("style")) { } else if (aAs.LowerCaseEqualsASCII("style")) {
auto status = mDocument->PreloadStyle( auto status = mDocument->PreloadStyle(
aURI, Encoding::ForLabel(aCharset), aCORS, aURI, Encoding::ForLabel(aCharset), aCORS,
PreloadReferrerPolicy(aReferrerPolicy), aIntegrity, true); PreloadReferrerPolicy(aReferrerPolicy), aIntegrity,
aFromHeader ? css::StylePreloadKind::FromLinkRelPreloadHeader
: css::StylePreloadKind::FromLinkRelPreloadElement);
switch (status) { switch (status) {
case dom::SheetPreloadStatus::AlreadyComplete: case dom::SheetPreloadStatus::AlreadyComplete:
return {nullptr, /* already_complete = */ true}; return {nullptr, /* already_complete = */ true};

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

@ -103,7 +103,8 @@ class PreloadService {
const nsAString& aAs, const nsAString& aType, const nsAString& aCharset, const nsAString& aAs, const nsAString& aType, const nsAString& aCharset,
const nsAString& aSrcset, const nsAString& aSizes, const nsAString& aSrcset, const nsAString& aSizes,
const nsAString& aIntegrity, const nsAString& aCORS, const nsAString& aIntegrity, const nsAString& aCORS,
const nsAString& aReferrerPolicy); const nsAString& aReferrerPolicy,
bool aFromHeader);
private: private:
nsRefPtrHashtable<PreloadHashKey, PreloaderBase> mPreloads; nsRefPtrHashtable<PreloadHashKey, PreloaderBase> mPreloads;