| 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
|
|
|