Bug 990250 - Fold nsIStyleSheet into CSSStyleSheet. r=dbaron
authorCameron McCormack <cam@mcc.id.au>
Tue, 17 Nov 2015 17:04:09 +1100
changeset 294568 5160a4dfba49bde4a8af379a2e1320766560df8c
parent 294567 a56e745bf9fe5ee9aaa22b8176e5d4852e7db955
child 294569 2f103f5a44ffcbef4fc27617a6a6431b96699631
push id8824
push userraliiev@mozilla.com
push dateMon, 14 Dec 2015 20:18:56 +0000
treeherdermozilla-aurora@e2031358e2a6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs990250
milestone45.0a1
Bug 990250 - Fold nsIStyleSheet into CSSStyleSheet. r=dbaron
chrome/nsChromeRegistry.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
dom/base/nsIDocument.h
dom/base/nsIDocumentObserver.h
dom/base/nsStyleLinkElement.cpp
dom/html/HTMLLinkElement.cpp
dom/html/HTMLStyleElement.cpp
dom/html/nsHTMLDocument.cpp
dom/ipc/ContentParent.cpp
dom/xul/nsXULElement.cpp
editor/libeditor/nsStyleSheetTxns.cpp
embedding/components/webbrowserpersist/nsWebBrowserPersist.h
layout/base/nsDocumentViewer.cpp
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/base/nsStyleSheetService.cpp
layout/base/nsStyleSheetService.h
layout/inspector/inDOMUtils.cpp
layout/style/CSSStyleSheet.cpp
layout/style/CSSStyleSheet.h
layout/style/Loader.cpp
layout/style/moz.build
layout/style/nsDOMCSSDeclaration.cpp
layout/style/nsIStyleSheet.h
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/chrome/nsChromeRegistry.cpp
+++ b/chrome/nsChromeRegistry.cpp
@@ -396,82 +396,74 @@ nsresult nsChromeRegistry::RefreshWindow
   nsCOMPtr<nsIDocument> document = aWindow->GetDoc();
   if (!document)
     return NS_OK;
 
   // Deal with the agent sheets first.  Have to do all the style sets by hand.
   nsCOMPtr<nsIPresShell> shell = document->GetShell();
   if (shell) {
     // Reload only the chrome URL agent style sheets.
-    nsCOMArray<nsIStyleSheet> agentSheets;
+    nsTArray<RefPtr<CSSStyleSheet>> agentSheets;
     rv = shell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMArray<nsIStyleSheet> newAgentSheets;
-    for (int32_t l = 0; l < agentSheets.Count(); ++l) {
-      nsIStyleSheet *sheet = agentSheets[l];
-
+    nsTArray<RefPtr<CSSStyleSheet>> newAgentSheets;
+    for (CSSStyleSheet* sheet : agentSheets) {
       nsIURI* uri = sheet->GetSheetURI();
 
       if (IsChromeURI(uri)) {
         // Reload the sheet.
         RefPtr<CSSStyleSheet> newSheet;
         rv = document->LoadChromeSheetSync(uri, true,
                                            getter_AddRefs(newSheet));
         if (NS_FAILED(rv)) return rv;
         if (newSheet) {
-          rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
+          rv = newAgentSheets.AppendElement(newSheet) ? NS_OK : NS_ERROR_FAILURE;
           if (NS_FAILED(rv)) return rv;
         }
       }
       else {  // Just use the same sheet.
-        rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE;
+        rv = newAgentSheets.AppendElement(sheet) ? NS_OK : NS_ERROR_FAILURE;
         if (NS_FAILED(rv)) return rv;
       }
     }
 
     rv = shell->SetAgentStyleSheets(newAgentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  // Build an array of nsIURIs of style sheets we need to load.
-  nsCOMArray<nsIStyleSheet> oldSheets;
-  nsCOMArray<nsIStyleSheet> newSheets;
+  int32_t count = document->GetNumberOfStyleSheets();
 
-  int32_t count = document->GetNumberOfStyleSheets();
+  // Build an array of style sheets we need to reload.
+  nsTArray<RefPtr<CSSStyleSheet>> oldSheets(count);
+  nsTArray<RefPtr<CSSStyleSheet>> newSheets(count);
 
   // Iterate over the style sheets.
-  int32_t i;
-  for (i = 0; i < count; i++) {
+  for (int32_t i = 0; i < count; i++) {
     // Get the style sheet
-    nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i);
-
-    if (!oldSheets.AppendObject(styleSheet)) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
+    CSSStyleSheet* 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.
-  for (i = 0; i < count; i++) {
-    RefPtr<CSSStyleSheet> sheet = do_QueryObject(oldSheets[i]);
+  for (CSSStyleSheet* sheet : oldSheets) {
     nsIURI* uri = sheet ? sheet->GetOriginalURI() : nullptr;
 
     if (uri && IsChromeURI(uri)) {
       // Reload the sheet.
       RefPtr<CSSStyleSheet> newSheet;
       // XXX what about chrome sheets that have a title or are disabled?  This
       // only works by sheer dumb luck.
       document->LoadChromeSheetSync(uri, false, getter_AddRefs(newSheet));
       // Even if it's null, we put in in there.
-      newSheets.AppendObject(newSheet);
-    }
-    else {
+      newSheets.AppendElement(newSheet);
+    } else {
       // Just use the same sheet.
-      newSheets.AppendObject(sheet);
+      newSheets.AppendElement(sheet);
     }
   }
 
   // Now notify the document that multiple sheets have been added and removed.
   document->UpdateStyleSheets(oldSheets, newSheets);
   return NS_OK;
 }
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -94,17 +94,16 @@
 #include "nsROCSSPrimitiveValue.h"
 #include "nsIBaseWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "GeckoProfiler.h"
 #include "mozilla/Preferences.h"
 #include "nsIContentIterator.h"
 #include "nsIDOMStyleSheet.h"
-#include "nsIStyleSheet.h"
 #include "nsIStyleSheetService.h"
 #include "nsContentPermissionHelper.h"
 #include "nsNetUtil.h"
 #include "nsDocument.h"
 #include "HTMLImageElement.h"
 #include "mozilla/css/ImageLoader.h"
 
 #ifdef XP_WIN
@@ -3239,17 +3238,17 @@ nsDOMWindowUtils::AddSheet(nsIDOMStyleSh
   NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
                 aSheetType == USER_SHEET ||
                 aSheetType == AUTHOR_SHEET);
 
   nsCOMPtr<nsIDocument> doc = GetDocument();
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
-  nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
+  RefPtr<CSSStyleSheet> sheet = do_QueryObject(aSheet);
   NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
   if (sheet->GetOwningDocument()) {
     return NS_ERROR_INVALID_ARG;
   }
   return doc->AddAdditionalStyleSheet(type, sheet);
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -720,73 +720,58 @@ nsDOMStyleSheetList::Length()
     return 0;
   }
 
   // XXX Find the number and then cache it. We'll use the
   // observer notification to figure out if new ones have
   // been added or removed.
   if (-1 == mLength) {
     mLength = mDocument->GetNumberOfStyleSheets();
-
-#ifdef DEBUG
-    int32_t i;
-    for (i = 0; i < mLength; i++) {
-      nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(i);
-      nsCOMPtr<nsIDOMStyleSheet> domss(do_QueryInterface(sheet));
-      NS_ASSERTION(domss, "All \"normal\" sheets implement nsIDOMStyleSheet");
-    }
-#endif
   }
   return mLength;
 }
 
 CSSStyleSheet*
 nsDOMStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   if (!mDocument || aIndex >= (uint32_t)mDocument->GetNumberOfStyleSheets()) {
     aFound = false;
     return nullptr;
   }
 
   aFound = true;
-  nsIStyleSheet *sheet = mDocument->GetStyleSheetAt(aIndex);
+  CSSStyleSheet* sheet = mDocument->GetStyleSheetAt(aIndex);
   NS_ASSERTION(sheet, "Must have a sheet");
 
   return static_cast<CSSStyleSheet*>(sheet);
 }
 
 void
 nsDOMStyleSheetList::NodeWillBeDestroyed(const nsINode *aNode)
 {
   mDocument = nullptr;
 }
 
 void
 nsDOMStyleSheetList::StyleSheetAdded(nsIDocument *aDocument,
-                                     nsIStyleSheet* aStyleSheet,
+                                     CSSStyleSheet* aStyleSheet,
                                      bool aDocumentSheet)
 {
   if (aDocumentSheet && -1 != mLength) {
-    nsCOMPtr<nsIDOMStyleSheet> domss(do_QueryInterface(aStyleSheet));
-    if (domss) {
-      mLength++;
-    }
+    mLength++;
   }
 }
 
 void
 nsDOMStyleSheetList::StyleSheetRemoved(nsIDocument *aDocument,
-                                       nsIStyleSheet* aStyleSheet,
+                                       CSSStyleSheet* aStyleSheet,
                                        bool aDocumentSheet)
 {
   if (aDocumentSheet && -1 != mLength) {
-    nsCOMPtr<nsIDOMStyleSheet> domss(do_QueryInterface(aStyleSheet));
-    if (domss) {
-      mLength--;
-    }
+    mLength--;
   }
 }
 
 // nsOnloadBlocker implementation
 NS_IMPL_ISUPPORTS(nsOnloadBlocker, nsIRequest)
 
 NS_IMETHODIMP
 nsOnloadBlocker::GetName(nsACString &aResult)
@@ -1342,17 +1327,17 @@ nsDOMStyleSheetSetList::EnsureFresh()
   if (!mDocument) {
     return; // Spec says "no exceptions", and we have no style sets if we have
             // no document, for sure
   }
 
   int32_t count = mDocument->GetNumberOfStyleSheets();
   nsAutoString title;
   for (int32_t index = 0; index < count; index++) {
-    nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
+    CSSStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
     NS_ASSERTION(sheet, "Null sheet in sheet list!");
     sheet->GetTitle(title);
     if (!title.IsEmpty() && !mNames.Contains(title) && !Add(title)) {
       return;
     }
   }
 }
 
@@ -1619,29 +1604,26 @@ nsDocument::~nsDocument()
   mSubDocuments = nullptr;
 
   // Destroy link map now so we don't waste time removing
   // links one by one
   DestroyElementMaps();
 
   nsAutoScriptBlocker scriptBlocker;
 
-  int32_t indx; // must be signed
-  uint32_t count = mChildren.ChildCount();
-  for (indx = int32_t(count) - 1; indx >= 0; --indx) {
+  for (uint32_t indx = mChildren.ChildCount(); indx-- != 0; ) {
     mChildren.ChildAt(indx)->UnbindFromTree();
     mChildren.RemoveChildAt(indx);
   }
   mFirstChild = nullptr;
   mCachedRootElement = nullptr;
 
   // Let the stylesheets know we're going away
-  indx = mStyleSheets.Count();
-  while (--indx >= 0) {
-    mStyleSheets[indx]->SetOwningDocument(nullptr);
+  for (CSSStyleSheet* sheet : mStyleSheets) {
+    sheet->SetOwningDocument(nullptr);
   }
   if (mAttrStyleSheet) {
     mAttrStyleSheet->SetOwningDocument(nullptr);
   }
   // We don't own the mOnDemandBuiltInUASheets, so we don't need to reset them.
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
@@ -2291,50 +2273,46 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
     win->RefreshCompartmentPrincipal();
   }
 }
 
 void
 nsDocument::RemoveDocStyleSheetsFromStyleSets()
 {
   // The stylesheets should forget us
-  int32_t indx = mStyleSheets.Count();
-  while (--indx >= 0) {
-    nsIStyleSheet* sheet = mStyleSheets[indx];
+  for (CSSStyleSheet* sheet : Reversed(mStyleSheets)) {
     sheet->SetOwningDocument(nullptr);
 
     if (sheet->IsApplicable()) {
       nsCOMPtr<nsIPresShell> shell = GetShell();
       if (shell) {
         shell->StyleSet()->RemoveDocStyleSheet(sheet);
       }
     }
     // XXX Tell observers?
   }
 }
 
 void
-nsDocument::RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, SheetType aType)
+nsDocument::RemoveStyleSheetsFromStyleSets(
+    nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
+    SheetType aType)
 {
   // The stylesheets should forget us
-  int32_t indx = aSheets.Count();
-  while (--indx >= 0) {
-    nsIStyleSheet* sheet = aSheets[indx];
+  for (CSSStyleSheet* sheet : Reversed(aSheets)) {
     sheet->SetOwningDocument(nullptr);
 
     if (sheet->IsApplicable()) {
       nsCOMPtr<nsIPresShell> shell = GetShell();
       if (shell) {
         shell->StyleSet()->RemoveStyleSheet(aType, sheet);
       }
     }
-
     // XXX Tell observers?
   }
-
 }
 
 void
 nsDocument::ResetStylesheetsToURI(nsIURI* aURI)
 {
   MOZ_ASSERT(aURI);
 
   mozAutoDocUpdate upd(this, UPDATE_STYLE, true);
@@ -2374,59 +2352,49 @@ nsDocument::ResetStylesheetsToURI(nsIURI
 
   // Now set up our style sets
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     FillStyleSet(shell->StyleSet());
   }
 }
 
-static bool
-AppendAuthorSheet(nsIStyleSheet *aSheet, void *aData)
-{
-  nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
-  styleSet->AppendStyleSheet(SheetType::Doc, aSheet);
-  return true;
-}
-
 static void
 AppendSheetsToStyleSet(nsStyleSet* aStyleSet,
-                       const nsCOMArray<nsIStyleSheet>& aSheets,
+                       const nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
                        SheetType aType)
 {
-  for (int32_t i = aSheets.Count() - 1; i >= 0; --i) {
-    aStyleSet->AppendStyleSheet(aType, aSheets[i]);
+  for (CSSStyleSheet* sheet : Reversed(aSheets)) {
+    aStyleSet->AppendStyleSheet(aType, sheet);
   }
 }
 
 
 void
 nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
 {
   NS_PRECONDITION(aStyleSet, "Must have a style set");
   NS_PRECONDITION(aStyleSet->SheetCount(SheetType::Doc) == 0,
                   "Style set already has document sheets?");
 
-  int32_t i;
-  for (i = mStyleSheets.Count() - 1; i >= 0; --i) {
-    nsIStyleSheet* sheet = mStyleSheets[i];
+  for (CSSStyleSheet* sheet : Reversed(mStyleSheets)) {
     if (sheet->IsApplicable()) {
       aStyleSet->AddDocStyleSheet(sheet, this);
     }
   }
 
   nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
   if (sheetService) {
-    sheetService->AuthorStyleSheets()->EnumerateForwards(AppendAuthorSheet,
-                                                         aStyleSet);
+    for (CSSStyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
+      aStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
+    }
   }
 
   // Iterate backwards to maintain order
-  for (i = mOnDemandBuiltInUASheets.Count() - 1; i >= 0; --i) {
-    nsIStyleSheet* sheet = mOnDemandBuiltInUASheets[i];
+  for (CSSStyleSheet* sheet : Reversed(mOnDemandBuiltInUASheets)) {
     if (sheet->IsApplicable()) {
       aStyleSet->PrependStyleSheet(SheetType::Agent, sheet);
     }
   }
 
   AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eAgentSheet],
                          SheetType::Agent);
   AppendSheetsToStyleSet(aStyleSet, mAdditionalSheets[eUserSheet],
@@ -4012,30 +3980,28 @@ nsDocument::RemoveChildAt(uint32_t aInde
 
   doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
   mCachedRootElement = nullptr;
 }
 
 void
 nsDocument::EnsureOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
 {
-  // Contains() takes nsISupport*, so annoyingly we have to cast here
-  if (mOnDemandBuiltInUASheets.Contains(static_cast<nsIStyleSheet*>(aSheet))) {
+  if (mOnDemandBuiltInUASheets.Contains(aSheet)) {
     return;
   }
   BeginUpdate(UPDATE_STYLE);
   AddOnDemandBuiltInUASheet(aSheet);
   EndUpdate(UPDATE_STYLE);
 }
 
 void
 nsDocument::AddOnDemandBuiltInUASheet(CSSStyleSheet* aSheet)
 {
-  // Contains() takes nsISupport*, so annoyingly we have to cast here
-  MOZ_ASSERT(!mOnDemandBuiltInUASheets.Contains(static_cast<nsIStyleSheet*>(aSheet)));
+  MOZ_ASSERT(!mOnDemandBuiltInUASheets.Contains(aSheet));
 
   // Prepend here so that we store the sheets in mOnDemandBuiltInUASheets in
   // the same order that they should end up in the style set.
   mOnDemandBuiltInUASheets.InsertElementAt(0, aSheet);
 
   if (aSheet->IsApplicable()) {
     // This is like |AddStyleSheetToStyleSets|, but for an agent sheet.
     nsCOMPtr<nsIPresShell> shell = GetShell();
@@ -4049,196 +4015,191 @@ nsDocument::AddOnDemandBuiltInUASheet(CS
   }
 
   NotifyStyleSheetAdded(aSheet, false);
 }
 
 int32_t
 nsDocument::GetNumberOfStyleSheets() const
 {
-  return mStyleSheets.Count();
-}
-
-nsIStyleSheet*
+  return mStyleSheets.Length();
+}
+
+CSSStyleSheet*
 nsDocument::GetStyleSheetAt(int32_t aIndex) const
 {
-  NS_ENSURE_TRUE(0 <= aIndex && aIndex < mStyleSheets.Count(), nullptr);
-  return mStyleSheets[aIndex];
+  return mStyleSheets.SafeElementAt(aIndex, nullptr);
 }
 
 int32_t
-nsDocument::GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const
+nsDocument::GetIndexOfStyleSheet(CSSStyleSheet* aSheet) const
 {
   return mStyleSheets.IndexOf(aSheet);
 }
 
 void
-nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet)
+nsDocument::AddStyleSheetToStyleSets(CSSStyleSheet* aSheet)
 {
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     shell->StyleSet()->AddDocStyleSheet(aSheet, this);
   }
 }
 
 #define DO_STYLESHEET_NOTIFICATION(className, type, memberName, argName)      \
   do {                                                                        \
-    RefPtr<CSSStyleSheet> cssSheet = do_QueryObject(aSheet);                \
-    if (!cssSheet) {                                                          \
-      return;                                                                 \
-    }                                                                         \
-                                                                              \
     className##Init init;                                                     \
     init.mBubbles = true;                                                     \
     init.mCancelable = true;                                                  \
-    init.mStylesheet = cssSheet;                                              \
+    init.mStylesheet = aSheet;                                                \
     init.memberName = argName;                                                \
                                                                               \
     RefPtr<className> event =                                               \
       className::Constructor(this, NS_LITERAL_STRING(type), init);            \
     event->SetTrusted(true);                                                  \
     event->SetTarget(this);                                                   \
     RefPtr<AsyncEventDispatcher> asyncDispatcher =                          \
       new AsyncEventDispatcher(this, event);                                  \
     asyncDispatcher->mOnlyChromeDispatch = true;                              \
     asyncDispatcher->PostDOMEvent();                                          \
   } while (0);
 
 void
-nsDocument::NotifyStyleSheetAdded(nsIStyleSheet* aSheet, bool aDocumentSheet)
+nsDocument::NotifyStyleSheetAdded(CSSStyleSheet* aSheet, bool aDocumentSheet)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetAdded, (this, aSheet, aDocumentSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent,
                                "StyleSheetAdded",
                                mDocumentSheet,
                                aDocumentSheet);
   }
 }
 
 void
-nsDocument::NotifyStyleSheetRemoved(nsIStyleSheet* aSheet, bool aDocumentSheet)
+nsDocument::NotifyStyleSheetRemoved(CSSStyleSheet* aSheet, bool aDocumentSheet)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleSheetRemoved, (this, aSheet, aDocumentSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleSheetChangeEvent,
                                "StyleSheetRemoved",
                                mDocumentSheet,
                                aDocumentSheet);
   }
 }
 
 void
