OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "config.h" | |
32 #include "core/html/HTMLDimension.h" | |
33 | |
34 #include "wtf/text/WTFString.h" | |
35 | |
36 namespace WebCore { | |
37 | |
38 template <typename CharacterType> | |
39 static Length parseDimension(const CharacterType* characters, size_t lastParsedI
ndex, size_t endOfCurrentToken) | |
40 { | |
41 LengthType type = Fixed; | |
42 double value = 0.; | |
43 | |
44 // HTML5's split removes leading and trailing spaces so we need to skip the
leading spaces here. | |
45 while (lastParsedIndex < endOfCurrentToken && isASCIISpace((characters[lastP
arsedIndex]))) | |
46 ++lastParsedIndex; | |
47 | |
48 // This is Step 5.5. in the algorithm. Going to the last step would make the
code less readable. | |
49 if (lastParsedIndex >= endOfCurrentToken) | |
50 return Length(value, Relative); | |
51 | |
52 size_t position = lastParsedIndex; | |
53 while (position < endOfCurrentToken && isASCIIDigit(characters[position])) | |
54 ++position; | |
55 | |
56 if (position > lastParsedIndex) { | |
57 bool ok = false; | |
58 unsigned integerValue = charactersToUIntStrict(characters + lastParsedIn
dex, position - lastParsedIndex, &ok); | |
59 ASSERT(ok); | |
60 value += integerValue; | |
61 | |
62 if (characters[position] == '.') { | |
63 ++position; | |
64 size_t fractionStart = position; | |
65 Vector<CharacterType> fractionNumbers; | |
66 while (position < endOfCurrentToken && (isASCIIDigit(characters[posi
tion]) || isASCIISpace(characters[position]))) { | |
67 if (isASCIIDigit(characters[position])) | |
68 fractionNumbers.append(characters[position]); | |
69 ++position; | |
70 } | |
71 | |
72 if (fractionNumbers.size()) { | |
73 double fractionValue = charactersToUIntStrict(fractionNumbers.da
ta(), fractionNumbers.size(), &ok); | |
74 ASSERT(ok); | |
75 | |
76 value += fractionValue / pow(10., static_cast<double>(fractionNu
mbers.size())); | |
77 } | |
78 } | |
79 } | |
80 | |
81 while (position < endOfCurrentToken && isASCIISpace(characters[position])) | |
82 ++position; | |
83 | |
84 if (position < endOfCurrentToken) { | |
85 if (characters[position] == '*') | |
86 type = Relative; | |
87 else if (characters[position] == '%') | |
88 type = Percent; | |
89 } | |
90 | |
91 return Length(value, type); | |
92 } | |
93 | |
94 static Length parseDimension(const String& rawToken, size_t lastParsedIndex, siz
e_t endOfCurrentToken) | |
95 { | |
96 if (rawToken.is8Bit()) | |
97 return parseDimension<LChar>(rawToken.characters8(), lastParsedIndex, en
dOfCurrentToken); | |
98 return parseDimension<UChar>(rawToken.characters16(), lastParsedIndex, endOf
CurrentToken); | |
99 } | |
100 | |
101 // This implements the "rules for parsing a list of dimensions" per HTML5. | |
102 // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsynta
xes.html#rules-for-parsing-a-list-of-dimensions | |
103 Vector<Length> parseListOfDimensions(const String& input) | |
104 { | |
105 static const char comma = ','; | |
106 | |
107 // Step 2. Remove the last character if it's a comma. | |
108 String trimmedString = input; | |
109 if (trimmedString.endsWith(comma)) | |
110 trimmedString.truncate(trimmedString.length() - 1); | |
111 | |
112 // HTML5's split doesn't return a token for an empty string so | |
113 // we need to match them here. | |
114 if (trimmedString.isEmpty()) | |
115 return Vector<Length>(); | |
116 | |
117 // Step 3. To avoid String copies, we just look for commas instead of splitt
ing. | |
118 Vector<Length> parsedLength; | |
119 size_t lastParsedIndex = 0; | |
120 while (true) { | |
121 size_t nextComma = trimmedString.find(comma, lastParsedIndex); | |
122 if (nextComma == notFound) | |
123 break; | |
124 | |
125 parsedLength.append(parseDimension(trimmedString, lastParsedIndex, nextC
omma)); | |
126 lastParsedIndex = nextComma + 1; | |
127 } | |
128 | |
129 parsedLength.append(parseDimension(trimmedString, lastParsedIndex, trimmedSt
ring.length())); | |
130 return parsedLength; | |
131 } | |
132 | |
133 } // namespace WebCore | |
OLD | NEW |