OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 * Library General Public License for more details. | 13 * Library General Public License for more details. |
14 * | 14 * |
15 * You should have received a copy of the GNU Library General Public License | 15 * You should have received a copy of the GNU Library General Public License |
16 * along with this library; see the file COPYING.LIB. If not, write to | 16 * along with this library; see the file COPYING.LIB. If not, write to |
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 * Boston, MA 02110-1301, USA. | 18 * Boston, MA 02110-1301, USA. |
19 */ | 19 */ |
20 | 20 |
21 #include "config.h" | 21 #include "config.h" |
22 #include "core/svg/SVGStringList.h" | 22 #include "core/svg/SVGStringList.h" |
23 | 23 |
24 #include "core/svg/SVGElement.h" | 24 #include "core/svg/SVGElement.h" |
25 #include "core/svg/SVGParserUtilities.h" | 25 #include "core/svg/SVGParserUtilities.h" |
26 #include "wtf/text/StringBuilder.h" | 26 #include "wtf/text/StringBuilder.h" |
27 | 27 |
28 namespace WebCore { | 28 namespace WebCore { |
29 | 29 |
30 void SVGStringList::commitChange(SVGElement* contextElement) | 30 SVGStringList::SVGStringList() |
| 31 : NewSVGPropertyBase(classType()) |
31 { | 32 { |
32 ASSERT(contextElement); | |
33 contextElement->invalidateSVGAttributes(); | |
34 contextElement->svgAttributeChanged(m_attributeName); | |
35 } | 33 } |
36 | 34 |
37 void SVGStringList::reset(const String& string) | 35 SVGStringList::~SVGStringList() |
38 { | 36 { |
39 parse(string, ' '); | 37 } |
40 | 38 |
41 // Add empty string, if list is empty. | 39 void SVGStringList::initialize(const String& item) |
42 if (isEmpty()) | 40 { |
43 append(emptyString()); | 41 m_values.clear(); |
| 42 m_values.append(item); |
| 43 } |
| 44 |
| 45 String SVGStringList::getItem(size_t index, ExceptionState& exceptionState) |
| 46 { |
| 47 if (!checkIndexBound(index, exceptionState)) |
| 48 return String(); |
| 49 |
| 50 return m_values.at(index); |
| 51 } |
| 52 |
| 53 void SVGStringList::insertItemBefore(const String& newItem, size_t index) |
| 54 { |
| 55 // Spec: If the index is greater than or equal to numberOfItems, then the ne
w item is appended to the end of the list. |
| 56 if (index > m_values.size()) |
| 57 index = m_values.size(); |
| 58 |
| 59 // 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 |
| 60 // 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. |
| 61 m_values.insert(index, newItem); |
| 62 } |
| 63 |
| 64 String SVGStringList::removeItem(size_t index, ExceptionState& exceptionState) |
| 65 { |
| 66 if (!checkIndexBound(index, exceptionState)) |
| 67 return String(); |
| 68 |
| 69 String oldItem = m_values.at(index); |
| 70 m_values.remove(index); |
| 71 return oldItem; |
| 72 } |
| 73 |
| 74 void SVGStringList::appendItem(const String& newItem) |
| 75 { |
| 76 m_values.append(newItem); |
| 77 } |
| 78 |
| 79 void SVGStringList::replaceItem(const String& newItem, size_t index, ExceptionSt
ate& exceptionState) |
| 80 { |
| 81 if (!checkIndexBound(index, exceptionState)) |
| 82 return; |
| 83 |
| 84 // Update the value at the desired position 'index'. |
| 85 m_values[index] = newItem; |
44 } | 86 } |
45 | 87 |
46 template<typename CharType> | 88 template<typename CharType> |
47 void SVGStringList::parseInternal(const CharType*& ptr, const CharType* end, UCh
ar delimiter) | 89 void SVGStringList::parseInternal(const CharType*& ptr, const CharType* end) |
48 { | 90 { |
| 91 const UChar delimiter = ' '; |
| 92 |
49 while (ptr < end) { | 93 while (ptr < end) { |
50 const CharType* start = ptr; | 94 const CharType* start = ptr; |
51 while (ptr < end && *ptr != delimiter && !isSVGSpace(*ptr)) | 95 while (ptr < end && *ptr != delimiter && !isSVGSpace(*ptr)) |
52 ptr++; | 96 ptr++; |
53 if (ptr == start) | 97 if (ptr == start) |
54 break; | 98 break; |
55 append(String(start, ptr - start)); | 99 m_values.append(String(start, ptr - start)); |
56 skipOptionalSVGSpacesOrDelimiter(ptr, end, delimiter); | 100 skipOptionalSVGSpacesOrDelimiter(ptr, end, delimiter); |
57 } | 101 } |
58 } | 102 } |
59 | 103 |
60 void SVGStringList::parse(const String& data, UChar delimiter) | 104 PassRefPtr<SVGStringList> SVGStringList::clone() |
| 105 { |
| 106 RefPtr<SVGStringList> svgStringList = create(); |
| 107 svgStringList->m_values = m_values; |
| 108 return svgStringList.release(); |
| 109 } |
| 110 |
| 111 void SVGStringList::setValueAsString(const String& data, ExceptionState&) |
61 { | 112 { |
62 // FIXME: Add more error checking and reporting. | 113 // FIXME: Add more error checking and reporting. |
63 clear(); | 114 m_values.clear(); |
64 if (data.isEmpty()) | 115 if (data.isEmpty()) |
65 return; | 116 return; |
66 if (data.is8Bit()) { | 117 if (data.is8Bit()) { |
67 const LChar* ptr = data.characters8(); | 118 const LChar* ptr = data.characters8(); |
68 const LChar* end = ptr + data.length(); | 119 const LChar* end = ptr + data.length(); |
69 parseInternal(ptr, end, delimiter); | 120 parseInternal(ptr, end); |
70 } else { | 121 } else { |
71 const UChar* ptr = data.characters16(); | 122 const UChar* ptr = data.characters16(); |
72 const UChar* end = ptr + data.length(); | 123 const UChar* end = ptr + data.length(); |
73 parseInternal(ptr, end, delimiter); | 124 parseInternal(ptr, end); |
74 } | 125 } |
75 } | 126 } |
76 | 127 |
| 128 PassRefPtr<NewSVGPropertyBase> SVGStringList::cloneForAnimation(const String& st
ring) const |
| 129 { |
| 130 RefPtr<SVGStringList> svgStringList = create(); |
| 131 svgStringList->setValueAsString(string, IGNORE_EXCEPTION); |
| 132 return svgStringList.release(); |
| 133 } |
| 134 |
77 String SVGStringList::valueAsString() const | 135 String SVGStringList::valueAsString() const |
78 { | 136 { |
79 StringBuilder builder; | 137 StringBuilder builder; |
80 | 138 |
81 unsigned size = this->size(); | 139 Vector<String>::const_iterator it = m_values.begin(); |
82 for (unsigned i = 0; i < size; ++i) { | 140 Vector<String>::const_iterator itEnd = m_values.end(); |
83 if (i > 0) | 141 if (it != itEnd) { |
| 142 builder.append(*it); |
| 143 ++it; |
| 144 |
| 145 for (; it != itEnd; ++it) { |
84 builder.append(' '); | 146 builder.append(' '); |
85 | 147 builder.append(*it); |
86 builder.append(at(i)); | 148 } |
87 } | 149 } |
88 | 150 |
89 return builder.toString(); | 151 return builder.toString(); |
90 } | 152 } |
91 | 153 |
| 154 bool SVGStringList::checkIndexBound(size_t index, ExceptionState& exceptionState
) |
| 155 { |
| 156 if (index >= m_values.size()) { |
| 157 exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::inde
xExceedsMaximumBound("index", index, m_values.size())); |
| 158 return false; |
| 159 } |
| 160 |
| 161 return true; |
92 } | 162 } |
| 163 |
| 164 void SVGStringList::add(PassRefPtr<NewSVGPropertyBase> other, SVGElement* contex
tElement) |
| 165 { |
| 166 // SVGStringList is never animated. |
| 167 ASSERT_NOT_REACHED(); |
| 168 } |
| 169 |
| 170 void SVGStringList::calculateAnimatedValue(SVGAnimationElement*, float, unsigned
, PassRefPtr<NewSVGPropertyBase>, PassRefPtr<NewSVGPropertyBase>, PassRefPtr<New
SVGPropertyBase>, SVGElement*) |
| 171 { |
| 172 // SVGStringList is never animated. |
| 173 ASSERT_NOT_REACHED(); |
| 174 } |
| 175 |
| 176 float SVGStringList::calculateDistance(PassRefPtr<NewSVGPropertyBase>, SVGElemen
t*) |
| 177 { |
| 178 // SVGStringList is never animated. |
| 179 ASSERT_NOT_REACHED(); |
| 180 |
| 181 return -1.0f; |
| 182 } |
| 183 |
| 184 } |
OLD | NEW |