1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 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 ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25 #include "config.h" 26 #include "DOMTokenList.h" 27 28 #include "HTMLParserIdioms.h" 29 #include <wtf/text/StringBuilder.h> 30 31 namespace WebCore { 32 33 bool DOMTokenList::validateToken(const AtomicString& token, ExceptionCode& ec) 34 { 35 if (token.isEmpty()) { 36 ec = SYNTAX_ERR; 37 return false; 38 } 39 40 unsigned length = token.length(); 41 for (unsigned i = 0; i < length; ++i) { 42 if (isHTMLSpace(token[i])) { 43 ec = INVALID_CHARACTER_ERR; 44 return false; 45 } 46 } 47 48 return true; 49 } 50 51 String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token) 52 { 53 if (input.isEmpty()) 54 return token; 55 56 StringBuilder builder; 57 builder.append(input); 58 if (input[input.length()-1] != ' ') 59 builder.append(' '); 60 builder.append(token); 61 return builder.toString(); 62 } 63 64 String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token) 65 { 66 // Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string 67 68 unsigned inputLength = input.length(); 69 Vector<UChar> output; // 3 70 output.reserveCapacity(inputLength); 71 unsigned position = 0; // 4 72 73 // Step 5 74 while (position < inputLength) { 75 if (isHTMLSpace(input[position])) { // 6 76 output.append(input[position++]); // 6.1, 6.2 77 continue; // 6.3 78 } 79 80 // Step 7 81 Vector<UChar> s; 82 while (position < inputLength && isNotHTMLSpace(input[position])) 83 s.append(input[position++]); 84 85 // Step 8 86 if (s == token) { 87 // Step 8.1 88 while (position < inputLength && isHTMLSpace(input[position])) 89 ++position; 90 91 // Step 8.2 92 size_t j = output.size(); 93 while (j > 0 && isHTMLSpace(output[j - 1])) 94 --j; 95 output.resize(j); 96 97 // Step 8.3 98 if (position < inputLength && !output.isEmpty()) 99 output.append(' '); 100 } else 101 output.append(s); // Step 9 102 } 103 104 output.shrinkToFit(); 105 return String::adopt(output); 106 } 107 108 } // namespace WebCore 109