-nsDocument::AddStyleSheet(nsIStyleSheet* aSheet)
+nsDocument::AddStyleSheet(CSSStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
-  mStyleSheets.AppendObject(aSheet);
+  mStyleSheets.AppendElement(aSheet);
   aSheet->SetOwningDocument(this);
 
   if (aSheet->IsApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
 void
-nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet)
+nsDocument::RemoveStyleSheetFromStyleSets(CSSStyleSheet* aSheet)
 {
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     shell->StyleSet()->RemoveDocStyleSheet(aSheet);
   }
 }
 
 void
-nsDocument::RemoveStyleSheet(nsIStyleSheet* aSheet)
+nsDocument::RemoveStyleSheet(CSSStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
-  nsCOMPtr<nsIStyleSheet> sheet = aSheet; // hold ref so it won't die too soon
-
-  if (!mStyleSheets.RemoveObject(aSheet)) {
+  RefPtr<CSSStyleSheet> sheet = aSheet; // hold ref so it won't die too soon
+
+  if (!mStyleSheets.RemoveElement(aSheet)) {
     NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found");
     return;
   }
 
   if (!mIsGoingAway) {
     if (aSheet->IsApplicable()) {
       RemoveStyleSheetFromStyleSets(aSheet);
     }
 
     NotifyStyleSheetRemoved(aSheet, true);
   }
 
   aSheet->SetOwningDocument(nullptr);
 }
 
 void
-nsDocument::UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets,
-                              nsCOMArray<nsIStyleSheet>& aNewSheets)
+nsDocument::UpdateStyleSheets(nsTArray<RefPtr<CSSStyleSheet>>& aOldSheets,
+                              nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
 {
   BeginUpdate(UPDATE_STYLE);
 
   // XXX Need to set the sheet on the ownernode, if any
-  NS_PRECONDITION(aOldSheets.Count() == aNewSheets.Count(),
+  NS_PRECONDITION(aOldSheets.Length() == aNewSheets.Length(),
                   "The lists must be the same length!");
-  int32_t count = aOldSheets.Count();
-
-  nsCOMPtr<nsIStyleSheet> oldSheet;
+  int32_t count = aOldSheets.Length();
+
+  RefPtr<CSSStyleSheet> oldSheet;
   int32_t i;
   for (i = 0; i < count; ++i) {
     oldSheet = aOldSheets[i];
 
     // First remove the old sheet.
     NS_ASSERTION(oldSheet, "None of the old sheets should be null");
     int32_t oldIndex = mStyleSheets.IndexOf(oldSheet);
     RemoveStyleSheet(oldSheet);  // This does the right notifications
 
     // Now put the new one in its place.  If it's null, just ignore it.
-    nsIStyleSheet* newSheet = aNewSheets[i];
+    CSSStyleSheet* newSheet = aNewSheets[i];
     if (newSheet) {
-      mStyleSheets.InsertObjectAt(newSheet, oldIndex);
+      mStyleSheets.InsertElementAt(oldIndex, newSheet);
       newSheet->SetOwningDocument(this);
       if (newSheet->IsApplicable()) {
         AddStyleSheetToStyleSets(newSheet);
       }
 
       NotifyStyleSheetAdded(newSheet, true);
     }
   }
 
   EndUpdate(UPDATE_STYLE);
 }
 
 void
-nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, int32_t aIndex)
+nsDocument::InsertStyleSheetAt(CSSStyleSheet* aSheet, int32_t aIndex)
 {
   NS_PRECONDITION(aSheet, "null ptr");
-  mStyleSheets.InsertObjectAt(aSheet, aIndex);
+
+  mStyleSheets.InsertElementAt(aIndex, aSheet);
 
   aSheet->SetOwningDocument(this);
 
   if (aSheet->IsApplicable()) {
     AddStyleSheetToStyleSets(aSheet);
   }
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
 
 void
-nsDocument::SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
+nsDocument::SetStyleSheetApplicableState(CSSStyleSheet* aSheet,
                                          bool aApplicable)
 {
   NS_PRECONDITION(aSheet, "null arg");
 
   // If we're actually in the document style sheet list
-  if (-1 != mStyleSheets.IndexOf(aSheet)) {
+  if (mStyleSheets.IndexOf(aSheet) != mStyleSheets.NoIndex) {
     if (aApplicable) {
       AddStyleSheetToStyleSets(aSheet);
     } else {
       RemoveStyleSheetFromStyleSets(aSheet);
     }
   }
 
   // We have to always notify, since this will be called for sheets
@@ -4289,19 +4250,19 @@ ConvertAdditionalSheetType(nsIDocument::
     default:
       MOZ_ASSERT(false, "wrong type");
       // we must return something although this should never happen
       return SheetType::Count;
   }
 }
 
 static int32_t
-FindSheet(const nsCOMArray<nsIStyleSheet>& aSheets, nsIURI* aSheetURI)
-{
-  for (int32_t i = aSheets.Count() - 1; i >= 0; i-- ) {
+FindSheet(const nsTArray<RefPtr<CSSStyleSheet>>& aSheets, nsIURI* aSheetURI)
+{
+  for (int32_t i = aSheets.Length() - 1; i >= 0; i-- ) {
     bool bEqual;
     nsIURI* uri = aSheets[i]->GetSheetURI();
 
     if (uri && NS_SUCCEEDED(uri->Equals(aSheetURI, &bEqual)) && bEqual)
       return i;
   }
 
   return -1;
@@ -4345,25 +4306,25 @@ nsDocument::LoadAdditionalStyleSheet(add
 
   sheet->SetOwningDocument(this);
   MOZ_ASSERT(sheet->IsApplicable());
 
   return AddAdditionalStyleSheet(aType, sheet);
 }
 
 nsresult
-nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet)
+nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, CSSStyleSheet* aSheet)
 {
   if (mAdditionalSheets[aType].Contains(aSheet))
     return NS_ERROR_INVALID_ARG;
 
   if (!aSheet->IsApplicable())
     return NS_ERROR_INVALID_ARG;
 
-  mAdditionalSheets[aType].AppendObject(aSheet);
+  mAdditionalSheets[aType].AppendElement(aSheet);
 
   BeginUpdate(UPDATE_STYLE);
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     SheetType type = ConvertAdditionalSheetType(aType);
     shell->StyleSet()->AppendStyleSheet(type, aSheet);
   }
 
@@ -4374,22 +4335,22 @@ nsDocument::AddAdditionalStyleSheet(addi
   return NS_OK;
 }
 
 void
 nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
 {
   MOZ_ASSERT(aSheetURI);
 
-  nsCOMArray<nsIStyleSheet>& sheets = mAdditionalSheets[aType];
+  nsTArray<RefPtr<CSSStyleSheet>>& sheets = mAdditionalSheets[aType];
 
   int32_t i = FindSheet(mAdditionalSheets[aType], aSheetURI);
   if (i >= 0) {
-    nsCOMPtr<nsIStyleSheet> sheetRef = sheets[i];
-    sheets.RemoveObjectAt(i);
+    RefPtr<CSSStyleSheet> sheetRef = sheets[i];
+    sheets.RemoveElementAt(i);
 
     BeginUpdate(UPDATE_STYLE);
     if (!mIsGoingAway) {
       MOZ_ASSERT(sheetRef->IsApplicable());
       nsCOMPtr<nsIPresShell> shell = GetShell();
       if (shell) {
         SheetType type = ConvertAdditionalSheetType(aType);
         shell->StyleSet()->RemoveStyleSheet(type, sheetRef);
@@ -4400,20 +4361,20 @@ nsDocument::RemoveAdditionalStyleSheet(a
     // these additional sheets.
     NotifyStyleSheetRemoved(sheetRef, false);
     EndUpdate(UPDATE_STYLE);
 
     sheetRef->SetOwningDocument(nullptr);
   }
 }
 
-nsIStyleSheet*
+CSSStyleSheet*
 nsDocument::FirstAdditionalAuthorSheet()
 {
-  return mAdditionalSheets[eAuthorSheet].SafeObjectAt(0);
+  return mAdditionalSheets[eAuthorSheet].SafeElementAt(0, nullptr);
 }
 
 nsIGlobalObject*
 nsDocument::GetScopeObject() const
 {
   nsCOMPtr<nsIGlobalObject> scope(do_QueryReferent(mScopeObject));
   return scope;
 }
@@ -5150,17 +5111,17 @@ nsDocument::DocumentStatesChanged(EventS
   // Invalidate our cached state.
   mGotDocumentState &= ~aStateMask;
   mDocumentState &= ~aStateMask;
 
   NS_DOCUMENT_NOTIFY_OBSERVERS(DocumentStatesChanged, (this, aStateMask));
 }
 
 void
-nsDocument::StyleRuleChanged(nsIStyleSheet* aSheet,
+nsDocument::StyleRuleChanged(CSSStyleSheet* aSheet,
                              css::Rule* aOldStyleRule,
                              css::Rule* aNewStyleRule)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged,
                                (this, aSheet,
                                 aOldStyleRule, aNewStyleRule));
 
   if (StyleSheetChangeEventsEnabled()) {
@@ -5168,33 +5129,33 @@ nsDocument::StyleRuleChanged(nsIStyleShe
                                "StyleRuleChanged",
                                mRule,
                                aNewStyleRule ? aNewStyleRule->GetDOMRule()
                                              : nullptr);
   }
 }
 
 void
-nsDocument::StyleRuleAdded(nsIStyleSheet* aSheet,
+nsDocument::StyleRuleAdded(CSSStyleSheet* aSheet,
                            css::Rule* aStyleRule)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded,
                                (this, aSheet, aStyleRule));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
                                "StyleRuleAdded",
                                mRule,
                                aStyleRule ? aStyleRule->GetDOMRule()
                                           : nullptr);
   }
 }
 
 void
-nsDocument::StyleRuleRemoved(nsIStyleSheet* aSheet,
+nsDocument::StyleRuleRemoved(CSSStyleSheet* aSheet,
                              css::Rule* aStyleRule)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved,
                                (this, aSheet, aStyleRule));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
                                "StyleRuleRemoved",
@@ -6423,23 +6384,21 @@ void
 nsIDocument::GetSelectedStyleSheetSet(nsAString& aSheetSet)
 {
   aSheetSet.Truncate();
 
   // Look through our sheets, find the selected set title
   int32_t count = GetNumberOfStyleSheets();
   nsAutoString title;
   for (int32_t index = 0; index < count; index++) {
-    nsIStyleSheet* sheet = GetStyleSheetAt(index);
+    CSSStyleSheet* sheet = GetStyleSheetAt(index);
     NS_ASSERTION(sheet, "Null sheet in sheet list!");
 
-    nsCOMPtr<nsIDOMStyleSheet> domSheet = do_QueryInterface(sheet);
-    NS_ASSERTION(domSheet, "Sheet must QI to nsIDOMStyleSheet");
     bool disabled;
-    domSheet->GetDisabled(&disabled);
+    sheet->GetDisabled(&disabled);
     if (disabled) {
       // Disabled sheets don't affect the currently selected set
       continue;
     }
 
     sheet->GetTitle(title);
 
     if (aSheetSet.IsEmpty()) {
@@ -6539,17 +6498,17 @@ nsDocument::EnableStyleSheetsForSet(cons
 void
 nsDocument::EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
                                             bool aUpdateCSSLoader)
 {
   BeginUpdate(UPDATE_STYLE);
   int32_t count = GetNumberOfStyleSheets();
   nsAutoString title;
   for (int32_t index = 0; index < count; index++) {
-    nsIStyleSheet* sheet = GetStyleSheetAt(index);
+    CSSStyleSheet* sheet = GetStyleSheetAt(index);
     NS_ASSERTION(sheet, "Null sheet in sheet list!");
     sheet->GetTitle(title);
     if (!title.IsEmpty()) {
       sheet->SetEnabled(title.Equals(aSheetSet));
     }
   }
   if (aUpdateCSSLoader) {
     CSSLoader()->SetPreferredSheet(aSheetSet);
@@ -10168,34 +10127,31 @@ nsIDocument::CreateStaticClone(nsIDocShe
       } else {
         clonedDoc->mOriginalDocument = this;
       }
 
       clonedDoc->mOriginalDocument->mStaticCloneCount++;
 
       int32_t sheetsCount = GetNumberOfStyleSheets();
       for (int32_t i = 0; i < sheetsCount; ++i) {
-        RefPtr<CSSStyleSheet> sheet = do_QueryObject(GetStyleSheetAt(i));
+        RefPtr<CSSStyleSheet> sheet = GetStyleSheetAt(i);
         if (sheet) {
           if (sheet->IsApplicable()) {
             RefPtr<CSSStyleSheet> clonedSheet =
               sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
             NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
             if (clonedSheet) {
               clonedDoc->AddStyleSheet(clonedSheet);
             }
           }
         }
       }
 
-      sheetsCount = thisAsDoc->mOnDemandBuiltInUASheets.Count();
       // Iterate backwards to maintain order
-      for (int32_t i = sheetsCount - 1; i >= 0; --i) {
-        RefPtr<CSSStyleSheet> sheet =
-          do_QueryObject(thisAsDoc->mOnDemandBuiltInUASheets[i]);
+      for (CSSStyleSheet* sheet : Reversed(thisAsDoc->mOnDemandBuiltInUASheets)) {
         if (sheet) {
           if (sheet->IsApplicable()) {
             RefPtr<CSSStyleSheet> clonedSheet =
               sheet->Clone(nullptr, nullptr, clonedDoc, nullptr);
             NS_WARN_IF_FALSE(clonedSheet, "Cloning a stylesheet didn't work!");
             if (clonedSheet) {
               clonedDoc->AddOnDemandBuiltInUASheet(clonedSheet);
             }
@@ -12273,17 +12229,17 @@ nsDocument::OnAppThemeChanged()
 {
   // Bail out if there is no theme support set up properly.
   auto themeOrigin = Preferences::GetString("b2g.theme.origin");
   if (!themeOrigin || !Preferences::GetBool("dom.mozApps.themable")) {
     return;
   }
 
   for (int32_t i = 0; i < GetNumberOfStyleSheets(); i++) {
-    RefPtr<CSSStyleSheet> sheet =  do_QueryObject(GetStyleSheetAt(i));
+    RefPtr<CSSStyleSheet> sheet = GetStyleSheetAt(i);
     if (!sheet) {
       continue;
     }
 
     nsINode* owningNode = sheet->GetOwnerNode();
     if (!owningNode) {
       continue;
     }
@@ -12640,25 +12596,29 @@ nsIDocument::DocAddSizeOfExcludingThis(n
 void
 nsIDocument::DocAddSizeOfIncludingThis(nsWindowSizes* aWindowSizes) const
 {
   aWindowSizes->mDOMOtherSize += aWindowSizes->mMallocSizeOf(this);
   DocAddSizeOfExcludingThis(aWindowSizes);
 }
 
 static size_t
-SizeOfStyleSheetsElementIncludingThis(nsIStyleSheet* aStyleSheet,
-                                      MallocSizeOf aMallocSizeOf,
-                                      void* aData)
-{
-  if (!aStyleSheet->GetOwningDocument()) {
-    // Avoid over-reporting shared sheets.
-    return 0;
-  }
-  return aStyleSheet->SizeOfIncludingThis(aMallocSizeOf);
+SizeOfOwnedSheetArrayExcludingThis(const nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
+                                   MallocSizeOf aMallocSizeOf)
+{
+  size_t n = 0;
+  n += aSheets.ShallowSizeOfExcludingThis(aMallocSizeOf);
+  for (CSSStyleSheet* sheet : aSheets) {
+    if (!sheet->GetOwningDocument()) {
+      // Avoid over-reporting shared sheets.
+      continue;
+    }
+    n += sheet->SizeOfIncludingThis(aMallocSizeOf);
+  }
+  return n;
 }
 
 size_t
 nsDocument::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // This SizeOfExcludingThis() overrides the one from nsINode.  But
   // nsDocuments can only appear at the top of the DOM tree, and we use the
   // specialized DocAddSizeOfExcludingThis() in that case.  So this should never
@@ -12699,36 +12659,28 @@ nsDocument::DocAddSizeOfExcludingThis(ns
     *p += nodeSize;
 
     if (EventListenerManager* elm = node->GetExistingListenerManager()) {
       aWindowSizes->mDOMEventListenersCount += elm->ListenerCount();
     }
   }
 
   aWindowSizes->mStyleSheetsSize +=
-    mStyleSheets.SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
-                                     aWindowSizes->mMallocSizeOf);
+    SizeOfOwnedSheetArrayExcludingThis(mStyleSheets,
+                                       aWindowSizes->mMallocSizeOf);
   // Note that we do not own the sheets pointed to by mOnDemandBuiltInUASheets
-  // (the nsLayoutStyleSheetCache singleton does) so pass nullptr as the
-  // aSizeOfElementIncludingThis callback argument.
-  aWindowSizes->mStyleSheetsSize +=
-    mOnDemandBuiltInUASheets.SizeOfExcludingThis(nullptr,
-                                                 aWindowSizes->mMallocSizeOf);
+  // (the nsLayoutStyleSheetCache singleton does).
   aWindowSizes->mStyleSheetsSize +=
-    mAdditionalSheets[eAgentSheet].
-      SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
-                          aWindowSizes->mMallocSizeOf);
-  aWindowSizes->mStyleSheetsSize +=
-    mAdditionalSheets[eUserSheet].
-      SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
-                          aWindowSizes->mMallocSizeOf);
-  aWindowSizes->mStyleSheetsSize +=
-    mAdditionalSheets[eAuthorSheet].
-      SizeOfExcludingThis(SizeOfStyleSheetsElementIncludingThis,
-                          aWindowSizes->mMallocSizeOf);
+    mOnDemandBuiltInUASheets.ShallowSizeOfExcludingThis(
+        aWindowSizes->mMallocSizeOf);
+  for (auto& sheetArray : mAdditionalSheets) {
+    aWindowSizes->mStyleSheetsSize +=
+      SizeOfOwnedSheetArrayExcludingThis(sheetArray,
+                                         aWindowSizes->mMallocSizeOf);
+  }
   // Lumping in the loader with the style-sheets size is not ideal,
   // but most of the things in there are in fact stylesheets, so it
   // doesn't seem worthwhile to separate it out.
   aWindowSizes->mStyleSheetsSize +=
     CSSLoader()->SizeOfIncludingThis(aWindowSizes->mMallocSizeOf);
 
   aWindowSizes->mDOMOtherSize +=
     mAttrStyleSheet ?
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -796,34 +796,39 @@ public:
 
   virtual void EnsureOnDemandBuiltInUASheet(mozilla::CSSStyleSheet* aSheet) override;
 
   /**
    * Get the (document) style sheets owned by this document.
    * These are ordered, highest priority last
    */
   virtual int32_t GetNumberOfStyleSheets() const override;
-  virtual nsIStyleSheet* GetStyleSheetAt(int32_t aIndex) const override;
-  virtual int32_t GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const override;
-  virtual void AddStyleSheet(nsIStyleSheet* aSheet) override;
-  virtual void RemoveStyleSheet(nsIStyleSheet* aSheet) override;
+  virtual mozilla::CSSStyleSheet* GetStyleSheetAt(int32_t aIndex) const override;
+  virtual int32_t GetIndexOfStyleSheet(mozilla::CSSStyleSheet* aSheet) const override;
+  virtual void AddStyleSheet(mozilla::CSSStyleSheet* aSheet) override;
+  virtual void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet) override;
 
-  virtual void UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets,
-                                 nsCOMArray<nsIStyleSheet>& aNewSheets) override;
-  virtual void AddStyleSheetToStyleSets(nsIStyleSheet* aSheet);
-  virtual void RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet);
+  virtual void UpdateStyleSheets(
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets) override;
+  virtual void AddStyleSheetToStyleSets(mozilla::CSSStyleSheet* aSheet);
+  virtual void RemoveStyleSheetFromStyleSets(mozilla::CSSStyleSheet* aSheet);
 
-  virtual void InsertStyleSheetAt(nsIStyleSheet* aSheet, int32_t aIndex) override;
-  virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
+  virtual void InsertStyleSheetAt(mozilla::CSSStyleSheet* aSheet,
+                                  int32_t aIndex) override;
+  virtual void SetStyleSheetApplicableState(mozilla::CSSStyleSheet* aSheet,
                                             bool aApplicable) override;
 
-  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) override;
-  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet) override;
-  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) override;
-  virtual nsIStyleSheet* FirstAdditionalAuthorSheet() override;
+  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
+                                            nsIURI* aSheetURI) override;
+  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
+                                           mozilla::CSSStyleSheet* aSheet) override;
+  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
+                                          nsIURI* sheetURI) override;
+  virtual mozilla::CSSStyleSheet* FirstAdditionalAuthorSheet() override;
 
   virtual nsIChannel* GetChannel() const override {
     return mChannel;
   }
 
   virtual nsIChannel* GetFailedChannel() const override {
     return mFailedChannel;
   }
@@ -873,22 +878,22 @@ public:
   virtual void SetReadyStateInternal(ReadyState rs) override;
 
   virtual void ContentStateChanged(nsIContent* aContent,
                                    mozilla::EventStates aStateMask)
                                      override;
   virtual void DocumentStatesChanged(
                  mozilla::EventStates aStateMask) override;
 
-  virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet,
+  virtual void StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aOldStyleRule,
                                 mozilla::css::Rule* aNewStyleRule) override;
-  virtual void StyleRuleAdded(nsIStyleSheet* aStyleSheet,
+  virtual void StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet,
                               mozilla::css::Rule* aStyleRule) override;
-  virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
+  virtual void StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aStyleRule) override;
 
   virtual void FlushPendingNotifications(mozFlushType aType) override;
   virtual void FlushExternalResources(mozFlushType aType) override;
   virtual void SetXMLDeclaration(const char16_t *aVersion,
                                  const char16_t *aEncoding,
                                  const int32_t aStandalone) override;
   virtual void GetXMLDeclaration(nsAString& aVersion,
@@ -1489,18 +1494,19 @@ public:
 
 protected:
   already_AddRefed<nsIPresShell> doCreateShell(nsPresContext* aContext,
                                                nsViewManager* aViewManager,
                                                nsStyleSet* aStyleSet,
                                                nsCompatibility aCompatMode);
 
   void RemoveDocStyleSheetsFromStyleSets();
-  void RemoveStyleSheetsFromStyleSets(nsCOMArray<nsIStyleSheet>& aSheets, 
-                                      mozilla::SheetType aType);
+  void RemoveStyleSheetsFromStyleSets(
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets,
+      mozilla::SheetType aType);
   void ResetStylesheetsToURI(nsIURI* aURI);
   void FillStyleSet(nsStyleSet* aStyleSet);
 
   // Return whether all the presshells for this document are safe to flush
   bool IsSafeToFlush() const;
 
   void DispatchPageTransition(mozilla::dom::EventTarget* aDispatchTarget,
                               const nsAString& aType,
@@ -1543,19 +1549,19 @@ protected:
   // parsed into.
   nsCOMPtr<nsIParser> mParser;
 
   // Weak reference to our sink for in case we no longer have a parser.  This
   // will allow us to flush out any pending stuff from the sink even if
   // EndLoad() has already happened.
   nsWeakPtr mWeakSink;
 
-  nsCOMArray<nsIStyleSheet> mStyleSheets;
-  nsCOMArray<nsIStyleSheet> mOnDemandBuiltInUASheets;
-  nsCOMArray<nsIStyleSheet> mAdditionalSheets[AdditionalSheetTypeCount];
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>> mStyleSheets;
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>> mOnDemandBuiltInUASheets;
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
 
   // Array of observers
   nsTObserverArray<nsIDocumentObserver*> mObservers;
 
   // Tracker for animations that are waiting to start.
   // nullptr until GetOrCreatePendingAnimationTracker is called.
   RefPtr<mozilla::PendingAnimationTracker> mPendingAnimationTracker;
 
@@ -1704,18 +1710,18 @@ public:
   mozilla::EventStates mDocumentState;
   mozilla::EventStates mGotDocumentState;
 
   RefPtr<nsDOMNavigationTiming> mTiming;
 private:
   friend class nsUnblockOnloadEvent;
   // Recomputes the visibility state but doesn't set the new value.
   mozilla::dom::VisibilityState GetVisibilityState() const;
-  void NotifyStyleSheetAdded(nsIStyleSheet* aSheet, bool aDocumentSheet);
-  void NotifyStyleSheetRemoved(nsIStyleSheet* aSheet, bool aDocumentSheet);
+  void NotifyStyleSheetAdded(mozilla::CSSStyleSheet* aSheet, bool aDocumentSheet);
+  void NotifyStyleSheetRemoved(mozilla::CSSStyleSheet* aSheet, bool aDocumentSheet);
 
   void PostUnblockOnloadEvent();
   void DoUnblockOnload();
 
   nsresult CheckFrameOptions();
   bool IsLoopDocument(nsIChannel* aChannel);
   nsresult InitCSP(nsIChannel* aChannel);
 
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -67,17 +67,16 @@ class nsILoadContext;
 class nsIObjectLoadingContent;
 class nsIObserver;
 class nsIPresShell;
 class nsIPrincipal;
 class nsIRequest;
 class nsIRunnable;
 class nsIStreamListener;
 class nsIStructuredCloneContainer;
-class nsIStyleSheet;
 class nsIURI;
 class nsIVariant;
 class nsLocation;
 class nsViewManager;
 class nsPresContext;
 class nsRange;
 class nsScriptLoader;
 class nsSMILAnimationController;
@@ -151,18 +150,18 @@ template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0x4307abe8, 0x5386, 0x4024, \
-  { 0xa2, 0xfe, 0x4a, 0x80, 0xe8, 0x47, 0x46, 0x90 } }
+{ 0xecc9e376, 0x6c31, 0x4f04, \
+  { 0xbe, 0xde, 0xd6, 0x27, 0x61, 0xd7, 0x00, 0x84 } }
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
   DocumentFlavorSVG, // SVGDocument
   DocumentFlavorPlain, // Just a Document
 };
@@ -920,74 +919,79 @@ public:
   virtual int32_t GetNumberOfStyleSheets() const = 0;
 
   /**
    * Get a particular stylesheet
    * @param aIndex the index the stylesheet lives at.  This is zero-based
    * @return the stylesheet at aIndex.  Null if aIndex is out of range.
    * @throws no exceptions
    */
-  virtual nsIStyleSheet* GetStyleSheetAt(int32_t aIndex) const = 0;
+  virtual mozilla::CSSStyleSheet* GetStyleSheetAt(int32_t aIndex) const = 0;
 
   /**
    * Insert a sheet at a particular spot in the stylesheet list (zero-based)
    * @param aSheet the sheet to insert
    * @param aIndex the index to insert at.  This index will be
    *   adjusted for the "special" sheets.
    * @throws no exceptions
    */
-  virtual void InsertStyleSheetAt(nsIStyleSheet* aSheet, int32_t aIndex) = 0;
+  virtual void InsertStyleSheetAt(mozilla::CSSStyleSheet* aSheet,
+                                  int32_t aIndex) = 0;
 
   /**
    * Get the index of a particular stylesheet.  This will _always_
    * consider the "special" sheets as part of the sheet list.
    * @param aSheet the sheet to get the index of
    * @return aIndex the index of the sheet in the full list
    */
-  virtual int32_t GetIndexOfStyleSheet(nsIStyleSheet* aSheet) const = 0;
+  virtual int32_t GetIndexOfStyleSheet(mozilla::CSSStyleSheet* aSheet) const = 0;
 
   /**
    * Replace the stylesheets in aOldSheets with the stylesheets in
    * aNewSheets. The two lists must have equal length, and the sheet
    * at positon J in the first list will be replaced by the sheet at
    * position J in the second list.  Some sheets in the second list
    * may be null; if so the corresponding sheets in the first list
    * will simply be removed.
    */
-  virtual void UpdateStyleSheets(nsCOMArray<nsIStyleSheet>& aOldSheets,
-                                 nsCOMArray<nsIStyleSheet>& aNewSheets) = 0;
+  virtual void UpdateStyleSheets(
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aOldSheets,
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets) = 0;
 
   /**
    * Add a stylesheet to the document
    */
-  virtual void AddStyleSheet(nsIStyleSheet* aSheet) = 0;
+  virtual void AddStyleSheet(mozilla::CSSStyleSheet* aSheet) = 0;
 
   /**
    * Remove a stylesheet from the document
    */
-  virtual void RemoveStyleSheet(nsIStyleSheet* aSheet) = 0;
+  virtual void RemoveStyleSheet(mozilla::CSSStyleSheet* aSheet) = 0;
 
   /**
    * Notify the document that the applicable state of the sheet changed
    * and that observers should be notified and style sets updated
    */
-  virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
+  virtual void SetStyleSheetApplicableState(mozilla::CSSStyleSheet* aSheet,
                                             bool aApplicable) = 0;
 
   enum additionalSheetType {
     eAgentSheet,
     eUserSheet,
     eAuthorSheet,
     AdditionalSheetTypeCount
   };
 
-  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) = 0;
-  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet) = 0;
-  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) = 0;
-  virtual nsIStyleSheet* FirstAdditionalAuthorSheet() = 0;
+  virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
+                                            nsIURI* aSheetURI) = 0;
+  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType,
+                                           mozilla::CSSStyleSheet* aSheet) = 0;
+  virtual void RemoveAdditionalStyleSheet(additionalSheetType aType,
+                                          nsIURI* sheetURI) = 0;
+  virtual mozilla::CSSStyleSheet* FirstAdditionalAuthorSheet() = 0;
 
   /**
    * Get this document's CSSLoader.  This is guaranteed to not return null.
    */
   mozilla::css::Loader* CSSLoader() const {
     return mCSSLoader;
   }
 
