Bug 990250 - Fold nsIStyleSheet into CSSStyleSheet. r=dbaron
authorCameron McCormack <cam@mcc.id.au>
Tue, 17 Nov 2015 17:04:09 +1100
changeset 272917 5160a4dfba49bde4a8af379a2e1320766560df8c
parent 272916 a56e745bf9fe5ee9aaa22b8176e5d4852e7db955
child 272918 2f103f5a44ffcbef4fc27617a6a6431b96699631
push id29688
push userkwierso@gmail.com
push dateTue, 17 Nov 2015 21:10:09 +0000
treeherdermozilla-central@eed903a7e4e7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs990250
milestone45.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 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;