| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 class SVGListProperty : public SVGProperty { | 42 class SVGListProperty : public SVGProperty { |
| 43 public: | 43 public: |
| 44 typedef SVGListProperty<PropertyType> Self; | 44 typedef SVGListProperty<PropertyType> Self; |
| 45 | 45 |
| 46 typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; | 46 typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; |
| 47 typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; | 47 typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; |
| 48 typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; | 48 typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; |
| 49 typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTea
rOff; | 49 typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTea
rOff; |
| 50 typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCa
che ListWrapperCache; | 50 typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCa
che ListWrapperCache; |
| 51 | 51 |
| 52 bool canAlterList(ExceptionState& es) const | 52 bool canAlterList(ExceptionState& exceptionState) const |
| 53 { | 53 { |
| 54 if (m_role == AnimValRole) { | 54 if (m_role == AnimValRole) { |
| 55 es.throwUninformativeAndGenericDOMException(NoModificationAllowedErr
or); | 55 exceptionState.throwUninformativeAndGenericDOMException(NoModificati
onAllowedError); |
| 56 return false; | 56 return false; |
| 57 } | 57 } |
| 58 | 58 |
| 59 return true; | 59 return true; |
| 60 } | 60 } |
| 61 | 61 |
| 62 static void detachListWrappersAndResize(ListWrapperCache* wrappers, unsigned
newListSize = 0) | 62 static void detachListWrappersAndResize(ListWrapperCache* wrappers, unsigned
newListSize = 0) |
| 63 { | 63 { |
| 64 // See SVGPropertyTearOff::detachWrapper() for an explanation about what
's happening here. | 64 // See SVGPropertyTearOff::detachWrapper() for an explanation about what
's happening here. |
| 65 ASSERT(wrappers); | 65 ASSERT(wrappers); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 90 ASSERT(m_role == AnimValRole); | 90 ASSERT(m_role == AnimValRole); |
| 91 if (m_ownsValues) | 91 if (m_ownsValues) |
| 92 delete m_values; | 92 delete m_values; |
| 93 m_values = values; | 93 m_values = values; |
| 94 m_ownsValues = shouldOwnValues; | 94 m_ownsValues = shouldOwnValues; |
| 95 m_wrappers = wrappers; | 95 m_wrappers = wrappers; |
| 96 ASSERT(m_values->size() == m_wrappers->size()); | 96 ASSERT(m_values->size() == m_wrappers->size()); |
| 97 } | 97 } |
| 98 | 98 |
| 99 // SVGList::clear() | 99 // SVGList::clear() |
| 100 void clearValues(ExceptionState& es) | 100 void clearValues(ExceptionState& exceptionState) |
| 101 { | 101 { |
| 102 if (!canAlterList(es)) | 102 if (!canAlterList(exceptionState)) |
| 103 return; | 103 return; |
| 104 | 104 |
| 105 m_values->clear(); | 105 m_values->clear(); |
| 106 commitChange(); | 106 commitChange(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void clearValuesAndWrappers(ExceptionState& es) | 109 void clearValuesAndWrappers(ExceptionState& exceptionState) |
| 110 { | 110 { |
| 111 if (!canAlterList(es)) | 111 if (!canAlterList(exceptionState)) |
| 112 return; | 112 return; |
| 113 | 113 |
| 114 detachListWrappers(0); | 114 detachListWrappers(0); |
| 115 m_values->clear(); | 115 m_values->clear(); |
| 116 commitChange(); | 116 commitChange(); |
| 117 } | 117 } |
| 118 | 118 |
| 119 // SVGList::numberOfItems() | 119 // SVGList::numberOfItems() |
| 120 unsigned numberOfItems() const | 120 unsigned numberOfItems() const |
| 121 { | 121 { |
| 122 return m_values->size(); | 122 return m_values->size(); |
| 123 } | 123 } |
| 124 | 124 |
| 125 // SVGList::initialize() | 125 // SVGList::initialize() |
| 126 ListItemType initializeValues(const ListItemType& newItem, ExceptionState& e
s) | 126 ListItemType initializeValues(const ListItemType& newItem, ExceptionState& e
xceptionState) |
| 127 { | 127 { |
| 128 if (!canAlterList(es)) | 128 if (!canAlterList(exceptionState)) |
| 129 return ListItemType(); | 129 return ListItemType(); |
| 130 | 130 |
| 131 // Spec: If the inserted item is already in a list, it is removed from i
ts previous list before it is inserted into this list. | 131 // Spec: If the inserted item is already in a list, it is removed from i
ts previous list before it is inserted into this list. |
| 132 processIncomingListItemValue(newItem, 0); | 132 processIncomingListItemValue(newItem, 0); |
| 133 | 133 |
| 134 // Spec: Clears all existing current items from the list and re-initiali
zes the list to hold the single item specified by the parameter. | 134 // Spec: Clears all existing current items from the list and re-initiali
zes the list to hold the single item specified by the parameter. |
| 135 m_values->clear(); | 135 m_values->clear(); |
| 136 m_values->append(newItem); | 136 m_values->append(newItem); |
| 137 | 137 |
| 138 commitChange(); | 138 commitChange(); |
| 139 return newItem; | 139 return newItem; |
| 140 } | 140 } |
| 141 | 141 |
| 142 PassListItemTearOff initializeValuesAndWrappers(PassListItemTearOff passNewI
tem, ExceptionState& es) | 142 PassListItemTearOff initializeValuesAndWrappers(PassListItemTearOff passNewI
tem, ExceptionState& exceptionState) |
| 143 { | 143 { |
| 144 ASSERT(m_wrappers); | 144 ASSERT(m_wrappers); |
| 145 if (!canAlterList(es)) | 145 if (!canAlterList(exceptionState)) |
| 146 return 0; | 146 return 0; |
| 147 | 147 |
| 148 // Not specified, but FF/Opera do it this way, and it's just sane. | 148 // Not specified, but FF/Opera do it this way, and it's just sane. |
| 149 if (!passNewItem) { | 149 if (!passNewItem) { |
| 150 es.throwUninformativeAndGenericTypeError(); | 150 exceptionState.throwUninformativeAndGenericTypeError(); |
| 151 return 0; | 151 return 0; |
| 152 } | 152 } |
| 153 | 153 |
| 154 RefPtr<ListItemTearOff> newItem = passNewItem; | 154 RefPtr<ListItemTearOff> newItem = passNewItem; |
| 155 ASSERT(m_values->size() == m_wrappers->size()); | 155 ASSERT(m_values->size() == m_wrappers->size()); |
| 156 | 156 |
| 157 // Spec: If the inserted item is already in a list, it is removed from i
ts previous list before it is inserted into this list. | 157 // Spec: If the inserted item is already in a list, it is removed from i
ts previous list before it is inserted into this list. |
| 158 processIncomingListItemWrapper(newItem, 0); | 158 processIncomingListItemWrapper(newItem, 0); |
| 159 | 159 |
| 160 // Spec: Clears all existing current items from the list and re-initiali
zes the list to hold the single item specified by the parameter. | 160 // Spec: Clears all existing current items from the list and re-initiali
zes the list to hold the single item specified by the parameter. |
| 161 detachListWrappers(0); | 161 detachListWrappers(0); |
| 162 m_values->clear(); | 162 m_values->clear(); |
| 163 | 163 |
| 164 m_values->append(newItem->propertyReference()); | 164 m_values->append(newItem->propertyReference()); |
| 165 m_wrappers->append(newItem); | 165 m_wrappers->append(newItem); |
| 166 | 166 |
| 167 commitChange(); | 167 commitChange(); |
| 168 return newItem.release(); | 168 return newItem.release(); |
| 169 } | 169 } |
| 170 | 170 |
| 171 // SVGList::getItem() | 171 // SVGList::getItem() |
| 172 bool canGetItem(unsigned index, ExceptionState& es) | 172 bool canGetItem(unsigned index, ExceptionState& exceptionState) |
| 173 { | 173 { |
| 174 if (index >= m_values->size()) { | 174 if (index >= m_values->size()) { |
| 175 es.throwUninformativeAndGenericDOMException(IndexSizeError); | 175 exceptionState.throwUninformativeAndGenericDOMException(IndexSizeErr
or); |
| 176 return false; | 176 return false; |
| 177 } | 177 } |
| 178 | 178 |
| 179 return true; | 179 return true; |
| 180 } | 180 } |
| 181 | 181 |
| 182 ListItemType getItemValues(unsigned index, ExceptionState& es) | 182 ListItemType getItemValues(unsigned index, ExceptionState& exceptionState) |
| 183 { | 183 { |
| 184 if (!canGetItem(index, es)) | 184 if (!canGetItem(index, exceptionState)) |
| 185 return ListItemType(); | 185 return ListItemType(); |
| 186 | 186 |
| 187 // Spec: Returns the specified item from the list. The returned item is
the item itself and not a copy. | 187 // Spec: Returns the specified item from the list. The returned item is
the item itself and not a copy. |
| 188 return m_values->at(index); | 188 return m_values->at(index); |
| 189 } | 189 } |
| 190 | 190 |
| 191 PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* an
imatedList, unsigned index, ExceptionState& es) | 191 PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* an
imatedList, unsigned index, ExceptionState& exceptionState) |
| 192 { | 192 { |
| 193 ASSERT(m_wrappers); | 193 ASSERT(m_wrappers); |
| 194 if (!canGetItem(index, es)) | 194 if (!canGetItem(index, exceptionState)) |
| 195 return 0; | 195 return 0; |
| 196 | 196 |
| 197 // Spec: Returns the specified item from the list. The returned item is
the item itself and not a copy. | 197 // Spec: Returns the specified item from the list. The returned item is
the item itself and not a copy. |
| 198 // Any changes made to the item are immediately reflected in the list. | 198 // Any changes made to the item are immediately reflected in the list. |
| 199 ASSERT(m_values->size() == m_wrappers->size()); | 199 ASSERT(m_values->size() == m_wrappers->size()); |
| 200 RefPtr<ListItemTearOff> wrapper = m_wrappers->at(index); | 200 RefPtr<ListItemTearOff> wrapper = m_wrappers->at(index); |
| 201 if (!wrapper) { | 201 if (!wrapper) { |
| 202 // Create new wrapper, which is allowed to directly modify the item
in the list, w/o copying and cache the wrapper in our map. | 202 // Create new wrapper, which is allowed to directly modify the item
in the list, w/o copying and cache the wrapper in our map. |
| 203 // It is also associated with our animated property, so it can notif
y the SVG Element which holds the SVGAnimated*List | 203 // It is also associated with our animated property, so it can notif
y the SVG Element which holds the SVGAnimated*List |
| 204 // that it has been modified (and thus can call svgAttributeChanged(
associatedAttributeName)). | 204 // that it has been modified (and thus can call svgAttributeChanged(
associatedAttributeName)). |
| 205 wrapper = ListItemTearOff::create(animatedList, UndefinedRole, m_val
ues->at(index)); | 205 wrapper = ListItemTearOff::create(animatedList, UndefinedRole, m_val
ues->at(index)); |
| 206 m_wrappers->at(index) = wrapper; | 206 m_wrappers->at(index) = wrapper; |
| 207 } | 207 } |
| 208 | 208 |
| 209 return wrapper.release(); | 209 return wrapper.release(); |
| 210 } | 210 } |
| 211 | 211 |
| 212 // SVGList::insertItemBefore() | 212 // SVGList::insertItemBefore() |
| 213 ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned in
dex, ExceptionState& es) | 213 ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned in
dex, ExceptionState& exceptionState) |
| 214 { | 214 { |
| 215 if (!canAlterList(es)) | 215 if (!canAlterList(exceptionState)) |
| 216 return ListItemType(); | 216 return ListItemType(); |
| 217 | 217 |
| 218 // Spec: If the index is greater than or equal to numberOfItems, then th
e new item is appended to the end of the list. | 218 // Spec: If the index is greater than or equal to numberOfItems, then th
e new item is appended to the end of the list. |
| 219 if (index > m_values->size()) | 219 if (index > m_values->size()) |
| 220 index = m_values->size(); | 220 index = m_values->size(); |
| 221 | 221 |
| 222 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 222 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 223 if (!processIncomingListItemValue(newItem, &index)) { | 223 if (!processIncomingListItemValue(newItem, &index)) { |
| 224 // Inserting the item before itself is a no-op. | 224 // Inserting the item before itself is a no-op. |
| 225 return newItem; | 225 return newItem; |
| 226 } | 226 } |
| 227 | 227 |
| 228 // Spec: Inserts a new item into the list at the specified position. The
index of the item before which the new item is to be | 228 // Spec: Inserts a new item into the list at the specified position. The
index of the item before which the new item is to be |
| 229 // inserted. The first item is number 0. If the index is equal to 0, the
n the new item is inserted at the front of the list. | 229 // inserted. The first item is number 0. If the index is equal to 0, the
n the new item is inserted at the front of the list. |
| 230 m_values->insert(index, newItem); | 230 m_values->insert(index, newItem); |
| 231 | 231 |
| 232 commitChange(); | 232 commitChange(); |
| 233 return newItem; | 233 return newItem; |
| 234 } | 234 } |
| 235 | 235 |
| 236 PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff pa
ssNewItem, unsigned index, ExceptionState& es) | 236 PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff pa
ssNewItem, unsigned index, ExceptionState& exceptionState) |
| 237 { | 237 { |
| 238 ASSERT(m_wrappers); | 238 ASSERT(m_wrappers); |
| 239 if (!canAlterList(es)) | 239 if (!canAlterList(exceptionState)) |
| 240 return 0; | 240 return 0; |
| 241 | 241 |
| 242 // Not specified, but FF/Opera do it this way, and it's just sane. | 242 // Not specified, but FF/Opera do it this way, and it's just sane. |
| 243 if (!passNewItem) { | 243 if (!passNewItem) { |
| 244 es.throwUninformativeAndGenericTypeError(); | 244 exceptionState.throwUninformativeAndGenericTypeError(); |
| 245 return 0; | 245 return 0; |
| 246 } | 246 } |
| 247 | 247 |
| 248 // Spec: If the index is greater than or equal to numberOfItems, then th
e new item is appended to the end of the list. | 248 // Spec: If the index is greater than or equal to numberOfItems, then th
e new item is appended to the end of the list. |
| 249 if (index > m_values->size()) | 249 if (index > m_values->size()) |
| 250 index = m_values->size(); | 250 index = m_values->size(); |
| 251 | 251 |
| 252 RefPtr<ListItemTearOff> newItem = passNewItem; | 252 RefPtr<ListItemTearOff> newItem = passNewItem; |
| 253 ASSERT(m_values->size() == m_wrappers->size()); | 253 ASSERT(m_values->size() == m_wrappers->size()); |
| 254 | 254 |
| 255 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 255 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 256 if (!processIncomingListItemWrapper(newItem, &index)) | 256 if (!processIncomingListItemWrapper(newItem, &index)) |
| 257 return newItem.release(); | 257 return newItem.release(); |
| 258 | 258 |
| 259 // Spec: Inserts a new item into the list at the specified position. The
index of the item before which the new item is to be | 259 // Spec: Inserts a new item into the list at the specified position. The
index of the item before which the new item is to be |
| 260 // inserted. The first item is number 0. If the index is equal to 0, the
n the new item is inserted at the front of the list. | 260 // inserted. The first item is number 0. If the index is equal to 0, the
n the new item is inserted at the front of the list. |
| 261 m_values->insert(index, newItem->propertyReference()); | 261 m_values->insert(index, newItem->propertyReference()); |
| 262 | 262 |
| 263 // Store new wrapper at position 'index', change its underlying value, s
o mutations of newItem, directly affect the item in the list. | 263 // Store new wrapper at position 'index', change its underlying value, s
o mutations of newItem, directly affect the item in the list. |
| 264 m_wrappers->insert(index, newItem); | 264 m_wrappers->insert(index, newItem); |
| 265 | 265 |
| 266 commitChange(); | 266 commitChange(); |
| 267 return newItem.release(); | 267 return newItem.release(); |
| 268 } | 268 } |
| 269 | 269 |
| 270 // SVGList::replaceItem() | 270 // SVGList::replaceItem() |
| 271 bool canReplaceItem(unsigned index, ExceptionState& es) | 271 bool canReplaceItem(unsigned index, ExceptionState& exceptionState) |
| 272 { | 272 { |
| 273 if (!canAlterList(es)) | 273 if (!canAlterList(exceptionState)) |
| 274 return false; | 274 return false; |
| 275 | 275 |
| 276 if (index >= m_values->size()) { | 276 if (index >= m_values->size()) { |
| 277 es.throwUninformativeAndGenericDOMException(IndexSizeError); | 277 exceptionState.throwUninformativeAndGenericDOMException(IndexSizeErr
or); |
| 278 return false; | 278 return false; |
| 279 } | 279 } |
| 280 | 280 |
| 281 return true; | 281 return true; |
| 282 } | 282 } |
| 283 | 283 |
| 284 ListItemType replaceItemValues(const ListItemType& newItem, unsigned index,
ExceptionState& es) | 284 ListItemType replaceItemValues(const ListItemType& newItem, unsigned index,
ExceptionState& exceptionState) |
| 285 { | 285 { |
| 286 if (!canReplaceItem(index, es)) | 286 if (!canReplaceItem(index, exceptionState)) |
| 287 return ListItemType(); | 287 return ListItemType(); |
| 288 | 288 |
| 289 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 289 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 290 // Spec: If the item is already in this list, note that the index of the
item to replace is before the removal of the item. | 290 // Spec: If the item is already in this list, note that the index of the
item to replace is before the removal of the item. |
| 291 if (!processIncomingListItemValue(newItem, &index)) { | 291 if (!processIncomingListItemValue(newItem, &index)) { |
| 292 // Replacing the item with itself is a no-op. | 292 // Replacing the item with itself is a no-op. |
| 293 return newItem; | 293 return newItem; |
| 294 } | 294 } |
| 295 | 295 |
| 296 if (m_values->isEmpty()) { | 296 if (m_values->isEmpty()) { |
| 297 // 'newItem' already lived in our list, we removed it, and now we're
empty, which means there's nothing to replace. | 297 // 'newItem' already lived in our list, we removed it, and now we're
empty, which means there's nothing to replace. |
| 298 es.throwUninformativeAndGenericDOMException(IndexSizeError); | 298 exceptionState.throwUninformativeAndGenericDOMException(IndexSizeErr
or); |
| 299 return ListItemType(); | 299 return ListItemType(); |
| 300 } | 300 } |
| 301 | 301 |
| 302 // Update the value at the desired position 'index'. | 302 // Update the value at the desired position 'index'. |
| 303 m_values->at(index) = newItem; | 303 m_values->at(index) = newItem; |
| 304 | 304 |
| 305 commitChange(); | 305 commitChange(); |
| 306 return newItem; | 306 return newItem; |
| 307 } | 307 } |
| 308 | 308 |
| 309 PassListItemTearOff replaceItemValuesAndWrappers(PassListItemTearOff passNew
Item, unsigned index, ExceptionState& es) | 309 PassListItemTearOff replaceItemValuesAndWrappers(PassListItemTearOff passNew
Item, unsigned index, ExceptionState& exceptionState) |
| 310 { | 310 { |
| 311 ASSERT(m_wrappers); | 311 ASSERT(m_wrappers); |
| 312 if (!canReplaceItem(index, es)) | 312 if (!canReplaceItem(index, exceptionState)) |
| 313 return 0; | 313 return 0; |
| 314 | 314 |
| 315 // Not specified, but FF/Opera do it this way, and it's just sane. | 315 // Not specified, but FF/Opera do it this way, and it's just sane. |
| 316 if (!passNewItem) { | 316 if (!passNewItem) { |
| 317 es.throwUninformativeAndGenericTypeError(); | 317 exceptionState.throwUninformativeAndGenericTypeError(); |
| 318 return 0; | 318 return 0; |
| 319 } | 319 } |
| 320 | 320 |
| 321 ASSERT(m_values->size() == m_wrappers->size()); | 321 ASSERT(m_values->size() == m_wrappers->size()); |
| 322 RefPtr<ListItemTearOff> newItem = passNewItem; | 322 RefPtr<ListItemTearOff> newItem = passNewItem; |
| 323 | 323 |
| 324 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 324 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 325 // Spec: If the item is already in this list, note that the index of the
item to replace is before the removal of the item. | 325 // Spec: If the item is already in this list, note that the index of the
item to replace is before the removal of the item. |
| 326 if (!processIncomingListItemWrapper(newItem, &index)) | 326 if (!processIncomingListItemWrapper(newItem, &index)) |
| 327 return newItem.release(); | 327 return newItem.release(); |
| 328 | 328 |
| 329 if (m_values->isEmpty()) { | 329 if (m_values->isEmpty()) { |
| 330 ASSERT(m_wrappers->isEmpty()); | 330 ASSERT(m_wrappers->isEmpty()); |
| 331 // 'passNewItem' already lived in our list, we removed it, and now w
e're empty, which means there's nothing to replace. | 331 // 'passNewItem' already lived in our list, we removed it, and now w
e're empty, which means there's nothing to replace. |
| 332 es.throwUninformativeAndGenericDOMException(IndexSizeError); | 332 exceptionState.throwUninformativeAndGenericDOMException(IndexSizeErr
or); |
| 333 return 0; | 333 return 0; |
| 334 } | 334 } |
| 335 | 335 |
| 336 // Detach the existing wrapper. | 336 // Detach the existing wrapper. |
| 337 RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index); | 337 RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index); |
| 338 if (oldItem) | 338 if (oldItem) |
| 339 oldItem->detachWrapper(); | 339 oldItem->detachWrapper(); |
| 340 | 340 |
| 341 // Update the value and the wrapper at the desired position 'index'. | 341 // Update the value and the wrapper at the desired position 'index'. |
| 342 m_values->at(index) = newItem->propertyReference(); | 342 m_values->at(index) = newItem->propertyReference(); |
| 343 m_wrappers->at(index) = newItem; | 343 m_wrappers->at(index) = newItem; |
| 344 | 344 |
| 345 commitChange(); | 345 commitChange(); |
| 346 return newItem.release(); | 346 return newItem.release(); |
| 347 } | 347 } |
| 348 | 348 |
| 349 // SVGList::removeItem() | 349 // SVGList::removeItem() |
| 350 bool canRemoveItem(unsigned index, ExceptionState& es) | 350 bool canRemoveItem(unsigned index, ExceptionState& exceptionState) |
| 351 { | 351 { |
| 352 if (!canAlterList(es)) | 352 if (!canAlterList(exceptionState)) |
| 353 return false; | 353 return false; |
| 354 | 354 |
| 355 if (index >= m_values->size()) { | 355 if (index >= m_values->size()) { |
| 356 es.throwUninformativeAndGenericDOMException(IndexSizeError); | 356 exceptionState.throwUninformativeAndGenericDOMException(IndexSizeErr
or); |
| 357 return false; | 357 return false; |
| 358 } | 358 } |
| 359 | 359 |
| 360 return true; | 360 return true; |
| 361 } | 361 } |
| 362 | 362 |
| 363 ListItemType removeItemValues(unsigned index, ExceptionState& es) | 363 ListItemType removeItemValues(unsigned index, ExceptionState& exceptionState
) |
| 364 { | 364 { |
| 365 if (!canRemoveItem(index, es)) | 365 if (!canRemoveItem(index, exceptionState)) |
| 366 return ListItemType(); | 366 return ListItemType(); |
| 367 | 367 |
| 368 ListItemType oldItem = m_values->at(index); | 368 ListItemType oldItem = m_values->at(index); |
| 369 m_values->remove(index); | 369 m_values->remove(index); |
| 370 | 370 |
| 371 commitChange(); | 371 commitChange(); |
| 372 return oldItem; | 372 return oldItem; |
| 373 } | 373 } |
| 374 | 374 |
| 375 PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff*
animatedList, unsigned index, ExceptionState& es) | 375 PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff*
animatedList, unsigned index, ExceptionState& exceptionState) |
| 376 { | 376 { |
| 377 ASSERT(m_wrappers); | 377 ASSERT(m_wrappers); |
| 378 if (!canRemoveItem(index, es)) | 378 if (!canRemoveItem(index, exceptionState)) |
| 379 return 0; | 379 return 0; |
| 380 | 380 |
| 381 ASSERT(m_values->size() == m_wrappers->size()); | 381 ASSERT(m_values->size() == m_wrappers->size()); |
| 382 | 382 |
| 383 // Detach the existing wrapper. | 383 // Detach the existing wrapper. |
| 384 RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index); | 384 RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index); |
| 385 if (!oldItem) | 385 if (!oldItem) |
| 386 oldItem = ListItemTearOff::create(animatedList, UndefinedRole, m_val
ues->at(index)); | 386 oldItem = ListItemTearOff::create(animatedList, UndefinedRole, m_val
ues->at(index)); |
| 387 | 387 |
| 388 oldItem->detachWrapper(); | 388 oldItem->detachWrapper(); |
| 389 m_wrappers->remove(index); | 389 m_wrappers->remove(index); |
| 390 m_values->remove(index); | 390 m_values->remove(index); |
| 391 | 391 |
| 392 commitChange(); | 392 commitChange(); |
| 393 return oldItem.release(); | 393 return oldItem.release(); |
| 394 } | 394 } |
| 395 | 395 |
| 396 // SVGList::appendItem() | 396 // SVGList::appendItem() |
| 397 ListItemType appendItemValues(const ListItemType& newItem, ExceptionState& e
s) | 397 ListItemType appendItemValues(const ListItemType& newItem, ExceptionState& e
xceptionState) |
| 398 { | 398 { |
| 399 if (!canAlterList(es)) | 399 if (!canAlterList(exceptionState)) |
| 400 return ListItemType(); | 400 return ListItemType(); |
| 401 | 401 |
| 402 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 402 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 403 processIncomingListItemValue(newItem, 0); | 403 processIncomingListItemValue(newItem, 0); |
| 404 | 404 |
| 405 // Append the value at the end of the list. | 405 // Append the value at the end of the list. |
| 406 m_values->append(newItem); | 406 m_values->append(newItem); |
| 407 | 407 |
| 408 commitChange(ListModificationAppend); | 408 commitChange(ListModificationAppend); |
| 409 return newItem; | 409 return newItem; |
| 410 } | 410 } |
| 411 | 411 |
| 412 PassListItemTearOff appendItemValuesAndWrappers(PassListItemTearOff passNewI
tem, ExceptionState& es) | 412 PassListItemTearOff appendItemValuesAndWrappers(PassListItemTearOff passNewI
tem, ExceptionState& exceptionState) |
| 413 { | 413 { |
| 414 ASSERT(m_wrappers); | 414 ASSERT(m_wrappers); |
| 415 if (!canAlterList(es)) | 415 if (!canAlterList(exceptionState)) |
| 416 return 0; | 416 return 0; |
| 417 | 417 |
| 418 // Not specified, but FF/Opera do it this way, and it's just sane. | 418 // Not specified, but FF/Opera do it this way, and it's just sane. |
| 419 if (!passNewItem) { | 419 if (!passNewItem) { |
| 420 es.throwUninformativeAndGenericTypeError(); | 420 exceptionState.throwUninformativeAndGenericTypeError(); |
| 421 return 0; | 421 return 0; |
| 422 } | 422 } |
| 423 | 423 |
| 424 RefPtr<ListItemTearOff> newItem = passNewItem; | 424 RefPtr<ListItemTearOff> newItem = passNewItem; |
| 425 ASSERT(m_values->size() == m_wrappers->size()); | 425 ASSERT(m_values->size() == m_wrappers->size()); |
| 426 | 426 |
| 427 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 427 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
| 428 processIncomingListItemWrapper(newItem, 0); | 428 processIncomingListItemWrapper(newItem, 0); |
| 429 | 429 |
| 430 // Append the value and wrapper at the end of the list. | 430 // Append the value and wrapper at the end of the list. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 | 473 |
| 474 SVGPropertyRole m_role; | 474 SVGPropertyRole m_role; |
| 475 bool m_ownsValues; | 475 bool m_ownsValues; |
| 476 PropertyType* m_values; | 476 PropertyType* m_values; |
| 477 ListWrapperCache* m_wrappers; | 477 ListWrapperCache* m_wrappers; |
| 478 }; | 478 }; |
| 479 | 479 |
| 480 } | 480 } |
| 481 | 481 |
| 482 #endif // SVGListProperty_h | 482 #endif // SVGListProperty_h |
| OLD | NEW |