@@ -1280,22 +1284,22 @@ public:
 
   // Notify that a document state has changed.
   // This should only be called by callers whose state is also reflected in the
   // implementation of nsDocument::GetDocumentState.
   virtual void DocumentStatesChanged(mozilla::EventStates aStateMask) = 0;
 
   // Observation hooks for style data to propagate notifications
   // to document observers
-  virtual void StyleRuleChanged(nsIStyleSheet* aStyleSheet,
+  virtual void StyleRuleChanged(mozilla::CSSStyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aOldStyleRule,
                                 mozilla::css::Rule* aNewStyleRule) = 0;
-  virtual void StyleRuleAdded(nsIStyleSheet* aStyleSheet,
+  virtual void StyleRuleAdded(mozilla::CSSStyleSheet* aStyleSheet,
                               mozilla::css::Rule* aStyleRule) = 0;
-  virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
+  virtual void StyleRuleRemoved(mozilla::CSSStyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aStyleRule) = 0;
 
   /**
    * Flush notifications for this document and its parent documents
    * (since those may affect the layout of this one).
    */
   virtual void FlushPendingNotifications(mozFlushType aType) = 0;
 
--- a/dom/base/nsIDocumentObserver.h
+++ b/dom/base/nsIDocumentObserver.h
@@ -6,28 +6,28 @@
 #ifndef nsIDocumentObserver_h___
 #define nsIDocumentObserver_h___
 
 #include "mozilla/EventStates.h"
 #include "nsISupports.h"
 #include "nsIMutationObserver.h"
 
 class nsIContent;
-class nsIStyleSheet;
 class nsIDocument;
 
 namespace mozilla {
+class CSSStyleSheet;
 namespace css {
 class Rule;
 } // namespace css
 } // namespace mozilla
 
 #define NS_IDOCUMENT_OBSERVER_IID \
-{ 0xce1d53d0, 0x4739, 0x44e5, \
-  { 0xb4, 0xae, 0x60, 0xe8, 0x82, 0xcb, 0x73, 0x1b } }
+{ 0x21c8ad67, 0x3a7d, 0x4881, \
+  { 0xa5, 0x43, 0xcb, 0xa9, 0xbb, 0xe4, 0x9e, 0x39 } }
 
 typedef uint32_t nsUpdateType;
 
 #define UPDATE_CONTENT_MODEL 0x00000001
 #define UPDATE_STYLE         0x00000002
 #define UPDATE_ALL (UPDATE_CONTENT_MODEL | UPDATE_STYLE)
 
 // Document observer interface
@@ -97,48 +97,48 @@ public:
    * notification is passed on to all of the document observers.   
    *
    * @param aDocument The document being observed
    * @param aStyleSheet the StyleSheet that has been added
    * @param aDocumentSheet True if sheet is in document's style sheet list,
    *                       false if sheet is not (i.e., UA or user sheet)
    */
   virtual void StyleSheetAdded(nsIDocument *aDocument,
-                               nsIStyleSheet* aStyleSheet,
+                               mozilla::CSSStyleSheet* aStyleSheet,
                                bool aDocumentSheet) = 0;
 
   /**
    * A StyleSheet has just been removed from the document.  This
    * method is called automatically when a StyleSheet gets removed
    * from the document, even if the stylesheet is not applicable. The
    * notification is passed on to all of the document observers.
    *
    * @param aDocument The document being observed
    * @param aStyleSheet the StyleSheet that has been removed
    * @param aDocumentSheet True if sheet is in document's style sheet list,
    *                       false if sheet is not (i.e., UA or user sheet)
    */
   virtual void StyleSheetRemoved(nsIDocument *aDocument,
-                                 nsIStyleSheet* aStyleSheet,
+                                 mozilla::CSSStyleSheet* aStyleSheet,
                                  bool aDocumentSheet) = 0;
   
   /**
    * A StyleSheet has just changed its applicable state.
    * This method is called automatically when the applicable state
    * of a StyleSheet gets changed. The style sheet passes this
    * notification to the document. The notification is passed on 
    * to all of the document observers.
    *
    * @param aDocument The document being observed
    * @param aStyleSheet the StyleSheet that has changed state
    * @param aApplicable true if the sheet is applicable, false if
    *        it is not applicable
    */
   virtual void StyleSheetApplicableStateChanged(nsIDocument *aDocument,
-                                                nsIStyleSheet* aStyleSheet,
+                                                mozilla::CSSStyleSheet* aStyleSheet,
                                                 bool aApplicable) = 0;
 
   /**
    * A StyleRule has just been modified within a style sheet.
    * This method is called automatically when the rule gets
    * modified. The style sheet passes this notification to 
    * the document. The notification is passed on to all of 
    * the document observers.
@@ -155,48 +155,48 @@ public:
    * @param aStyleSheet the StyleSheet that contians the rule
    * @param aOldStyleRule The rule being removed.  This rule may not be
    *                      fully valid anymore -- however, it can still
    *                      be used for pointer comparison and
    *                      |QueryInterface|.
    * @param aNewStyleRule The rule being added.
    */
   virtual void StyleRuleChanged(nsIDocument *aDocument,
-                                nsIStyleSheet* aStyleSheet,
+                                mozilla::CSSStyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aOldStyleRule,
                                 mozilla::css::Rule* aNewStyleRule) = 0;
 
   /**
    * A StyleRule has just been added to a style sheet.
    * This method is called automatically when the rule gets
    * added to the sheet. The style sheet passes this
    * notification to the document. The notification is passed on 
    * to all of the document observers.
    *
    * @param aDocument The document being observed
    * @param aStyleSheet the StyleSheet that has been modified
    * @param aStyleRule the rule that was added
    */
   virtual void StyleRuleAdded(nsIDocument *aDocument,
-                              nsIStyleSheet* aStyleSheet,
+                              mozilla::CSSStyleSheet* aStyleSheet,
                               mozilla::css::Rule* aStyleRule) = 0;
 
   /**
    * A StyleRule has just been removed from a style sheet.
    * This method is called automatically when the rule gets
    * removed from the sheet. The style sheet passes this
    * notification to the document. The notification is passed on 
    * to all of the document observers.
    *
    * @param aDocument The document being observed
    * @param aStyleSheet the StyleSheet that has been modified
    * @param aStyleRule the rule that was removed
    */
   virtual void StyleRuleRemoved(nsIDocument *aDocument,
-                                nsIStyleSheet* aStyleSheet,
+                                mozilla::CSSStyleSheet* aStyleSheet,
                                 mozilla::css::Rule* aStyleRule) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentObserver, NS_IDOCUMENT_OBSERVER_IID)
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE                              \
     virtual void BeginUpdate(nsIDocument* aDocument,                         \
                              nsUpdateType aUpdateType) override;
@@ -216,43 +216,44 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumen
                                      mozilla::EventStates aStateMask) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_DOCUMENTSTATESCHANGED                    \
     virtual void DocumentStatesChanged(nsIDocument* aDocument,               \
                                        mozilla::EventStates aStateMask) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED                          \
     virtual void StyleSheetAdded(nsIDocument* aDocument,                     \
-                                 nsIStyleSheet* aStyleSheet,                 \
+                                 mozilla::CSSStyleSheet* aStyleSheet,        \
                                  bool aDocumentSheet) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED                        \
     virtual void StyleSheetRemoved(nsIDocument* aDocument,                   \
-                                   nsIStyleSheet* aStyleSheet,               \
+                                   mozilla::CSSStyleSheet* aStyleSheet,      \
                                    bool aDocumentSheet) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED         \
