OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "config.h" | 25 #include "config.h" |
26 #include "core/dom/DOMTokenList.h" | 26 #include "core/dom/DOMTokenList.h" |
27 | 27 |
28 #include "bindings/v8/ExceptionState.h" | 28 #include "bindings/v8/ExceptionState.h" |
29 #include "core/dom/ExceptionCode.h" | 29 #include "core/dom/ExceptionCode.h" |
30 #include "core/html/parser/HTMLParserIdioms.h" | 30 #include "core/html/parser/HTMLParserIdioms.h" |
31 #include "wtf/text/StringBuilder.h" | 31 #include "wtf/text/StringBuilder.h" |
32 | 32 |
33 namespace WebCore { | 33 namespace WebCore { |
34 | 34 |
35 bool DOMTokenList::validateToken(const AtomicString& token, ExceptionState& exce
ptionState) | 35 bool DOMTokenList::validateToken(const String& token, ExceptionState& exceptionS
tate) |
36 { | 36 { |
37 if (token.isEmpty()) { | 37 if (token.isEmpty()) { |
38 exceptionState.throwDOMException(SyntaxError, "The token provided must n
ot be empty."); | 38 exceptionState.throwDOMException(SyntaxError, "The token provided must n
ot be empty."); |
39 return false; | 39 return false; |
40 } | 40 } |
41 | 41 |
42 unsigned length = token.length(); | 42 unsigned length = token.length(); |
43 for (unsigned i = 0; i < length; ++i) { | 43 for (unsigned i = 0; i < length; ++i) { |
44 if (isHTMLSpace<UChar>(token[i])) { | 44 if (isHTMLSpace<UChar>(token[i])) { |
45 exceptionState.throwDOMException(InvalidCharacterError, "The token p
rovided ('" + token + "') contains HTML space characters, which are not valid in
tokens."); | 45 exceptionState.throwDOMException(InvalidCharacterError, "The token p
rovided ('" + token + "') contains HTML space characters, which are not valid in
tokens."); |
(...skipping 21 matching lines...) Expand all Loading... |
67 return containsInternal(token); | 67 return containsInternal(token); |
68 } | 68 } |
69 | 69 |
70 void DOMTokenList::add(const AtomicString& token, ExceptionState& exceptionState
) | 70 void DOMTokenList::add(const AtomicString& token, ExceptionState& exceptionState
) |
71 { | 71 { |
72 Vector<String> tokens; | 72 Vector<String> tokens; |
73 tokens.append(token.string()); | 73 tokens.append(token.string()); |
74 add(tokens, exceptionState); | 74 add(tokens, exceptionState); |
75 } | 75 } |
76 | 76 |
| 77 // Optimally, this should take a Vector<AtomicString> const ref in argument but
the |
| 78 // bindings generator does not handle that. |
77 void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionSt
ate) | 79 void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionSt
ate) |
78 { | 80 { |
79 Vector<String> filteredTokens; | 81 Vector<String> filteredTokens; |
80 filteredTokens.reserveCapacity(tokens.size()); | 82 filteredTokens.reserveCapacity(tokens.size()); |
81 for (size_t i = 0; i < tokens.size(); ++i) { | 83 for (size_t i = 0; i < tokens.size(); ++i) { |
82 if (!validateToken(tokens[i], exceptionState)) | 84 if (!validateToken(tokens[i], exceptionState)) |
83 return; | 85 return; |
84 if (containsInternal(tokens[i])) | 86 if (containsInternal(AtomicString(tokens[i]))) |
85 continue; | 87 continue; |
86 if (filteredTokens.contains(tokens[i])) | 88 if (filteredTokens.contains(tokens[i])) |
87 continue; | 89 continue; |
88 filteredTokens.append(tokens[i]); | 90 filteredTokens.append(tokens[i]); |
89 } | 91 } |
90 | 92 |
91 if (filteredTokens.isEmpty()) | 93 if (filteredTokens.isEmpty()) |
92 return; | 94 return; |
93 | 95 |
94 setValue(addTokens(value(), filteredTokens)); | 96 setValue(addTokens(value(), filteredTokens)); |
95 } | 97 } |
96 | 98 |
97 void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionSt
ate) | 99 void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionSt
ate) |
98 { | 100 { |
99 Vector<String> tokens; | 101 Vector<String> tokens; |
100 tokens.append(token.string()); | 102 tokens.append(token.string()); |
101 remove(tokens, exceptionState); | 103 remove(tokens, exceptionState); |
102 } | 104 } |
103 | 105 |
| 106 // Optimally, this should take a Vector<AtomicString> const ref in argument but
the |
| 107 // bindings generator does not handle that. |
104 void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptio
nState) | 108 void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptio
nState) |
105 { | 109 { |
106 if (!validateTokens(tokens, exceptionState)) | 110 if (!validateTokens(tokens, exceptionState)) |
107 return; | 111 return; |
108 | 112 |
109 // Check using containsInternal first since it is a lot faster than going | 113 // Check using containsInternal first since it is a lot faster than going |
110 // through the string character by character. | 114 // through the string character by character. |
111 bool found = false; | 115 bool found = false; |
112 for (size_t i = 0; i < tokens.size(); ++i) { | 116 for (size_t i = 0; i < tokens.size(); ++i) { |
113 if (containsInternal(tokens[i])) { | 117 if (containsInternal(AtomicString(tokens[i]))) { |
114 found = true; | 118 found = true; |
115 break; | 119 break; |
116 } | 120 } |
117 } | 121 } |
118 | 122 |
119 if (found) | 123 if (found) |
120 setValue(removeTokens(value(), tokens)); | 124 setValue(removeTokens(value(), tokens)); |
121 } | 125 } |
122 | 126 |
123 bool DOMTokenList::toggle(const AtomicString& token, ExceptionState& exceptionSt
ate) | 127 bool DOMTokenList::toggle(const AtomicString& token, ExceptionState& exceptionSt
ate) |
(...skipping 30 matching lines...) Expand all Loading... |
154 | 158 |
155 void DOMTokenList::removeInternal(const AtomicString& token) | 159 void DOMTokenList::removeInternal(const AtomicString& token) |
156 { | 160 { |
157 // Check using contains first since it uses AtomicString comparisons instead | 161 // Check using contains first since it uses AtomicString comparisons instead |
158 // of character by character testing. | 162 // of character by character testing. |
159 if (!containsInternal(token)) | 163 if (!containsInternal(token)) |
160 return; | 164 return; |
161 setValue(removeToken(value(), token)); | 165 setValue(removeToken(value(), token)); |
162 } | 166 } |
163 | 167 |
164 String DOMTokenList::addToken(const AtomicString& input, const AtomicString& tok
en) | 168 AtomicString DOMTokenList::addToken(const AtomicString& input, const AtomicStrin
g& token) |
165 { | 169 { |
166 Vector<String> tokens; | 170 Vector<String> tokens; |
167 tokens.append(token.string()); | 171 tokens.append(token.string()); |
168 return addTokens(input, tokens); | 172 return addTokens(input, tokens); |
169 } | 173 } |
170 | 174 |
171 String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>&
tokens) | 175 // This returns an AtomicString because it is always passed as argument to setVa
lue() and setValue() |
| 176 // takes an AtomicString in argument. |
| 177 AtomicString DOMTokenList::addTokens(const AtomicString& input, const Vector<Str
ing>& tokens) |
172 { | 178 { |
173 bool needsSpace = false; | 179 bool needsSpace = false; |
174 | 180 |
175 StringBuilder builder; | 181 StringBuilder builder; |
176 if (!input.isEmpty()) { | 182 if (!input.isEmpty()) { |
177 builder.append(input); | 183 builder.append(input); |
178 needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); | 184 needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); |
179 } | 185 } |
180 | 186 |
181 for (size_t i = 0; i < tokens.size(); ++i) { | 187 for (size_t i = 0; i < tokens.size(); ++i) { |
182 if (needsSpace) | 188 if (needsSpace) |
183 builder.append(' '); | 189 builder.append(' '); |
184 builder.append(tokens[i]); | 190 builder.append(tokens[i]); |
185 needsSpace = true; | 191 needsSpace = true; |
186 } | 192 } |
187 | 193 |
188 return builder.toString(); | 194 return builder.toAtomicString(); |
189 } | 195 } |
190 | 196 |
191 String DOMTokenList::removeToken(const AtomicString& input, const AtomicString&
token) | 197 AtomicString DOMTokenList::removeToken(const AtomicString& input, const AtomicSt
ring& token) |
192 { | 198 { |
193 Vector<String> tokens; | 199 Vector<String> tokens; |
194 tokens.append(token.string()); | 200 tokens.append(token.string()); |
195 return removeTokens(input, tokens); | 201 return removeTokens(input, tokens); |
196 } | 202 } |
197 | 203 |
198 String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String
>& tokens) | 204 // This returns an AtomicString because it is always passed as argument to setVa
lue() and setValue() |
| 205 // takes an AtomicString in argument. |
| 206 AtomicString DOMTokenList::removeTokens(const AtomicString& input, const Vector<
String>& tokens) |
199 { | 207 { |
200 // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/mu
ltipage/common-microsyntaxes.html#remove-a-token-from-a-string | 208 // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/mu
ltipage/common-microsyntaxes.html#remove-a-token-from-a-string |
201 // New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string | 209 // New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string |
202 | 210 |
203 unsigned inputLength = input.length(); | 211 unsigned inputLength = input.length(); |
204 StringBuilder output; // 3 | 212 StringBuilder output; // 3 |
205 output.reserveCapacity(inputLength); | 213 output.reserveCapacity(inputLength); |
206 unsigned position = 0; // 4 | 214 unsigned position = 0; // 4 |
207 | 215 |
208 // Step 5 | 216 // Step 5 |
(...skipping 22 matching lines...) Expand all Loading... |
231 output.resize(j); | 239 output.resize(j); |
232 | 240 |
233 // Step 8.3 | 241 // Step 8.3 |
234 if (position < inputLength && !output.isEmpty()) | 242 if (position < inputLength && !output.isEmpty()) |
235 output.append(' '); | 243 output.append(' '); |
236 } else { | 244 } else { |
237 output.append(token); // Step 9 | 245 output.append(token); // Step 9 |
238 } | 246 } |
239 } | 247 } |
240 | 248 |
241 return output.toString(); | 249 return output.toAtomicString(); |
242 } | 250 } |
243 | 251 |
244 } // namespace WebCore | 252 } // namespace WebCore |
OLD | NEW |