| 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 |