-    virtual void StyleSheetApplicableStateChanged(nsIDocument* aDocument,    \
-                                                  nsIStyleSheet* aStyleSheet,\
-                                                  bool aApplicable) override;
+    virtual void StyleSheetApplicableStateChanged(                           \
+        nsIDocument* aDocument,                                              \
+        mozilla::CSSStyleSheet* aStyleSheet,                                 \
+        bool aApplicable) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED                         \
     virtual void StyleRuleChanged(nsIDocument* aDocument,                    \
-                                  nsIStyleSheet* aStyleSheet,                \
+                                  mozilla::CSSStyleSheet* aStyleSheet,       \
                                   mozilla::css::Rule* aOldStyleRule,         \
                                   mozilla::css::Rule* aNewStyleRule) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED                           \
     virtual void StyleRuleAdded(nsIDocument* aDocument,                      \
-                                nsIStyleSheet* aStyleSheet,                  \
+                                mozilla::CSSStyleSheet* aStyleSheet,         \
                                 mozilla::css::Rule* aStyleRule) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED                         \
     virtual void StyleRuleRemoved(nsIDocument* aDocument,                    \
-                                  nsIStyleSheet* aStyleSheet,                \
+                                  mozilla::CSSStyleSheet* aStyleSheet,       \
                                   mozilla::css::Rule* aStyleRule) override;
 
 #define NS_DECL_NSIDOCUMENTOBSERVER                                          \
     NS_DECL_NSIDOCUMENTOBSERVER_BEGINUPDATE                                  \
     NS_DECL_NSIDOCUMENTOBSERVER_ENDUPDATE                                    \
     NS_DECL_NSIDOCUMENTOBSERVER_BEGINLOAD                                    \
     NS_DECL_NSIDOCUMENTOBSERVER_ENDLOAD                                      \
     NS_DECL_NSIDOCUMENTOBSERVER_CONTENTSTATECHANGED                          \
@@ -302,45 +303,45 @@ void                                    
 }
 
 #define NS_IMPL_NSIDOCUMENTOBSERVER_CONTENT(_class)                       \
 NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(_class)
 
 #define NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(_class)                    \
 void                                                                      \
 _class::StyleSheetAdded(nsIDocument* aDocument,                           \
-                        nsIStyleSheet* aStyleSheet,                       \
-                        bool aDocumentSheet)                            \
+                        mozilla::CSSStyleSheet* aStyleSheet,              \
+                        bool aDocumentSheet)                              \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::StyleSheetRemoved(nsIDocument* aDocument,                         \
-                          nsIStyleSheet* aStyleSheet,                     \
-                          bool aDocumentSheet)                          \
+                          mozilla::CSSStyleSheet* aStyleSheet,            \
+                          bool aDocumentSheet)                            \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::StyleSheetApplicableStateChanged(nsIDocument* aDocument,          \
-                                         nsIStyleSheet* aStyleSheet,      \
-                                         bool aApplicable)              \
+                                         mozilla::CSSStyleSheet* aStyleSheet,\
+                                         bool aApplicable)                \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::StyleRuleChanged(nsIDocument* aDocument,                          \
-                         nsIStyleSheet* aStyleSheet,                      \
+                         mozilla::CSSStyleSheet* aStyleSheet,             \
                          mozilla::css::Rule* aOldStyleRule,               \
                          mozilla::css::Rule* aNewStyleRule)               \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::StyleRuleAdded(nsIDocument* aDocument,                            \
-                       nsIStyleSheet* aStyleSheet,                        \
+                       mozilla::CSSStyleSheet* aStyleSheet,               \
                        mozilla::css::Rule* aStyleRule)                    \
 {                                                                         \
 }                                                                         \
 void                                                                      \
 _class::StyleRuleRemoved(nsIDocument* aDocument,                          \
-                         nsIStyleSheet* aStyleSheet,                      \
+                         mozilla::CSSStyleSheet* aStyleSheet,             \
                          mozilla::css::Rule* aStyleRule)                  \
 {                                                                         \
 }
 
 #endif /* nsIDocumentObserver_h___ */
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -283,27 +283,16 @@ UpdateIsElementInStyleScopeFlagOnSubtree
       if (n->IsElement()) {
         n->ClearIsElementInStyleScope();
       }
       n = n->GetNextNode(aElement);
     }
   }
 }
 
