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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned in
dex, ExceptionCode& ec) | 214 ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned in
dex, ExceptionCode& ec) |
215 { | 215 { |
216 if (!canAlterList(ec)) | 216 if (!canAlterList(ec)) |
217 return ListItemType(); | 217 return ListItemType(); |
218 | 218 |
219 // 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 // Spec: If the index is greater than or equal to numberOfItems, then th
e new item is appended to the end of the list. |
220 if (index > m_values->size()) | 220 if (index > m_values->size()) |
221 index = m_values->size(); | 221 index = m_values->size(); |
222 | 222 |
223 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 223 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
224 processIncomingListItemValue(newItem, &index); | 224 if (!processIncomingListItemValue(newItem, &index)) { |
| 225 // Inserting the item before itself is a no-op. |
| 226 return newItem; |
| 227 } |
225 | 228 |
226 // 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 // 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 |
227 // 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 // 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. |
228 m_values->insert(index, newItem); | 231 m_values->insert(index, newItem); |
229 | 232 |
230 commitChange(); | 233 commitChange(); |
231 return newItem; | 234 return newItem; |
232 } | 235 } |
233 | 236 |
234 PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff pa
ssNewItem, unsigned index, ExceptionCode& ec) | 237 PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff pa
ssNewItem, unsigned index, ExceptionCode& ec) |
235 { | 238 { |
236 ASSERT(m_wrappers); | 239 ASSERT(m_wrappers); |
237 if (!canAlterList(ec)) | 240 if (!canAlterList(ec)) |
238 return 0; | 241 return 0; |
239 | 242 |
240 // Not specified, but FF/Opera do it this way, and it's just sane. | 243 // Not specified, but FF/Opera do it this way, and it's just sane. |
241 if (!passNewItem) { | 244 if (!passNewItem) { |
242 ec = SVGException::SVG_WRONG_TYPE_ERR; | 245 ec = SVGException::SVG_WRONG_TYPE_ERR; |
243 return 0; | 246 return 0; |
244 } | 247 } |
245 | 248 |
246 // 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 // Spec: If the index is greater than or equal to numberOfItems, then th
e new item is appended to the end of the list. |
247 if (index > m_values->size()) | 250 if (index > m_values->size()) |
248 index = m_values->size(); | 251 index = m_values->size(); |
249 | 252 |
250 RefPtr<ListItemTearOff> newItem = passNewItem; | 253 RefPtr<ListItemTearOff> newItem = passNewItem; |
251 ASSERT(m_values->size() == m_wrappers->size()); | 254 ASSERT(m_values->size() == m_wrappers->size()); |
252 | 255 |
253 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. | 256 // Spec: If newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
254 processIncomingListItemWrapper(newItem, &index); | 257 if (!processIncomingListItemWrapper(newItem, &index)) |
| 258 return newItem.release(); |
255 | 259 |
256 // 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 // 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 |
257 // 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 // 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. |
258 m_values->insert(index, newItem->propertyReference()); | 262 m_values->insert(index, newItem->propertyReference()); |
259 | 263 |
260 // Store new wrapper at position 'index', change its underlying value, s
o mutations of newItem, directly affect the item in the list. | 264 // Store new wrapper at position 'index', change its underlying value, s
o mutations of newItem, directly affect the item in the list. |
261 m_wrappers->insert(index, newItem); | 265 m_wrappers->insert(index, newItem); |
262 | 266 |
263 commitChange(); | 267 commitChange(); |
264 return newItem.release(); | 268 return newItem.release(); |
(...skipping 13 matching lines...) Expand all Loading... |
278 return true; | 282 return true; |
279 } | 283 } |
280 | 284 |
281 ListItemType replaceItemValues(const ListItemType& newItem, unsigned index,
ExceptionCode& ec) | 285 ListItemType replaceItemValues(const ListItemType& newItem, unsigned index,
ExceptionCode& ec) |
282 { | 286 { |
283 if (!canReplaceItem(index, ec)) | 287 if (!canReplaceItem(index, ec)) |
284 return ListItemType(); | 288 return ListItemType(); |
285 | 289 |
286 // 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 newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
287 // 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 // 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. |
288 processIncomingListItemValue(newItem, &index); | 292 if (!processIncomingListItemValue(newItem, &index)) { |
| 293 // Replacing the item with itself is a no-op. |
| 294 return newItem; |
| 295 } |
289 | 296 |
290 if (m_values->isEmpty()) { | 297 if (m_values->isEmpty()) { |
291 // 'newItem' already lived in our list, we removed it, and now we're
empty, which means there's nothing to replace. | 298 // 'newItem' already lived in our list, we removed it, and now we're
empty, which means there's nothing to replace. |
292 ec = INDEX_SIZE_ERR; | 299 ec = INDEX_SIZE_ERR; |
293 return ListItemType(); | 300 return ListItemType(); |
294 } | 301 } |
295 | 302 |
296 // Update the value at the desired position 'index'. | 303 // Update the value at the desired position 'index'. |
297 m_values->at(index) = newItem; | 304 m_values->at(index) = newItem; |
298 | 305 |
(...skipping 11 matching lines...) Expand all Loading... |
310 if (!passNewItem) { | 317 if (!passNewItem) { |
311 ec = SVGException::SVG_WRONG_TYPE_ERR; | 318 ec = SVGException::SVG_WRONG_TYPE_ERR; |
312 return 0; | 319 return 0; |
313 } | 320 } |
314 | 321 |
315 ASSERT(m_values->size() == m_wrappers->size()); | 322 ASSERT(m_values->size() == m_wrappers->size()); |
316 RefPtr<ListItemTearOff> newItem = passNewItem; | 323 RefPtr<ListItemTearOff> newItem = passNewItem; |
317 | 324 |
318 // 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 newItem is already in a list, it is removed from its previou
s list before it is inserted into this list. |
319 // 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 // 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. |
320 processIncomingListItemWrapper(newItem, &index); | 327 if (!processIncomingListItemWrapper(newItem, &index)) |
| 328 return newItem.release(); |
321 | 329 |
322 if (m_values->isEmpty()) { | 330 if (m_values->isEmpty()) { |
323 ASSERT(m_wrappers->isEmpty()); | 331 ASSERT(m_wrappers->isEmpty()); |
324 // 'passNewItem' already lived in our list, we removed it, and now w
e're empty, which means there's nothing to replace. | 332 // 'passNewItem' already lived in our list, we removed it, and now w
e're empty, which means there's nothing to replace. |
325 ec = INDEX_SIZE_ERR; | 333 ec = INDEX_SIZE_ERR; |
326 return 0; | 334 return 0; |
327 } | 335 } |
328 | 336 |
329 // Detach the existing wrapper. | 337 // Detach the existing wrapper. |
330 RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index); | 338 RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 if (m_ownsValues) | 462 if (m_ownsValues) |
455 delete m_values; | 463 delete m_values; |
456 } | 464 } |
457 | 465 |
458 virtual void commitChange() = 0; | 466 virtual void commitChange() = 0; |
459 virtual void commitChange(ListModification) | 467 virtual void commitChange(ListModification) |
460 { | 468 { |
461 commitChange(); | 469 commitChange(); |
462 } | 470 } |
463 | 471 |
464 virtual void processIncomingListItemValue(const ListItemType& newItem, unsig
ned* indexToModify) = 0; | 472 virtual bool processIncomingListItemValue(const ListItemType& newItem, unsig
ned* indexToModify) = 0; |
465 virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem
, unsigned* indexToModify) = 0; | 473 virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem
, unsigned* indexToModify) = 0; |
466 | 474 |
467 SVGPropertyRole m_role; | 475 SVGPropertyRole m_role; |
468 bool m_ownsValues; | 476 bool m_ownsValues; |
469 PropertyType* m_values; | 477 PropertyType* m_values; |
470 ListWrapperCache* m_wrappers; | 478 ListWrapperCache* m_wrappers; |
471 }; | 479 }; |
472 | 480 |
473 } | 481 } |
474 | 482 |
475 #endif // ENABLE(SVG) | 483 #endif // ENABLE(SVG) |
476 #endif // SVGListProperty_h | 484 #endif // SVGListProperty_h |
OLD | NEW |