| 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 |