-static Element*
-GetScopeElement(nsIStyleSheet* aSheet)
-{
-  RefPtr<CSSStyleSheet> cssStyleSheet = do_QueryObject(aSheet);
-  if (!cssStyleSheet) {
-    return nullptr;
-  }
-
-  return cssStyleSheet->GetScopeElement();
-}
-
 nsresult
 nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
                                        ShadowRoot* aOldShadowRoot,
                                        nsICSSLoaderObserver* aObserver,
                                        bool* aWillNotify,
                                        bool* aIsAlternate,
                                        bool aForceUpdate)
 {
@@ -325,17 +314,18 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
   // Check for a ShadowRoot because link elements are inert in a
   // ShadowRoot.
   ShadowRoot* containingShadow = thisContent->GetContainingShadow();
   if (thisContent->IsHTMLElement(nsGkAtoms::link) &&
       (aOldShadowRoot || containingShadow)) {
     return NS_OK;
   }
 
-  Element* oldScopeElement = GetScopeElement(mStyleSheet);
+  Element* oldScopeElement =
+    mStyleSheet ? mStyleSheet->GetScopeElement() : nullptr;
 
   if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
     MOZ_ASSERT(!(aOldDocument && aOldShadowRoot),
                "ShadowRoot content is never in document, thus "
                "there should not be a old document and old "
                "ShadowRoot simultaneously.");
 
     // We're removing the link element from the document or shadow tree,
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -16,17 +16,16 @@
 #include "nsContentUtils.h"
 #include "nsGenericHTMLElement.h"
 #include "nsGkAtoms.h"
 #include "nsDOMTokenList.h"
 #include "nsIDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsINode.h"
-#include "nsIStyleSheet.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsIURL.h"
 #include "nsPIDOMWindow.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsUnicharUtils.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
--- a/dom/html/HTMLStyleElement.cpp
+++ b/dom/html/HTMLStyleElement.cpp
@@ -3,17 +3,16 @@
 /* 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/. */
 #include "mozilla/dom/HTMLStyleElement.h"
 #include "mozilla/dom/HTMLStyleElementBinding.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsIDOMStyleSheet.h"
-#include "nsIStyleSheet.h"
 #include "nsIDocument.h"
 #include "nsUnicharUtils.h"
 #include "nsThreadUtils.h"
 #include "nsContentUtils.h"
 #include "nsStubMutationObserver.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
 
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -2636,22 +2636,22 @@ nsHTMLDocument::TearingDownEditor(nsIEdi
   if (IsEditingOn()) {
     EditingState oldState = mEditingState;
     mEditingState = eTearingDown;
 
     nsCOMPtr<nsIPresShell> presShell = GetShell();
     if (!presShell)
       return;
 
-    nsCOMArray<nsIStyleSheet> agentSheets;
+    nsTArray<RefPtr<CSSStyleSheet>> agentSheets;
     presShell->GetAgentStyleSheets(agentSheets);
 
-    agentSheets.RemoveObject(nsLayoutStylesheetCache::ContentEditableSheet());
+    agentSheets.RemoveElement(nsLayoutStylesheetCache::ContentEditableSheet());
     if (oldState == eDesignMode)
-      agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
+      agentSheets.RemoveElement(nsLayoutStylesheetCache::DesignModeSheet());
 
     presShell->SetAgentStyleSheets(agentSheets);
 
     presShell->ReconstructStyleData();
   }
 }
 
 nsresult
@@ -2775,48 +2775,44 @@ nsHTMLDocument::EditingStateChanged()
     nsAutoEditingState push(this, eSettingUp);
 
     nsCOMPtr<nsIPresShell> presShell = GetShell();
     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
     // Before making this window editable, we need to modify UA style sheet
     // because new style may change whether focused element will be focusable
     // or not.
-    nsCOMArray<nsIStyleSheet> agentSheets;
+    nsTArray<RefPtr<CSSStyleSheet>> agentSheets;
     rv = presShell->GetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     CSSStyleSheet* contentEditableSheet =
       nsLayoutStylesheetCache::ContentEditableSheet();
 
-    bool result;
-
     if (!agentSheets.Contains(contentEditableSheet)) {
-      bool result = agentSheets.AppendObject(contentEditableSheet);
-      NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+      agentSheets.AppendElement(contentEditableSheet);
     }
 
     // Should we update the editable state of all the nodes in the document? We
     // need to do this when the designMode value changes, as that overrides
     // specific states on the elements.
     if (designMode) {
       // designMode is being turned on (overrides contentEditable).
       CSSStyleSheet* designModeSheet =
         nsLayoutStylesheetCache::DesignModeSheet();
       if (!agentSheets.Contains(designModeSheet)) {
-        result = agentSheets.AppendObject(designModeSheet);
-        NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
+        agentSheets.AppendElement(designModeSheet);
       }
 
       updateState = true;
       spellRecheckAll = oldState == eContentEditable;
     }
     else if (oldState == eDesignMode) {
       // designMode is being turned off (contentEditable is still on).
-      agentSheets.RemoveObject(nsLayoutStylesheetCache::DesignModeSheet());
+      agentSheets.RemoveElement(nsLayoutStylesheetCache::DesignModeSheet());
       updateState = true;
     }
 
     rv = presShell->SetAgentStyleSheets(agentSheets);
     NS_ENSURE_SUCCESS(rv, rv);
 
     presShell->ReconstructStyleData();
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -31,16 +31,17 @@
 #include "BlobParent.h"
 #include "CrashReporterParent.h"
 #include "GMPServiceParent.h"
 #include "HandlerServiceParent.h"
 #include "IHistory.h"
 #include "imgIContainer.h"
 #include "mozIApplication.h"
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/CSSStyleSheet.h"
 #include "mozilla/DataStorage.h"
 #include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
 #include "mozilla/docshell/OfflineCacheUpdateParent.h"
 #include "mozilla/dom/DataStoreService.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/File.h"
@@ -137,17 +138,16 @@
 #include "nsIMozBrowserFrame.h"
 #include "nsIMutable.h"
 #include "nsIObserverService.h"
 #include "nsIPresShell.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISiteSecurityService.h"
 #include "nsISpellChecker.h"
-#include "nsIStyleSheet.h"
 #include "nsISupportsPrimitives.h"
 #include "nsISystemMessagesInternal.h"
 #include "nsITimer.h"
 #include "nsIURIFixup.h"
 #include "nsIWindowMediator.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIXULWindow.h"
 #include "nsIDOMChromeWindow.h"
@@ -2571,34 +2571,31 @@ ContentParent::InitInternal(ProcessPrior
         Unused << SendAppInit();
     }
 
     nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
     if (sheetService) {
         // This looks like a lot of work, but in a normal browser session we just
         // send two loads.
 
-        nsCOMArray<nsIStyleSheet>& agentSheets = *sheetService->AgentStyleSheets();
-        for (uint32_t i = 0; i < agentSheets.Length(); i++) {
+        for (CSSStyleSheet* sheet : *sheetService->AgentStyleSheets()) {
             URIParams uri;
-            SerializeURI(agentSheets[i]->GetSheetURI(), uri);
+            SerializeURI(sheet->GetSheetURI(), uri);
             Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AGENT_SHEET);
         }
 
-        nsCOMArray<nsIStyleSheet>& userSheets = *sheetService->UserStyleSheets();
-        for (uint32_t i = 0; i < userSheets.Length(); i++) {
+        for (CSSStyleSheet* sheet : *sheetService->UserStyleSheets()) {
             URIParams uri;
-            SerializeURI(userSheets[i]->GetSheetURI(), uri);
+            SerializeURI(sheet->GetSheetURI(), uri);
             Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::USER_SHEET);
         }
 
-        nsCOMArray<nsIStyleSheet>& authorSheets = *sheetService->AuthorStyleSheets();
-        for (uint32_t i = 0; i < authorSheets.Length(); i++) {
+        for (CSSStyleSheet* sheet : *sheetService->AuthorStyleSheets()) {
             URIParams uri;
-            SerializeURI(authorSheets[i]->GetSheetURI(), uri);
+            SerializeURI(sheet->GetSheetURI(), uri);
             Unused << SendLoadAndRegisterSheet(uri, nsIStyleSheetService::AUTHOR_SHEET);
         }
     }
 
 #ifdef MOZ_CONTENT_SANDBOX
     bool shouldSandbox = true;
 #ifdef MOZ_NUWA_PROCESS
     if (IsNuwaProcess()) {
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -48,17 +48,16 @@
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFNode.h"
 #include "nsIRDFService.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIServiceManager.h"
 #include "mozilla/css/StyleRule.h"
-#include "nsIStyleSheet.h"
 #include "nsIURL.h"
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIXULDocument.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsLayoutCID.h"
 #include "nsContentCID.h"
 #include "mozilla/dom/Event.h"
--- a/editor/libeditor/nsStyleSheetTxns.cpp
+++ b/editor/libeditor/nsStyleSheetTxns.cpp
@@ -14,33 +14,31 @@
 #include "nsError.h"                    // for NS_OK, etc
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIDocumentObserver.h"        // for UPDATE_STYLE
 #include "nsIEditor.h"                  // for nsIEditor
 
 using namespace mozilla;
 
-class nsIStyleSheet;
-
 static void
-AddStyleSheet(nsIEditor* aEditor, nsIStyleSheet* aSheet)
+AddStyleSheet(nsIEditor* aEditor, CSSStyleSheet* aSheet)
 {
   nsCOMPtr<nsIDOMDocument> domDoc;
   aEditor->GetDocument(getter_AddRefs(domDoc));
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
   if (doc) {
     doc->BeginUpdate(UPDATE_STYLE);
     doc->AddStyleSheet(aSheet);
     doc->EndUpdate(UPDATE_STYLE);
   }
 }
 
 static void
-RemoveStyleSheet(nsIEditor *aEditor, nsIStyleSheet *aSheet)
+RemoveStyleSheet(nsIEditor* aEditor, CSSStyleSheet* aSheet)
 {
   nsCOMPtr<nsIDOMDocument> domDoc;
   aEditor->GetDocument(getter_AddRefs(domDoc));
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
   if (doc) {
     doc->BeginUpdate(UPDATE_STYLE);
     doc->RemoveStyleSheet(aSheet);
     doc->EndUpdate(UPDATE_STYLE);
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.h
+++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.h
@@ -11,17 +11,16 @@
 #include "nsWeakReference.h"
 
 #include "nsIInterfaceRequestor.h"
 #include "nsIMIMEService.h"
 #include "nsIStreamListener.h"
 #include "nsIOutputStream.h"
 #include "nsIInputStream.h"
 #include "nsIChannel.h"
-#include "nsIStyleSheet.h"
 #include "nsIDocumentEncoder.h"
 #include "nsITransport.h"
 #include "nsIProgressEventSink.h"
 #include "nsIFile.h"
 #include "nsIWebProgressListener2.h"
 #include "nsIWebBrowserPersistDocument.h"
 
 #include "mozilla/UniquePtr.h"
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2131,32 +2131,16 @@ nsDocumentViewer::RequestWindowClose(boo
     mDeferredWindowClose = true;
   } else
 #endif
     *aCanClose = true;
 
   return NS_OK;
 }
 
-static bool
-AppendAgentSheet(nsIStyleSheet *aSheet, void *aData)
-{
-  nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
-  styleSet->AppendStyleSheet(SheetType::Agent, aSheet);
-  return true;
-}
-
-static bool
-PrependUserSheet(nsIStyleSheet *aSheet, void *aData)
-{
-  nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
-  styleSet->PrependStyleSheet(SheetType::User, aSheet);
-  return true;
-}
-
 nsresult
 nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument,
                                    nsStyleSet** aStyleSet)
 {
   // Make sure this does the same thing as PresShell::AddSheet wrt ordering.
 
   // this should eventually get expanded to allow for creating
   // different sets for different media
@@ -2310,22 +2294,24 @@ nsDocumentViewer::CreateStyleSet(nsIDocu
   } else {
     // SVG documents may have scrollbars and need the scrollbar styling.
     sheet = nsLayoutStylesheetCache::MinimalXULSheet();
     if (sheet) {
       styleSet->PrependStyleSheet(SheetType::Agent, sheet);
     }
   }
 
-  nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
+  nsStyleSheetService* sheetService = nsStyleSheetService::GetInstance();
   if (sheetService) {
-    sheetService->AgentStyleSheets()->EnumerateForwards(AppendAgentSheet,
-                                                        styleSet);
-    sheetService->UserStyleSheets()->EnumerateBackwards(PrependUserSheet,
-                                                        styleSet);
+    for (CSSStyleSheet* sheet : *sheetService->AgentStyleSheets()) {
+      styleSet->AppendStyleSheet(SheetType::Agent, sheet);
+    }
+    for (CSSStyleSheet* sheet : Reversed(*sheetService->UserStyleSheets())) {
+      styleSet->PrependStyleSheet(SheetType::User, sheet);
+    }
   }
 
   // Caller will handle calling EndUpdate, per contract.
   *aStyleSet = styleSet;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -57,25 +57,25 @@ class nsViewManager;
 class nsView;
 class nsRenderingContext;
 class nsIPageSequenceFrame;
 class nsCanvasFrame;
 class nsAString;
 class nsCaret;
 namespace mozilla {
 class AccessibleCaretEventHub;
+class CSSStyleSheet;
 class TouchCaret;
 class SelectionCarets;
 } // namespace mozilla
 class nsFrameSelection;
 class nsFrameManager;
 class nsILayoutHistoryState;
 class nsIReflowCallback;
 class nsIDOMNode;
-class nsIStyleSheet;
 class nsCSSFrameConstructor;
 class nsISelection;
 template<class E> class nsCOMArray;
 class nsWeakFrame;
 class nsIScrollableFrame;
 class gfxContext;
 class nsIDOMEvent;
 class nsDisplayList;
@@ -135,20 +135,20 @@ typedef struct CapturingContentInfo {
   // capture should only be allowed during a mousedown event
   bool mAllowed;
   bool mPointerLock;
   bool mRetargetToElement;
   bool mPreventDrag;
   mozilla::StaticRefPtr<nsIContent> mContent;
 } CapturingContentInfo;
 
-// ae50e013-b2f1-4d4e-94c7-77cbcdab1c23
+// cf2a1f1f-ed15-42bd-b1ea-59e5d4602118
 #define NS_IPRESSHELL_IID \
-{ 0xae50e013, 0xb2f1, 0x4d4e, \
-  { 0x94, 0xc7, 0x77, 0xcb, 0xcd, 0xab, 0x1c, 0x23 } }
+{ 0xcf2a1f1f, 0xed15, 0x42bd, \
+  { 0xb1, 0xea, 0x59, 0xe5, 0xd4, 0x60, 0x21, 0x18 } }
 
 // debug VerifyReflow flags
 #define VERIFY_REFLOW_ON                    0x01
 #define VERIFY_REFLOW_NOISY                 0x02
 #define VERIFY_REFLOW_ALL                   0x04
 #define VERIFY_REFLOW_DUMP_COMMANDS         0x08
 #define VERIFY_REFLOW_NOISY_RC              0x10
 #define VERIFY_REFLOW_REALLY_NOISY_RC       0x20
@@ -953,32 +953,34 @@ public:
   /**
    * Indicates whether theme support is enabled.
    */
   bool IsThemeSupportEnabled() const { return !mIsThemeSupportDisabled; }
 
   /**
    * Get the set of agent style sheets for this presentation
    */
-  virtual nsresult GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets) = 0;
+  virtual nsresult GetAgentStyleSheets(
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets) = 0;
 
   /**
    * Replace the set of agent style sheets
    */
-  virtual nsresult SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets) = 0;
+  virtual nsresult SetAgentStyleSheets(
+      const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets) = 0;
 
   /**
    * Add an override style sheet for this presentation
    */
-  virtual nsresult AddOverrideStyleSheet(nsIStyleSheet *aSheet) = 0;
+  virtual nsresult AddOverrideStyleSheet(mozilla::CSSStyleSheet* aSheet) = 0;
 
   /**
    * Remove an override style sheet
    */
-  virtual nsresult RemoveOverrideStyleSheet(nsIStyleSheet *aSheet) = 0;
+  virtual nsresult RemoveOverrideStyleSheet(mozilla::CSSStyleSheet* aSheet) = 0;
 
   /**
    * Reconstruct frames for all elements in the document
    */
   virtual nsresult ReconstructFrames() = 0;
 
   /**
    * Notify that a content node's state has changed
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1421,74 +1421,73 @@ PresShell::AddUserSheet(nsISupports* aSh
   // service sheets, but before other user sheets; see nsIStyleSheetService.idl
   // for the ordering.  Just remove and readd all the nsStyleSheetService
   // sheets.
   nsCOMPtr<nsIStyleSheetService> dummy =
     do_GetService(NS_STYLESHEETSERVICE_CONTRACTID);
 
   mStyleSet->BeginUpdate();
 
-  nsStyleSheetService *sheetService = nsStyleSheetService::gInstance;
-  nsCOMArray<nsIStyleSheet> & userSheets = *sheetService->UserStyleSheets();
-  int32_t i;
+  nsStyleSheetService* sheetService = nsStyleSheetService::gInstance;
+  nsTArray<RefPtr<CSSStyleSheet>>& userSheets = *sheetService->UserStyleSheets();
   // Iterate forwards when removing so the searches for RemoveStyleSheet are as
   // short as possible.
-  for (i = 0; i < userSheets.Count(); ++i) {
-    mStyleSet->RemoveStyleSheet(SheetType::User, userSheets[i]);
+  for (CSSStyleSheet* sheet : userSheets) {
+    mStyleSet->RemoveStyleSheet(SheetType::User, sheet);
   }
 
   // Now iterate backwards, so that the order of userSheets will be the same as
   // the order of sheets from it in the style set.
-  for (i = userSheets.Count() - 1; i >= 0; --i) {
-    mStyleSet->PrependStyleSheet(SheetType::User, userSheets[i]);
+  for (CSSStyleSheet* sheet : Reversed(userSheets)) {
+    mStyleSet->PrependStyleSheet(SheetType::User, sheet);
   }
 
   mStyleSet->EndUpdate();
 
   ReconstructStyleData();
 }
 
 void
 PresShell::AddAgentSheet(nsISupports* aSheet)
 {
   // Make sure this does what nsDocumentViewer::CreateStyleSet does
   // wrt ordering.
-  nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
+  RefPtr<CSSStyleSheet> sheet = do_QueryObject(aSheet);
   if (!sheet) {
     return;
   }
 
   mStyleSet->AppendStyleSheet(SheetType::Agent, sheet);
   ReconstructStyleData();
 }
 
 void
 PresShell::AddAuthorSheet(nsISupports* aSheet)
 {
-  nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
+  RefPtr<CSSStyleSheet> sheet = do_QueryObject(aSheet);
   if (!sheet) {
     return;
   }
 
   // Document specific "additional" Author sheets should be stronger than the ones
   // added with the StyleSheetService.
-  nsIStyleSheet* firstAuthorSheet = mDocument->FirstAdditionalAuthorSheet();
+  CSSStyleSheet* firstAuthorSheet = mDocument->FirstAdditionalAuthorSheet();
   if (firstAuthorSheet) {
     mStyleSet->InsertStyleSheetBefore(SheetType::Doc, sheet, firstAuthorSheet);
   } else {
     mStyleSet->AppendStyleSheet(SheetType::Doc, sheet);
   }
 
   ReconstructStyleData();
 }
 
 void
 PresShell::RemoveSheet(SheetType aType, nsISupports* aSheet)
 {
-  nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
+  RefPtr<CSSStyleSheet> sheet = do_QueryObject(aSheet);
   if (!sheet) {
     return;
   }
 
   mStyleSet->RemoveStyleSheet(aType, sheet);
   ReconstructStyleData();
 }
 
@@ -4496,17 +4495,17 @@ nsIPresShell::ReconstructStyleDataIntern
 
 void
 nsIPresShell::ReconstructStyleDataExternal()
 {
   ReconstructStyleDataInternal();
 }
 
 void
-PresShell::RecordStyleSheetChange(nsIStyleSheet* aStyleSheet)
+PresShell::RecordStyleSheetChange(CSSStyleSheet* aStyleSheet)
 {
   // too bad we can't check that the update is UPDATE_STYLE
   NS_ASSERTION(mUpdateCount != 0, "must be in an update");
 
   if (mStylesHaveChanged)
     return;
 
   RefPtr<CSSStyleSheet> cssStyleSheet = do_QueryObject(aStyleSheet);
@@ -4517,71 +4516,71 @@ PresShell::RecordStyleSheetChange(nsISty
       return;
     }
   }
 
   mStylesHaveChanged = true;
 }
 
 void
-PresShell::StyleSheetAdded(nsIDocument *aDocument,
-                           nsIStyleSheet* aStyleSheet,
+PresShell::StyleSheetAdded(nsIDocument* aDocument,
+                           CSSStyleSheet* aStyleSheet,
                            bool aDocumentSheet)
 {
   // We only care when enabled sheets are added
   NS_PRECONDITION(aStyleSheet, "Must have a style sheet!");
 
   if (aStyleSheet->IsApplicable() && aStyleSheet->HasRules()) {
     RecordStyleSheetChange(aStyleSheet);
   }
 }
 
 void
-PresShell::StyleSheetRemoved(nsIDocument *aDocument,
-                             nsIStyleSheet* aStyleSheet,
+PresShell::StyleSheetRemoved(nsIDocument* aDocument,
+                             CSSStyleSheet* aStyleSheet,
                              bool aDocumentSheet)
 {
   // We only care when enabled sheets are removed
   NS_PRECONDITION(aStyleSheet, "Must have a style sheet!");
 
   if (aStyleSheet->IsApplicable() && aStyleSheet->HasRules()) {
     RecordStyleSheetChange(aStyleSheet);
   }
 }
 
 void
-PresShell::StyleSheetApplicableStateChanged(nsIDocument *aDocument,
-                                            nsIStyleSheet* aStyleSheet,
+PresShell::StyleSheetApplicableStateChanged(nsIDocument* aDocument,
+                                            CSSStyleSheet* aStyleSheet,
                                             bool aApplicable)
 {
   if (aStyleSheet->HasRules()) {
     RecordStyleSheetChange(aStyleSheet);
   }
 }
 
 void
-PresShell::StyleRuleChanged(nsIDocument *aDocument,
-                            nsIStyleSheet* aStyleSheet,
+PresShell::StyleRuleChanged(nsIDocument* aDocument,
+                            CSSStyleSheet* aStyleSheet,
                             mozilla::css::Rule* aOldStyleRule,
                             mozilla::css::Rule* aNewStyleRule)
 {
   RecordStyleSheetChange(aStyleSheet);
 }
 
 void
-PresShell::StyleRuleAdded(nsIDocument *aDocument,
-                          nsIStyleSheet* aStyleSheet,
+PresShell::StyleRuleAdded(nsIDocument* aDocument,
+                          CSSStyleSheet* aStyleSheet,
                           mozilla::css::Rule* aStyleRule)
 {
   RecordStyleSheetChange(aStyleSheet);
 }
 
 void
-PresShell::StyleRuleRemoved(nsIDocument *aDocument,
-                            nsIStyleSheet* aStyleSheet,
+PresShell::StyleRuleRemoved(nsIDocument* aDocument,
+                            CSSStyleSheet* aStyleSheet,
                             mozilla::css::Rule* aStyleRule)
 {
   RecordStyleSheetChange(aStyleSheet);
 }
 
 nsIFrame*
 PresShell::GetRealPrimaryFrameFor(nsIContent* aContent) const
 {
@@ -8597,44 +8596,47 @@ PresShell::IsVisible()
   nsIFrame* frame = view->GetFrame();
   if (!frame)
     return true;
 
   return frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY);
 }
 
 nsresult
-PresShell::GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets)
+PresShell::GetAgentStyleSheets(nsTArray<RefPtr<CSSStyleSheet>>& aSheets)
 {
   aSheets.Clear();
   int32_t sheetCount = mStyleSet->SheetCount(SheetType::Agent);
 
+  if (!aSheets.SetCapacity(sheetCount, fallible)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
   for (int32_t i = 0; i < sheetCount; ++i) {
-    nsIStyleSheet *sheet = mStyleSet->StyleSheetAt(SheetType::Agent, i);
-    if (!aSheets.AppendObject(sheet))
-      return NS_ERROR_OUT_OF_MEMORY;
+    CSSStyleSheet* sheet = mStyleSet->StyleSheetAt(SheetType::Agent, i);
+    aSheets.AppendElement(sheet);
   }
 
   return NS_OK;
 }
 
 nsresult
-PresShell::SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets)
+PresShell::SetAgentStyleSheets(const nsTArray<RefPtr<CSSStyleSheet>>& aSheets)
 {
   return mStyleSet->ReplaceSheets(SheetType::Agent, aSheets);
 }
 
 nsresult
-PresShell::AddOverrideStyleSheet(nsIStyleSheet *aSheet)
+PresShell::AddOverrideStyleSheet(CSSStyleSheet* aSheet)
 {
   return mStyleSet->PrependStyleSheet(SheetType::Override, aSheet);
 }
 
 nsresult
-PresShell::RemoveOverrideStyleSheet(nsIStyleSheet *aSheet)
+PresShell::RemoveOverrideStyleSheet(CSSStyleSheet* aSheet)
 {
   return mStyleSet->RemoveStyleSheet(SheetType::Override, aSheet);
 }
 
 static void
 FreezeElement(nsISupports *aSupports, void * /* unused */)
 {
   nsCOMPtr<nsIObjectLoadingContent> olc(do_QueryInterface(aSupports));
@@ -9727,41 +9729,41 @@ FindTopFrame(nsIFrame* aRoot)
 
 nsStyleSet*
 PresShell::CloneStyleSet(nsStyleSet* aSet)
 {
   nsStyleSet *clone = new nsStyleSet();
 
   int32_t i, n = aSet->SheetCount(SheetType::Override);
   for (i = 0; i < n; i++) {
-    nsIStyleSheet* ss = aSet->StyleSheetAt(SheetType::Override, i);
+    CSSStyleSheet* ss = aSet->StyleSheetAt(SheetType::Override, i);
     if (ss)
       clone->AppendStyleSheet(SheetType::Override, ss);
   }
 
   // The document expects to insert document stylesheets itself
 #if 0
   n = aSet->SheetCount(SheetType::Doc);
   for (i = 0; i < n; i++) {
-    nsIStyleSheet* ss = aSet->StyleSheetAt(SheetType::Doc, i);
+    CSSStyleSheet* ss = aSet->StyleSheetAt(SheetType::Doc, i);
     if (ss)
       clone->AddDocStyleSheet(ss, mDocument);
   }
 #endif
 
   n = aSet->SheetCount(SheetType::User);
   for (i = 0; i < n; i++) {
-    nsIStyleSheet* ss = aSet->StyleSheetAt(SheetType::User, i);
+    CSSStyleSheet* ss = aSet->StyleSheetAt(SheetType::User, i);
     if (ss)
       clone->AppendStyleSheet(SheetType::User, ss);
   }
 
   n = aSet->SheetCount(SheetType::Agent);
   for (i = 0; i < n; i++) {
-    nsIStyleSheet* ss = aSet->StyleSheetAt(SheetType::Agent, i);
+    CSSStyleSheet* ss = aSet->StyleSheetAt(SheetType::Agent, i);
     if (ss)
       clone->AppendStyleSheet(SheetType::Agent, ss);
   }
   return clone;
 }
 
 // After an incremental reflow, we verify the correctness by doing a
 // full reflow into a fresh frame tree.
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -156,21 +156,23 @@ public:
 
   virtual void SetIgnoreFrameDestruction(bool aIgnore) override;
   virtual void NotifyDestroyingFrame(nsIFrame* aFrame) override;
 
   virtual nsresult CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState) override;
 
   virtual void UnsuppressPainting() override;
 
-  virtual nsresult GetAgentStyleSheets(nsCOMArray<nsIStyleSheet>& aSheets) override;
-  virtual nsresult SetAgentStyleSheets(const nsCOMArray<nsIStyleSheet>& aSheets) override;
+  virtual nsresult GetAgentStyleSheets(
+      nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets) override;
+  virtual nsresult SetAgentStyleSheets(
+      const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets) override;
 
-  virtual nsresult AddOverrideStyleSheet(nsIStyleSheet *aSheet) override;
-  virtual nsresult RemoveOverrideStyleSheet(nsIStyleSheet *aSheet) override;
+  virtual nsresult AddOverrideStyleSheet(mozilla::CSSStyleSheet* aSheet) override;
+  virtual nsresult RemoveOverrideStyleSheet(mozilla::CSSStyleSheet* aSheet) override;
 
   virtual nsresult HandleEventWithTarget(
                                  mozilla::WidgetEvent* aEvent,
                                  nsIFrame* aFrame,
                                  nsIContent* aContent,
                                  nsEventStatus* aStatus) override;
   virtual nsIFrame* GetEventTargetFrame() override;
   virtual already_AddRefed<nsIContent> GetEventTargetContent(
@@ -511,17 +513,17 @@ protected:
   bool mCaretEnabled;
 #ifdef DEBUG
   nsStyleSet* CloneStyleSet(nsStyleSet* aSet);
   bool VerifyIncrementalReflow();
   bool mInVerifyReflow;
   void ShowEventTargetDebug();
 #endif
 
-  void RecordStyleSheetChange(nsIStyleSheet* aStyleSheet);
+  void RecordStyleSheetChange(mozilla::CSSStyleSheet* aStyleSheet);
 
   void RemovePreferenceStyles();
 
   // methods for painting a range to an offscreen buffer
 
   // given a display list, clip the items within the list to
   // the range
   nsRect ClipListToRange(nsDisplayListBuilder *aBuilder,
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -2,17 +2,16 @@
 /* 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/. */
 
 /* implementation of interface for managing user and user-agent style sheets */
 
 #include "nsStyleSheetService.h"
-#include "nsIStyleSheet.h"
 #include "mozilla/CSSStyleSheet.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/unused.h"
 #include "mozilla/css/Loader.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "nsIURI.h"
 #include "nsCOMPtr.h"
@@ -74,24 +73,24 @@ nsStyleSheetService::RegisterFromEnumera
     nsCOMPtr<nsIURI> uri;
     NS_NewURI(getter_AddRefs(uri), spec);
     if (uri)
       LoadAndRegisterSheetInternal(uri, aSheetType);
   }
 }
 
 int32_t
-nsStyleSheetService::FindSheetByURI(const nsCOMArray<nsIStyleSheet> &sheets,
-                                    nsIURI *sheetURI)
+nsStyleSheetService::FindSheetByURI(const nsTArray<RefPtr<CSSStyleSheet>>& aSheets,
+                                    nsIURI* aSheetURI)
 {
-  for (int32_t i = sheets.Count() - 1; i >= 0; i-- ) {
+  for (int32_t i = aSheets.Length() - 1; i >= 0; i-- ) {
     bool bEqual;
-    nsIURI* uri = sheets[i]->GetSheetURI();
+    nsIURI* uri = aSheets[i]->GetSheetURI();
     if (uri
-        && NS_SUCCEEDED(uri->Equals(sheetURI, &bEqual))
+        && NS_SUCCEEDED(uri->Equals(aSheetURI, &bEqual))
         && bEqual) {
       return i;
     }
   }
 
   return -1;
 }
 
@@ -148,18 +147,19 @@ nsStyleSheetService::LoadAndRegisterShee
         break;
       default:
         return NS_ERROR_INVALID_ARG;
     }
     nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
     if (serv) {
       // We're guaranteed that the new sheet is the last sheet in
       // mSheets[aSheetType]
-      const nsCOMArray<nsIStyleSheet> & sheets = mSheets[aSheetType];
-      serv->NotifyObservers(sheets[sheets.Count() - 1], message, nullptr);
+      CSSStyleSheet* sheet = mSheets[aSheetType].LastElement();
+      serv->NotifyObservers(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, sheet),
+                            message, nullptr);
     }
 
     if (XRE_IsParentProcess()) {
       nsTArray<dom::ContentParent*> children;
       dom::ContentParent::GetAll(children);
 
       if (children.IsEmpty()) {
         return rv;
@@ -203,19 +203,17 @@ nsStyleSheetService::LoadAndRegisterShee
 
   RefPtr<css::Loader> loader = new css::Loader();
 
   RefPtr<CSSStyleSheet> sheet;
   nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true,
                                       getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!mSheets[aSheetType].AppendObject(sheet)) {
-    rv = NS_ERROR_OUT_OF_MEMORY;
-  }
+  mSheets[aSheetType].AppendElement(sheet);
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsStyleSheetService::SheetRegistered(nsIURI *sheetURI,
                                      uint32_t aSheetType, bool *_retval)
 {
@@ -270,35 +268,37 @@ nsStyleSheetService::UnregisterSheet(nsI
 {
   NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
                 aSheetType == USER_SHEET ||
                 aSheetType == AUTHOR_SHEET);
   NS_ENSURE_ARG_POINTER(aSheetURI);
 
   int32_t foundIndex = FindSheetByURI(mSheets[aSheetType], aSheetURI);
   NS_ENSURE_TRUE(foundIndex >= 0, NS_ERROR_INVALID_ARG);
-  nsCOMPtr<nsIStyleSheet> sheet = mSheets[aSheetType][foundIndex];
-  mSheets[aSheetType].RemoveObjectAt(foundIndex);
+  RefPtr<CSSStyleSheet> sheet = mSheets[aSheetType][foundIndex];
+  mSheets[aSheetType].RemoveElementAt(foundIndex);
 
   const char* message;
   switch (aSheetType) {
     case AGENT_SHEET:
       message = "agent-sheet-removed";
       break;
     case USER_SHEET:
       message = "user-sheet-removed";
       break;
     case AUTHOR_SHEET:
       message = "author-sheet-removed";
       break;
   }
 
   nsCOMPtr<nsIObserverService> serv = services::GetObserverService();
-  if (serv)
-    serv->NotifyObservers(sheet, message, nullptr);
+  if (serv) {
+    serv->NotifyObservers(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, sheet),
+                          message, nullptr);
+  }
 
   if (XRE_IsParentProcess()) {
     nsTArray<dom::ContentParent*> children;
     dom::ContentParent::GetAll(children);
 
     if (children.IsEmpty()) {
       return NS_OK;
     }
@@ -324,41 +324,32 @@ nsStyleSheetService::GetInstance()
     nsCOMPtr<nsIStyleSheetService> dummy =
       do_GetService(NS_STYLESHEETSERVICE_CONTRACTID);
     first = false;
   }
 
   return gInstance;
 }
 
-static size_t
-SizeOfElementIncludingThis(nsIStyleSheet* aElement,
-                           MallocSizeOf aMallocSizeOf, void *aData)
-{
-  return aElement->SizeOfIncludingThis(aMallocSizeOf);
-}
-
 MOZ_DEFINE_MALLOC_SIZE_OF(StyleSheetServiceMallocSizeOf)
 
 NS_IMETHODIMP
 nsStyleSheetService::CollectReports(nsIHandleReportCallback* aHandleReport,
                                     nsISupports* aData, bool aAnonymize)
 {
   return MOZ_COLLECT_REPORT(
     "explicit/layout/style-sheet-service", KIND_HEAP, UNITS_BYTES,
     SizeOfIncludingThis(StyleSheetServiceMallocSizeOf),
     "Memory used for style sheets held by the style sheet service.");
 }
 
 size_t
 nsStyleSheetService::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
-  n += mSheets[AGENT_SHEET].SizeOfExcludingThis(SizeOfElementIncludingThis,
-                                                aMallocSizeOf);
-  n += mSheets[USER_SHEET].SizeOfExcludingThis(SizeOfElementIncludingThis,
-                                               aMallocSizeOf);
-  n += mSheets[AUTHOR_SHEET].SizeOfExcludingThis(SizeOfElementIncludingThis,
-                                                 aMallocSizeOf);
+  for (auto& sheetArray : mSheets) {
+    n += sheetArray.ShallowSizeOfExcludingThis(aMallocSizeOf);
+    for (CSSStyleSheet* sheet : sheetArray) {
+      n += sheet->SizeOfIncludingThis(aMallocSizeOf);
+    }
+  }
   return n;
 }
