15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 268abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "core/dom/DOMTokenList.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h" 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h" 31e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/text/StringBuilder.h" 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool DOMTokenList::validateToken(const String& token, ExceptionState& exceptionState) 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (token.isEmpty()) { 38a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) exceptionState.throwDOMException(SyntaxError, "The token provided must not be empty."); 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 429e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) if (token.find(isHTMLSpace) != kNotFound) { 439e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) exceptionState.throwDOMException(InvalidCharacterError, "The token provided ('" + token + "') contains HTML space characters, which are not valid in tokens."); 449e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles) return false; 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 50a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool DOMTokenList::validateTokens(const Vector<String>& tokens, ExceptionState& exceptionState) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 53a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!validateToken(tokens[i], exceptionState)) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool DOMTokenList::contains(const AtomicString& token, ExceptionState& exceptionState) const 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 62a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!validateToken(token, exceptionState)) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return containsInternal(token); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void DOMTokenList::add(const AtomicString& token, ExceptionState& exceptionState) 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 7151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) add(tokens, exceptionState); 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Optimally, this should take a Vector<AtomicString> const ref in argument but the 7509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// bindings generator does not handle that. 7651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionState) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> filteredTokens; 791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) filteredTokens.reserveCapacity(tokens.size()); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 81a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!validateToken(tokens[i], exceptionState)) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 8309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (containsInternal(AtomicString(tokens[i]))) 841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) continue; 851e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (filteredTokens.contains(tokens[i])) 861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) continue; 871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) filteredTokens.append(tokens[i]); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (filteredTokens.isEmpty()) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(addTokens(value(), filteredTokens)); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionState) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) remove(tokens, exceptionState); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Optimally, this should take a Vector<AtomicString> const ref in argument but the 10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// bindings generator does not handle that. 10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptionState) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 107a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!validateTokens(tokens, exceptionState)) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check using containsInternal first since it is a lot faster than going 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // through the string character by character. 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool found = false; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (containsInternal(AtomicString(tokens[i]))) { 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) found = true; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (found) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(removeTokens(value(), tokens)); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool DOMTokenList::toggle(const AtomicString& token, ExceptionState& exceptionState) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!validateToken(token, exceptionState)) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (containsInternal(token)) { 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeInternal(token); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addInternal(token); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool DOMTokenList::toggle(const AtomicString& token, bool force, ExceptionState& exceptionState) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 139a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (!validateToken(token, exceptionState)) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (force) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addInternal(token); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeInternal(token); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return force; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DOMTokenList::addInternal(const AtomicString& token) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!containsInternal(token)) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(addToken(value(), token)); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DOMTokenList::removeInternal(const AtomicString& token) 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check using contains first since it uses AtomicString comparisons instead 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of character by character testing. 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!containsInternal(token)) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(removeToken(value(), token)); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)AtomicString DOMTokenList::addToken(const AtomicString& input, const AtomicString& token) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return addTokens(input, tokens); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// This returns an AtomicString because it is always passed as argument to setValue() and setValue() 17309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// takes an AtomicString in argument. 17409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)AtomicString DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needsSpace = false; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuilder builder; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!input.isEmpty()) { 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) builder.append(input); 18106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) needsSpace = !isHTMLSpace<UChar>(input[input.length() - 1]); 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needsSpace) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) builder.append(' '); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) builder.append(tokens[i]); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsSpace = true; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return builder.toAtomicString(); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)AtomicString DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return removeTokens(input, tokens); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// This returns an AtomicString because it is always passed as argument to setValue() and setValue() 20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// takes an AtomicString in argument. 20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)AtomicString DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned inputLength = input.length(); 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuilder output; // 3 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.reserveCapacity(inputLength); 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned position = 0; // 4 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 5 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (position < inputLength) { 21506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (isHTMLSpace<UChar>(input[position])) { // 6 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.append(input[position++]); // 6.1, 6.2 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; // 6.3 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 7 2217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch StringBuilder tokenBuilder; 22206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while (position < inputLength && isNotHTMLSpace<UChar>(input[position])) 2237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch tokenBuilder.append(input[position++]); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8 2267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch String token = tokenBuilder.toString(); 2277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (tokens.contains(token)) { 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8.1 22906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while (position < inputLength && isHTMLSpace<UChar>(input[position])) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++position; 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8.2 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t j = output.length(); 23406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while (j > 0 && isHTMLSpace<UChar>(output[j - 1])) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --j; 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.resize(j); 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8.3 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (position < inputLength && !output.isEmpty()) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.append(' '); 2417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } else { 2427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch output.append(token); // Step 9 2437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return output.toAtomicString(); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 249c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 250