OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 164 |
165 bool adjustFromToListValues(PassRefPtrWillBeRawPtr<Derived> fromList, PassRe
fPtrWillBeRawPtr<Derived> toList, float percentage, AnimationMode); | 165 bool adjustFromToListValues(PassRefPtrWillBeRawPtr<Derived> fromList, PassRe
fPtrWillBeRawPtr<Derived> toList, float percentage, AnimationMode); |
166 | 166 |
167 virtual PassRefPtrWillBeRawPtr<ItemPropertyType> createPaddingItem() const | 167 virtual PassRefPtrWillBeRawPtr<ItemPropertyType> createPaddingItem() const |
168 { | 168 { |
169 return ItemPropertyType::create(); | 169 return ItemPropertyType::create(); |
170 } | 170 } |
171 | 171 |
172 private: | 172 private: |
173 inline bool checkIndexBound(size_t, ExceptionState&); | 173 inline bool checkIndexBound(size_t, ExceptionState&); |
174 bool removeFromOldOwnerListAndAdjustIndex(PassRefPtrWillBeRawPtr<ItemPropert
yType>, size_t* indexToModify); | |
175 size_t findItem(PassRefPtrWillBeRawPtr<ItemPropertyType>); | 174 size_t findItem(PassRefPtrWillBeRawPtr<ItemPropertyType>); |
176 | 175 |
177 WillBeHeapVector<RefPtrWillBeMember<ItemPropertyType>> m_values; | 176 WillBeHeapVector<RefPtrWillBeMember<ItemPropertyType>> m_values; |
178 | 177 |
179 static PassRefPtrWillBeRawPtr<Derived> toDerived(PassRefPtrWillBeRawPtr<SVGP
ropertyBase> passBase) | 178 static PassRefPtrWillBeRawPtr<Derived> toDerived(PassRefPtrWillBeRawPtr<SVGP
ropertyBase> passBase) |
180 { | 179 { |
181 if (!passBase) | 180 if (!passBase) |
182 return nullptr; | 181 return nullptr; |
183 | 182 |
184 RefPtrWillBeRawPtr<SVGPropertyBase> base = passBase; | 183 RefPtrWillBeRawPtr<SVGPropertyBase> base = passBase; |
(...skipping 29 matching lines...) Expand all Loading... |
214 } | 213 } |
215 | 214 |
216 m_values.clear(); | 215 m_values.clear(); |
217 } | 216 } |
218 | 217 |
219 template<typename Derived, typename ItemProperty> | 218 template<typename Derived, typename ItemProperty> |
220 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::initialize(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem) | 219 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::initialize(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem) |
221 { | 220 { |
222 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; | 221 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; |
223 | 222 |
224 // Spec: If the inserted item is already in a list, it is removed from its p
revious list before it is inserted into this list. | |
225 removeFromOldOwnerListAndAdjustIndex(newItem, 0); | |
226 | |
227 // Spec: Clears all existing current items from the list and re-initializes
the list to hold the single item specified by the parameter. | 223 // Spec: Clears all existing current items from the list and re-initializes
the list to hold the single item specified by the parameter. |
228 clear(); | 224 clear(); |
229 append(newItem); | 225 append(newItem); |
230 return newItem.release(); | 226 return newItem.release(); |
231 } | 227 } |
232 | 228 |
233 template<typename Derived, typename ItemProperty> | 229 template<typename Derived, typename ItemProperty> |
234 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::getItem(size_t index, ExceptionState& exceptionState) | 230 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::getItem(size_t index, ExceptionState& exceptionState) |
235 { | 231 { |
236 if (!checkIndexBound(index, exceptionState)) | 232 if (!checkIndexBound(index, exceptionState)) |
237 return nullptr; | 233 return nullptr; |
238 | 234 |
239 ASSERT(index < m_values.size()); | 235 ASSERT(index < m_values.size()); |
240 ASSERT(m_values.at(index)->ownerList() == this); | 236 ASSERT(m_values.at(index)->ownerList() == this); |
241 return m_values.at(index); | 237 return m_values.at(index); |
242 } | 238 } |
243 | 239 |
244 template<typename Derived, typename ItemProperty> | 240 template<typename Derived, typename ItemProperty> |
245 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::insertItemBefore(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem, size_t ind
ex) | 241 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::insertItemBefore(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem, size_t ind
ex) |
246 { | 242 { |
247 // Spec: If the index is greater than or equal to length, then the new item
is appended to the end of the list. | 243 // Spec: If the index is greater than or equal to length, then the new item
is appended to the end of the list. |
248 if (index > m_values.size()) | 244 if (index > m_values.size()) |
249 index = m_values.size(); | 245 index = m_values.size(); |
250 | 246 |
251 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; | 247 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; |
252 | 248 |
253 // Spec: If newItem is already in a list, it is removed from its previous li
st before it is inserted into this list. | |
254 if (!removeFromOldOwnerListAndAdjustIndex(newItem, &index)) { | |
255 // Inserting the item before itself is a no-op. | |
256 return newItem.release(); | |
257 } | |
258 | |
259 // Spec: Inserts a new item into the list at the specified position. The ind
ex of the item before which the new item is to be | 249 // Spec: Inserts a new item into the list at the specified position. The ind
ex 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, then th
e new item is inserted at the front of the list. | 250 // inserted. The first item is number 0. If the index is equal to 0, then th
e new item is inserted at the front of the list. |
261 m_values.insert(index, newItem); | 251 m_values.insert(index, newItem); |
262 newItem->setOwnerList(this); | 252 newItem->setOwnerList(this); |
263 | 253 |
264 return newItem.release(); | 254 return newItem.release(); |
265 } | 255 } |
266 | 256 |
267 template<typename Derived, typename ItemProperty> | 257 template<typename Derived, typename ItemProperty> |
268 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::removeItem(size_t index, ExceptionState& exceptionState) | 258 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::removeItem(size_t index, ExceptionState& exceptionState) |
269 { | 259 { |
270 if (index >= m_values.size()) { | 260 if (index >= m_values.size()) { |
271 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde
xExceedsMaximumBound("index", index, m_values.size())); | 261 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde
xExceedsMaximumBound("index", index, m_values.size())); |
272 return nullptr; | 262 return nullptr; |
273 } | 263 } |
274 ASSERT(m_values.at(index)->ownerList() == this); | 264 ASSERT(m_values.at(index)->ownerList() == this); |
275 RefPtrWillBeRawPtr<ItemPropertyType> oldItem = m_values.at(index); | 265 RefPtrWillBeRawPtr<ItemPropertyType> oldItem = m_values.at(index); |
276 m_values.remove(index); | 266 m_values.remove(index); |
277 oldItem->setOwnerList(0); | 267 oldItem->setOwnerList(0); |
278 return oldItem.release(); | 268 return oldItem.release(); |
279 } | 269 } |
280 | 270 |
281 template<typename Derived, typename ItemProperty> | 271 template<typename Derived, typename ItemProperty> |
282 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::appendItem(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem) | 272 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::appendItem(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem) |
283 { | 273 { |
284 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; | 274 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; |
285 | 275 |
286 // Spec: If newItem is already in a list, it is removed from its previous li
st before it is inserted into this list. | |
287 removeFromOldOwnerListAndAdjustIndex(newItem, 0); | |
288 | |
289 // Append the value and wrapper at the end of the list. | 276 // Append the value and wrapper at the end of the list. |
290 append(newItem); | 277 append(newItem); |
291 | 278 |
292 return newItem.release(); | 279 return newItem.release(); |
293 } | 280 } |
294 | 281 |
295 template<typename Derived, typename ItemProperty> | 282 template<typename Derived, typename ItemProperty> |
296 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::replaceItem(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem, size_t index, E
xceptionState& exceptionState) | 283 PassRefPtrWillBeRawPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty
>::replaceItem(PassRefPtrWillBeRawPtr<ItemProperty> passNewItem, size_t index, E
xceptionState& exceptionState) |
297 { | 284 { |
298 if (!checkIndexBound(index, exceptionState)) | 285 if (!checkIndexBound(index, exceptionState)) |
299 return nullptr; | 286 return nullptr; |
300 | 287 |
301 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; | 288 RefPtrWillBeRawPtr<ItemPropertyType> newItem = passNewItem; |
302 | 289 |
303 // Spec: If newItem is already in a list, it is removed from its previous li
st before it is inserted into this list. | |
304 // Spec: If the item is already in this list, note that the index of the ite
m to replace is before the removal of the item. | |
305 if (!removeFromOldOwnerListAndAdjustIndex(newItem, &index)) { | |
306 // Replacing the item with itself is a no-op. | |
307 return newItem.release(); | |
308 } | |
309 | |
310 if (m_values.isEmpty()) { | 290 if (m_values.isEmpty()) { |
311 // 'newItem' already lived in our list, we removed it, and now we're emp
ty, which means there's nothing to replace. | 291 // 'newItem' already lived in our list, we removed it, and now we're emp
ty, which means there's nothing to replace. |
312 exceptionState.throwDOMException(IndexSizeError, String::format("Failed
to replace the provided item at index %zu.", index)); | 292 exceptionState.throwDOMException(IndexSizeError, String::format("Failed
to replace the provided item at index %zu.", index)); |
313 return nullptr; | 293 return nullptr; |
314 } | 294 } |
315 | 295 |
316 // Update the value at the desired position 'index'. | 296 // Update the value at the desired position 'index'. |
317 RefPtrWillBeMember<ItemPropertyType>& position = m_values[index]; | 297 RefPtrWillBeMember<ItemPropertyType>& position = m_values[index]; |
318 ASSERT(position->ownerList() == this); | 298 ASSERT(position->ownerList() == this); |
319 position->setOwnerList(0); | 299 position->setOwnerList(0); |
320 position = newItem; | 300 position = newItem; |
321 newItem->setOwnerList(this); | 301 newItem->setOwnerList(this); |
322 | 302 |
323 return newItem.release(); | 303 return newItem.release(); |
324 } | 304 } |
325 | 305 |
326 template<typename Derived, typename ItemProperty> | 306 template<typename Derived, typename ItemProperty> |
327 bool SVGListPropertyHelper<Derived, ItemProperty>::checkIndexBound(size_t index,
ExceptionState& exceptionState) | 307 bool SVGListPropertyHelper<Derived, ItemProperty>::checkIndexBound(size_t index,
ExceptionState& exceptionState) |
328 { | 308 { |
329 if (index >= m_values.size()) { | 309 if (index >= m_values.size()) { |
330 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde
xExceedsMaximumBound("index", index, m_values.size())); | 310 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde
xExceedsMaximumBound("index", index, m_values.size())); |
331 return false; | 311 return false; |
332 } | 312 } |
333 | 313 |
334 return true; | 314 return true; |
335 } | 315 } |
336 | 316 |
337 template<typename Derived, typename ItemProperty> | 317 template<typename Derived, typename ItemProperty> |
338 bool SVGListPropertyHelper<Derived, ItemProperty>::removeFromOldOwnerListAndAdju
stIndex(PassRefPtrWillBeRawPtr<ItemPropertyType> passItem, size_t* indexToModify
) | |
339 { | |
340 RefPtrWillBeRawPtr<ItemPropertyType> item = passItem; | |
341 ASSERT(item); | |
342 RefPtrWillBeRawPtr<Derived> ownerList = toDerived(item->ownerList()); | |
343 if (!ownerList) | |
344 return true; | |
345 | |
346 // Spec: If newItem is already in a list, it is removed from its previous li
st before it is inserted into this list. | |
347 // 'newItem' is already living in another list. If it's not our list, synchr
onize the other lists wrappers after the removal. | |
348 bool livesInOtherList = ownerList.get() != this; | |
349 size_t indexToRemove = ownerList->findItem(item); | |
350 ASSERT(indexToRemove != WTF::kNotFound); | |
351 | |
352 // Do not remove newItem if already in this list at the target index. | |
353 if (!livesInOtherList && indexToModify && indexToRemove == *indexToModify) | |
354 return false; | |
355 | |
356 ownerList->removeItem(indexToRemove, ASSERT_NO_EXCEPTION); | |
357 | |
358 if (!indexToModify) | |
359 return true; | |
360 | |
361 // If the item lived in our list, adjust the insertion index. | |
362 if (!livesInOtherList) { | |
363 size_t& index = *indexToModify; | |
364 // 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. | |
365 if (static_cast<size_t>(indexToRemove) < index) | |
366 --index; | |
367 } | |
368 | |
369 return true; | |
370 } | |
371 | |
372 template<typename Derived, typename ItemProperty> | |
373 size_t SVGListPropertyHelper<Derived, ItemProperty>::findItem(PassRefPtrWillBeRa
wPtr<ItemPropertyType> item) | 318 size_t SVGListPropertyHelper<Derived, ItemProperty>::findItem(PassRefPtrWillBeRa
wPtr<ItemPropertyType> item) |
374 { | 319 { |
375 return m_values.find(item); | 320 return m_values.find(item); |
376 } | 321 } |
377 | 322 |
378 template<typename Derived, typename ItemProperty> | 323 template<typename Derived, typename ItemProperty> |
379 void SVGListPropertyHelper<Derived, ItemProperty>::deepCopy(PassRefPtrWillBeRawP
tr<Derived> passFrom) | 324 void SVGListPropertyHelper<Derived, ItemProperty>::deepCopy(PassRefPtrWillBeRawP
tr<Derived> passFrom) |
380 { | 325 { |
381 RefPtrWillBeRawPtr<Derived> from = passFrom; | 326 RefPtrWillBeRawPtr<Derived> from = passFrom; |
382 | 327 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 for (size_t i = 0; i < paddingCount; ++i) | 363 for (size_t i = 0; i < paddingCount; ++i) |
419 append(createPaddingItem()); | 364 append(createPaddingItem()); |
420 } | 365 } |
421 | 366 |
422 return true; | 367 return true; |
423 } | 368 } |
424 | 369 |
425 } | 370 } |
426 | 371 |
427 #endif // SVGListPropertyHelper_h | 372 #endif // SVGListPropertyHelper_h |
OLD | NEW |