--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -137,31 +137,32 @@ static const char* const gStateStrings[]
********************************/
NS_IMPL_ISUPPORTS(SheetLoadData, nsIRunnable,
nsIThreadObserver)
SheetLoadData::SheetLoadData(Loader* aLoader,
const nsAString& aTitle,
nsIURI* aURI,
StyleSheet* aSheet,
+ bool aSyncLoad,
nsIStyleSheetLinkingElement* aOwningElement,
IsAlternate aIsAlternate,
MediaMatched aMediaMatches,
nsICSSLoaderObserver* aObserver,
nsIPrincipal* aLoaderPrincipal,
nsINode* aRequestingNode)
: mLoader(aLoader)
, mTitle(aTitle)
, mEncoding(nullptr)
, mURI(aURI)
, mLineNumber(1)
, mSheet(aSheet)
, mNext(nullptr)
, mPendingChildren(0)
- , mSyncLoad(false)
+ , mSyncLoad(aSyncLoad)
, mIsNonDocumentSheet(false)
, mIsLoading(false)
, mIsBeingParsed(false)
, mIsCancelled(false)
, mMustNotify(false)
, mWasAlternate(aIsAlternate == IsAlternate::Yes)
, mMediaMatched(aMediaMatches == MediaMatched::Yes)
, mUseSystemPrincipal(false)
@@ -1895,16 +1896,17 @@ Loader::LoadInlineStyle(const SheetInfo&
principal =
BasePrincipal::Cast(aInfo.mTriggeringPrincipal)->PrincipalToInherit();
}
SheetLoadData* data = new SheetLoadData(this,
aInfo.mTitle,
nullptr,
sheet,
+ false,
owningElement,
isAlternate,
matched,
aObserver,
nullptr,
aInfo.mContent);
// We never actually load this, so just set its principal directly
@@ -1954,16 +1956,22 @@ Loader::LoadStyleLink(const SheetInfo& a
? aInfo.mTriggeringPrincipal.get()
: loadingPrincipal;
nsINode* context = aInfo.mContent;
if (!context) {
context = mDocument;
}
+ bool syncLoad = aInfo.mContent &&
+ aInfo.mContent->IsInUAWidget() &&
+ IsChromeURI(aInfo.mURI);
+ LOG((" Link sync load: '%s'", syncLoad ? "true" : "false"));
+ MOZ_ASSERT_IF(syncLoad, !aObserver);
+
nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aInfo.mURI, context, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
// 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
// implement that via nsDataDocumentContentPolicy, which doesn't have a good
// way to communicate back to us that _it_ is the thing that blocked the
// load.
if (aInfo.mContent && !mDocument->IsLoadedAsData()) {
@@ -1979,17 +1987,17 @@ Loader::LoadStyleLink(const SheetInfo& a
}
StyleSheetState state;
RefPtr<StyleSheet> sheet;
auto isAlternate = IsAlternateSheet(aInfo.mTitle, aInfo.mHasAlternateRel);
rv = CreateSheet(aInfo,
principal,
eAuthorSheetFeatures,
- false,
+ syncLoad,
state,
&sheet);
if (NS_FAILED(rv)) {
return Err(rv);
}
LOG((" Sheet is alternate: %d", static_cast<int>(isAlternate)));
@@ -2019,31 +2027,33 @@ Loader::LoadStyleLink(const SheetInfo& a
return LoadSheetResult { Completed::No, isAlternate, matched };
}
// Now we need to actually load it.
SheetLoadData* data = new SheetLoadData(this,
aInfo.mTitle,
aInfo.mURI,
sheet,
+ syncLoad,
owningElement,
isAlternate,
matched,
aObserver,
principal,
context);
NS_ADDREF(data);
auto result = LoadSheetResult { Completed::No, isAlternate, matched };
MOZ_ASSERT(result.ShouldBlock() == !data->ShouldDefer(),
"These should better match!");
// If we have to parse and it's a non-blocking non-inline sheet, defer it.
- if (state == eSheetNeedsParser &&
+ if (!syncLoad &&
+ state == eSheetNeedsParser &&
mSheets->mLoadingDatas.Count() != 0 &&
!result.ShouldBlock()) {
LOG((" Deferring sheet load"));
URIPrincipalReferrerPolicyAndCORSModeHashKey key(data->mURI,
data->mLoaderPrincipal,
data->mSheet->GetCORSMode(),
data->mSheet->GetReferrerPolicy());
mSheets->mPendingDatas.Put(&key, data);
@@ -2053,17 +2063,19 @@ Loader::LoadStyleLink(const SheetInfo& a
}
// Load completion will free the data
rv = LoadSheet(data, state, false);
if (NS_FAILED(rv)) {
return Err(rv);
}
- data->mMustNotify = true;
+ if (!syncLoad) {
+ data->mMustNotify = true;
+ }
return result;
}
static bool
HaveAncestorDataWithURI(SheetLoadData *aData, nsIURI *aURI)
{
if (!aData->mURI) {
// Inline style; this won't have any ancestors
@@ -2391,16 +2403,17 @@ Loader::PostLoadEvent(nsIURI* aURI,
MOZ_ASSERT(aObserver || !mObservers.IsEmpty() || aElement,
"Must have observer or element");
RefPtr<SheetLoadData> evt =
new SheetLoadData(this,
EmptyString(), // title doesn't matter here
aURI,
aSheet,
+ false,
aElement,
aWasAlternate,
aMediaMatched,
aObserver,
nullptr,
mDocument);
if (!mPostedEvents.AppendElement(evt)) {
--- a/layout/style/SheetLoadData.h
+++ b/layout/style/SheetLoadData.h
@@ -44,16 +44,17 @@ protected:
virtual ~SheetLoadData();
public:
// Data for loading a sheet linked from a document
SheetLoadData(Loader* aLoader,
const nsAString& aTitle,
nsIURI* aURI,
StyleSheet* aSheet,
+ bool aSyncLoad,
nsIStyleSheetLinkingElement* aOwningElement,
IsAlternate aIsAlternate,
MediaMatched aMediaMatched,
nsICSSLoaderObserver* aObserver,
nsIPrincipal* aLoaderPrincipal,
nsINode* aRequestingNode);
// Data for loading a sheet linked from an @import rule
@@ -119,18 +120,19 @@ public:
// Load data for the sheet that @import-ed us if we were @import-ed
// during the parse
RefPtr<SheetLoadData> mParentData;
// Number of sheets we @import-ed that are still loading
uint32_t mPendingChildren;
- // mSyncLoad is true when the load needs to be synchronous -- right
- // now only for LoadSheetSync and children of sync loads.
+ // mSyncLoad is true when the load needs to be synchronous.
+ // For LoadSheetSync, <link> to chrome stylesheets in UA Widgets,
+ // and children of sync loads.
bool mSyncLoad : 1;
// mIsNonDocumentSheet is true if the load was triggered by LoadSheetSync or
// LoadSheet or an @import from such a sheet. Non-document sheet loads can
// proceed even if we have no document.
bool mIsNonDocumentSheet : 1;
// mIsLoading is true from the moment we are placed in the loader's