-
-
--- a/layout/base/nsStyleSheetService.h
+++ b/layout/base/nsStyleSheetService.h
@@ -11,23 +11,26 @@
 
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsIMemoryReporter.h"
 #include "nsIStyleSheetService.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 
+namespace mozilla {
+class CSSStyleSheet;
+}
 class nsICategoryManager;
 class nsIMemoryReporter;
 class nsISimpleEnumerator;
-class nsIStyleSheet;
 
 #define NS_STYLESHEETSERVICE_CID \
-{0xfcca6f83, 0x9f7d, 0x44e4, {0xa7, 0x4b, 0xb5, 0x94, 0x33, 0xe6, 0xc8, 0xc3}}
+{ 0x3b55e72e, 0xab7e, 0x431b, \
+  { 0x89, 0xc0, 0x3b, 0x06, 0xa8, 0xb1, 0x40, 0x16 } }
 
 #define NS_STYLESHEETSERVICE_CONTRACTID \
   "@mozilla.org/content/style-sheet-service;1"
 
 class nsStyleSheetService final
   : public nsIStyleSheetService
   , public nsIMemoryReporter
 {
@@ -35,37 +38,46 @@ class nsStyleSheetService final
   nsStyleSheetService();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTYLESHEETSERVICE
   NS_DECL_NSIMEMORYREPORTER
 
   nsresult Init();
 
-  nsCOMArray<nsIStyleSheet>* AgentStyleSheets() { return &mSheets[AGENT_SHEET]; }
-  nsCOMArray<nsIStyleSheet>* UserStyleSheets() { return &mSheets[USER_SHEET]; }
-  nsCOMArray<nsIStyleSheet>* AuthorStyleSheets() { return &mSheets[AUTHOR_SHEET]; }
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>>* AgentStyleSheets()
+  {
+    return &mSheets[AGENT_SHEET];
+  }
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>>* UserStyleSheets()
+  {
+    return &mSheets[USER_SHEET];
+  }
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>>* AuthorStyleSheets()
+  {
+    return &mSheets[AUTHOR_SHEET];
+  }
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   static nsStyleSheetService *GetInstance();
   static nsStyleSheetService *gInstance;
 
  private:
   ~nsStyleSheetService();
 
   void RegisterFromEnumerator(nsICategoryManager  *aManager,
                                           const char          *aCategory,
                                           nsISimpleEnumerator *aEnumerator,
                                           uint32_t             aSheetType);
 
-  int32_t FindSheetByURI(const nsCOMArray<nsIStyleSheet> &sheets,
-                                     nsIURI *sheetURI);
+  int32_t FindSheetByURI(const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aSheets,
+                         nsIURI* aSheetURI);
 
   // Like LoadAndRegisterSheet, but doesn't notify.  If successful, the
   // new sheet will be the last sheet in mSheets[aSheetType].
   nsresult LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
                                         uint32_t aSheetType);
 
-  nsCOMArray<nsIStyleSheet> mSheets[3];
+  nsTArray<RefPtr<mozilla::CSSStyleSheet>> mSheets[3];
 };
 
 #endif
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -69,17 +69,17 @@ NS_IMPL_ISUPPORTS(inDOMUtils, inIDOMUtil
 // inIDOMUtils
 
 NS_IMETHODIMP
 inDOMUtils::GetAllStyleSheets(nsIDOMDocument *aDocument, uint32_t *aLength,
                               nsISupports ***aSheets)
 {
   NS_ENSURE_ARG_POINTER(aDocument);
 
-  nsCOMArray<nsIStyleSheet> sheets;
+  nsTArray<RefPtr<CSSStyleSheet>> sheets;
 
   nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
   MOZ_ASSERT(document);
 
   // Get the agent, then user and finally xbl sheets in the style set.
   nsIPresShell* presShell = document->GetShell();
   if (presShell) {
     nsStyleSet* styleSet = presShell->StyleSet();
@@ -104,24 +104,24 @@ inDOMUtils::GetAllStyleSheets(nsIDOMDocu
     }
   }
 
   // Get the document sheets.
   for (int32_t i = 0; i < document->GetNumberOfStyleSheets(); i++) {
     sheets.AppendElement(document->GetStyleSheetAt(i));
   }
 
-  nsISupports** ret = static_cast<nsISupports**>(moz_xmalloc(sheets.Count() *
+  nsISupports** ret = static_cast<nsISupports**>(moz_xmalloc(sheets.Length() *
                                                  sizeof(nsISupports*)));
 
-  for (int32_t i = 0; i < sheets.Count(); i++) {
-    NS_ADDREF(ret[i] = sheets[i]);
+  for (size_t i = 0; i < sheets.Length(); i++) {
+    NS_ADDREF(ret[i] = NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, sheets[i]));
   }
 
-  *aLength = sheets.Count();
+  *aLength = sheets.Length();
   *aSheets = ret;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 inDOMUtils::IsIgnorableWhitespace(nsIDOMCharacterData *aDataNode,
                                   bool *aReturn)
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -1248,35 +1248,34 @@ CSSStyleSheet::TraverseInner(nsCycleColl
   // because otherwise there are no JS wrappers for anything in the inner.
   if (mInner->mSheets.Length() != 1) {
     return;
   }
 
   RefPtr<CSSStyleSheet>* childSheetSlot = &mInner->mFirstChild;
   while (*childSheetSlot) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "child sheet");
-    cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIStyleSheet*, childSheetSlot->get()));
+    cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, childSheetSlot->get()));
     childSheetSlot = &(*childSheetSlot)->mNext;
   }
 
   const nsCOMArray<css::Rule>& rules = mInner->mOrderedRules;
   for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mOrderedRules[i]");
     cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule());
   }
 }
 
 // QueryInterface implementation for CSSStyleSheet
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSStyleSheet)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsIStyleSheet)
   NS_INTERFACE_MAP_ENTRY(nsIDOMStyleSheet)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleSheet)
   NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleSheet)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCSSStyleSheet)
   if (aIID.Equals(NS_GET_IID(CSSStyleSheet)))
     foundInterface = reinterpret_cast<nsISupports*>(this);
   else
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSStyleSheet)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSStyleSheet)
@@ -1366,29 +1365,29 @@ CSSStyleSheet::SetPrincipal(nsIPrincipal
   if (aPrincipal) {
     mInner->mPrincipal = aPrincipal;
 #ifdef DEBUG
     mInner->mPrincipalSet = true;
 #endif
   }
 }
 
-/* virtual */ nsIURI*
+nsIURI*
 CSSStyleSheet::GetSheetURI() const
 {
   return mInner->mSheetURI;
 }
 
-/* virtual */ nsIURI*
+nsIURI*
 CSSStyleSheet::GetBaseURI() const
 {
   return mInner->mBaseURI;
 }
 
-/* virtual */ void
+void
 CSSStyleSheet::GetType(nsString& aType) const
 {
   aType.AssignLiteral("text/css");
 }
 
 bool
 CSSStyleSheet::UseForPresentation(nsPresContext* aPresContext,
                                   nsMediaQueryResultCacheKey& aKey) const
