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" 2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/DOMTokenList.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28df95704c49daea886ddad70775bda23618d6274dBen Murdoch#include "bindings/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) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 35df95704c49daea886ddad70775bda23618d6274dBen Murdochbool DOMTokenList::validateToken(const AtomicString& token, ExceptionState& es) 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (token.isEmpty()) { 38df95704c49daea886ddad70775bda23618d6274dBen Murdoch es.throwDOMException(SyntaxError); 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = token.length(); 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < length; ++i) { 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHTMLSpace(token[i])) { 45df95704c49daea886ddad70775bda23618d6274dBen Murdoch es.throwDOMException(InvalidCharacterError); 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 53df95704c49daea886ddad70775bda23618d6274dBen Murdochbool DOMTokenList::validateTokens(const Vector<String>& tokens, ExceptionState& es) 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 56df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!validateToken(tokens[i], es)) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 63df95704c49daea886ddad70775bda23618d6274dBen Murdochbool DOMTokenList::contains(const AtomicString& token, ExceptionState& es) const 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 65df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!validateToken(token, es)) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return containsInternal(token); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 70df95704c49daea886ddad70775bda23618d6274dBen Murdochvoid DOMTokenList::add(const AtomicString& token, ExceptionState& es) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 74df95704c49daea886ddad70775bda23618d6274dBen Murdoch add(tokens, es); 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 77df95704c49daea886ddad70775bda23618d6274dBen Murdochvoid DOMTokenList::add(const Vector<String>& tokens, ExceptionState& es) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> filteredTokens; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 81df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!validateToken(tokens[i], es)) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!containsInternal(tokens[i])) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) filteredTokens.append(tokens[i]); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (filteredTokens.isEmpty()) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(addTokens(value(), filteredTokens)); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 93df95704c49daea886ddad70775bda23618d6274dBen Murdochvoid DOMTokenList::remove(const AtomicString& token, ExceptionState& es) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 97df95704c49daea886ddad70775bda23618d6274dBen Murdoch remove(tokens, es); 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 100df95704c49daea886ddad70775bda23618d6274dBen Murdochvoid DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& es) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 102df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!validateTokens(tokens, es)) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check using containsInternal first since it is a lot faster than going 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // through the string character by character. 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool found = false; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (containsInternal(tokens[i])) { 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) found = true; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (found) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(removeTokens(value(), tokens)); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 119df95704c49daea886ddad70775bda23618d6274dBen Murdochbool DOMTokenList::toggle(const AtomicString& token, ExceptionState& es) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 121df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!validateToken(token, es)) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (containsInternal(token)) { 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeInternal(token); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addInternal(token); 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 132df95704c49daea886ddad70775bda23618d6274dBen Murdochbool DOMTokenList::toggle(const AtomicString& token, bool force, ExceptionState& es) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 134df95704c49daea886ddad70775bda23618d6274dBen Murdoch if (!validateToken(token, es)) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (force) 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addInternal(token); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) removeInternal(token); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return force; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DOMTokenList::addInternal(const AtomicString& token) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!containsInternal(token)) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(addToken(value(), token)); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void DOMTokenList::removeInternal(const AtomicString& token) 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check using contains first since it uses AtomicString comparisons instead 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of character by character testing. 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!containsInternal(token)) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setValue(removeToken(value(), token)); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return addTokens(input, tokens); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens) 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needsSpace = false; 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuilder builder; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!input.isEmpty()) { 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) builder.append(input); 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsSpace = !isHTMLSpace(input[input.length() - 1]); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < tokens.size(); ++i) { 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needsSpace) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) builder.append(' '); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) builder.append(tokens[i]); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needsSpace = true; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return builder.toString(); 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<String> tokens; 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tokens.append(token.string()); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return removeTokens(input, tokens); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned inputLength = input.length(); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuilder output; // 3 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.reserveCapacity(inputLength); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned position = 0; // 4 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 5 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (position < inputLength) { 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHTMLSpace(input[position])) { // 6 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.append(input[position++]); // 6.1, 6.2 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; // 6.3 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 7 2127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch StringBuilder tokenBuilder; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (position < inputLength && isNotHTMLSpace(input[position])) 2147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch tokenBuilder.append(input[position++]); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8 2177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch String token = tokenBuilder.toString(); 2187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (tokens.contains(token)) { 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8.1 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (position < inputLength && isHTMLSpace(input[position])) 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++position; 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8.2 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t j = output.length(); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (j > 0 && isHTMLSpace(output[j - 1])) 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --j; 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.resize(j); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Step 8.3 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (position < inputLength && !output.isEmpty()) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) output.append(' '); 2327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } else { 2337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch output.append(token); // Step 9 2347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return output.toString(); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 241