Bug 1382078 Part 1 - Add method to nsBindingManager to iterate all bound contents. r=emilio
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 28 Aug 2017 17:47:55 +0800
changeset 428299 4c8b4641d5f25a3fee09ef0ed36bbb122cc36748
parent 428298 9638b85c359051c792baab365d4a3b1ad30359a4
child 428300 af60919d25dc5109e61c4aed6af2cb1cf560b0b8
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1382078
milestone57.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 1382078 Part 1 - Add method to nsBindingManager to iterate all bound contents. r=emilio MozReview-Commit-ID: H00b3pGNC8V
dom/xbl/nsBindingManager.cpp
dom/xbl/nsBindingManager.h
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -704,99 +704,72 @@ nsBindingManager::WalkRules(nsIStyleRule
 
   // If "content" is non-null that means we cut off inheritance at some point
   // in the loop.
   *aCutOffInheritance = (content != nullptr);
 
   return NS_OK;
 }
 
-typedef nsTHashtable<nsPtrHashKey<nsIStyleRuleProcessor> > RuleProcessorSet;
+void
+nsBindingManager::EnumerateBoundContentBindings(
+  const BoundContentBindingCallback& aCallback) const
+{
+  if (!mBoundContentSet) {
+    return;
+  }
 
-static RuleProcessorSet*
-GetContentSetRuleProcessors(nsTHashtable<nsRefPtrHashKey<nsIContent>>* aContentSet)
-{
-  RuleProcessorSet* set = nullptr;
-
-  for (auto iter = aContentSet->Iter(); !iter.Done(); iter.Next()) {
+  for (auto iter = mBoundContentSet->Iter(); !iter.Done(); iter.Next()) {
     nsIContent* boundContent = iter.Get()->GetKey();
-    for (nsXBLBinding* binding = boundContent->GetXBLBinding(); binding;
+    for (nsXBLBinding* binding = boundContent->GetXBLBinding();
+         binding;
          binding = binding->GetBaseBinding()) {
-      nsIStyleRuleProcessor* ruleProc =
-        binding->PrototypeBinding()->GetRuleProcessor();
-      if (ruleProc) {
-        if (!set) {
-          set = new RuleProcessorSet;
-        }
-        set->PutEntry(ruleProc);
-      }
+      aCallback(binding);
     }
   }
-
-  return set;
 }
 
 void
 nsBindingManager::WalkAllRules(nsIStyleRuleProcessor::EnumFunc aFunc,
                                ElementDependentRuleProcessorData* aData)
 {
-  if (!mBoundContentSet) {
-    return;
-  }
-
-  nsAutoPtr<RuleProcessorSet> set;
-  set = GetContentSetRuleProcessors(mBoundContentSet);
-  if (!set) {
-    return;
-  }
-
-  for (auto iter = set->Iter(); !iter.Done(); iter.Next()) {
-    nsIStyleRuleProcessor* ruleProcessor = iter.Get()->GetKey();
-    (*(aFunc))(ruleProcessor, aData);
-  }
+  EnumerateBoundContentBindings([=](nsXBLBinding* aBinding) {
+    nsIStyleRuleProcessor* ruleProcessor =
+      aBinding->PrototypeBinding()->GetRuleProcessor();
+    if (ruleProcessor) {
+      (*(aFunc))(ruleProcessor, aData);
+    }
+  });
 }
 
 nsresult
 nsBindingManager::MediumFeaturesChanged(nsPresContext* aPresContext,
                                         bool* aRulesChanged)
 {
   *aRulesChanged = false;
-  if (!mBoundContentSet) {
-    return NS_OK;
-  }
+  RefPtr<nsPresContext> presContext = aPresContext;
 
-  nsAutoPtr<RuleProcessorSet> set;
-  set = GetContentSetRuleProcessors(mBoundContentSet);
-  if (!set) {
-    return NS_OK;
-  }
-
-  for (auto iter = set->Iter(); !iter.Done(); iter.Next()) {
-    nsIStyleRuleProcessor* ruleProcessor = iter.Get()->GetKey();
-    bool thisChanged = ruleProcessor->MediumFeaturesChanged(aPresContext);
-    *aRulesChanged = *aRulesChanged || thisChanged;
-  }
+  EnumerateBoundContentBindings([=](nsXBLBinding* aBinding) {
+    nsIStyleRuleProcessor* ruleProcessor =
+      aBinding->PrototypeBinding()->GetRuleProcessor();
+    if (ruleProcessor) {
+      bool thisChanged = ruleProcessor->MediumFeaturesChanged(presContext);
+      *aRulesChanged = *aRulesChanged || thisChanged;
+    }
+  });
 
   return NS_OK;
 }
 
 void
 nsBindingManager::AppendAllSheets(nsTArray<StyleSheet*>& aArray)
 {
-  if (!mBoundContentSet) {
-    return;
-  }
-
-  for (auto iter = mBoundContentSet->Iter(); !iter.Done(); iter.Next()) {
-    nsIContent* boundContent = iter.Get()->GetKey();
-    for (nsXBLBinding* binding = boundContent->GetXBLBinding(); binding;
-         binding = binding->GetBaseBinding()) {
-      binding->PrototypeBinding()->AppendStyleSheetsTo(aArray);
-    }
-  }
+  EnumerateBoundContentBindings([&aArray](nsXBLBinding* aBinding) {
+    aBinding->PrototypeBinding()->AppendStyleSheetsTo(aArray);
+  });
 }
 
 static void
 InsertAppendedContent(XBLChildrenElement* aPoint,
                       nsIContent* aFirstNewContent)
 {
   int32_t insertionIndex;
   if (nsIContent* prevSibling = aFirstNewContent->GetPreviousSibling()) {
--- a/dom/xbl/nsBindingManager.h
+++ b/dom/xbl/nsBindingManager.h
@@ -188,16 +188,22 @@ protected:
   void DoProcessAttachedQueue();
 
   // Post an event to process the attached queue.
   void PostProcessAttachedQueueEvent();
 
   // Call PostProcessAttachedQueueEvent() on a timer.
   static void PostPAQEventCallback(nsITimer* aTimer, void* aClosure);
 
+  // Enumerate each bound content's bindings (including its base bindings)
+  // in mBoundContentSet.
+  using BoundContentBindingCallback = std::function<void (nsXBLBinding*)>;
+  void EnumerateBoundContentBindings(
+    const BoundContentBindingCallback& aCallback) const;
+
 // MEMBER VARIABLES
 protected:
   // A set of nsIContent that currently have a binding installed.
   nsAutoPtr<nsTHashtable<nsRefPtrHashKey<nsIContent> > > mBoundContentSet;
 
   // A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect
   // wrapper for JS objects).  For XBL bindings that implement XPIDL
   // interfaces, and that get referred to from C++, this table caches