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 |
11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
12 * | 12 * |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND AN
Y | 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR AN
Y | 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR |
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 17 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND O
N | 19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 21 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
23 */ | 23 */ |
24 | 24 |
25 #include "core/dom/DOMTokenList.h" | 25 #include "core/dom/DOMTokenList.h" |
26 | 26 |
27 #include "bindings/core/v8/ExceptionState.h" | 27 #include "bindings/core/v8/ExceptionState.h" |
28 #include "core/dom/ExceptionCode.h" | 28 #include "core/dom/ExceptionCode.h" |
29 #include "core/html/parser/HTMLParserIdioms.h" | 29 #include "core/html/parser/HTMLParserIdioms.h" |
30 #include "wtf/text/StringBuilder.h" | 30 #include "wtf/text/StringBuilder.h" |
31 | 31 |
32 namespace blink { | 32 namespace blink { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 return containsInternal(token); | 102 return containsInternal(token); |
103 } | 103 } |
104 | 104 |
105 void DOMTokenList::add(const AtomicString& token, | 105 void DOMTokenList::add(const AtomicString& token, |
106 ExceptionState& exceptionState) { | 106 ExceptionState& exceptionState) { |
107 Vector<String> tokens; | 107 Vector<String> tokens; |
108 tokens.append(token.getString()); | 108 tokens.append(token.getString()); |
109 add(tokens, exceptionState); | 109 add(tokens, exceptionState); |
110 } | 110 } |
111 | 111 |
112 // Optimally, this should take a Vector<AtomicString> const ref in argument but
the | 112 // Optimally, this should take a Vector<AtomicString> const ref in argument but |
113 // bindings generator does not handle that. | 113 // the bindings generator does not handle that. |
114 void DOMTokenList::add(const Vector<String>& tokens, | 114 void DOMTokenList::add(const Vector<String>& tokens, |
115 ExceptionState& exceptionState) { | 115 ExceptionState& exceptionState) { |
116 Vector<String> filteredTokens; | 116 Vector<String> filteredTokens; |
117 filteredTokens.reserveCapacity(tokens.size()); | 117 filteredTokens.reserveCapacity(tokens.size()); |
118 for (size_t i = 0; i < tokens.size(); ++i) { | 118 for (size_t i = 0; i < tokens.size(); ++i) { |
119 if (!validateToken(tokens[i], exceptionState)) | 119 if (!validateToken(tokens[i], exceptionState)) |
120 return; | 120 return; |
121 if (containsInternal(AtomicString(tokens[i]))) | 121 if (containsInternal(AtomicString(tokens[i]))) |
122 continue; | 122 continue; |
123 if (filteredTokens.contains(tokens[i])) | 123 if (filteredTokens.contains(tokens[i])) |
124 continue; | 124 continue; |
125 filteredTokens.append(tokens[i]); | 125 filteredTokens.append(tokens[i]); |
126 } | 126 } |
127 | 127 |
128 if (!filteredTokens.isEmpty()) | 128 if (!filteredTokens.isEmpty()) |
129 setValue(addTokens(value(), filteredTokens)); | 129 setValue(addTokens(value(), filteredTokens)); |
130 } | 130 } |
131 | 131 |
132 void DOMTokenList::remove(const AtomicString& token, | 132 void DOMTokenList::remove(const AtomicString& token, |
133 ExceptionState& exceptionState) { | 133 ExceptionState& exceptionState) { |
134 Vector<String> tokens; | 134 Vector<String> tokens; |
135 tokens.append(token.getString()); | 135 tokens.append(token.getString()); |
136 remove(tokens, exceptionState); | 136 remove(tokens, exceptionState); |
137 } | 137 } |
138 | 138 |
139 // Optimally, this should take a Vector<AtomicString> const ref in argument but
the | 139 // Optimally, this should take a Vector<AtomicString> const ref in argument but |
140 // bindings generator does not handle that. | 140 // the bindings generator does not handle that. |
141 void DOMTokenList::remove(const Vector<String>& tokens, | 141 void DOMTokenList::remove(const Vector<String>& tokens, |
142 ExceptionState& exceptionState) { | 142 ExceptionState& exceptionState) { |
143 if (!validateTokens(tokens, exceptionState)) | 143 if (!validateTokens(tokens, exceptionState)) |
144 return; | 144 return; |
145 | 145 |
146 // Check using containsInternal first since it is a lot faster than going | 146 // Check using containsInternal first since it is a lot faster than going |
147 // through the string character by character. | 147 // through the string character by character. |
148 bool found = false; | 148 bool found = false; |
149 for (size_t i = 0; i < tokens.size(); ++i) { | 149 for (size_t i = 0; i < tokens.size(); ++i) { |
150 if (containsInternal(AtomicString(tokens[i]))) { | 150 if (containsInternal(AtomicString(tokens[i]))) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 setValue(removeToken(value(), token)); | 202 setValue(removeToken(value(), token)); |
203 } | 203 } |
204 | 204 |
205 AtomicString DOMTokenList::addToken(const AtomicString& input, | 205 AtomicString DOMTokenList::addToken(const AtomicString& input, |
206 const AtomicString& token) { | 206 const AtomicString& token) { |
207 Vector<String> tokens; | 207 Vector<String> tokens; |
208 tokens.append(token.getString()); | 208 tokens.append(token.getString()); |
209 return addTokens(input, tokens); | 209 return addTokens(input, tokens); |
210 } | 210 } |
211 | 211 |
212 // This returns an AtomicString because it is always passed as argument to setVa
lue() and setValue() | 212 // This returns an AtomicString because it is always passed as argument to |
213 // takes an AtomicString in argument. | 213 // setValue() and setValue() takes an AtomicString in argument. |
214 AtomicString DOMTokenList::addTokens(const AtomicString& input, | 214 AtomicString DOMTokenList::addTokens(const AtomicString& input, |
215 const Vector<String>& tokens) { | 215 const Vector<String>& tokens) { |
216 bool needsSpace = false; | 216 bool needsSpace = false; |
217 | 217 |
218 StringBuilder builder; | 218 StringBuilder builder; |
219 if (!input.isEmpty()) { | 219 if (!input.isEmpty()) { |
220 builder.append(input); | 220 builder.append(input); |
221 needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); | 221 needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); |
222 } | 222 } |
223 | 223 |
224 for (size_t i = 0; i < tokens.size(); ++i) { | 224 for (size_t i = 0; i < tokens.size(); ++i) { |
225 if (needsSpace) | 225 if (needsSpace) |
226 builder.append(' '); | 226 builder.append(' '); |
227 builder.append(tokens[i]); | 227 builder.append(tokens[i]); |
228 needsSpace = true; | 228 needsSpace = true; |
229 } | 229 } |
230 | 230 |
231 return builder.toAtomicString(); | 231 return builder.toAtomicString(); |
232 } | 232 } |
233 | 233 |
234 AtomicString DOMTokenList::removeToken(const AtomicString& input, | 234 AtomicString DOMTokenList::removeToken(const AtomicString& input, |
235 const AtomicString& token) { | 235 const AtomicString& token) { |
236 Vector<String> tokens; | 236 Vector<String> tokens; |
237 tokens.append(token.getString()); | 237 tokens.append(token.getString()); |
238 return removeTokens(input, tokens); | 238 return removeTokens(input, tokens); |
239 } | 239 } |
240 | 240 |
241 // This returns an AtomicString because it is always passed as argument to setVa
lue() and setValue() | 241 // This returns an AtomicString because it is always passed as argument to |
242 // takes an AtomicString in argument. | 242 // setValue() and setValue() takes an AtomicString in argument. |
243 AtomicString DOMTokenList::removeTokens(const AtomicString& input, | 243 AtomicString DOMTokenList::removeTokens(const AtomicString& input, |
244 const Vector<String>& tokens) { | 244 const Vector<String>& tokens) { |
245 // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/mult
ipage/common-microsyntaxes.html#remove-a-token-from-a-string | 245 // Algorithm defined at |
| 246 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyn
taxes.html#remove-a-token-from-a-string |
246 // New spec is at https://dom.spec.whatwg.org/#remove-a-token-from-a-string | 247 // New spec is at https://dom.spec.whatwg.org/#remove-a-token-from-a-string |
247 | 248 |
248 unsigned inputLength = input.length(); | 249 unsigned inputLength = input.length(); |
249 StringBuilder output; // 3 | 250 StringBuilder output; // 3 |
250 output.reserveCapacity(inputLength); | 251 output.reserveCapacity(inputLength); |
251 unsigned position = 0; // 4 | 252 unsigned position = 0; // 4 |
252 | 253 |
253 // Step 5 | 254 // Step 5 |
254 while (position < inputLength) { | 255 while (position < inputLength) { |
255 if (isHTMLSpace<UChar>(input[position])) { // 6 | 256 if (isHTMLSpace<UChar>(input[position])) { // 6 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 return new DOMTokenListIterationSource(this); | 307 return new DOMTokenListIterationSource(this); |
307 } | 308 } |
308 | 309 |
309 const AtomicString DOMTokenList::item(unsigned index) const { | 310 const AtomicString DOMTokenList::item(unsigned index) const { |
310 if (index >= length()) | 311 if (index >= length()) |
311 return AtomicString(); | 312 return AtomicString(); |
312 return m_tokens[index]; | 313 return m_tokens[index]; |
313 } | 314 } |
314 | 315 |
315 } // namespace blink | 316 } // namespace blink |
OLD | NEW |