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
validateToken(const AtomicString & token,ExceptionCode & ec)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
addToken(const AtomicString & input,const AtomicString & token)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
removeToken(const AtomicString & input,const AtomicString & token)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