Bug 1253788 - Don't reload inline chrome:// style sheets in nsXBLPrototypeResources. r=bzbarsky
--- a/chrome/nsChromeRegistry.cpp
+++ b/chrome/nsChromeRegistry.cpp
@@ -439,21 +439,23 @@ nsresult nsChromeRegistry::RefreshWindow
// Iterate over the style sheets.
for (int32_t i = 0; i < count; i++) {
// Get the style sheet
StyleSheetHandle styleSheet = document->GetStyleSheetAt(i);
oldSheets.AppendElement(styleSheet);
}
// Iterate over our old sheets and kick off a sync load of the new
- // sheet if and only if it's a chrome URL.
+ // sheet if and only if it's a non-inline sheet with a chrome URL.
for (StyleSheetHandle sheet : oldSheets) {
- nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr;
+ MOZ_ASSERT(sheet, "GetStyleSheetAt shouldn't return nullptr for "
+ "in-range sheet indexes");
+ nsIURI* uri = sheet->GetSheetURI();
- if (uri && IsChromeURI(uri)) {
+ if (!sheet->IsInline() && IsChromeURI(uri)) {
// Reload the sheet.
StyleSheetHandle::RefPtr newSheet;
// XXX what about chrome sheets that have a title or are disabled? This
// only works by sheer dumb luck.
document->LoadChromeSheetSync(uri, false, &newSheet);
// Even if it's null, we put in in there.
newSheets.AppendElement(newSheet);
} else {
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -214,17 +214,17 @@ nsStyleLinkElement::UpdateStyleSheet(nsI
{
if (aForceReload) {
// We remove this stylesheet from the cache to load a new version.
nsCOMPtr<nsIContent> thisContent;
CallQueryInterface(this, getter_AddRefs(thisContent));
nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
if (doc && doc->CSSLoader()->GetEnabled() &&
- mStyleSheet && mStyleSheet->GetOriginalURI()) {
+ mStyleSheet && !mStyleSheet->IsInline()) {
doc->CSSLoader()->ObsoleteSheet(mStyleSheet->GetOriginalURI());
}
}
return DoUpdateStyleSheet(nullptr, nullptr, aObserver, aWillNotify,
aIsAlternate, aForceReload);
}
nsresult
--- a/dom/xbl/nsXBLPrototypeResources.cpp
+++ b/dom/xbl/nsXBLPrototypeResources.cpp
@@ -75,31 +75,33 @@ nsXBLPrototypeResources::FlushSkinSheets
// If doc is null, we're in the process of tearing things down, so just
// return without rebuilding anything.
if (!doc) {
return NS_OK;
}
// We have scoped stylesheets. Reload any chrome stylesheets we
// encounter. (If they aren't skin sheets, it doesn't matter, since
- // they'll still be in the chrome cache.
+ // they'll still be in the chrome cache. Skip inline sheets, which
+ // skin sheets can't be, and which in any case don't have a usable
+ // URL to reload.)
nsTArray<StyleSheetHandle::RefPtr> oldSheets;
oldSheets.SwapElements(mStyleSheetList);
mozilla::css::Loader* cssLoader = doc->CSSLoader();
for (size_t i = 0, count = oldSheets.Length(); i < count; ++i) {
StyleSheetHandle oldSheet = oldSheets[i];
nsIURI* uri = oldSheet->GetSheetURI();
StyleSheetHandle::RefPtr newSheet;
- if (IsChromeURI(uri)) {
+ if (!oldSheet->IsInline() && IsChromeURI(uri)) {
if (NS_FAILED(cssLoader->LoadSheetSync(uri, &newSheet)))
continue;
}
else {
newSheet = oldSheet;
}
mStyleSheetList.AppendElement(newSheet);
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -220,16 +220,19 @@ public:
*/
nsresult InsertRuleInternal(const nsAString& aRule,
uint32_t aIndex, uint32_t* aReturn);
/* Get the URI this sheet was originally loaded from, if any. Can
return null */
nsIURI* GetOriginalURI() const { return mInner->mOriginalSheetURI; }
+ // Whether the sheet is for an inline <style> element.
+ bool IsInline() const { return mInner->IsInline(); }
+
// nsICSSLoaderObserver interface
NS_IMETHOD StyleSheetLoaded(StyleSheetHandle aSheet, bool aWasAlternate,
nsresult aStatus) override;
void EnsureUniqueInner();
// Append all of this sheet's child sheets to aArray.
void AppendAllChildSheets(nsTArray<CSSStyleSheet*>& aArray);
--- a/layout/style/StyleSheetHandle.h
+++ b/layout/style/StyleSheetHandle.h
@@ -99,16 +99,17 @@ public:
inline MozExternalRefCountType AddRef();
inline MozExternalRefCountType Release();
// Style sheet interface. These inline methods are defined in
// StyleSheetHandleInlines.h and just forward to the underlying
// CSSStyleSheet or ServoStyleSheet. See corresponding comments in
// CSSStyleSheet.h for descriptions of these methods.
+ inline bool IsInline() const;
inline nsIURI* GetSheetURI() const;
inline nsIURI* GetOriginalURI() const;
inline nsIURI* GetBaseURI() const;
inline void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI);
inline bool IsApplicable() const;
inline void SetParsingMode(css::SheetParsingMode aMode);
inline bool HasRules() const;
inline nsIDocument* GetOwningDocument() const;
--- a/layout/style/StyleSheetHandleInlines.h
+++ b/layout/style/StyleSheetHandleInlines.h
@@ -43,16 +43,22 @@ StyleSheetHandle::Ptr::AddRef()
}
MozExternalRefCountType
StyleSheetHandle::Ptr::Release()
{
FORWARD(Release, ());
}
+bool
+StyleSheetHandle::Ptr::IsInline() const
+{
+ FORWARD(IsInline, ());
+}
+
nsIURI*
StyleSheetHandle::Ptr::GetSheetURI() const
{
FORWARD(GetSheetURI, ());
}
nsIURI*
StyleSheetHandle::Ptr::GetOriginalURI() const
--- a/layout/style/StyleSheetInfo.h
+++ b/layout/style/StyleSheetInfo.h
@@ -35,16 +35,19 @@ public:
const dom::SRIMetadata& aIntegrity);
StyleSheetInfo(const StyleSheetInfo& aCopy);
nsIURI* GetSheetURI() const { return mSheetURI; }
nsIURI* GetOriginalURI() const { return mOriginalSheetURI; }
nsIURI* GetBaseURI() const { return mBaseURI; }
void SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, nsIURI* aBaseURI);
+ // Whether the sheet is for an inline <style> element.
+ bool IsInline() const { return !mOriginalSheetURI; }
+
nsIPrincipal* Principal() const { return mPrincipal; }
void SetPrincipal(nsIPrincipal* aPrincipal);
CORSMode GetCORSMode() const { return mCORSMode; }
net::ReferrerPolicy GetReferrerPolicy() const { return mReferrerPolicy; }
void GetIntegrity(dom::SRIMetadata& aResult) const { aResult = mIntegrity; }
protected: