Index: Source/WebCore/svg/properties/SVGListPropertyTearOff.h |
=================================================================== |
--- Source/WebCore/svg/properties/SVGListPropertyTearOff.h (revision 143078) |
+++ Source/WebCore/svg/properties/SVGListPropertyTearOff.h (working copy) |
@@ -47,30 +47,35 @@ |
return adoptRef(new Self(animatedProperty, role, values, wrappers)); |
} |
- int removeItemFromList(ListItemTearOff* removeItem, bool shouldSynchronizeWrappers) |
+ int findItem(ListItemTearOff* item) const |
{ |
ASSERT(m_values); |
ASSERT(m_wrappers); |
- // Lookup item in cache and remove its corresponding wrapper. |
unsigned size = m_wrappers->size(); |
ASSERT(size == m_values->size()); |
- for (unsigned i = 0; i < size; ++i) { |
- RefPtr<ListItemTearOff>& item = m_wrappers->at(i); |
- if (item != removeItem) |
- continue; |
+ for (size_t i = 0; i < size; ++i) { |
+ if (item == m_wrappers->at(i)) |
+ return i; |
+ } |
- item->detachWrapper(); |
- m_wrappers->remove(i); |
- m_values->remove(i); |
+ return -1; |
+ } |
- if (shouldSynchronizeWrappers) |
- commitChange(); |
+ void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) |
+ { |
+ ASSERT(m_values); |
+ ASSERT(m_wrappers); |
+ ASSERT(m_values->size() == m_wrappers->size()); |
+ ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_wrappers->size()); |
- return i; |
- } |
+ RefPtr<ListItemTearOff>& item = m_wrappers->at(itemIndex); |
+ item->detachWrapper(); |
+ m_wrappers->remove(itemIndex); |
+ m_values->remove(itemIndex); |
- return -1; |
+ if (shouldSynchronizeWrappers) |
+ commitChange(); |
} |
// SVGList API |
@@ -144,19 +149,20 @@ |
m_animatedProperty->commitChange(); |
} |
- virtual void processIncomingListItemValue(const ListItemType&, unsigned*) |
+ virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) |
{ |
ASSERT_NOT_REACHED(); |
+ return true; |
} |
- virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) |
+ virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) |
{ |
SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(); |
// newItem has been created manually, it doesn't belong to any SVGElement. |
// (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createSVGLength())") |
if (!animatedPropertyOfItem) |
- return; |
+ return true; |
// newItem belongs to a SVGElement, but its associated SVGAnimatedProperty is not an animated list tear off. |
// (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)") |
@@ -167,25 +173,34 @@ |
// that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would |
// mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that. |
newItem = ListItemTearOff::create(newItem->propertyReference()); |
- return; |
+ return true; |
} |
// Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. |
// 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. |
bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; |
- int removedIndex = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList); |
- ASSERT(removedIndex != -1); |
+ AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem); |
+ int indexToRemove = propertyTearOff->findItem(newItem.get()); |
+ ASSERT(indexToRemove != -1); |
+ // Do not remove newItem if already in this list at the target index. |
+ if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify) |
+ return false; |
+ |
+ propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); |
+ |
if (!indexToModify) |
- return; |
+ return true; |
// If the item lived in our list, adjust the insertion index. |
if (!livesInOtherList) { |
unsigned& index = *indexToModify; |
// Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item. |
- if (static_cast<unsigned>(removedIndex) < index) |
+ if (static_cast<unsigned>(indexToRemove) < index) |
--index; |
} |
+ |
+ return true; |
} |
// Back pointer to the animated property that created us |