Bug 1025725 - Part 3: Encapsulate nsXBLPrototypeResources::mStyleSheetList. r=bzbarsky, a=sledru
authorCameron McCormack <cam@mcc.id.au>
Thu, 19 Jun 2014 17:02:56 +1000
changeset 201040 9e809dfdf2ae
parent 201039 df0670536f69
child 201041 a917c02f2145
push id6426
push userryanvm@gmail.com
push dateThu, 10 Jul 2014 13:15:51 +0000
treeherdermozilla-aurora@4c63c27ed22d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, sledru
bugs1025725
milestone32.0a2
Bug 1025725 - Part 3: Encapsulate nsXBLPrototypeResources::mStyleSheetList. r=bzbarsky, a=sledru
content/base/src/ShadowRoot.cpp
dom/xbl/nsBindingManager.cpp
dom/xbl/nsXBLPrototypeBinding.cpp
dom/xbl/nsXBLPrototypeBinding.h
dom/xbl/nsXBLPrototypeResources.cpp
dom/xbl/nsXBLPrototypeResources.h
dom/xbl/nsXBLResourceLoader.cpp
--- a/content/base/src/ShadowRoot.cpp
+++ b/content/base/src/ShadowRoot.cpp
@@ -142,50 +142,40 @@ ShadowRoot::InsertSheet(nsCSSStyleSheet*
 {
   nsCOMPtr<nsIStyleSheetLinkingElement>
     linkingElement = do_QueryInterface(aLinkingContent);
   MOZ_ASSERT(linkingElement, "The only styles in a ShadowRoot should come "
                              "from <style>.");
 
   linkingElement->SetStyleSheet(aSheet); // This sets the ownerNode on the sheet
 
-  nsTArray<nsRefPtr<nsCSSStyleSheet> >* sheets =
-    mProtoBinding->GetOrCreateStyleSheets();
-  MOZ_ASSERT(sheets, "Style sheets array should never be null.");
-
   // Find the correct position to insert into the style sheet list (must
   // be in tree order).
-  for (uint32_t i = 0; i <= sheets->Length(); i++) {
-    if (i == sheets->Length()) {
-      sheets->AppendElement(aSheet);
+  for (size_t i = 0; i <= mProtoBinding->SheetCount(); i++) {
+    if (i == mProtoBinding->SheetCount()) {
+      mProtoBinding->AppendStyleSheet(aSheet);
       break;
     }
 
-    nsINode* sheetOwnerNode = sheets->ElementAt(i)->GetOwnerNode();
+    nsINode* sheetOwnerNode = mProtoBinding->StyleSheetAt(i)->GetOwnerNode();
     if (nsContentUtils::PositionIsBefore(aLinkingContent, sheetOwnerNode)) {
-      sheets->InsertElementAt(i, aSheet);
+      mProtoBinding->InsertStyleSheetAt(i, aSheet);
       break;
     }
   }
 
   if (aSheet->IsApplicable()) {
     StyleSheetChanged();
   }
 }
 
 void
 ShadowRoot::RemoveSheet(nsCSSStyleSheet* aSheet)
 {
-  nsTArray<nsRefPtr<nsCSSStyleSheet> >* sheets =
-    mProtoBinding->GetOrCreateStyleSheets();
-  MOZ_ASSERT(sheets, "Style sheets array should never be null.");
-
-  DebugOnly<bool> found = sheets->RemoveElement(aSheet);
-  MOZ_ASSERT(found, "Trying to remove a sheet from a ShadowRoot "
-                    "that does not exist.");
+  mProtoBinding->RemoveStyleSheet(aSheet);
 
   if (aSheet->IsApplicable()) {
     StyleSheetChanged();
   }
 }
 
 Element*
 ShadowRoot::GetElementById(const nsAString& aElementId)
@@ -727,33 +717,23 @@ ShadowRootStyleSheetList::ShadowRootStyl
 ShadowRootStyleSheetList::~ShadowRootStyleSheetList()
 {
   MOZ_COUNT_DTOR(ShadowRootStyleSheetList);
 }
 
 nsCSSStyleSheet*
 ShadowRootStyleSheetList::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
-  nsTArray<nsRefPtr<nsCSSStyleSheet>>* sheets =
-    mShadowRoot->mProtoBinding->GetStyleSheets();
+  aFound = aIndex < mShadowRoot->mProtoBinding->SheetCount();
 
-  if (!sheets) {
-    aFound = false;
+  if (!aFound) {
     return nullptr;
   }
 
-  aFound = aIndex < sheets->Length();
-  return sheets->SafeElementAt(aIndex);
+  return mShadowRoot->mProtoBinding->StyleSheetAt(aIndex);
 }
 
 uint32_t
 ShadowRootStyleSheetList::Length()
 {
-  nsTArray<nsRefPtr<nsCSSStyleSheet> >* sheets =
-    mShadowRoot->mProtoBinding->GetStyleSheets();
-
-  if (!sheets) {
-    return 0;
-  }
-
-  return sheets->Length();
+  return mShadowRoot->mProtoBinding->SheetCount();
 }
 
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -812,23 +812,17 @@ nsBindingManager::MediumFeaturesChanged(
 static PLDHashOperator
 EnumAppendAllSheets(nsRefPtrHashKey<nsIContent> *aKey, void* aClosure)
 {
   nsIContent *boundContent = aKey->GetKey();
   nsTArray<nsCSSStyleSheet*>* array =
     static_cast<nsTArray<nsCSSStyleSheet*>*>(aClosure);
   for (nsXBLBinding *binding = boundContent->GetXBLBinding(); binding;
        binding = binding->GetBaseBinding()) {
-    nsXBLPrototypeResources::sheet_array_type* sheets =
-      binding->PrototypeBinding()->GetStyleSheets();
-    if (sheets) {
-      // Copy from nsTArray<nsRefPtr<nsCSSStyleSheet> > to
-      // nsTArray<nsCSSStyleSheet*>.
-      array->AppendElements(*sheets);
-    }
+    binding->PrototypeBinding()->AppendStyleSheetsTo(*array);
   }
   return PL_DHASH_NEXT;
 }
 
 void
 nsBindingManager::AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray)
 {
   if (mBoundContentSet) {
--- a/dom/xbl/nsXBLPrototypeBinding.cpp
+++ b/dom/xbl/nsXBLPrototypeBinding.cpp
@@ -225,19 +225,17 @@ nsXBLPrototypeBinding::LoadResources()
   }
 
   return true;
 }
 
 nsresult
 nsXBLPrototypeBinding::AddResource(nsIAtom* aResourceType, const nsAString& aSrc)
 {
-  if (!mResources) {
-    mResources = new nsXBLPrototypeResources(this);
-  }
+  EnsureResources();
 
   mResources->AddResource(aResourceType, aSrc);
   return NS_OK;
 }
 
 nsresult
 nsXBLPrototypeBinding::FlushSkinSheets()
 {
@@ -585,36 +583,16 @@ nsXBLPrototypeBinding::GetRuleProcessor(
 {
   if (mResources) {
     return mResources->GetRuleProcessor();
   }
 
   return nullptr;
 }
 
-nsXBLPrototypeResources::sheet_array_type*
-nsXBLPrototypeBinding::GetOrCreateStyleSheets()
-{
-  if (!mResources) {
-    mResources = new nsXBLPrototypeResources(this);
-  }
-
-  return &mResources->mStyleSheetList;
-}
-
-nsXBLPrototypeResources::sheet_array_type*
-nsXBLPrototypeBinding::GetStyleSheets()
-{
-  if (mResources) {
-    return &mResources->mStyleSheetList;
-  }
-
-  return nullptr;
-}
-
 void
 nsXBLPrototypeBinding::EnsureAttributeTable()
 {
   if (!mAttributeTable) {
     mAttributeTable = new nsClassHashtable<nsUint32HashKey, InnerAttributeTable>(4);
   }
 }
 
@@ -1693,8 +1671,68 @@ nsXBLPrototypeBinding::ResolveBaseBindin
 
     return NS_NewURI(getter_AddRefs(mBaseBindingURI), value,
                      doc->GetDocumentCharacterSet().get(),
                      doc->GetDocBaseURI());
   }
 
   return NS_OK;
 }
+
+void
+nsXBLPrototypeBinding::EnsureResources()
+{
+  if (!mResources) {
+    mResources = new nsXBLPrototypeResources(this);
+  }
+}
+
+void
+nsXBLPrototypeBinding::AppendStyleSheet(nsCSSStyleSheet* aSheet)
+{
+  EnsureResources();
+  mResources->AppendStyleSheet(aSheet);
+}
+
+void
+nsXBLPrototypeBinding::RemoveStyleSheet(nsCSSStyleSheet* aSheet)
+{
+  if (!mResources) {
+    MOZ_ASSERT(false, "Trying to remove a sheet that does not exist.");
+    return;
+  }
+
+  mResources->RemoveStyleSheet(aSheet);
+} 
+void
+nsXBLPrototypeBinding::InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet)
+{
+  EnsureResources();
+  mResources->InsertStyleSheetAt(aIndex, aSheet);
+}
+
+nsCSSStyleSheet*
+nsXBLPrototypeBinding::StyleSheetAt(size_t aIndex) const
+{
+  MOZ_ASSERT(mResources);
+  return mResources->StyleSheetAt(aIndex);
+}
+
+size_t
+nsXBLPrototypeBinding::SheetCount() const
+{
+  return mResources ? mResources->SheetCount() : 0;
+}
+
+bool
+nsXBLPrototypeBinding::HasStyleSheets() const
+{
+  return mResources && mResources->HasStyleSheets();
+}
+
+void
+nsXBLPrototypeBinding::AppendStyleSheetsTo(
+                                      nsTArray<nsCSSStyleSheet*>& aResult) const
+{
+  if (mResources) {
+    mResources->AppendStyleSheetsTo(aResult);
+  }
+}
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -108,23 +108,25 @@ public:
   void SetBasePrototype(nsXBLPrototypeBinding* aBinding);
   nsXBLPrototypeBinding* GetBasePrototype() { return mBaseBinding; }
 
   nsXBLDocumentInfo* XBLDocumentInfo() const { return mXBLDocInfoWeak; }
   bool IsChrome() { return mXBLDocInfoWeak->IsChrome(); }
 
   void SetInitialAttributes(nsIContent* aBoundElement, nsIContent* aAnonymousContent);
 
-  nsIStyleRuleProcessor* GetRuleProcessor();
-  nsXBLPrototypeResources::sheet_array_type* GetOrCreateStyleSheets();
-  nsXBLPrototypeResources::sheet_array_type* GetStyleSheets();
+  void AppendStyleSheet(nsCSSStyleSheet* aSheet);
+  void RemoveStyleSheet(nsCSSStyleSheet* aSheet);
+  void InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet);
+  nsCSSStyleSheet* StyleSheetAt(size_t aIndex) const;
+  size_t SheetCount() const;
+  bool HasStyleSheets() const;
+  void AppendStyleSheetsTo(nsTArray<nsCSSStyleSheet*>& aResult) const;
 
-  bool HasStyleSheets() {
-    return mResources && mResources->mStyleSheetList.Length() > 0;
-  }
+  nsIStyleRuleProcessor* GetRuleProcessor();
 
   nsresult FlushSkinSheets();
 
   nsIAtom* GetBaseTag(int32_t* aNamespaceID);
   void SetBaseTag(int32_t aNamespaceID, nsIAtom* aTag);
 
   bool ImplementsInterface(REFNSIID aIID) const;
 
@@ -259,16 +261,19 @@ protected:
   void EnsureAttributeTable();
   // Ad an entry to the attribute table
   void AddToAttributeTable(int32_t aSourceNamespaceID, nsIAtom* aSourceTag,
                            int32_t aDestNamespaceID, nsIAtom* aDestTag,
                            nsIContent* aContent);
   void ConstructAttributeTable(nsIContent* aElement);
   void CreateKeyHandlers();
 
+private:
+  void EnsureResources();
+
 // MEMBER VARIABLES
 protected:
   nsCOMPtr<nsIURI> mBindingURI;
   nsCOMPtr<nsIURI> mAlternateBindingURI; // Alternate id-less URI that is only non-null on the first binding.
   nsCOMPtr<nsIContent> mBinding; // Strong. We own a ref to our content element in the binding doc.
   nsAutoPtr<nsXBLPrototypeHandler> mPrototypeHandler; // Strong. DocInfo owns us, and we own the handlers.
 
   // the url of the base binding
--- a/dom/xbl/nsXBLPrototypeResources.cpp
+++ b/dom/xbl/nsXBLPrototypeResources.cpp
@@ -12,17 +12,19 @@
 #include "nsXBLPrototypeBinding.h"
 #include "nsIDocumentObserver.h"
 #include "mozilla/css/Loader.h"
 #include "nsIURI.h"
 #include "nsLayoutCID.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsStyleSet.h"
 #include "mozilla/dom/URL.h"
+#include "mozilla/DebugOnly.h"
 
+using namespace mozilla;
 using mozilla::dom::IsChromeURI;
 
 nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding)
 {
   MOZ_COUNT_CTOR(nsXBLPrototypeResources);
 
   mLoader = new nsXBLResourceLoader(aBinding, this);
 }
