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 |
| 71 RefPtr<ListItemTearOff>& item = m_wrappers->at(itemIndex); |
| 72 item->detachWrapper(); |
| 73 m_wrappers->remove(itemIndex); |
| 74 m_values->remove(itemIndex); |
| 75 |
| 76 if (shouldSynchronizeWrappers) |
| 77 commitChange(); |
| 78 } |
| 79 |
76 // SVGList API | 80 // SVGList API |
77 void clear(ExceptionCode& ec) | 81 void clear(ExceptionCode& ec) |
78 { | 82 { |
79 Base::clearValuesAndWrappers(ec); | 83 Base::clearValuesAndWrappers(ec); |
80 } | 84 } |
81 | 85 |
82 PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCod
e& ec) | 86 PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCod
e& ec) |
83 { | 87 { |
84 return Base::initializeValuesAndWrappers(passNewItem, ec); | 88 return Base::initializeValuesAndWrappers(passNewItem, ec); |
85 } | 89 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 ListItemTearOff* item = m_wrappers->at(i).get(); | 141 ListItemTearOff* item = m_wrappers->at(i).get(); |
138 if (!item) | 142 if (!item) |
139 continue; | 143 continue; |
140 item->setAnimatedProperty(m_animatedProperty.get()); | 144 item->setAnimatedProperty(m_animatedProperty.get()); |
141 item->setValue(m_values->at(i)); | 145 item->setValue(m_values->at(i)); |
142 } | 146 } |
143 | 147 |
144 m_animatedProperty->commitChange(); | 148 m_animatedProperty->commitChange(); |
145 } | 149 } |
146 | 150 |
147 virtual void processIncomingListItemValue(const ListItemType&, unsigned*) | 151 virtual bool processIncomingListItemValue(const ListItemType&, unsigned*) |
148 { | 152 { |
149 ASSERT_NOT_REACHED(); | 153 ASSERT_NOT_REACHED(); |
| 154 return true; |
150 } | 155 } |
151 | 156 |
152 virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem
, unsigned* indexToModify) | 157 virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem
, unsigned* indexToModify) |
153 { | 158 { |
154 SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(
); | 159 SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty(
); |
155 | 160 |
156 // newItem has been created manually, it doesn't belong to any SVGElemen
t. | 161 // newItem has been created manually, it doesn't belong to any SVGElemen
t. |
157 // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createS
VGLength())") | 162 // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createS
VGLength())") |
158 if (!animatedPropertyOfItem) | 163 if (!animatedPropertyOfItem) |
159 return; | 164 return true; |
160 | 165 |
161 // newItem belongs to a SVGElement, but its associated SVGAnimatedProper
ty is not an animated list tear off. | 166 // 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)") | 167 // (for example: "textElement.x.baseVal.appendItem(rectElement.width.bas
eVal)") |
163 if (!animatedPropertyOfItem->isAnimatedListTearOff()) { | 168 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. | 169 // 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: | 170 // 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 | 171 // 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 | 172 // 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. | 173 // mutate the rectElement width _and_ the textElement x list. That's
obviously wrong, take care of that. |
169 newItem = ListItemTearOff::create(newItem->propertyReference()); | 174 newItem = ListItemTearOff::create(newItem->propertyReference()); |
170 return; | 175 return true; |
171 } | 176 } |
172 | 177 |
173 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 178 // 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. | 179 // '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; | 180 bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; |
176 int removedIndex = static_cast<AnimatedListPropertyTearOff*>(animatedPro
pertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList); | 181 AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListP
ropertyTearOff*>(animatedPropertyOfItem); |
177 ASSERT(removedIndex != -1); | 182 int indexToRemove = propertyTearOff->findItem(newItem.get()); |
| 183 ASSERT(indexToRemove != -1); |
| 184 |
| 185 // Do not remove newItem if already in this list at the target index. |
| 186 if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToR
emove) == *indexToModify) |
| 187 return false; |
| 188 |
| 189 propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); |
178 | 190 |
179 if (!indexToModify) | 191 if (!indexToModify) |
180 return; | 192 return true; |
181 | 193 |
182 // If the item lived in our list, adjust the insertion index. | 194 // If the item lived in our list, adjust the insertion index. |
183 if (!livesInOtherList) { | 195 if (!livesInOtherList) { |
184 unsigned& index = *indexToModify; | 196 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. | 197 // 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) | 198 if (static_cast<unsigned>(indexToRemove) < index) |
187 --index; | 199 --index; |
188 } | 200 } |
| 201 |
| 202 return true; |
189 } | 203 } |
190 | 204 |
191 // Back pointer to the animated property that created us | 205 // Back pointer to the animated property that created us |
192 // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAni
matedLengthList object | 206 // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAni
matedLengthList object |
193 RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; | 207 RefPtr<AnimatedListPropertyTearOff> m_animatedProperty; |
194 }; | 208 }; |
195 | 209 |
196 } | 210 } |
197 | 211 |
198 #endif // ENABLE(SVG) | 212 #endif // ENABLE(SVG) |
199 #endif // SVGListPropertyTearOff_h | 213 #endif // SVGListPropertyTearOff_h |
OLD | NEW |