@@ -1401,51 +1400,51 @@ CSSStyleSheet::UseForPresentation(nsPres
 
 
 void
 CSSStyleSheet::SetMedia(nsMediaList* aMedia)
 {
   mMedia = aMedia;
 }
 
-/* virtual */ bool
+bool
 CSSStyleSheet::HasRules() const
 {
   return StyleRuleCount() != 0;
 }
 
-/* virtual */ bool
+bool
 CSSStyleSheet::IsApplicable() const
 {
   return !mDisabled && mInner->mComplete;
 }
 
-/* virtual */ void
+void
 CSSStyleSheet::SetEnabled(bool aEnabled)
 {
   // Internal method, so callers must handle BeginUpdate/EndUpdate
   bool oldDisabled = mDisabled;
   mDisabled = !aEnabled;
 
   if (mInner->mComplete && oldDisabled != mDisabled) {
     ClearRuleCascades();
 
     if (mDocument) {
       mDocument->SetStyleSheetApplicableState(this, !mDisabled);
     }
   }
 }
 
-/* virtual */ bool
+bool
 CSSStyleSheet::IsComplete() const
 {
   return mInner->mComplete;
 }
 
-/* virtual */ void
+void
 CSSStyleSheet::SetComplete()
 {
   NS_ASSERTION(!mDirty, "Can't set a dirty sheet complete!");
   mInner->mComplete = true;
   if (mDocument && !mDisabled) {
     // Let the document know
     mDocument->BeginUpdate(UPDATE_STYLE);
     mDocument->SetStyleSheetApplicableState(this, true);
@@ -1455,29 +1454,29 @@ CSSStyleSheet::SetComplete()
   if (mOwningNode && !mDisabled &&
       mOwningNode->HasFlag(NODE_IS_IN_SHADOW_TREE) &&
       mOwningNode->IsContent()) {
     ShadowRoot* shadowRoot = mOwningNode->AsContent()->GetContainingShadow();
     shadowRoot->StyleSheetChanged();
   }
 }
 
-/* virtual */ nsIStyleSheet*
+CSSStyleSheet*
 CSSStyleSheet::GetParentSheet() const
 {
   return mParent;
 }
 
-/* virtual */ nsIDocument*
+nsIDocument*
 CSSStyleSheet::GetOwningDocument() const
 {
   return mDocument;
 }
 
-/* virtual */ void
+void
 CSSStyleSheet::SetOwningDocument(nsIDocument* aDocument)
 { // not ref counted
   mDocument = aDocument;
   // Now set the same document on all our child sheets....
   // XXXbz this is a little bogus; see the XXX comment where we
   // declare mFirstChild.
   for (CSSStyleSheet* child = mInner->mFirstChild;
        child; child = child->mNext) {
@@ -1495,22 +1494,19 @@ CSSStyleSheet::FindOwningWindowInnerID()
     windowID = mDocument->InnerWindowID();
   }
 
   if (windowID == 0 && mOwningNode) {
     windowID = mOwningNode->OwnerDoc()->InnerWindowID();
   }
 
   if (windowID == 0 && mOwnerRule) {
-    nsCOMPtr<nsIStyleSheet> sheet = static_cast<css::Rule*>(mOwnerRule)->GetStyleSheet();
+    RefPtr<CSSStyleSheet> sheet = static_cast<css::Rule*>(mOwnerRule)->GetStyleSheet();
     if (sheet) {
-      RefPtr<CSSStyleSheet> cssSheet = do_QueryObject(sheet);
-      if (cssSheet) {
-        windowID = cssSheet->FindOwningWindowInnerID();
-      }
+      windowID = sheet->FindOwningWindowInnerID();
     }
   }
 
   if (windowID == 0 && mParent) {
     windowID = mParent->FindOwningWindowInnerID();
   }
 
   return windowID;
@@ -1633,17 +1629,17 @@ struct ListEnumData {
     : mOut(aOut),
       mIndent(aIndent)
   {
   }
   FILE*   mOut;
   int32_t mIndent;
 };
 
-/* virtual */ void
+void
 CSSStyleSheet::List(FILE* out, int32_t aIndent) const
 {
 
   int32_t index;
 
   // Indent
   nsAutoCString str;
   for (index = aIndent; --index >= 0; ) {
@@ -1826,17 +1822,17 @@ CSSStyleSheet::GetHref(nsAString& aHref)
     CopyUTF8toUTF16(str, aHref);
   } else {
     SetDOMStringToNull(aHref);
   }
 
   return NS_OK;
 }
 
-/* virtual */ void
+void
 CSSStyleSheet::GetTitle(nsString& aTitle) const
 {
   aTitle = mTitle;
 }
 
 NS_IMETHODIMP
 CSSStyleSheet::GetTitle(nsAString& aTitle)
 {
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -12,17 +12,16 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/IncrementalClearCOMRuleArray.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Element.h"
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
-#include "nsIStyleSheet.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsTArrayForwardDeclare.h"
 #include "nsString.h"
 #include "mozilla/CORSMode.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "mozilla/net/ReferrerPolicy.h"
@@ -107,57 +106,78 @@ private:
 };
 
 
 // -------------------------------
 // CSS Style Sheet
 //
 
 // CID for the CSSStyleSheet class
-// ca926f30-2a7e-477e-8467-803fb32af20a
+// 7985c7ac-9ddc-444d-9899-0c86ec122f54
 #define NS_CSS_STYLE_SHEET_IMPL_CID     \
-{ 0xca926f30, 0x2a7e, 0x477e, \
- { 0x84, 0x67, 0x80, 0x3f, 0xb3, 0x2a, 0xf2, 0x0a } }
+{ 0x7985c7ac, 0x9ddc, 0x444d, \
+  { 0x98, 0x99, 0x0c, 0x86, 0xec, 0x12, 0x2f, 0x54 } }
 
 
-class CSSStyleSheet final : public nsIStyleSheet,
-                            public nsIDOMCSSStyleSheet,
+class CSSStyleSheet final : public nsIDOMCSSStyleSheet,
                             public nsICSSLoaderObserver,
                             public nsWrapperCache
 {
 public:
   typedef net::ReferrerPolicy ReferrerPolicy;
   CSSStyleSheet(CORSMode aCORSMode, ReferrerPolicy aReferrerPolicy);
   CSSStyleSheet(CORSMode aCORSMode, ReferrerPolicy aReferrerPolicy,
                 const dom::SRIMetadata& aIntegrity);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(CSSStyleSheet,
-                                                         nsIStyleSheet)
+                                                         nsIDOMCSSStyleSheet)
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_SHEET_IMPL_CID)
 
-  // nsIStyleSheet interface
-  virtual nsIURI* GetSheetURI() const override;
-  virtual nsIURI* GetBaseURI() const override;
-  virtual void GetTitle(nsString& aTitle) const override;
-  virtual void GetType(nsString& aType) const override;
-  virtual bool HasRules() const override;
-  virtual bool IsApplicable() const override;
-  virtual void SetEnabled(bool aEnabled) override;
-  virtual bool IsComplete() const override;
-  virtual void SetComplete() override;
-  virtual nsIStyleSheet* GetParentSheet() const override;  // may be null
-  virtual nsIDocument* GetOwningDocument() const override;  // may be null
-  virtual void SetOwningDocument(nsIDocument* aDocument) override;
+  nsIURI* GetSheetURI() const;
+  nsIURI* GetBaseURI() const;
+  void GetTitle(nsString& aTitle) const;
+  void GetType(nsString& aType) const;
+  bool HasRules() const;
+
+  /**
+   * Whether the sheet is applicable.  A sheet that is not applicable
+   * should never be inserted into a style set.  A sheet may not be
+   * applicable for a variety of reasons including being disabled and
+   * being incomplete.
+   */
+  bool IsApplicable() const;
+
+  /**
+   * Set the stylesheet to be enabled.  This may or may not make it
+   * applicable.  Note that this WILL inform the sheet's document of
+   * its new applicable state if the state changes but WILL NOT call
+   * BeginUpdate() or EndUpdate() on the document -- calling those is
+   * the caller's responsibility.  This allows use of SetEnabled when
+   * batched updates are desired.  If you want updates handled for
+   * you, see nsIDOMStyleSheet::SetDisabled().
+   */
+  void SetEnabled(bool aEnabled);
+
+  /**
+   * Whether the sheet is complete.
+   */
+  bool IsComplete() const;
+  void SetComplete();
+
+  // style sheet owner info
+  CSSStyleSheet* GetParentSheet() const;  // may be null
+  nsIDocument* GetOwningDocument() const;  // may be null
+  void SetOwningDocument(nsIDocument* aDocument);
 
   // Find the ID of the owner inner window.
   uint64_t FindOwningWindowInnerID() const;
 #ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
+  void List(FILE* out = stdout, int32_t aIndent = 0) const;
 #endif
 
   void AppendStyleSheet(CSSStyleSheet* aSheet);
 
   // XXX do these belong here or are they generic?
   void AppendStyleRule(css::Rule* aRule);
 
   int32_t StyleRuleCount() const;
@@ -245,17 +265,17 @@ public:
 
   // nsIDOMCSSStyleSheet interface
   NS_DECL_NSIDOMCSSSTYLESHEET
 
   // Function used as a callback to rebuild our inner's child sheet
   // list after we clone a unique inner for ourselves.
   static bool RebuildChildList(css::Rule* aRule, void* aBuilder);
 
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
 
   // Get this style sheet's CORS mode
   CORSMode GetCORSMode() const { return mInner->mCORSMode; }
 
   // Get this style sheet's Referrer Policy
   ReferrerPolicy GetReferrerPolicy() const { return mInner->mReferrerPolicy; }
 
   // Get this style sheet's integrity metadata
@@ -263,25 +283,25 @@ public:
 
   dom::Element* GetScopeElement() const { return mScopeElement; }
   void SetScopeElement(dom::Element* aScopeElement)
   {
     mScopeElement = aScopeElement;
   }
 
   // WebIDL StyleSheet API
-  // Our nsIStyleSheet::GetType is a const method, so it ends up
+  // Our CSSStyleSheet::GetType is a const method, so it ends up
   // ambiguous with with the XPCOM version.  Just disambiguate.
   void GetType(nsString& aType) {
     const_cast<const CSSStyleSheet*>(this)->GetType(aType);
   }
   // Our XPCOM GetHref is fine for WebIDL
   nsINode* GetOwnerNode() const { return mOwningNode; }
   CSSStyleSheet* GetParentStyleSheet() const { return mParent; }
-  // Our nsIStyleSheet::GetTitle is a const method, so it ends up
+  // Our CSSStyleSheet::GetTitle is a const method, so it ends up
   // ambiguous with with the XPCOM version.  Just disambiguate.
   void GetTitle(nsString& aTitle) {
     const_cast<const CSSStyleSheet*>(this)->GetTitle(aTitle);
   }
   nsMediaList* Media();
   bool Disabled() const { return mDisabled; }
   // The XPCOM SetDisabled is fine for WebIDL
 
@@ -302,17 +322,17 @@ public:
   }
 
   // WebIDL miscellaneous bits
   dom::ParentObject GetParentObject() const {
     if (mOwningNode) {
       return dom::ParentObject(mOwningNode);
     }
 
-    return dom::ParentObject(static_cast<nsIStyleSheet*>(mParent), mParent);
+    return dom::ParentObject(static_cast<nsIDOMCSSStyleSheet*>(mParent), mParent);
   }
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   // Changes to sheets should be inside of a WillDirty-DidDirty pair.
   // However, the calls do not need to be matched; it's ok to call
   // WillDirty and then make no change and skip the DidDirty call.
   void WillDirty();
   void DidDirty();
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1343,22 +1343,20 @@ Loader::InsertSheetInDoc(CSSStyleSheet* 
    * case we'll just want to append anyway.  We want to break out of
    * the loop when insertionPoint points to just before the index we
    * want to insert at.  In other words, when we leave the loop
    * insertionPoint is the index of the stylesheet that immediately
    * precedes the one we're inserting.
    */
   int32_t insertionPoint;
   for (insertionPoint = sheetCount - 1; insertionPoint >= 0; --insertionPoint) {
-    nsIStyleSheet *curSheet = aDocument->GetStyleSheetAt(insertionPoint);
+    CSSStyleSheet* curSheet = aDocument->GetStyleSheetAt(insertionPoint);
     NS_ASSERTION(curSheet, "There must be a sheet here!");
-    nsCOMPtr<nsIDOMStyleSheet> domSheet = do_QueryInterface(curSheet);
-    NS_ASSERTION(domSheet, "All the \"normal\" sheets implement nsIDOMStyleSheet");
     nsCOMPtr<nsIDOMNode> sheetOwner;
-    domSheet->GetOwnerNode(getter_AddRefs(sheetOwner));
+    curSheet->GetOwnerNode(getter_AddRefs(sheetOwner));
     if (sheetOwner && !aLinkingContent) {
       // Keep moving; all sheets with a sheetOwner come after all
       // sheets without a linkingNode
       continue;
     }
 
     if (!sheetOwner) {
       // Aha!  The current sheet has no sheet owner, so we want to
@@ -2603,17 +2601,17 @@ Loader::StartAlternateLoads()
 NS_IMPL_CYCLE_COLLECTION_CLASS(Loader)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Loader)
   if (tmp->mSheets) {
     for (auto iter = tmp->mSheets->mCompleteSheets.Iter();
          !iter.Done();
          iter.Next()) {
       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "Sheet cache nsCSSLoader");
-      cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIStyleSheet*, iter.UserData()));
+      cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, iter.UserData()));
     }
   }
   nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver>>::ForwardIterator
     it(tmp->mObservers);
   while (it.HasMore()) {
     ImplCycleCollectionTraverse(cb, it.GetNext(),
                                 "mozilla::css::Loader.mObservers");
   }
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -57,17 +57,16 @@ EXPORTS += [
     'nsDOMCSSDeclaration.h',
     'nsDOMCSSRGBColor.h',
     'nsICSSDeclaration.h',
     'nsICSSLoaderObserver.h',
     'nsICSSPseudoComparator.h',
     'nsICSSStyleRuleDOMWrapper.h',
     'nsIStyleRule.h',
     'nsIStyleRuleProcessor.h',
-    'nsIStyleSheet.h',
     'nsLayoutStylesheetCache.h',
     'nsRuleData.h',
     'nsRuleNode.h',
     'nsRuleProcessorData.h',
     'nsRuleWalker.h',
     'nsStyleConsts.h',
     'nsStyleContext.h',
     'nsStyleCoord.h',
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -287,27 +287,26 @@ nsDOMCSSDeclaration::RemoveProperty(cons
 
   return RemoveProperty(propID);
 }
 
 /* static */ void
 nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(css::Rule* aRule,
                                                      CSSParsingEnvironment& aCSSParseEnv)
 {
-  nsIStyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nullptr;
-  RefPtr<CSSStyleSheet> cssSheet(do_QueryObject(sheet));
-  if (!cssSheet) {
+  CSSStyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nullptr;
+  if (!sheet) {
     aCSSParseEnv.mPrincipal = nullptr;
     return;
   }
 
   nsIDocument* document = sheet->GetOwningDocument();
   aCSSParseEnv.mSheetURI = sheet->GetSheetURI();
   aCSSParseEnv.mBaseURI = sheet->GetBaseURI();
-  aCSSParseEnv.mPrincipal = cssSheet->Principal();
+  aCSSParseEnv.mPrincipal = sheet->Principal();
   aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nullptr;
 }
 
 nsresult
 nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
                                         const nsAString& aPropValue,
                                         bool aIsImportant)
 {
deleted file mode 100644
--- a/layout/style/nsIStyleSheet.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-/*
- * interface representing a collection of style data attached to a
- * document, which may be or be combined into a style rule processor
- */
-
-#ifndef nsIStyleSheet_h___
-#define nsIStyleSheet_h___
-
-#include "mozilla/MemoryReporting.h"
-#include <stdio.h>
-#include "nsISupports.h"
-
-class nsString;
-class nsIURI;
-class nsIDocument;
-
-// IID for the nsIStyleSheet interface
-// 3eb34a60-04bd-41d9-9f60-882694e61c38
-#define NS_ISTYLE_SHEET_IID     \
-{ 0x3eb34a60, 0x04bd, 0x41d9,   \
- { 0x9f, 0x60, 0x88, 0x26, 0x94, 0xe6, 0x1c, 0x38 } }
-
-/**
- * A style sheet is a thing associated with a document that has style
- * rules.  Those style rules can be reached in one of two ways, depending
- * on which level of the nsStyleSet it is in:
- *   1) It can be |QueryInterface|d to nsIStyleRuleProcessor
- *   2) It can be |QueryInterface|d to CSSStyleSheet, with which the
- *      |nsStyleSet| uses an |nsCSSRuleProcessor| to access the rules.
- */
-class nsIStyleSheet : public nsISupports {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLE_SHEET_IID)
-
-  // basic style sheet data
-  virtual nsIURI* GetSheetURI() const = 0;
-  virtual nsIURI* GetBaseURI() const = 0;
-  virtual void GetTitle(nsString& aTitle) const = 0;
-  virtual void GetType(nsString& aType) const = 0;
-  virtual bool HasRules() const = 0;
-
-  /**
-   * Whether the sheet is applicable.  A sheet that is not applicable
-   * should never be inserted into a style set.  A sheet may not be
-   * applicable for a variety of reasons including being disabled and
-   * being incomplete.
-   *
-   */
-  virtual bool IsApplicable() const = 0;
-
-  /**
-   * Set the stylesheet to be enabled.  This may or may not make it
-   * applicable.  Note that this WILL inform the sheet's document of
-   * its new applicable state if the state changes but WILL NOT call
-   * BeginUpdate() or EndUpdate() on the document -- calling those is
-   * the caller's responsibility.  This allows use of SetEnabled when
-   * batched updates are desired.  If you want updates handled for
-   * you, see nsIDOMStyleSheet::SetDisabled().
-   */
-  virtual void SetEnabled(bool aEnabled) = 0;
-
-  /**
-   * Whether the sheet is complete.
-   */
-  virtual bool IsComplete() const = 0;
-  virtual void SetComplete() = 0;
-
-  // style sheet owner info
-  virtual nsIStyleSheet* GetParentSheet() const = 0;  // may be null
-  virtual nsIDocument* GetOwningDocument() const = 0; // may be null
-  virtual void SetOwningDocument(nsIDocument* aDocument) = 0;
-
-#ifdef DEBUG
-  virtual void List(FILE* out = stdout, int32_t aIndent = 0) const = 0;
-#endif
-
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIStyleSheet, NS_ISTYLE_SHEET_IID)
-
-#endif /* nsIStyleSheet_h___ */
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -192,18 +192,18 @@ nsStyleSet::nsStyleSet()
     mDirty(0),
     mUnusedRuleNodeCount(0)
 {
 }
 
 nsStyleSet::~nsStyleSet()
 {
   for (SheetType type : gCSSSheetTypes) {
-    for (uint32_t i = 0, n = mSheets[type].Length(); i < n; i++) {
-      static_cast<CSSStyleSheet*>(mSheets[type][i])->DropStyleSet(this);
+    for (CSSStyleSheet* sheet : mSheets[type]) {
+      sheet->DropStyleSet(this);
     }
   }
 
   // drop reference to cached rule processors
   nsCSSRuleProcessor* rp;
   rp = static_cast<nsCSSRuleProcessor*>(mRuleProcessors[SheetType::Agent].get());
   if (rp) {
     MOZ_ASSERT(rp->IsShared());
@@ -229,22 +229,19 @@ nsStyleSet::SizeOfIncludingThis(MallocSi
         nsCSSRuleProcessor* rp =
           static_cast<nsCSSRuleProcessor*>(mRuleProcessors[type].get());
         shared = rp->IsShared();
       }
       if (!shared) {
         n += mRuleProcessors[type]->SizeOfIncludingThis(aMallocSizeOf);
       }
     }
-    // mSheets is a C-style array of nsCOMArrays.  We do not own the sheets in
-    // the nsCOMArrays (either the nsLayoutStyleSheetCache singleton or our
-    // document owns them) so we do not count the sheets here (we pass nullptr
-    // as the aSizeOfElementIncludingThis argument).  All we're doing here is
-    // counting the size of the nsCOMArrays' buffers.
-    n += mSheets[type].SizeOfExcludingThis(nullptr, aMallocSizeOf);
+    // We don't own the sheets (either the nsLayoutStyleSheetCache singleton
+    // or our document owns them).
+    n += mSheets[type].ShallowSizeOfExcludingThis(aMallocSizeOf);
   }
 
   for (uint32_t i = 0; i < mScopedDocSheetRuleProcessors.Length(); i++) {
     n += mScopedDocSheetRuleProcessors[i]->SizeOfIncludingThis(aMallocSizeOf);
   }
   n += mScopedDocSheetRuleProcessors.ShallowSizeOfExcludingThis(aMallocSizeOf);
 
   n += mRoots.ShallowSizeOfExcludingThis(aMallocSizeOf);
@@ -445,18 +442,17 @@ nsStyleSet::GatherRuleProcessors(SheetTy
                                aType == SheetType::ScopedDoc ||
                                aType == SheetType::StyleAttr)) {
     // Don't regather if this level is disabled.  Note that we gather
     // preshint sheets no matter what, but then skip them for some
     // elements later if mAuthorStyleDisabled.
     return NS_OK;
   }
   switch (aType) {
-    // handle the types for which have a rule processor that does not
-    // implement the style sheet interface.
+    // levels that do not contain CSS style sheets
     case SheetType::Animation:
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] = PresContext()->AnimationManager();
       return NS_OK;
     case SheetType::Transition:
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] = PresContext()->TransitionManager();
       return NS_OK;
@@ -473,27 +469,26 @@ nsStyleSet::GatherRuleProcessors(SheetTy
       MOZ_ASSERT(mSheets[aType].IsEmpty());
       mRuleProcessors[aType] =
         PresContext()->Document()->GetSVGAttrAnimationRuleProcessor();
       return NS_OK;
     default:
       // keep going
       break;
   }