@@ -73,23 +75,23 @@ nsXBLPrototypeResources::FlushSkinSheets
     return NS_OK;
   }
 
   // We have scoped stylesheets.  Reload any chrome stylesheets we
   // encounter.  (If they aren't skin sheets, it doesn't matter, since
   // they'll still be in the chrome cache.
   mRuleProcessor = nullptr;
 
-  sheet_array_type oldSheets(mStyleSheetList);
-  mStyleSheetList.Clear();
+  nsTArray<nsRefPtr<nsCSSStyleSheet>> oldSheets;
+
+  oldSheets.SwapElements(mStyleSheetList);
 
   mozilla::css::Loader* cssLoader = doc->CSSLoader();
 
-  for (sheet_array_type::size_type i = 0, count = oldSheets.Length();
-       i < count; ++i) {
+  for (size_t i = 0, count = oldSheets.Length(); i < count; ++i) {
     nsCSSStyleSheet* oldSheet = oldSheets[i];
 
     nsIURI* uri = oldSheet->GetSheetURI();
 
     nsRefPtr<nsCSSStyleSheet> newSheet;
     if (IsChromeURI(uri)) {
       if (NS_FAILED(cssLoader->LoadSheetSync(uri, getter_AddRefs(newSheet))))
         continue;
@@ -129,8 +131,52 @@ nsXBLPrototypeResources::ClearLoader()
 
 void
 nsXBLPrototypeResources::GatherRuleProcessor()
 {
   mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList,
                                           nsStyleSet::eDocSheet,
                                           nullptr);
 }
+
+void
+nsXBLPrototypeResources::AppendStyleSheet(nsCSSStyleSheet* aSheet)
+{
+  mStyleSheetList.AppendElement(aSheet);
+}
+
+void
+nsXBLPrototypeResources::RemoveStyleSheet(nsCSSStyleSheet* aSheet)
+{
+  DebugOnly<bool> found = mStyleSheetList.RemoveElement(aSheet);
+  MOZ_ASSERT(found, "Trying to remove a sheet that does not exist.");
+}
+
+void
+nsXBLPrototypeResources::InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet)
+{
+  mStyleSheetList.InsertElementAt(aIndex, aSheet);
+}
+
+nsCSSStyleSheet*
+nsXBLPrototypeResources::StyleSheetAt(size_t aIndex) const
+{
+  return mStyleSheetList[aIndex];
+}
+
+size_t
+nsXBLPrototypeResources::SheetCount() const
+{
+  return mStyleSheetList.Length();
+}
+
+bool
+nsXBLPrototypeResources::HasStyleSheets() const
+{
+  return !mStyleSheetList.IsEmpty();
+}
+
+void
+nsXBLPrototypeResources::AppendStyleSheetsTo(
+                                      nsTArray<nsCSSStyleSheet*>& aResult) const
+{
+  aResult.AppendElements(mStyleSheetList);
+}
--- a/dom/xbl/nsXBLPrototypeResources.h
+++ b/dom/xbl/nsXBLPrototypeResources.h
@@ -31,33 +31,37 @@ public:
   nsresult FlushSkinSheets();
 
   nsresult Write(nsIObjectOutputStream* aStream);
 
   void Traverse(nsCycleCollectionTraversalCallback &cb) const;
 
   void ClearLoader();
 
-  typedef nsTArray<nsRefPtr<nsCSSStyleSheet> > sheet_array_type;
+  void AppendStyleSheet(nsCSSStyleSheet* aSheet);
+  void RemoveStyleSheet(nsCSSStyleSheet* aSheet);
+  void InsertStyleSheetAt(size_t aIndex, nsCSSStyleSheet* aSheet);
+  nsCSSStyleSheet* StyleSheetAt(size_t aIndex) const;
+  size_t SheetCount() const;
+  bool HasStyleSheets() const;
+  void AppendStyleSheetsTo(nsTArray<nsCSSStyleSheet*>& aResult) const;
 
   /**
    * Recreates mRuleProcessor to represent the current list of style sheets
    * stored in mStyleSheetList.  (Named GatherRuleProcessor to parallel
    * nsStyleSet::GatherRuleProcessors.)
    */
   void GatherRuleProcessor();
 
   nsCSSRuleProcessor* GetRuleProcessor() const { return mRuleProcessor; }
 
 private:
   // A loader object. Exists only long enough to load resources, and then it dies.
   nsRefPtr<nsXBLResourceLoader> mLoader;
 
-public:
   // A list of loaded stylesheets for this binding.
-  sheet_array_type mStyleSheetList;
+  nsTArray<nsRefPtr<nsCSSStyleSheet>> mStyleSheetList;
 
-private:
   // The list of stylesheets converted to a rule processor.
   nsRefPtr<nsCSSRuleProcessor> mRuleProcessor;
 };
 
 #endif
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -168,17 +168,17 @@ nsXBLResourceLoader::StyleSheetLoaded(ns
                                       bool aWasAlternate,
                                       nsresult aStatus)
 {
   if (!mResources) {
     // Our resources got destroyed -- just bail out
     return NS_OK;
   }
    
-  mResources->mStyleSheetList.AppendElement(aSheet);
+  mResources->AppendStyleSheet(aSheet);
 
   if (!mInLoadResourcesFunc)
     mPendingSheets--;
   
   if (mPendingSheets == 0) {
     // All stylesheets are loaded.  
     mResources->GatherRuleProcessor();