From: Olli Pettay <Olli.Pettay@helsinki.fi>
Date: Tue, 1 Mar 2011 15:50:19 +0200
Subject: Bug 630919, add collect and invalidate phases for tree ranges,
 r=enn+neil, a=jst

---
 layout/xul/base/src/tree/src/nsTreeSelection.cpp |   34 ++++++++++++++++++---
 1 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/layout/xul/base/src/tree/src/nsTreeSelection.cpp b/layout/xul/base/src/tree/src/nsTreeSelection.cpp
index a1812ce..7120195 100644
--- a/layout/xul/base/src/tree/src/nsTreeSelection.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeSelection.cpp
@@ -214,18 +214,40 @@ struct nsTreeRange
     return total;
   }
 
+  static void CollectRanges(nsTreeRange* aRange, nsTArray<PRInt32>& aRanges)
+  {
+    nsTreeRange* cur = aRange;
+    while (cur) {
+      aRanges.AppendElement(cur->mMin);
+      aRanges.AppendElement(cur->mMax);
+      cur = cur->mNext;
+    }
+  }
+  
+  static void InvalidateRanges(nsITreeBoxObject* aTree,
+                               nsTArray<PRInt32>& aRanges)
+  {
+    if (aTree) {
+      nsCOMPtr<nsITreeBoxObject> tree = aTree;
+      for (PRUint32 i = 0; i < aRanges.Length(); i += 2) {
+        aTree->InvalidateRange(aRanges[i], aRanges[i + 1]);
+      }
+    }
+  }
+
   void Invalidate() {
-    if (mSelection->mTree)
-      mSelection->mTree->InvalidateRange(mMin, mMax);
-    if (mNext)
-      mNext->Invalidate();
+    nsTArray<PRInt32> ranges;
+    CollectRanges(this, ranges);
+    InvalidateRanges(mSelection->mTree, ranges);
+    
   }
 
   void RemoveAllBut(PRInt32 aIndex) {
     if (aIndex >= mMin && aIndex <= mMax) {
 
       // Invalidate everything in this list.
-      mSelection->mFirstRange->Invalidate();
+      nsTArray<PRInt32> ranges;
+      CollectRanges(mSelection->mFirstRange, ranges);
 
       mMin = aIndex;
       mMax = aIndex;
@@ -241,6 +263,7 @@ struct nsTreeRange
         delete mSelection->mFirstRange;
         mSelection->mFirstRange = this;
       }
+      InvalidateRanges(mSelection->mTree, ranges);
     }
     else if (mNext)
       mNext->RemoveAllBut(aIndex);
@@ -451,6 +474,7 @@ NS_IMETHODIMP nsTreeSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEndInd
     if (mFirstRange) {
         mFirstRange->Invalidate();
         delete mFirstRange;
+        mFirstRange = nsnull;
     }
   }
 
