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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 | 92 |
93 ConstIterator begin() const { return ConstIterator(values_.begin()); } | 93 ConstIterator begin() const { return ConstIterator(values_.begin()); } |
94 ConstIterator end() const { return ConstIterator(values_.end()); } | 94 ConstIterator end() const { return ConstIterator(values_.end()); } |
95 | 95 |
96 void Append(ItemPropertyType* new_item) { | 96 void Append(ItemPropertyType* new_item) { |
97 DCHECK(new_item); | 97 DCHECK(new_item); |
98 values_.push_back(new_item); | 98 values_.push_back(new_item); |
99 new_item->SetOwnerList(this); | 99 new_item->SetOwnerList(this); |
100 } | 100 } |
101 | 101 |
102 bool operator==(const Derived&) const; | 102 bool operator==(const Derived& other) const { |
103 return values_ == other.values_; | |
104 } | |
103 bool operator!=(const Derived& other) const { return !(*this == other); } | 105 bool operator!=(const Derived& other) const { return !(*this == other); } |
104 | 106 |
105 bool IsEmpty() const { return !length(); } | 107 bool IsEmpty() const { return !length(); } |
106 | 108 |
107 virtual Derived* Clone() { | 109 virtual Derived* Clone() { |
108 Derived* svg_list = Derived::Create(); | 110 Derived* svg_list = Derived::Create(); |
109 svg_list->DeepCopy(static_cast<Derived*>(this)); | 111 svg_list->DeepCopy(static_cast<Derived*>(this)); |
110 return svg_list; | 112 return svg_list; |
111 } | 113 } |
112 | 114 |
(...skipping 22 matching lines...) Expand all Loading... | |
135 Derived* to_list, | 137 Derived* to_list, |
136 float percentage, | 138 float percentage, |
137 AnimationMode); | 139 AnimationMode); |
138 | 140 |
139 virtual ItemPropertyType* CreatePaddingItem() const { | 141 virtual ItemPropertyType* CreatePaddingItem() const { |
140 return ItemPropertyType::Create(); | 142 return ItemPropertyType::Create(); |
141 } | 143 } |
142 | 144 |
143 private: | 145 private: |
144 inline bool CheckIndexBound(size_t, ExceptionState&); | 146 inline bool CheckIndexBound(size_t, ExceptionState&); |
145 size_t FindItem(ItemPropertyType*); | |
146 | 147 |
147 HeapVector<Member<ItemPropertyType>> values_; | 148 HeapVector<Member<ItemPropertyType>> values_; |
148 }; | 149 }; |
149 | 150 |
150 template <typename Derived, typename ItemProperty> | 151 template <typename Derived, typename ItemProperty> |
151 bool SVGListPropertyHelper<Derived, ItemProperty>::operator==( | 152 void SVGListPropertyHelper<Derived, ItemProperty>::Clear() { |
152 const Derived& other) const { | 153 // Detach all list items as they are no longer part of this list. |
153 if (length() != other.length()) | 154 for (auto& value : values_) { |
154 return false; | 155 DCHECK_EQ(value->OwnerList(), this); |
155 | 156 value->SetOwnerList(nullptr); |
156 size_t size = length(); | |
157 for (size_t i = 0; i < size; ++i) { | |
158 if (*at(i) != *other.at(i)) | |
159 return false; | |
160 } | 157 } |
161 | |
162 return true; | |
163 } | |
164 | |
165 template <typename Derived, typename ItemProperty> | |
166 void SVGListPropertyHelper<Derived, ItemProperty>::Clear() { | |
167 // detach all list items as they are no longer part of this list | |
168 typename HeapVector<Member<ItemPropertyType>>::const_iterator it = | |
169 values_.begin(); | |
170 typename HeapVector<Member<ItemPropertyType>>::const_iterator it_end = | |
171 values_.end(); | |
172 for (; it != it_end; ++it) { | |
173 DCHECK_EQ((*it)->OwnerList(), this); | |
174 (*it)->SetOwnerList(nullptr); | |
175 } | |
176 | |
177 values_.clear(); | 158 values_.clear(); |
178 } | 159 } |
179 | 160 |
180 template <typename Derived, typename ItemProperty> | 161 template <typename Derived, typename ItemProperty> |
181 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::Initialize( | 162 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::Initialize( |
182 ItemProperty* new_item) { | 163 ItemProperty* new_item) { |
183 // Spec: Clears all existing current items from the list and re-initializes | 164 // Spec: Clears all existing current items from the list and re-initializes |
184 // the list to hold the single item specified by the parameter. | 165 // the list to hold the single item specified by the parameter. |
185 Clear(); | 166 Clear(); |
186 Append(new_item); | 167 Append(new_item); |
187 return new_item; | 168 return new_item; |
188 } | 169 } |
189 | 170 |
190 template <typename Derived, typename ItemProperty> | 171 template <typename Derived, typename ItemProperty> |
191 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::GetItem( | 172 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::GetItem( |
192 size_t index, | 173 size_t index, |
193 ExceptionState& exception_state) { | 174 ExceptionState& exception_state) { |
194 if (!CheckIndexBound(index, exception_state)) | 175 if (!CheckIndexBound(index, exception_state)) |
195 return nullptr; | 176 return nullptr; |
196 | 177 return at(index); |
197 DCHECK_LT(index, values_.size()); | |
198 DCHECK_EQ(values_.at(index)->OwnerList(), this); | |
199 return values_.at(index); | |
200 } | 178 } |
201 | 179 |
202 template <typename Derived, typename ItemProperty> | 180 template <typename Derived, typename ItemProperty> |
203 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::InsertItemBefore( | 181 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::InsertItemBefore( |
204 ItemProperty* new_item, | 182 ItemProperty* new_item, |
205 size_t index) { | 183 size_t index) { |
206 // Spec: If the index is greater than or equal to length, then the new item is | 184 // Spec: If the index is greater than or equal to length, then the new item is |
207 // appended to the end of the list. | 185 // appended to the end of the list. |
208 if (index > values_.size()) | 186 if (index > values_.size()) |
209 index = values_.size(); | 187 index = values_.size(); |
210 | 188 |
211 // Spec: Inserts a new item into the list at the specified position. The index | 189 // Spec: Inserts a new item into the list at the specified position. The index |
212 // of the item before which the new item is to be inserted. The first item is | 190 // of the item before which the new item is to be inserted. The first item is |
213 // number 0. If the index is equal to 0, then the new item is inserted at the | 191 // number 0. If the index is equal to 0, then the new item is inserted at the |
214 // front of the list. | 192 // front of the list. |
215 values_.insert(index, new_item); | 193 values_.insert(index, new_item); |
216 new_item->SetOwnerList(this); | 194 new_item->SetOwnerList(this); |
217 | |
218 return new_item; | 195 return new_item; |
219 } | 196 } |
220 | 197 |
221 template <typename Derived, typename ItemProperty> | 198 template <typename Derived, typename ItemProperty> |
222 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::RemoveItem( | 199 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::RemoveItem( |
223 size_t index, | 200 size_t index, |
224 ExceptionState& exception_state) { | 201 ExceptionState& exception_state) { |
225 if (index >= values_.size()) { | 202 if (!CheckIndexBound(index, exception_state)) |
226 exception_state.ThrowDOMException( | |
227 kIndexSizeError, ExceptionMessages::IndexExceedsMaximumBound( | |
228 "index", index, values_.size())); | |
229 return nullptr; | 203 return nullptr; |
230 } | 204 |
231 DCHECK_EQ(values_.at(index)->OwnerList(), this); | 205 DCHECK_EQ(values_.at(index)->OwnerList(), this); |
232 ItemPropertyType* old_item = values_.at(index); | 206 ItemPropertyType* old_item = values_.at(index); |
233 values_.erase(index); | 207 values_.erase(index); |
234 old_item->SetOwnerList(0); | 208 old_item->SetOwnerList(nullptr); |
235 return old_item; | 209 return old_item; |
236 } | 210 } |
237 | 211 |
238 template <typename Derived, typename ItemProperty> | 212 template <typename Derived, typename ItemProperty> |
239 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::AppendItem( | 213 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::AppendItem( |
240 ItemProperty* new_item) { | 214 ItemProperty* new_item) { |
241 // Append the value and wrapper at the end of the list. | 215 // Append the value and wrapper at the end of the list. |
242 Append(new_item); | 216 Append(new_item); |
243 | |
244 return new_item; | 217 return new_item; |
245 } | 218 } |
246 | 219 |
247 template <typename Derived, typename ItemProperty> | 220 template <typename Derived, typename ItemProperty> |
248 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::ReplaceItem( | 221 ItemProperty* SVGListPropertyHelper<Derived, ItemProperty>::ReplaceItem( |
249 ItemProperty* new_item, | 222 ItemProperty* new_item, |
250 size_t index, | 223 size_t index, |
251 ExceptionState& exception_state) { | 224 ExceptionState& exception_state) { |
252 if (!CheckIndexBound(index, exception_state)) | 225 if (!CheckIndexBound(index, exception_state)) |
253 return nullptr; | 226 return nullptr; |
254 | 227 |
255 if (values_.IsEmpty()) { | 228 if (values_.IsEmpty()) { |
256 // 'newItem' already lived in our list, we removed it, and now we're empty, | 229 // 'newItem' already lived in our list, we removed it, and now we're empty, |
257 // which means there's nothing to replace. | 230 // which means there's nothing to replace. |
231 // TODO(fs): This should not cause us to throw an exception. | |
pdr.
2017/06/04 17:05:08
Is this actually deadcode due to the CheckIndexBou
fs
2017/06/04 17:11:27
Yes, it certainly looks that way. Should check tha
| |
258 exception_state.ThrowDOMException( | 232 exception_state.ThrowDOMException( |
259 kIndexSizeError, | 233 kIndexSizeError, |
260 String::Format("Failed to replace the provided item at index %zu.", | 234 String::Format("Failed to replace the provided item at index %zu.", |
261 index)); | 235 index)); |
262 return nullptr; | 236 return nullptr; |
263 } | 237 } |
264 | 238 |
265 // Update the value at the desired position 'index'. | 239 // Update the value at the desired position 'index'. |
266 Member<ItemPropertyType>& position = values_[index]; | 240 Member<ItemPropertyType>& position = values_[index]; |
267 DCHECK_EQ(position->OwnerList(), this); | 241 DCHECK_EQ(position->OwnerList(), this); |
268 position->SetOwnerList(0); | 242 position->SetOwnerList(nullptr); |
269 position = new_item; | 243 position = new_item; |
270 new_item->SetOwnerList(this); | 244 new_item->SetOwnerList(this); |
271 | |
272 return new_item; | 245 return new_item; |
273 } | 246 } |
274 | 247 |
275 template <typename Derived, typename ItemProperty> | 248 template <typename Derived, typename ItemProperty> |
276 bool SVGListPropertyHelper<Derived, ItemProperty>::CheckIndexBound( | 249 bool SVGListPropertyHelper<Derived, ItemProperty>::CheckIndexBound( |
277 size_t index, | 250 size_t index, |
278 ExceptionState& exception_state) { | 251 ExceptionState& exception_state) { |
279 if (index >= values_.size()) { | 252 if (index >= values_.size()) { |
280 exception_state.ThrowDOMException( | 253 exception_state.ThrowDOMException( |
281 kIndexSizeError, ExceptionMessages::IndexExceedsMaximumBound( | 254 kIndexSizeError, ExceptionMessages::IndexExceedsMaximumBound( |
282 "index", index, values_.size())); | 255 "index", index, values_.size())); |
283 return false; | 256 return false; |
284 } | 257 } |
285 | |
286 return true; | 258 return true; |
287 } | 259 } |
288 | 260 |
289 template <typename Derived, typename ItemProperty> | 261 template <typename Derived, typename ItemProperty> |
290 size_t SVGListPropertyHelper<Derived, ItemProperty>::FindItem( | |
291 ItemPropertyType* item) { | |
292 return values_.Find(item); | |
293 } | |
294 | |
295 template <typename Derived, typename ItemProperty> | |
296 void SVGListPropertyHelper<Derived, ItemProperty>::DeepCopy(Derived* from) { | 262 void SVGListPropertyHelper<Derived, ItemProperty>::DeepCopy(Derived* from) { |
297 Clear(); | 263 Clear(); |
298 typename HeapVector<Member<ItemPropertyType>>::const_iterator it = | 264 for (const auto& from_value : from->values_) |
299 from->values_.begin(); | 265 Append(from_value->Clone()); |
300 typename HeapVector<Member<ItemPropertyType>>::const_iterator it_end = | |
301 from->values_.end(); | |
302 for (; it != it_end; ++it) { | |
303 Append((*it)->Clone()); | |
304 } | |
305 } | 266 } |
306 | 267 |
307 template <typename Derived, typename ItemProperty> | 268 template <typename Derived, typename ItemProperty> |
308 bool SVGListPropertyHelper<Derived, ItemProperty>::AdjustFromToListValues( | 269 bool SVGListPropertyHelper<Derived, ItemProperty>::AdjustFromToListValues( |
309 Derived* from_list, | 270 Derived* from_list, |
310 Derived* to_list, | 271 Derived* to_list, |
311 float percentage, | 272 float percentage, |
312 AnimationMode mode) { | 273 AnimationMode mode) { |
313 // If no 'to' value is given, nothing to animate. | 274 // If no 'to' value is given, nothing to animate. |
314 size_t to_list_size = to_list->length(); | 275 size_t to_list_size = to_list->length(); |
315 if (!to_list_size) | 276 if (!to_list_size) |
316 return false; | 277 return false; |
317 | 278 |
318 // If the 'from' value is given and it's length doesn't match the 'to' value | 279 // If the 'from' value is given and it's length doesn't match the 'to' value |
319 // list length, fallback to a discrete animation. | 280 // list length, fallback to a discrete animation. |
320 size_t from_list_size = from_list->length(); | 281 size_t from_list_size = from_list->length(); |
321 if (from_list_size != to_list_size && from_list_size) { | 282 if (from_list_size != to_list_size && from_list_size) { |
322 if (percentage < 0.5) { | 283 if (percentage < 0.5) { |
323 if (mode != kToAnimation) | 284 if (mode != kToAnimation) |
324 DeepCopy(from_list); | 285 DeepCopy(from_list); |
325 } else { | 286 } else { |
326 DeepCopy(to_list); | 287 DeepCopy(to_list); |
327 } | 288 } |
328 | |
329 return false; | 289 return false; |
330 } | 290 } |
331 | 291 |
332 DCHECK(!from_list_size || from_list_size == to_list_size); | 292 DCHECK(!from_list_size || from_list_size == to_list_size); |
333 if (length() < to_list_size) { | 293 for (size_t i = length(); i < to_list_size; ++i) |
334 size_t padding_count = to_list_size - length(); | 294 Append(CreatePaddingItem()); |
335 for (size_t i = 0; i < padding_count; ++i) | |
336 Append(CreatePaddingItem()); | |
337 } | |
338 | 295 |
339 return true; | 296 return true; |
340 } | 297 } |
341 | 298 |
342 } // namespace blink | 299 } // namespace blink |
343 | 300 |
344 #endif // SVGListPropertyHelper_h | 301 #endif // SVGListPropertyHelper_h |
OLD | NEW |