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