Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: Source/core/svg/properties/NewSVGListPropertyHelper.h

Issue 208133002: [SVG] Remove "New" prefix from properties implementation. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifndef NewSVGListPropertyHelper_h
32 #define NewSVGListPropertyHelper_h
33
34 #include "bindings/v8/ExceptionMessages.h"
35 #include "bindings/v8/ExceptionStatePlaceholder.h"
36 #include "core/dom/ExceptionCode.h"
37 #include "core/svg/properties/NewSVGProperty.h"
38 #include "wtf/PassRefPtr.h"
39 #include "wtf/Vector.h"
40
41 namespace WebCore {
42
43 // This is an implementation of the SVG*List property spec:
44 // http://www.w3.org/TR/SVG/single-page.html#types-InterfaceSVGLengthList
45 template<typename Derived, typename ItemProperty>
46 class NewSVGListPropertyHelper : public NewSVGPropertyBase {
47 public:
48 typedef ItemProperty ItemPropertyType;
49
50 NewSVGListPropertyHelper()
51 : NewSVGPropertyBase(Derived::classType())
52 {
53 }
54
55 ~NewSVGListPropertyHelper()
56 {
57 clear();
58 }
59
60 // used from Blink C++ code:
61
62 ItemPropertyType* at(size_t index)
63 {
64 ASSERT(index < m_values.size());
65 ASSERT(m_values.at(index)->ownerList() == this);
66 return m_values.at(index).get();
67 }
68
69 const ItemPropertyType* at(size_t index) const
70 {
71 return const_cast<NewSVGListPropertyHelper<Derived, ItemProperty>*>(this )->at(index);
72 }
73
74 class ConstIterator {
75 private:
76 typedef typename Vector<RefPtr<ItemPropertyType> >::const_iterator Wrapp edType;
77
78 public:
79 ConstIterator(WrappedType it)
80 : m_it(it)
81 {
82 }
83
84 ConstIterator& operator++() { ++m_it; return *this; }
85
86 bool operator==(const ConstIterator& o) const { return m_it == o.m_it; }
87 bool operator!=(const ConstIterator& o) const { return m_it != o.m_it; }
88
89 PassRefPtr<ItemPropertyType> operator*() { return *m_it; }
90 PassRefPtr<ItemPropertyType> operator->() { return *m_it; }
91
92 private:
93 WrappedType m_it;
94 };
95
96 ConstIterator begin() const
97 {
98 return ConstIterator(m_values.begin());
99 }
100
101 ConstIterator lastAppended() const
102 {
103 return ConstIterator(m_values.begin() + m_values.size() - 1);
104 }
105
106 ConstIterator end() const
107 {
108 return ConstIterator(m_values.end());
109 }
110
111 void append(PassRefPtr<ItemPropertyType> passNewItem)
112 {
113 RefPtr<ItemPropertyType> newItem = passNewItem;
114
115 ASSERT(newItem);
116 m_values.append(newItem);
117 newItem->setOwnerList(this);
118 }
119
120 bool operator==(const Derived&) const;
121 bool operator!=(const Derived& other) const
122 {
123 return !(*this == other);
124 }
125
126 bool isEmpty() const
127 {
128 return !length();
129 }
130
131 // SVGList*Property DOM spec:
132
133 size_t length() const
134 {
135 return m_values.size();
136 }
137
138 void clear();
139
140 PassRefPtr<ItemPropertyType> initialize(PassRefPtr<ItemPropertyType>);
141 PassRefPtr<ItemPropertyType> getItem(size_t, ExceptionState&);
142 PassRefPtr<ItemPropertyType> insertItemBefore(PassRefPtr<ItemPropertyType>, size_t);
143 PassRefPtr<ItemPropertyType> removeItem(size_t, ExceptionState&);
144 PassRefPtr<ItemPropertyType> appendItem(PassRefPtr<ItemPropertyType>);
145 PassRefPtr<ItemPropertyType> replaceItem(PassRefPtr<ItemPropertyType>, size_ t, ExceptionState&);
146
147 protected:
148 void deepCopy(PassRefPtr<Derived>);
149
150 private:
151 inline bool checkIndexBound(size_t, ExceptionState&);
152 bool removeFromOldOwnerListAndAdjustIndex(PassRefPtr<ItemPropertyType>, size _t* indexToModify);
153 size_t findItem(PassRefPtr<ItemPropertyType>);
154
155 Vector<RefPtr<ItemPropertyType> > m_values;
156
157 static PassRefPtr<Derived> toDerived(PassRefPtr<NewSVGPropertyBase> passBase )
158 {
159 if (!passBase)
160 return nullptr;
161
162 RefPtr<NewSVGPropertyBase> base = passBase;
163 ASSERT(base->type() == Derived::classType());
164 return static_pointer_cast<Derived>(base);
165 }
166 };
167
168 template<typename Derived, typename ItemProperty>
169 bool NewSVGListPropertyHelper<Derived, ItemProperty>::operator==(const Derived& other) const
170 {
171 if (length() != other.length())
172 return false;
173
174 size_t size = length();
175 for (size_t i = 0; i < size; ++i) {
176 if (*at(i) != *other.at(i))
177 return false;
178 }
179
180 return true;
181 }
182
183 template<typename Derived, typename ItemProperty>
184 void NewSVGListPropertyHelper<Derived, ItemProperty>::clear()
185 {
186 // detach all list items as they are no longer part of this list
187 typename Vector<RefPtr<ItemPropertyType> >::const_iterator it = m_values.beg in();
188 typename Vector<RefPtr<ItemPropertyType> >::const_iterator itEnd = m_values. end();
189 for (; it != itEnd; ++it) {
190 ASSERT((*it)->ownerList() == this);
191 (*it)->setOwnerList(0);
192 }
193
194 m_values.clear();
195 }
196
197 template<typename Derived, typename ItemProperty>
198 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::initia lize(PassRefPtr<ItemProperty> passNewItem)
199 {
200 RefPtr<ItemPropertyType> newItem = passNewItem;
201
202 // 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.
203 removeFromOldOwnerListAndAdjustIndex(newItem, 0);
204
205 // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter.
206 clear();
207 append(newItem);
208 return newItem.release();
209 }
210
211 template<typename Derived, typename ItemProperty>
212 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::getIte m(size_t index, ExceptionState& exceptionState)
213 {
214 if (!checkIndexBound(index, exceptionState))
215 return nullptr;
216
217 ASSERT(index < m_values.size());
218 ASSERT(m_values.at(index)->ownerList() == this);
219 return m_values.at(index);
220 }
221
222 template<typename Derived, typename ItemProperty>
223 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::insert ItemBefore(PassRefPtr<ItemProperty> passNewItem, size_t index)
224 {
225 // Spec: If the index is greater than or equal to length, then the new item is appended to the end of the list.
226 if (index > m_values.size())
227 index = m_values.size();
228
229 RefPtr<ItemPropertyType> newItem = passNewItem;
230
231 // Spec: If newItem is already in a list, it is removed from its previous li st before it is inserted into this list.
232 if (!removeFromOldOwnerListAndAdjustIndex(newItem, &index)) {
233 // Inserting the item before itself is a no-op.
234 return newItem.release();
235 }
236
237 // 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
238 // 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.
239 m_values.insert(index, newItem);
240 newItem->setOwnerList(this);
241
242 return newItem.release();
243 }
244
245 template<typename Derived, typename ItemProperty>
246 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::remove Item(size_t index, ExceptionState& exceptionState)
247 {
248 if (index >= m_values.size()) {
249 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde xExceedsMaximumBound("index", index, m_values.size()));
250 return nullptr;
251 }
252 ASSERT(m_values.at(index)->ownerList() == this);
253 RefPtr<ItemPropertyType> oldItem = m_values.at(index);
254 m_values.remove(index);
255 oldItem->setOwnerList(0);
256 return oldItem.release();
257 }
258
259 template<typename Derived, typename ItemProperty>
260 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::append Item(PassRefPtr<ItemProperty> passNewItem)
261 {
262 RefPtr<ItemPropertyType> newItem = passNewItem;
263
264 // Spec: If newItem is already in a list, it is removed from its previous li st before it is inserted into this list.
265 removeFromOldOwnerListAndAdjustIndex(newItem, 0);
266
267 // Append the value and wrapper at the end of the list.
268 append(newItem);
269
270 return newItem.release();
271 }
272
273 template<typename Derived, typename ItemProperty>
274 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::replac eItem(PassRefPtr<ItemProperty> passNewItem, size_t index, ExceptionState& except ionState)
275 {
276 if (!checkIndexBound(index, exceptionState))
277 return nullptr;
278
279 RefPtr<ItemPropertyType> newItem = passNewItem;
280
281 // Spec: If newItem is already in a list, it is removed from its previous li st before it is inserted into this list.
282 // 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.
283 if (!removeFromOldOwnerListAndAdjustIndex(newItem, &index)) {
284 // Replacing the item with itself is a no-op.
285 return newItem.release();
286 }
287
288 if (m_values.isEmpty()) {
289 // 'newItem' already lived in our list, we removed it, and now we're emp ty, which means there's nothing to replace.
290 exceptionState.throwDOMException(IndexSizeError, String::format("Failed to replace the provided item at index %zu.", index));
291 return nullptr;
292 }
293
294 // Update the value at the desired position 'index'.
295 RefPtr<ItemPropertyType>& position = m_values[index];
296 ASSERT(position->ownerList() == this);
297 position->setOwnerList(0);
298 position = newItem;
299 newItem->setOwnerList(this);
300
301 return newItem.release();
302 }
303
304 template<typename Derived, typename ItemProperty>
305 bool NewSVGListPropertyHelper<Derived, ItemProperty>::checkIndexBound(size_t ind ex, ExceptionState& exceptionState)
306 {
307 if (index >= m_values.size()) {
308 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde xExceedsMaximumBound("index", index, m_values.size()));
309 return false;
310 }
311
312 return true;
313 }
314
315 template<typename Derived, typename ItemProperty>
316 bool NewSVGListPropertyHelper<Derived, ItemProperty>::removeFromOldOwnerListAndA djustIndex(PassRefPtr<ItemPropertyType> passItem, size_t* indexToModify)
317 {
318 RefPtr<ItemPropertyType> item = passItem;
319 ASSERT(item);
320 RefPtr<Derived> ownerList = toDerived(item->ownerList());
321 if (!ownerList)
322 return true;
323
324 // Spec: If newItem is already in a list, it is removed from its previous li st before it is inserted into this list.
325 // 'newItem' is already living in another list. If it's not our list, synchr onize the other lists wrappers after the removal.
326 bool livesInOtherList = ownerList.get() != this;
327 size_t indexToRemove = ownerList->findItem(item);
328 ASSERT(indexToRemove != WTF::kNotFound);
329
330 // Do not remove newItem if already in this list at the target index.
331 if (!livesInOtherList && indexToModify && indexToRemove == *indexToModify)
332 return false;
333
334 ownerList->removeItem(indexToRemove, ASSERT_NO_EXCEPTION);
335
336 if (!indexToModify)
337 return true;
338
339 // If the item lived in our list, adjust the insertion index.
340 if (!livesInOtherList) {
341 size_t& index = *indexToModify;
342 // 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.
343 if (static_cast<size_t>(indexToRemove) < index)
344 --index;
345 }
346
347 return true;
348 }
349
350 template<typename Derived, typename ItemProperty>
351 size_t NewSVGListPropertyHelper<Derived, ItemProperty>::findItem(PassRefPtr<Item PropertyType> item)
352 {
353 return m_values.find(item);
354 }
355
356 template<typename Derived, typename ItemProperty>
357 void NewSVGListPropertyHelper<Derived, ItemProperty>::deepCopy(PassRefPtr<Derive d> passFrom)
358 {
359 RefPtr<Derived> from = passFrom;
360
361 clear();
362 typename Vector<RefPtr<ItemPropertyType> >::const_iterator it = from->m_valu es.begin();
363 typename Vector<RefPtr<ItemPropertyType> >::const_iterator itEnd = from->m_v alues.end();
364 for (; it != itEnd; ++it) {
365 append((*it)->clone());
366 }
367 }
368
369 }
370
371 #endif // NewSVGListPropertyHelper_h
OLDNEW
« no previous file with comments | « Source/core/svg/properties/NewSVGAnimatedProperty.cpp ('k') | Source/core/svg/properties/NewSVGListPropertyTearOffHelper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698