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 |