| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 using Base::m_role; | 40 using Base::m_role; |
| 41 using Base::m_values; | 41 using Base::m_values; |
| 42 using Base::m_wrappers; | 42 using Base::m_wrappers; |
| 43 | 43 |
| 44 static PassRefPtr<Self> create(AnimatedListPropertyTearOff* animatedProperty
, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers) | 44 static PassRefPtr<Self> create(AnimatedListPropertyTearOff* animatedProperty
, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers) |
| 45 { | 45 { |
| 46 ASSERT(animatedProperty); | 46 ASSERT(animatedProperty); |
| 47 return adoptRef(new Self(animatedProperty, role, values, wrappers)); | 47 return adoptRef(new Self(animatedProperty, role, values, wrappers)); |
| 48 } | 48 } |
| 49 | 49 |
| 50 int removeItemFromList(ListItemTearOff* removeItem, bool shouldSynchronizeWr
appers) | 50 int findItem(ListItemTearOff* item) const |
| 51 { | 51 { |
| 52 ASSERT(m_values); | 52 ASSERT(m_values); |
| 53 ASSERT(m_wrappers); | 53 ASSERT(m_wrappers); |
| 54 | 54 |
| 55 // Lookup item in cache and remove its corresponding wrapper. | |
| 56 unsigned size = m_wrappers->size(); | 55 unsigned size = m_wrappers->size(); |
| 57 ASSERT(size == m_values->size()); | 56 ASSERT(size == m_values->size()); |
| 58 for (unsigned i = 0; i < size; ++i) { | 57 for (size_t i = 0; i < size; ++i) { |
| 59 RefPtr<ListItemTearOff>& item = m_wrappers->at(i); | 58 if (item == m_wrappers->at(i)) |
| 60 if (item != removeItem) | 59 return i; |
| 61 continue; | |
| 62 | |
| 63 item->detachWrapper(); | |
| 64 m_wrappers->remove(i); | |
| 65 m_values->remove(i); | |
| 66 | |
| 67 if (shouldSynchronizeWrappers) | |
| 68 commitChange(); | |
| 69 | |
| 70 return i; | |
| 71 } | 60 } |
| 72 | 61 |
| 73 return -1; | 62 return -1; |
| 74 } | 63 } |
| 75 | 64 |
| 65 void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) |
| 66 { |
| 67 ASSERT(m_values); |
| 68 ASSERT(m_wrappers); |
| 69 ASSERT(m_values->size() == m_wrappers->size()); |
| 70 ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_wrappers->size()); |
| 71 |
| 72 RefPtr<ListItemTearOff>& item = m_wrappers->at(itemIndex); |
| 73 item->detachWrapper(); |
| 74 m_wrappers->remove(itemIndex); |
| 75 m_values->remove(itemIndex); |
| 76 |
| 77 if (shouldSynchronizeWrappers) |
| 78 commitChange(); |
| 79 } |
| 80 |
| 76 // SVGList API | 81 // SVGList API |
| 77 void clear(ExceptionCode& ec) | 82 void clear(ExceptionCode& ec) |
| 78 { | 83 { |
| 79 Base::clearValuesAndWrappers(ec); | 84 Base::clearValuesAndWrappers(ec); |
| 80 } | 85 } |
| 81 | 86 |
| 82 PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCod
e& ec) | 87 PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCod
e& ec) |
| 83 { | 88 { |
| 84 return Base::initializeValuesAndWrappers(passNewItem, ec); | 89 return Base::initializeValuesAndWrappers(passNewItem, ec); |
| 85 } | 90 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 ListItemTearOff* item = m_wrappers->at(i).get(); | 142 ListItemTearOff* item = m_wrappers->at(i).get(); |
| 138 if (!item) | 143 if (!item) |
| 139 continue; | 144 continue; |
| 140 item->setAnimatedProperty(m_animatedProperty.get()); | 145 item->setAnimatedProperty(m_animatedProperty.get()); |
| 141 item->setValue(m_values->at(i)); | 146 item->setValue(m_values->at(i)); |
| 142 } | 147 } |
| 143 | 148 |
| 144 m_animatedProperty->commitChange(); | 149 m_animatedProperty->commitChange(); |
| 145 } | 150 } |
| 146 | 151 |
| 147 virtual void processIncomingListItemValue(const ListItemType&, unsigned*) | 152 virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) |
| 148 { | 153 { |
| 149 ASSERT_NOT_REACHED(); | 154 ASSERT_NOT_REACHED(); |
| 155 return true; |
| 150 } | 156 } |
| 151 | 157 |
| 152 virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem
, unsigned* indexToModify) | 158 virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem
, unsigned* indexToModify) |
| 153 { | 159 { |
| 154 SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(
); | 160 SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(
); |
| 155 | 161 |
| 156 // newItem has been created manually, it doesn't belong to any SVGElemen
t. | 162 // newItem has been created manually, it doesn't belong to any SVGElemen
t. |
| 157 // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createS
VGLength())") | 163 // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createS
VGLength())") |
| 158 if (!animatedPropertyOfItem) | 164 if (!animatedPropertyOfItem) |
| 159 return; | 165 return true; |
| 160 | 166 |
| 161 // newItem belongs to a SVGElement, but its associated SVGAnimatedProper
ty is not an animated list tear off. | 167 // newItem belongs to a SVGElement, but its associated SVGAnimatedProper
ty is not an animated list tear off. |
| 162 // (for example: "textElement.x.baseVal.appendItem(rectElement.width.bas
eVal)") | 168 // (for example: "textElement.x.baseVal.appendItem(rectElement.width.bas
eVal)") |
| 163 if (!animatedPropertyOfItem->isAnimatedListTearOff()) { | 169 if (!animatedPropertyOfItem->isAnimatedListTearOff()) { |
| 164 // We have to copy the incoming newItem, as we're not allowed to ins
ert this tear off as is into our wrapper cache. | 170 // We have to copy the incoming newItem, as we're not allowed to ins
ert this tear off as is into our wrapper cache. |
| 165 // Otherwhise we'll end up having two SVGAnimatedPropertys that oper
ate on the same SVGPropertyTearOff. Consider the example above: | 171 // Otherwhise we'll end up having two SVGAnimatedPropertys that oper
ate on the same SVGPropertyTearOff. Consider the example above: |
| 166 // SVGRectElements SVGAnimatedLength 'width' property baseVal points
to the same tear off object | 172 // SVGRectElements SVGAnimatedLength 'width' property baseVal points
to the same tear off object |
| 167 // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. t
extElement.x.baseVal.getItem(0).value += 150 would | 173 // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. t
extElement.x.baseVal.getItem(0).value += 150 would |
| 168 // mutate the rectElement width _and_ the textElement x list. That's
obviously wrong, take care of that. | 174 // mutate the rectElement width _and_ the textElement x list. That's
obviously wrong, take care of that. |
| 169 newItem = ListItemTearOff::create(newItem->propertyReference()); | 175 newItem = ListItemTearOff::create(newItem->propertyReference()); |
| 170 return; | 176 return true; |
| 171 } | 177 } |
| 172 | 178 |
| 173 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 179 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 174 // 'newItem' is already living in another list. If it's not our list, sy
nchronize the other lists wrappers after the removal. | 180 // 'newItem' is already living in another list. If it's not our list, sy
nchronize the other lists wrappers after the removal. |
| 175 bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; | 181 bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; |
| 176 int removedIndex = static_cast<AnimatedListPropertyTearOff*>(animatedPro
pertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList); | 182 AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListP
ropertyTearOff*>(animatedPropertyOfItem); |
| 177 ASSERT(removedIndex != -1); | 183 int indexToRemove = propertyTearOff->findItem(newItem.get()); |
| 184 ASSERT(indexToRemove != -1); |
| 185 |
| 186 // Do not remove newItem if already in this list at the target index. |
| 187 if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToR
emove) == *indexToModify) |
| 188 return false; |
| 189 |
| 190 propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); |
| 178 | 191 |
| 179 if (!indexToModify) | 192 if (!indexToModify) |
| 180 return; | 193 return true; |
| 181 | 194 |
| 182 // If the item lived in our list, adjust the insertion index. | 195 // If the item lived in our list, adjust the insertion index. |
| 183 if (!livesInOtherList) { | 196 if (!livesInOtherList) { |
| 184 unsigned& index = *indexToModify; | 197 unsigned& index = *indexToModify; |
| 185 // 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. | 198 // 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. |
| 186 if (static_cast<unsigned>(removedIndex) < index) | 199 if (static_cast<unsigned>(indexToRemove) < index) |
| 187 --index; | 200 --index; |
| 188 } | 201 } |
| 202 |
| 203 return true; |
| 189 } | 204 } |
| 190 | 205 |
| 191 // Back pointer to the animated property that created us | 206 // Back pointer to the animated property that created us |
| 192 // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAni
matedLengthList object | 207 // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAni
matedLengthList object |
| 193 RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; | 208 RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; |
| 194 }; | 209 }; |
| 195 | 210 |
| 196 } | 211 } |
| 197 | 212 |
| 198 #endif // ENABLE(SVG) | 213 #endif // ENABLE(SVG) |
| 199 #endif // SVGListPropertyTearOff_h | 214 #endif // SVGListPropertyTearOff_h |
| OLD | NEW |