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 28 matching lines...) Expand all Loading... |
74 add(tokens, exceptionState); | 74 add(tokens, exceptionState); |
75 } | 75 } |
76 | 76 |
77 void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionSt
ate) | 77 void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionSt
ate) |
78 { | 78 { |
79 Vector<String> filteredTokens; | 79 Vector<String> filteredTokens; |
80 filteredTokens.reserveCapacity(tokens.size()); | 80 filteredTokens.reserveCapacity(tokens.size()); |
81 for (size_t i = 0; i < tokens.size(); ++i) { | 81 for (size_t i = 0; i < tokens.size(); ++i) { |
82 if (!validateToken(tokens[i], exceptionState)) | 82 if (!validateToken(tokens[i], exceptionState)) |
83 return; | 83 return; |
84 if (containsInternal(tokens[i])) | 84 if (containsInternal(AtomicString(tokens[i]))) |
85 continue; | 85 continue; |
86 if (filteredTokens.contains(tokens[i])) | 86 if (filteredTokens.contains(tokens[i])) |
87 continue; | 87 continue; |
88 filteredTokens.append(tokens[i]); | 88 filteredTokens.append(tokens[i]); |
89 } | 89 } |
90 | 90 |
91 if (filteredTokens.isEmpty()) | 91 if (filteredTokens.isEmpty()) |
92 return; | 92 return; |
93 | 93 |
94 setValue(addTokens(value(), filteredTokens)); | 94 setValue(addTokens(value(), filteredTokens)); |
95 } | 95 } |
96 | 96 |
97 void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionSt
ate) | 97 void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionSt
ate) |
98 { | 98 { |
99 Vector<String> tokens; | 99 Vector<String> tokens; |
100 tokens.append(token.string()); | 100 tokens.append(token.string()); |
101 remove(tokens, exceptionState); | 101 remove(tokens, exceptionState); |
102 } | 102 } |
103 | 103 |
104 void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptio
nState) | 104 void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptio
nState) |
105 { | 105 { |
106 if (!validateTokens(tokens, exceptionState)) | 106 if (!validateTokens(tokens, exceptionState)) |
107 return; | 107 return; |
108 | 108 |
109 // Check using containsInternal first since it is a lot faster than going | 109 // Check using containsInternal first since it is a lot faster than going |
110 // through the string character by character. | 110 // through the string character by character. |
111 bool found = false; | 111 bool found = false; |
112 for (size_t i = 0; i < tokens.size(); ++i) { | 112 for (size_t i = 0; i < tokens.size(); ++i) { |
113 if (containsInternal(tokens[i])) { | 113 if (containsInternal(AtomicString(tokens[i]))) { |
114 found = true; | 114 found = true; |
115 break; | 115 break; |
116 } | 116 } |
117 } | 117 } |
118 | 118 |
119 if (found) | 119 if (found) |
120 setValue(removeTokens(value(), tokens)); | 120 setValue(removeTokens(value(), tokens)); |
121 } | 121 } |
122 | 122 |
123 bool DOMTokenList::toggle(const AtomicString& token, ExceptionState& exceptionSt
ate) | 123 bool DOMTokenList::toggle(const AtomicString& token, ExceptionState& exceptionSt
ate) |
(...skipping 30 matching lines...) Expand all Loading... |
154 | 154 |
155 void DOMTokenList::removeInternal(const AtomicString& token) | 155 void DOMTokenList::removeInternal(const AtomicString& token) |
156 { | 156 { |
157 // Check using contains first since it uses AtomicString comparisons instead | 157 // Check using contains first since it uses AtomicString comparisons instead |
158 // of character by character testing. | 158 // of character by character testing. |
159 if (!containsInternal(token)) | 159 if (!containsInternal(token)) |
160 return; | 160 return; |
161 setValue(removeToken(value(), token)); | 161 setValue(removeToken(value(), token)); |
162 } | 162 } |
163 | 163 |
164 String DOMTokenList::addToken(const AtomicString& input, const AtomicString& tok
en) | 164 AtomicString DOMTokenList::addToken(const AtomicString& input, const AtomicStrin
g& token) |
165 { | 165 { |
166 Vector<String> tokens; | 166 Vector<String> tokens; |
167 tokens.append(token.string()); | 167 tokens.append(token.string()); |
168 return addTokens(input, tokens); | 168 return addTokens(input, tokens); |
169 } | 169 } |
170 | 170 |
171 String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>&
tokens) | 171 AtomicString DOMTokenList::addTokens(const AtomicString& input, const Vector<Str
ing>& tokens) |
172 { | 172 { |
173 bool needsSpace = false; | 173 bool needsSpace = false; |
174 | 174 |
175 StringBuilder builder; | 175 StringBuilder builder; |
176 if (!input.isEmpty()) { | 176 if (!input.isEmpty()) { |
177 builder.append(input); | 177 builder.append(input); |
178 needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); | 178 needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); |
179 } | 179 } |
180 | 180 |
181 for (size_t i = 0; i < tokens.size(); ++i) { | 181 for (size_t i = 0; i < tokens.size(); ++i) { |
182 if (needsSpace) | 182 if (needsSpace) |
183 builder.append(' '); | 183 builder.append(' '); |
184 builder.append(tokens[i]); | 184 builder.append(tokens[i]); |
185 needsSpace = true; | 185 needsSpace = true; |
186 } | 186 } |
187 | 187 |
188 return builder.toString(); | 188 return builder.toAtomicString(); |
189 } | 189 } |
190 | 190 |
191 String DOMTokenList::removeToken(const AtomicString& input, const AtomicString&
token) | 191 AtomicString DOMTokenList::removeToken(const AtomicString& input, const AtomicSt
ring& token) |
192 { | 192 { |
193 Vector<String> tokens; | 193 Vector<String> tokens; |
194 tokens.append(token.string()); | 194 tokens.append(token.string()); |
195 return removeTokens(input, tokens); | 195 return removeTokens(input, tokens); |
196 } | 196 } |
197 | 197 |
198 String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String
>& tokens) | 198 AtomicString DOMTokenList::removeTokens(const AtomicString& input, const Vector<
String>& tokens) |
199 { | 199 { |
200 // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/mu
ltipage/common-microsyntaxes.html#remove-a-token-from-a-string | 200 // 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 | 201 // New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string |
202 | 202 |
203 unsigned inputLength = input.length(); | 203 unsigned inputLength = input.length(); |
204 StringBuilder output; // 3 | 204 StringBuilder output; // 3 |
205 output.reserveCapacity(inputLength); | 205 output.reserveCapacity(inputLength); |
206 unsigned position = 0; // 4 | 206 unsigned position = 0; // 4 |
207 | 207 |
208 // Step 5 | 208 // Step 5 |
(...skipping 22 matching lines...) Expand all Loading... |
231 output.resize(j); | 231 output.resize(j); |
232 | 232 |
233 // Step 8.3 | 233 // Step 8.3 |
234 if (position < inputLength && !output.isEmpty()) | 234 if (position < inputLength && !output.isEmpty()) |
235 output.append(' '); | 235 output.append(' '); |
236 } else { | 236 } else { |
237 output.append(token); // Step 9 | 237 output.append(token); // Step 9 |
238 } | 238 } |
239 } | 239 } |
240 | 240 |
241 return output.toString(); | 241 return output.toAtomicString(); |
242 } | 242 } |
243 | 243 |
244 } // namespace WebCore | 244 } // namespace WebCore |
OLD | NEW |