Bug 1253788 - Don't reload inline chrome:// style sheets in nsXBLPrototypeResources. r=bzbarsky
authorCameron McCormack <cam@mcc.id.au>
Sat, 26 Mar 2016 17:02:30 +1100
changeset 290496 a1ff072697463083c31594b7281176c2cd7e16b8
parent 290495 880f8af31133bd65dde834e9472a66189335a79e
child 290497 1bfc39d87c3e71ffde4482abcd976668155c115b
push id30123
push userkwierso@gmail.com
push dateMon, 28 Mar 2016 20:04:22 +0000
treeherdermozilla-central@a66bf0a800f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1253788
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1253788 - Don't reload inline chrome:// style sheets in nsXBLPrototypeResources. r=bzbarsky
chrome/nsChromeRegistry.cpp
dom/base/nsStyleLinkElement.cpp
dom/xbl/nsXBLPrototypeResources.cpp
layout/style/CSSStyleSheet.h
layout/style/StyleSheetHandle.h
layout/style/StyleSheetHandleInlines.h
layout/style/StyleSheetInfo.h
--- 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: