Bug 632143 patch 0: Add helper-method 'UpdateListIndicesFromIndex' to DOMSVGxxxList classes. r=roc a=blocking-final+
authorDaniel Holbert <dholbert@cs.stanford.edu>
Tue, 15 Feb 2011 23:54:04 -0800
changeset 62656 58cb9a41c8b41c6c7364c87ea4300915e22c7e6a
parent 62655 b41a6a2499d14d116fe807b7094420008acb8af8
child 62657 78f8b9ee9ea854d04388907b069117dc771b7b49
push idunknown
push userunknown
push dateunknown
reviewersroc, blocking-final
bugs632143
milestone2.0b12pre
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 632143 patch 0: Add helper-method 'UpdateListIndicesFromIndex' to DOMSVGxxxList classes. r=roc a=blocking-final+
content/svg/content/src/DOMSVGLengthList.cpp
content/svg/content/src/DOMSVGNumberList.cpp
content/svg/content/src/DOMSVGPathSegList.cpp
content/svg/content/src/DOMSVGPathSegList.h
content/svg/content/src/DOMSVGPointList.cpp
--- a/content/svg/content/src/DOMSVGLengthList.cpp
+++ b/content/svg/content/src/DOMSVGLengthList.cpp
@@ -38,16 +38,35 @@
 #include "DOMSVGLengthList.h"
 #include "DOMSVGLength.h"
 #include "nsDOMError.h"
 #include "SVGAnimatedLengthList.h"
 #include "nsCOMPtr.h"
 
 // See the comment in this file's header.
 
+// local helper functions
+namespace {
+
+using mozilla::DOMSVGLength;
+
+void UpdateListIndicesFromIndex(nsTArray<DOMSVGLength*>& aItemsArray,
+                                PRUint32 aStartingIndex)
+{
+  PRUint32 length = aItemsArray.Length();
+
+  for (PRUint32 i = aStartingIndex; i < length; ++i) {
+    if (aItemsArray[i]) {
+      aItemsArray[i]->UpdateListIndex(i);
+    }
+  }
+}
+
+} // namespace
+
 namespace mozilla {
 
 // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
 // clear our DOMSVGAnimatedLengthList's weak ref to us to be safe. (The other
 // option would be to not unlink and rely on the breaking of the other edges in
 // the cycle, as NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGLengthList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGLengthList)
@@ -230,21 +249,17 @@ DOMSVGLengthList::InsertItemBefore(nsIDO
   InternalList().InsertItem(index, domItem->ToSVGLength());
   mItems.InsertElementAt(index, domItem.get());
 
   // This MUST come after the insertion into InternalList(), or else under the
   // insertion into InternalList() the values read from domItem would be bad
   // data from InternalList() itself!:
   domItem->InsertingIntoList(this, AttrEnum(), index, IsAnimValList());
 
-  for (PRUint32 i = index + 1; i < Length(); ++i) {
-    if (mItems[i]) {
-      mItems[i]->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(mItems, index + 1);
 
   Element()->DidChangeLengthList(AttrEnum(), PR_TRUE);
 #ifdef MOZ_SMIL
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   *_retval = domItem.forget().get();
@@ -313,21 +328,17 @@ DOMSVGLengthList::RemoveItem(PRUint32 in
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[index]->RemovingFromList();
   NS_ADDREF(*_retval = mItems[index]);
 
   InternalList().RemoveItem(index);
   mItems.RemoveElementAt(index);
 
-  for (PRUint32 i = index; i < Length(); ++i) {
-    if (mItems[i]) {
-      mItems[i]->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(mItems, index);
 
   Element()->DidChangeLengthList(AttrEnum(), PR_TRUE);
 #ifdef MOZ_SMIL
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   return NS_OK;
--- a/content/svg/content/src/DOMSVGNumberList.cpp
+++ b/content/svg/content/src/DOMSVGNumberList.cpp
@@ -40,16 +40,35 @@
 #include "nsDOMError.h"
 #include "SVGAnimatedNumberList.h"
 #include "nsCOMPtr.h"
 
 // See the comment in this file's header.
 
 namespace mozilla {
 
+// local helper functions
+namespace {
+
+using mozilla::DOMSVGNumber;
+
+void UpdateListIndicesFromIndex(nsTArray<DOMSVGNumber*>& aItemsArray,
+                                PRUint32 aStartingIndex)
+{
+  PRUint32 length = aItemsArray.Length();
+
+  for (PRUint32 i = aStartingIndex; i < length; ++i) {
+    if (aItemsArray[i]) {
+      aItemsArray[i]->UpdateListIndex(i);
+    }
+  }
+}
+
+} // namespace
+
 // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to
 // clear our DOMSVGAnimatedNumberList's weak ref to us to be safe. (The other
 // option would be to not unlink and rely on the breaking of the other edges in
 // the cycle, as NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGNumberList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGNumberList)
   // No need to null check tmp - script/SMIL can't detach us from mAList
   ( tmp->IsAnimValList() ? tmp->mAList->mAnimVal : tmp->mAList->mBaseVal ) = nsnull;
@@ -230,21 +249,17 @@ DOMSVGNumberList::InsertItemBefore(nsIDO
   InternalList().InsertItem(index, domItem->ToSVGNumber());
   mItems.InsertElementAt(index, domItem.get());
 
   // This MUST come after the insertion into InternalList(), or else under the
   // insertion into InternalList() the values read from domItem would be bad
   // data from InternalList() itself!:
   domItem->InsertingIntoList(this, AttrEnum(), index, IsAnimValList());
 
-  for (PRUint32 i = index + 1; i < Length(); ++i) {
-    if (mItems[i]) {
-      mItems[i]->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(mItems, index + 1);
 
   Element()->DidChangeNumberList(AttrEnum(), PR_TRUE);
 #ifdef MOZ_SMIL
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   *_retval = domItem.forget().get();
@@ -313,21 +328,17 @@ DOMSVGNumberList::RemoveItem(PRUint32 in
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[index]->RemovingFromList();
   NS_ADDREF(*_retval = mItems[index]);
 
   InternalList().RemoveItem(index);
   mItems.RemoveElementAt(index);
 
-  for (PRUint32 i = index; i < Length(); ++i) {
-    if (mItems[i]) {
-      mItems[i]->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(mItems, index);
 
   Element()->DidChangeNumberList(AttrEnum(), PR_TRUE);
 #ifdef MOZ_SMIL
   if (mAList->IsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   return NS_OK;
--- a/content/svg/content/src/DOMSVGPathSegList.cpp
+++ b/content/svg/content/src/DOMSVGPathSegList.cpp
@@ -355,22 +355,17 @@ DOMSVGPathSegList::InsertItemBefore(nsID
   InternalList().mData.InsertElementsAt(internalIndex, segAsRaw, 1 + argCount);
   mItems.InsertElementAt(aIndex, ItemProxy(domItem.get(), internalIndex));
 
   // This MUST come after the insertion into InternalList(), or else under the
   // insertion into InternalList() the values read from domItem would be bad
   // data from InternalList() itself!:
   domItem->InsertingIntoList(this, aIndex, IsAnimValList());
 
-  for (PRUint32 i = aIndex + 1; i < Length(); ++i) {
-    mItems[i].mInternalDataIndex += 1 + argCount;
-    if (ItemAt(i)) {
-      ItemAt(i)->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(aIndex + 1, argCount + 1);
 
   Element()->DidChangePathSegList(PR_TRUE);
 #ifdef MOZ_SMIL
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   *_retval = domItem.forget().get();
@@ -465,22 +460,17 @@ DOMSVGPathSegList::RemoveItem(PRUint32 a
 
   PRUint32 internalIndex = mItems[aIndex].mInternalDataIndex;
   PRUint32 segType = SVGPathSegUtils::DecodeType(InternalList().mData[internalIndex]);
   PRUint32 argCount = SVGPathSegUtils::ArgCountForType(segType);
 
   InternalList().mData.RemoveElementsAt(internalIndex, 1 + argCount);
   mItems.RemoveElementAt(aIndex);
 
-  for (PRUint32 i = aIndex; i < Length(); ++i) {
-    mItems[i].mInternalDataIndex -= 1 + argCount;
-    if (ItemAt(i)) {
-      ItemAt(i)->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(aIndex, -(argCount + 1));
 
   Element()->DidChangePathSegList(PR_TRUE);
 #ifdef MOZ_SMIL
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   return NS_OK;
@@ -496,9 +486,23 @@ DOMSVGPathSegList::AppendItem(nsIDOMSVGP
 void
 DOMSVGPathSegList::EnsureItemAt(PRUint32 aIndex)
 {
   if (!ItemAt(aIndex)) {
     ItemAt(aIndex) = DOMSVGPathSeg::CreateFor(this, aIndex, IsAnimValList());
   }
 }
 
+void
+DOMSVGPathSegList::UpdateListIndicesFromIndex(PRUint32 aStartingIndex,
+                                              PRInt32  aInternalDataIndexDelta)
+{
+  PRUint32 length = Length();
+
+  for (PRUint32 i = aStartingIndex; i < length; ++i) {
+    mItems[i].mInternalDataIndex += aInternalDataIndexDelta;
+    if (ItemAt(i)) {
+      ItemAt(i)->UpdateListIndex(i);
+    }
+  }
+}
+
 } // namespace mozilla
--- a/content/svg/content/src/DOMSVGPathSegList.h
+++ b/content/svg/content/src/DOMSVGPathSegList.h
@@ -185,16 +185,22 @@ private:
   SVGPathData& InternalList();
 
   SVGAnimatedPathSegList& InternalAList();
 
   /// Creates an instance of the appropriate DOMSVGPathSeg sub-class for
   // aIndex, if it doesn't already exist.
   void EnsureItemAt(PRUint32 aIndex);
 
+  // Calls UpdateListIndex on all elements in |mItems| that satisfy ItemAt(),
+  // from |aStartingIndex| to the end of |mItems|.  Also adjusts
+  // |mItems.mInternalDataIndex| by the requested amount.
+  void UpdateListIndicesFromIndex(PRUint32 aStartingIndex,
+                                  PRInt32  aInternalDataIndexDelta);
+
   DOMSVGPathSeg*& ItemAt(PRUint32 aIndex) {
     return mItems[aIndex].mItem;
   }
 
   /**
    * This struct is used in our array of mItems to provide us with somewhere to
    * store the indexes into the internal SVGPathData of the internal seg data
    * that our DOMSVGPathSeg items wrap (the internal segment data is or varying
--- a/content/svg/content/src/DOMSVGPointList.cpp
+++ b/content/svg/content/src/DOMSVGPointList.cpp
@@ -39,16 +39,36 @@
 #include "DOMSVGPoint.h"
 #include "nsDOMError.h"
 #include "SVGAnimatedPointList.h"
 #include "nsCOMPtr.h"
 #include "nsSVGAttrTearoffTable.h"
 
 // See the comment in this file's header.
 
+// local helper functions
+namespace {
+
+using mozilla::DOMSVGPoint;
+
+void
+UpdateListIndicesFromIndex(nsTArray<DOMSVGPoint*>& aItemsArray,
+                           PRUint32 aStartingIndex)
+{
+  PRUint32 length = aItemsArray.Length();
+
+  for (PRUint32 i = aStartingIndex; i < length; ++i) {
+    if (aItemsArray[i]) {
+      aItemsArray[i]->UpdateListIndex(i);
+    }
+  }
+}
+
+} // namespace
+
 namespace mozilla {
 
 static nsSVGAttrTearoffTable<void, DOMSVGPointList>
   sSVGPointListTearoffTable;
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(DOMSVGPointList, mElement)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPointList)
@@ -280,21 +300,17 @@ DOMSVGPointList::InsertItemBefore(nsIDOM
   InternalList().InsertItem(aIndex, domItem->ToSVGPoint());
   mItems.InsertElementAt(aIndex, domItem.get());
 
   // This MUST come after the insertion into InternalList(), or else under the
   // insertion into InternalList() the values read from domItem would be bad
   // data from InternalList() itself!:
   domItem->InsertingIntoList(this, aIndex, IsAnimValList());
 
-  for (PRUint32 i = aIndex + 1; i < Length(); ++i) {
-    if (mItems[i]) {
-      mItems[i]->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(mItems, aIndex + 1);
 
   Element()->DidChangePointList(PR_TRUE);
 #ifdef MOZ_SMIL
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   *_retval = domItem.forget().get();
@@ -363,21 +379,17 @@ DOMSVGPointList::RemoveItem(PRUint32 aIn
   // Notify the DOM item of removal *before* modifying the lists so that the
   // DOM item can copy its *old* value:
   mItems[aIndex]->RemovingFromList();
   NS_ADDREF(*_retval = mItems[aIndex]);
 
   InternalList().RemoveItem(aIndex);
   mItems.RemoveElementAt(aIndex);
 
-  for (PRUint32 i = aIndex; i < Length(); ++i) {
-    if (mItems[i]) {
-      mItems[i]->UpdateListIndex(i);
-    }
-  }
+  UpdateListIndicesFromIndex(mItems, aIndex);
 
   Element()->DidChangePointList(PR_TRUE);
 #ifdef MOZ_SMIL
   if (AttrIsAnimating()) {
     Element()->AnimationNeedsResample();
   }
 #endif
   return NS_OK;