+  MOZ_ASSERT(IsCSSSheetType(aType));
   if (aType == SheetType::ScopedDoc) {
     // Create a rule processor for each scope.
-    uint32_t count = mSheets[SheetType::ScopedDoc].Count();
+    uint32_t count = mSheets[SheetType::ScopedDoc].Length();
     if (count) {
       // Gather the scoped style sheets into an array as
       // CSSStyleSheets, and mark all of their scope elements
       // as scoped style roots.
       nsTArray<CSSStyleSheet*> sheets(count);
-      for (uint32_t i = 0; i < count; i++) {
-        RefPtr<CSSStyleSheet> sheet =
-          do_QueryObject(mSheets[SheetType::ScopedDoc].ObjectAt(i));
+      for (CSSStyleSheet* sheet : mSheets[SheetType::ScopedDoc]) {
         sheets.AppendElement(sheet);
 
         Element* scope = sheet->GetScopeElement();
         scope->SetIsScopedStyleRoot();
       }
 
       // Sort the scoped style sheets so that those for the same scope are
       // adjacent and that ancestor scopes come before descendent scopes.
@@ -532,180 +527,151 @@ nsStyleSet::GatherRuleProcessors(SheetTy
         mScopedDocSheetRuleProcessors.AppendElement
           (new nsCSSRuleProcessor(sheetsForScope, aType, scope, oldRP));
 
         start = end;
       } while (start < count);
     }
     return NS_OK;
   }
-  if (mSheets[aType].Count()) {
+  if (!mSheets[aType].IsEmpty()) {
     switch (aType) {
       case SheetType::Agent:
       case SheetType::User: {
         // levels containing non-scoped CSS style sheets whose rule processors
         // we want to re-use
-        nsCOMArray<nsIStyleSheet>& sheets = mSheets[aType];
-        nsTArray<RefPtr<CSSStyleSheet>> cssSheets(sheets.Count());
-        for (int32_t i = 0, i_end = sheets.Count(); i < i_end; ++i) {
-          RefPtr<CSSStyleSheet> cssSheet = do_QueryObject(sheets[i]);
-          NS_ASSERTION(cssSheet, "not a CSS sheet");
-          cssSheets.AppendElement(cssSheet);
-        }
-        nsTArray<CSSStyleSheet*> cssSheetsRaw(cssSheets.Length());
-        for (int32_t i = 0, i_end = cssSheets.Length(); i < i_end; ++i) {
-          cssSheetsRaw.AppendElement(cssSheets[i]);
+        nsTArray<CSSStyleSheet*> sheets(mSheets[aType].Length());
+        for (CSSStyleSheet* sheet : mSheets[aType]) {
+          sheets.AppendElement(sheet);
         }
         nsCSSRuleProcessor* rp =
-          RuleProcessorCache::GetRuleProcessor(cssSheetsRaw, PresContext());
+          RuleProcessorCache::GetRuleProcessor(sheets, PresContext());
         if (!rp) {
-          rp = new nsCSSRuleProcessor(cssSheets, aType, nullptr,
+          rp = new nsCSSRuleProcessor(mSheets[aType], aType, nullptr,
                                       static_cast<nsCSSRuleProcessor*>(
                                        oldRuleProcessor.get()),
                                       true /* aIsShared */);
           nsTArray<css::DocumentRule*> documentRules;
           nsDocumentRuleResultCacheKey cacheKey;
           rp->TakeDocumentRulesAndCacheKey(PresContext(),
                                            documentRules, cacheKey);
-          RuleProcessorCache::PutRuleProcessor(cssSheetsRaw,
+          RuleProcessorCache::PutRuleProcessor(sheets,
                                                Move(documentRules),
                                                cacheKey, rp);
         }
         mRuleProcessors[aType] = rp;
         rp->AddStyleSetRef();
         break;
       }
       case SheetType::Doc:
       case SheetType::Override: {
         // levels containing non-scoped CSS stylesheets whose rule processors
         // we don't want to re-use
-        nsCOMArray<nsIStyleSheet>& sheets = mSheets[aType];
-        nsTArray<RefPtr<CSSStyleSheet>> cssSheets(sheets.Count());
-        for (int32_t i = 0, i_end = sheets.Count(); i < i_end; ++i) {
-          RefPtr<CSSStyleSheet> cssSheet = do_QueryObject(sheets[i]);
-          NS_ASSERTION(cssSheet, "not a CSS sheet");
-          cssSheets.AppendElement(cssSheet);
-        }
         mRuleProcessors[aType] =
-          new nsCSSRuleProcessor(cssSheets, aType, nullptr,
+          new nsCSSRuleProcessor(mSheets[aType], aType, nullptr,
                                  static_cast<nsCSSRuleProcessor*>(
                                    oldRuleProcessor.get()));
       } break;
 
       default:
-        // levels containing non-CSS stylesheets
-        NS_ASSERTION(mSheets[aType].Count() == 1, "only one sheet per level");
-        mRuleProcessors[aType] = do_QueryInterface(mSheets[aType][0]);
+        MOZ_ASSERT_UNREACHABLE("non-CSS sheet types should be handled above");
         break;
     }
   }
 
   return NS_OK;
 }
 
-static bool
-IsScopedStyleSheet(nsIStyleSheet* aSheet)
-{
-  RefPtr<CSSStyleSheet> cssSheet = do_QueryObject(aSheet);
-  NS_ASSERTION(cssSheet, "expected aSheet to be a CSSStyleSheet");
-
-  return cssSheet->GetScopeElement();
-}
-
 nsresult
-nsStyleSet::AppendStyleSheet(SheetType aType, nsIStyleSheet *aSheet)
+nsStyleSet::AppendStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   NS_ASSERTION(aSheet->IsApplicable(),
                "Inapplicable sheet being placed in style set");
-  bool present = mSheets[aType].RemoveObject(aSheet);
-  if (!mSheets[aType].AppendObject(aSheet))
-    return NS_ERROR_OUT_OF_MEMORY;
+  bool present = mSheets[aType].RemoveElement(aSheet);
+  mSheets[aType].AppendElement(aSheet);
 
   if (!present && IsCSSSheetType(aType)) {
-    static_cast<CSSStyleSheet*>(aSheet)->AddStyleSet(this);
+    aSheet->AddStyleSet(this);
   }
 
   return DirtyRuleProcessors(aType);
 }
 
 nsresult
-nsStyleSet::PrependStyleSheet(SheetType aType, nsIStyleSheet *aSheet)
+nsStyleSet::PrependStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   NS_ASSERTION(aSheet->IsApplicable(),
                "Inapplicable sheet being placed in style set");
-  bool present = mSheets[aType].RemoveObject(aSheet);
-  if (!mSheets[aType].InsertObjectAt(aSheet, 0))
-    return NS_ERROR_OUT_OF_MEMORY;
+  bool present = mSheets[aType].RemoveElement(aSheet);
+  mSheets[aType].InsertElementAt(0, aSheet);
 
   if (!present && IsCSSSheetType(aType)) {
-    static_cast<CSSStyleSheet*>(aSheet)->AddStyleSet(this);
+    aSheet->AddStyleSet(this);
   }
 
   return DirtyRuleProcessors(aType);
 }
 
 nsresult
-nsStyleSet::RemoveStyleSheet(SheetType aType, nsIStyleSheet *aSheet)
+nsStyleSet::RemoveStyleSheet(SheetType aType, CSSStyleSheet* aSheet)
 {
   NS_PRECONDITION(aSheet, "null arg");
   NS_ASSERTION(aSheet->IsComplete(),
                "Incomplete sheet being removed from style set");
-  if (mSheets[aType].RemoveObject(aSheet)) {
+  if (mSheets[aType].RemoveElement(aSheet)) {
     if (IsCSSSheetType(aType)) {
-      static_cast<CSSStyleSheet*>(aSheet)->DropStyleSet(this);
+      aSheet->DropStyleSet(this);
     }
   }
 
   return DirtyRuleProcessors(aType);
 }
 
 nsresult
 nsStyleSet::ReplaceSheets(SheetType aType,
-                          const nsCOMArray<nsIStyleSheet> &aNewSheets)
+                          const nsTArray<RefPtr<CSSStyleSheet>>& aNewSheets)
 {
   bool cssSheetType = IsCSSSheetType(aType);
   if (cssSheetType) {
-    for (uint32_t i = 0, n = mSheets[aType].Length(); i < n; i++) {
-      static_cast<CSSStyleSheet*>(mSheets[aType][i])->DropStyleSet(this);
+    for (CSSStyleSheet* sheet : mSheets[aType]) {
+      sheet->DropStyleSet(this);
     }
   }
 
   mSheets[aType].Clear();
-  if (!mSheets[aType].AppendObjects(aNewSheets))
-    return NS_ERROR_OUT_OF_MEMORY;
+  mSheets[aType].AppendElements(aNewSheets);
 
   if (cssSheetType) {
-    for (uint32_t i = 0, n = mSheets[aType].Length(); i < n; i++) {
-      static_cast<CSSStyleSheet*>(mSheets[aType][i])->AddStyleSet(this);
+    for (CSSStyleSheet* sheet : mSheets[aType]) {
+      sheet->AddStyleSet(this);
     }
   }
 
   return DirtyRuleProcessors(aType);
 }
 
 nsresult
-nsStyleSet::InsertStyleSheetBefore(SheetType aType, nsIStyleSheet *aNewSheet,
-                                   nsIStyleSheet *aReferenceSheet)
+nsStyleSet::InsertStyleSheetBefore(SheetType aType, CSSStyleSheet* aNewSheet,
+                                   CSSStyleSheet* aReferenceSheet)
 {
   NS_PRECONDITION(aNewSheet && aReferenceSheet, "null arg");
   NS_ASSERTION(aNewSheet->IsApplicable(),
                "Inapplicable sheet being placed in style set");
 
-  bool present = mSheets[aType].RemoveObject(aNewSheet);
+  bool present = mSheets[aType].RemoveElement(aNewSheet);
   int32_t idx = mSheets[aType].IndexOf(aReferenceSheet);
   if (idx < 0)
     return NS_ERROR_INVALID_ARG;
 
-  if (!mSheets[aType].InsertObjectAt(aNewSheet, idx))
-    return NS_ERROR_OUT_OF_MEMORY;
+  mSheets[aType].InsertElementAt(idx, aNewSheet);
 
   if (!present && IsCSSSheetType(aType)) {
-    static_cast<CSSStyleSheet*>(aNewSheet)->AddStyleSet(this);
+    aNewSheet->AddStyleSet(this);
   }
 
   return DirtyRuleProcessors(aType);
 }
 
 static inline uint32_t
 DirtyBit(SheetType aType)
 {
@@ -740,66 +706,71 @@ nsStyleSet::SetAuthorStyleDisabled(bool 
     return EndUpdate();
   }
   return NS_OK;
 }
 
 // -------- Doc Sheets
 
 nsresult
-nsStyleSet::AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument)
+nsStyleSet::AddDocStyleSheet(CSSStyleSheet* aSheet, nsIDocument* aDocument)
 {
   NS_PRECONDITION(aSheet && aDocument, "null arg");
   NS_ASSERTION(aSheet->IsApplicable(),
                "Inapplicable sheet being placed in style set");
 
-  SheetType type = IsScopedStyleSheet(aSheet) ?
+  SheetType type = aSheet->GetScopeElement() ?
                      SheetType::ScopedDoc :
                      SheetType::Doc;
-  nsCOMArray<nsIStyleSheet>& sheets = mSheets[type];
+  nsTArray<RefPtr<CSSStyleSheet>>& sheets = mSheets[type];
 
-  bool present = sheets.RemoveObject(aSheet);
+  bool present = sheets.RemoveElement(aSheet);
   nsStyleSheetService *sheetService = nsStyleSheetService::GetInstance();
 
   // lowest index first
   int32_t newDocIndex = aDocument->GetIndexOfStyleSheet(aSheet);
 
-  int32_t count = sheets.Count();
+  int32_t count = sheets.Length();
   int32_t index;
   for (index = 0; index < count; index++) {
-    nsIStyleSheet* sheet = sheets.ObjectAt(index);
+    CSSStyleSheet* sheet = sheets[index];
     int32_t sheetDocIndex = aDocument->GetIndexOfStyleSheet(sheet);
     if (sheetDocIndex > newDocIndex)
       break;
 
     // If the sheet is not owned by the document it can be an author
     // sheet registered at nsStyleSheetService or an additional author
     // sheet on the document, which means the new 
     // doc sheet should end up before it.
-    if (sheetDocIndex < 0 &&
-        ((sheetService &&
-        sheetService->AuthorStyleSheets()->IndexOf(sheet) >= 0) ||
-        sheet == aDocument->FirstAdditionalAuthorSheet()))
+    if (sheetDocIndex < 0) {
+      if (sheetService) {
+        auto& authorSheets = *sheetService->AuthorStyleSheets();
+        if (authorSheets.IndexOf(sheet) != authorSheets.NoIndex) {
+          break;
+        }
+      }
+      if (sheet == aDocument->FirstAdditionalAuthorSheet()) {
         break;
+      }
+    }
   }
-  if (!sheets.InsertObjectAt(aSheet, index))
-    return NS_ERROR_OUT_OF_MEMORY;
+
+  sheets.InsertElementAt(index, aSheet);
 
   if (!present) {
-    static_cast<CSSStyleSheet*>(aSheet)->AddStyleSet(this);
+    aSheet->AddStyleSet(this);
   }
 
   return DirtyRuleProcessors(type);
 }
 
 nsresult
-nsStyleSet::RemoveDocStyleSheet(nsIStyleSheet *aSheet)
+nsStyleSet::RemoveDocStyleSheet(CSSStyleSheet* aSheet)
 {
-  RefPtr<CSSStyleSheet> cssSheet = do_QueryObject(aSheet);
-  bool isScoped = cssSheet && cssSheet->GetScopeElement();
+  bool isScoped = aSheet->GetScopeElement();
   return RemoveStyleSheet(isScoped ? SheetType::ScopedDoc : SheetType::Doc,
                           aSheet);
 }
 
 // Batching
 void
 nsStyleSet::BeginUpdate()
 {
@@ -2491,20 +2462,18 @@ nsStyleSet::MediumFeaturesChanged()
 
   return stylesChanged;
 }
 
 bool
 nsStyleSet::EnsureUniqueInnerOnCSSSheets()
 {
   nsAutoTArray<CSSStyleSheet*, 32> queue;
-  for (uint32_t i = 0; i < ArrayLength(gCSSSheetTypes); ++i) {
-    nsCOMArray<nsIStyleSheet> &sheets = mSheets[gCSSSheetTypes[i]];
-    for (uint32_t j = 0, j_end = sheets.Count(); j < j_end; ++j) {
-      CSSStyleSheet* sheet = static_cast<CSSStyleSheet*>(sheets[j]);
+  for (SheetType type : gCSSSheetTypes) {
+    for (CSSStyleSheet* sheet : mSheets[type]) {
       queue.AppendElement(sheet);
     }
   }
 
   if (mBindingManager) {
     mBindingManager->AppendAllSheets(queue);
   }
 
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -34,16 +34,17 @@ class nsCSSPageRule;
 class nsCSSCounterStyleRule;
 class nsICSSPseudoComparator;
 class nsRuleWalker;
 struct ElementDependentRuleProcessorData;
 struct nsFontFaceRuleContainer;
 struct TreeMatchContext;
 
 namespace mozilla {
+class CSSStyleSheet;
 class EventStates;
 } // namespace mozilla
 
 class nsEmptyStyleRule final : public nsIStyleRule
 {
 private:
   ~nsEmptyStyleRule() {}
 
@@ -306,45 +307,50 @@ class nsStyleSet final
   // rules during processing.
   void SetBindingManager(nsBindingManager* aBindingManager)
   {
     mBindingManager = aBindingManager;
   }
 
   // APIs to manipulate the style sheet lists.  The sheets in each
   // list are stored with the most significant sheet last.
-  nsresult AppendStyleSheet(mozilla::SheetType aType, nsIStyleSheet *aSheet);
-  nsresult PrependStyleSheet(mozilla::SheetType aType, nsIStyleSheet *aSheet);
-  nsresult RemoveStyleSheet(mozilla::SheetType aType, nsIStyleSheet *aSheet);
+  nsresult AppendStyleSheet(mozilla::SheetType aType,
+                            mozilla::CSSStyleSheet* aSheet);
+  nsresult PrependStyleSheet(mozilla::SheetType aType,
+                             mozilla::CSSStyleSheet* aSheet);
+  nsresult RemoveStyleSheet(mozilla::SheetType aType,
+                            mozilla::CSSStyleSheet* aSheet);
   nsresult ReplaceSheets(mozilla::SheetType aType,
-                         const nsCOMArray<nsIStyleSheet> &aNewSheets);
+                         const nsTArray<RefPtr<mozilla::CSSStyleSheet>>& aNewSheets);
   nsresult InsertStyleSheetBefore(mozilla::SheetType aType,
-                                  nsIStyleSheet *aNewSheet,
-                                  nsIStyleSheet *aReferenceSheet);
+                                  mozilla::CSSStyleSheet* aNewSheet,
+                                  mozilla::CSSStyleSheet* aReferenceSheet);
 
   // Enable/Disable entire author style level (Doc, ScopedDoc & PresHint levels)
   bool GetAuthorStyleDisabled();
   nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
 
   int32_t SheetCount(mozilla::SheetType aType) const {
-    return mSheets[aType].Count();
+    return mSheets[aType].Length();
   }
 
-  nsIStyleSheet* StyleSheetAt(mozilla::SheetType aType, int32_t aIndex) const {
-    return mSheets[aType].ObjectAt(aIndex);
+  mozilla::CSSStyleSheet* StyleSheetAt(mozilla::SheetType aType,
+                                       int32_t aIndex) const {
+    return mSheets[aType][aIndex];
   }
 
   void AppendAllXBLStyleSheets(nsTArray<mozilla::CSSStyleSheet*>& aArray) const {
     if (mBindingManager) {
       mBindingManager->AppendAllSheets(aArray);
     }
   }
 
-  nsresult RemoveDocStyleSheet(nsIStyleSheet* aSheet);
-  nsresult AddDocStyleSheet(nsIStyleSheet* aSheet, nsIDocument* aDocument);
+  nsresult RemoveDocStyleSheet(mozilla::CSSStyleSheet* aSheet);
+  nsresult AddDocStyleSheet(mozilla::CSSStyleSheet* aSheet,
+                            nsIDocument* aDocument);
 
   void     BeginUpdate();
   nsresult EndUpdate();
 
   // Methods for reconstructing the tree; BeginReconstruct basically moves the
   // old rule tree root and style context roots out of the way,
   // and EndReconstruct destroys the old rule tree when we're done
   nsresult BeginReconstruct();
@@ -468,17 +474,17 @@ private:
   nsPresContext* PresContext() { return mRuleTree->PresContext(); }
 
   // The sheets in each array in mSheets are stored with the most significant
   // sheet last.
   // The arrays for ePresHintSheet, eStyleAttrSheet, eTransitionSheet,
   // eAnimationSheet and eSVGAttrAnimationSheet are always empty.
   // (FIXME:  We should reduce the storage needed for them.)
   mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
-                           nsCOMArray<nsIStyleSheet>> mSheets;
+                           nsTArray<RefPtr<mozilla::CSSStyleSheet>>> mSheets;
 
   // mRuleProcessors[eScopedDocSheet] is always null; rule processors
   // for scoped style sheets are stored in mScopedDocSheetRuleProcessors.
   mozilla::EnumeratedArray<mozilla::SheetType, mozilla::SheetType::Count,
                            nsCOMPtr<nsIStyleRuleProcessor>> mRuleProcessors;
 
   // Rule processors for HTML5 scoped style sheets, one per scope.
   nsTArray<nsCOMPtr<nsIStyleRuleProcessor> > mScopedDocSheetRuleProcessors;