OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/css/parser/CSSPropertyParserHelpers.h" | 5 #include "core/css/parser/CSSPropertyParserHelpers.h" |
6 | 6 |
7 #include "core/css/CSSCalculationValue.h" | 7 #include "core/css/CSSCalculationValue.h" |
8 #include "core/css/CSSStringValue.h" | 8 #include "core/css/CSSStringValue.h" |
9 #include "core/css/CSSValuePair.h" | 9 #include "core/css/CSSValuePair.h" |
10 // TODO(timloh): Remove this dependency | 10 // TODO(timloh): Remove this dependency |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 explicit CalcParser(CSSParserTokenRange& range, ValueRange valueRange = Valu
eRangeAll) | 49 explicit CalcParser(CSSParserTokenRange& range, ValueRange valueRange = Valu
eRangeAll) |
50 : m_sourceRange(range) | 50 : m_sourceRange(range) |
51 , m_range(range) | 51 , m_range(range) |
52 { | 52 { |
53 const CSSParserToken& token = range.peek(); | 53 const CSSParserToken& token = range.peek(); |
54 if (token.functionId() == CSSValueCalc || token.functionId() == CSSValue
WebkitCalc) | 54 if (token.functionId() == CSSValueCalc || token.functionId() == CSSValue
WebkitCalc) |
55 m_calcValue = CSSCalcValue::create(consumeFunction(m_range), valueRa
nge); | 55 m_calcValue = CSSCalcValue::create(consumeFunction(m_range), valueRa
nge); |
56 } | 56 } |
57 | 57 |
58 const CSSCalcValue* value() const { return m_calcValue.get(); } | 58 const CSSCalcValue* value() const { return m_calcValue.get(); } |
59 RawPtr<CSSPrimitiveValue> consumeValue() | 59 CSSPrimitiveValue* consumeValue() |
60 { | 60 { |
61 if (!m_calcValue) | 61 if (!m_calcValue) |
62 return nullptr; | 62 return nullptr; |
63 m_sourceRange = m_range; | 63 m_sourceRange = m_range; |
64 return CSSPrimitiveValue::create(m_calcValue.release()); | 64 return CSSPrimitiveValue::create(m_calcValue.release()); |
65 } | 65 } |
66 RawPtr<CSSPrimitiveValue> consumeNumber() | 66 CSSPrimitiveValue* consumeNumber() |
67 { | 67 { |
68 if (!m_calcValue) | 68 if (!m_calcValue) |
69 return nullptr; | 69 return nullptr; |
70 m_sourceRange = m_range; | 70 m_sourceRange = m_range; |
71 CSSPrimitiveValue::UnitType unitType = m_calcValue->isInt() ? CSSPrimiti
veValue::UnitType::Integer : CSSPrimitiveValue::UnitType::Number; | 71 CSSPrimitiveValue::UnitType unitType = m_calcValue->isInt() ? CSSPrimiti
veValue::UnitType::Integer : CSSPrimitiveValue::UnitType::Number; |
72 return cssValuePool().createValue(m_calcValue->doubleValue(), unitType); | 72 return cssValuePool().createValue(m_calcValue->doubleValue(), unitType); |
73 } | 73 } |
74 | 74 |
75 bool consumeNumberRaw(double& result) | 75 bool consumeNumberRaw(double& result) |
76 { | 76 { |
77 if (!m_calcValue || m_calcValue->category() != CalcNumber) | 77 if (!m_calcValue || m_calcValue->category() != CalcNumber) |
78 return false; | 78 return false; |
79 m_sourceRange = m_range; | 79 m_sourceRange = m_range; |
80 result = m_calcValue->doubleValue(); | 80 result = m_calcValue->doubleValue(); |
81 return true; | 81 return true; |
82 } | 82 } |
83 | 83 |
84 private: | 84 private: |
85 CSSParserTokenRange& m_sourceRange; | 85 CSSParserTokenRange& m_sourceRange; |
86 CSSParserTokenRange m_range; | 86 CSSParserTokenRange m_range; |
87 Member<CSSCalcValue> m_calcValue; | 87 Member<CSSCalcValue> m_calcValue; |
88 }; | 88 }; |
89 | 89 |
90 RawPtr<CSSPrimitiveValue> consumeInteger(CSSParserTokenRange& range, double mini
mumValue) | 90 CSSPrimitiveValue* consumeInteger(CSSParserTokenRange& range, double minimumValu
e) |
91 { | 91 { |
92 const CSSParserToken& token = range.peek(); | 92 const CSSParserToken& token = range.peek(); |
93 if (token.type() == NumberToken) { | 93 if (token.type() == NumberToken) { |
94 if (token.numericValueType() == NumberValueType || token.numericValue()
< minimumValue) | 94 if (token.numericValueType() == NumberValueType || token.numericValue()
< minimumValue) |
95 return nullptr; | 95 return nullptr; |
96 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), CSSPrimitiveValue::UnitType::Integer); | 96 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), CSSPrimitiveValue::UnitType::Integer); |
97 } | 97 } |
98 CalcParser calcParser(range); | 98 CalcParser calcParser(range); |
99 if (const CSSCalcValue* calculation = calcParser.value()) { | 99 if (const CSSCalcValue* calculation = calcParser.value()) { |
100 if (calculation->category() != CalcNumber || !calculation->isInt()) | 100 if (calculation->category() != CalcNumber || !calculation->isInt()) |
101 return nullptr; | 101 return nullptr; |
102 double value = calculation->doubleValue(); | 102 double value = calculation->doubleValue(); |
103 if (value < minimumValue) | 103 if (value < minimumValue) |
104 return nullptr; | 104 return nullptr; |
105 return calcParser.consumeNumber(); | 105 return calcParser.consumeNumber(); |
106 } | 106 } |
107 return nullptr; | 107 return nullptr; |
108 } | 108 } |
109 | 109 |
110 RawPtr<CSSPrimitiveValue> consumePositiveInteger(CSSParserTokenRange& range) | 110 CSSPrimitiveValue* consumePositiveInteger(CSSParserTokenRange& range) |
111 { | 111 { |
112 return consumeInteger(range, 1); | 112 return consumeInteger(range, 1); |
113 } | 113 } |
114 | 114 |
115 bool consumeNumberRaw(CSSParserTokenRange& range, double& result) | 115 bool consumeNumberRaw(CSSParserTokenRange& range, double& result) |
116 { | 116 { |
117 if (range.peek().type() == NumberToken) { | 117 if (range.peek().type() == NumberToken) { |
118 result = range.consumeIncludingWhitespace().numericValue(); | 118 result = range.consumeIncludingWhitespace().numericValue(); |
119 return true; | 119 return true; |
120 } | 120 } |
121 CalcParser calcParser(range, ValueRangeAll); | 121 CalcParser calcParser(range, ValueRangeAll); |
122 return calcParser.consumeNumberRaw(result); | 122 return calcParser.consumeNumberRaw(result); |
123 } | 123 } |
124 | 124 |
125 // TODO(timloh): Work out if this can just call consumeNumberRaw | 125 // TODO(timloh): Work out if this can just call consumeNumberRaw |
126 RawPtr<CSSPrimitiveValue> consumeNumber(CSSParserTokenRange& range, ValueRange v
alueRange) | 126 CSSPrimitiveValue* consumeNumber(CSSParserTokenRange& range, ValueRange valueRan
ge) |
127 { | 127 { |
128 const CSSParserToken& token = range.peek(); | 128 const CSSParserToken& token = range.peek(); |
129 if (token.type() == NumberToken) { | 129 if (token.type() == NumberToken) { |
130 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) | 130 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) |
131 return nullptr; | 131 return nullptr; |
132 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), token.unitType()); | 132 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), token.unitType()); |
133 } | 133 } |
134 CalcParser calcParser(range, ValueRangeAll); | 134 CalcParser calcParser(range, ValueRangeAll); |
135 if (const CSSCalcValue* calculation = calcParser.value()) { | 135 if (const CSSCalcValue* calculation = calcParser.value()) { |
136 // TODO(rwlbuis) Calcs should not be subject to parse time range checks. | 136 // TODO(rwlbuis) Calcs should not be subject to parse time range checks. |
137 // spec: https://drafts.csswg.org/css-values-3/#calc-range | 137 // spec: https://drafts.csswg.org/css-values-3/#calc-range |
138 if (calculation->category() != CalcNumber || (valueRange == ValueRangeNo
nNegative && calculation->isNegative())) | 138 if (calculation->category() != CalcNumber || (valueRange == ValueRangeNo
nNegative && calculation->isNegative())) |
139 return nullptr; | 139 return nullptr; |
140 return calcParser.consumeNumber(); | 140 return calcParser.consumeNumber(); |
141 } | 141 } |
142 return nullptr; | 142 return nullptr; |
143 } | 143 } |
144 | 144 |
145 inline bool shouldAcceptUnitlessLength(double value, CSSParserMode cssParserMode
, UnitlessQuirk unitless) | 145 inline bool shouldAcceptUnitlessLength(double value, CSSParserMode cssParserMode
, UnitlessQuirk unitless) |
146 { | 146 { |
147 // TODO(timloh): Presentational HTML attributes shouldn't use the CSS parser
for lengths | 147 // TODO(timloh): Presentational HTML attributes shouldn't use the CSS parser
for lengths |
148 return value == 0 | 148 return value == 0 |
149 || isUnitLessLengthParsingEnabledForMode(cssParserMode) | 149 || isUnitLessLengthParsingEnabledForMode(cssParserMode) |
150 || (cssParserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow)
; | 150 || (cssParserMode == HTMLQuirksMode && unitless == UnitlessQuirk::Allow)
; |
151 } | 151 } |
152 | 152 |
153 RawPtr<CSSPrimitiveValue> consumeLength(CSSParserTokenRange& range, CSSParserMod
e cssParserMode, ValueRange valueRange, UnitlessQuirk unitless) | 153 CSSPrimitiveValue* consumeLength(CSSParserTokenRange& range, CSSParserMode cssPa
rserMode, ValueRange valueRange, UnitlessQuirk unitless) |
154 { | 154 { |
155 const CSSParserToken& token = range.peek(); | 155 const CSSParserToken& token = range.peek(); |
156 if (token.type() == DimensionToken) { | 156 if (token.type() == DimensionToken) { |
157 switch (token.unitType()) { | 157 switch (token.unitType()) { |
158 case CSSPrimitiveValue::UnitType::QuirkyEms: | 158 case CSSPrimitiveValue::UnitType::QuirkyEms: |
159 if (cssParserMode != UASheetMode) | 159 if (cssParserMode != UASheetMode) |
160 return nullptr; | 160 return nullptr; |
161 /* fallthrough intentional */ | 161 /* fallthrough intentional */ |
162 case CSSPrimitiveValue::UnitType::Ems: | 162 case CSSPrimitiveValue::UnitType::Ems: |
163 case CSSPrimitiveValue::UnitType::Rems: | 163 case CSSPrimitiveValue::UnitType::Rems: |
(...skipping 28 matching lines...) Expand all Loading... |
192 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), unitType); | 192 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), unitType); |
193 } | 193 } |
194 if (cssParserMode == SVGAttributeMode) | 194 if (cssParserMode == SVGAttributeMode) |
195 return nullptr; | 195 return nullptr; |
196 CalcParser calcParser(range, valueRange); | 196 CalcParser calcParser(range, valueRange); |
197 if (calcParser.value() && calcParser.value()->category() == CalcLength) | 197 if (calcParser.value() && calcParser.value()->category() == CalcLength) |
198 return calcParser.consumeValue(); | 198 return calcParser.consumeValue(); |
199 return nullptr; | 199 return nullptr; |
200 } | 200 } |
201 | 201 |
202 RawPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRange& range, ValueRange
valueRange) | 202 CSSPrimitiveValue* consumePercent(CSSParserTokenRange& range, ValueRange valueRa
nge) |
203 { | 203 { |
204 const CSSParserToken& token = range.peek(); | 204 const CSSParserToken& token = range.peek(); |
205 if (token.type() == PercentageToken) { | 205 if (token.type() == PercentageToken) { |
206 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) | 206 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) |
207 return nullptr; | 207 return nullptr; |
208 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), CSSPrimitiveValue::UnitType::Percentage); | 208 return cssValuePool().createValue(range.consumeIncludingWhitespace().num
ericValue(), CSSPrimitiveValue::UnitType::Percentage); |
209 } | 209 } |
210 CalcParser calcParser(range, valueRange); | 210 CalcParser calcParser(range, valueRange); |
211 if (const CSSCalcValue* calculation = calcParser.value()) { | 211 if (const CSSCalcValue* calculation = calcParser.value()) { |
212 if (calculation->category() == CalcPercent) | 212 if (calculation->category() == CalcPercent) |
213 return calcParser.consumeValue(); | 213 return calcParser.consumeValue(); |
214 } | 214 } |
215 return nullptr; | 215 return nullptr; |
216 } | 216 } |
217 | 217 |
218 RawPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSS
ParserMode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless) | 218 CSSPrimitiveValue* consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserM
ode cssParserMode, ValueRange valueRange, UnitlessQuirk unitless) |
219 { | 219 { |
220 const CSSParserToken& token = range.peek(); | 220 const CSSParserToken& token = range.peek(); |
221 if (token.type() == DimensionToken || token.type() == NumberToken) | 221 if (token.type() == DimensionToken || token.type() == NumberToken) |
222 return consumeLength(range, cssParserMode, valueRange, unitless); | 222 return consumeLength(range, cssParserMode, valueRange, unitless); |
223 if (token.type() == PercentageToken) | 223 if (token.type() == PercentageToken) |
224 return consumePercent(range, valueRange); | 224 return consumePercent(range, valueRange); |
225 CalcParser calcParser(range, valueRange); | 225 CalcParser calcParser(range, valueRange); |
226 if (const CSSCalcValue* calculation = calcParser.value()) { | 226 if (const CSSCalcValue* calculation = calcParser.value()) { |
227 if (calculation->category() == CalcLength || calculation->category() ==
CalcPercent || calculation->category() == CalcPercentLength) | 227 if (calculation->category() == CalcLength || calculation->category() ==
CalcPercent || calculation->category() == CalcPercentLength) |
228 return calcParser.consumeValue(); | 228 return calcParser.consumeValue(); |
229 } | 229 } |
230 return nullptr; | 230 return nullptr; |
231 } | 231 } |
232 | 232 |
233 RawPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange& range) | 233 CSSPrimitiveValue* consumeAngle(CSSParserTokenRange& range) |
234 { | 234 { |
235 const CSSParserToken& token = range.peek(); | 235 const CSSParserToken& token = range.peek(); |
236 if (token.type() == DimensionToken) { | 236 if (token.type() == DimensionToken) { |
237 switch (token.unitType()) { | 237 switch (token.unitType()) { |
238 case CSSPrimitiveValue::UnitType::Degrees: | 238 case CSSPrimitiveValue::UnitType::Degrees: |
239 case CSSPrimitiveValue::UnitType::Radians: | 239 case CSSPrimitiveValue::UnitType::Radians: |
240 case CSSPrimitiveValue::UnitType::Gradians: | 240 case CSSPrimitiveValue::UnitType::Gradians: |
241 case CSSPrimitiveValue::UnitType::Turns: | 241 case CSSPrimitiveValue::UnitType::Turns: |
242 return cssValuePool().createValue(range.consumeIncludingWhitespace()
.numericValue(), token.unitType()); | 242 return cssValuePool().createValue(range.consumeIncludingWhitespace()
.numericValue(), token.unitType()); |
243 default: | 243 default: |
244 return nullptr; | 244 return nullptr; |
245 } | 245 } |
246 } | 246 } |
247 if (token.type() == NumberToken && token.numericValue() == 0) { | 247 if (token.type() == NumberToken && token.numericValue() == 0) { |
248 range.consumeIncludingWhitespace(); | 248 range.consumeIncludingWhitespace(); |
249 return cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Degree
s); | 249 return cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Degree
s); |
250 } | 250 } |
251 CalcParser calcParser(range, ValueRangeAll); | 251 CalcParser calcParser(range, ValueRangeAll); |
252 if (const CSSCalcValue* calculation = calcParser.value()) { | 252 if (const CSSCalcValue* calculation = calcParser.value()) { |
253 if (calculation->category() == CalcAngle) | 253 if (calculation->category() == CalcAngle) |
254 return calcParser.consumeValue(); | 254 return calcParser.consumeValue(); |
255 } | 255 } |
256 return nullptr; | 256 return nullptr; |
257 } | 257 } |
258 | 258 |
259 RawPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange& range, ValueRange val
ueRange) | 259 CSSPrimitiveValue* consumeTime(CSSParserTokenRange& range, ValueRange valueRange
) |
260 { | 260 { |
261 const CSSParserToken& token = range.peek(); | 261 const CSSParserToken& token = range.peek(); |
262 if (token.type() == DimensionToken) { | 262 if (token.type() == DimensionToken) { |
263 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) | 263 if (valueRange == ValueRangeNonNegative && token.numericValue() < 0) |
264 return nullptr; | 264 return nullptr; |
265 CSSPrimitiveValue::UnitType unit = token.unitType(); | 265 CSSPrimitiveValue::UnitType unit = token.unitType(); |
266 if (unit == CSSPrimitiveValue::UnitType::Milliseconds || unit == CSSPrim
itiveValue::UnitType::Seconds) | 266 if (unit == CSSPrimitiveValue::UnitType::Milliseconds || unit == CSSPrim
itiveValue::UnitType::Seconds) |
267 return cssValuePool().createValue(range.consumeIncludingWhitespace()
.numericValue(), token.unitType()); | 267 return cssValuePool().createValue(range.consumeIncludingWhitespace()
.numericValue(), token.unitType()); |
268 return nullptr; | 268 return nullptr; |
269 } | 269 } |
270 CalcParser calcParser(range, valueRange); | 270 CalcParser calcParser(range, valueRange); |
271 if (const CSSCalcValue* calculation = calcParser.value()) { | 271 if (const CSSCalcValue* calculation = calcParser.value()) { |
272 if (calculation->category() == CalcTime) | 272 if (calculation->category() == CalcTime) |
273 return calcParser.consumeValue(); | 273 return calcParser.consumeValue(); |
274 } | 274 } |
275 return nullptr; | 275 return nullptr; |
276 } | 276 } |
277 | 277 |
278 RawPtr<CSSPrimitiveValue> consumeIdent(CSSParserTokenRange& range) | 278 CSSPrimitiveValue* consumeIdent(CSSParserTokenRange& range) |
279 { | 279 { |
280 if (range.peek().type() != IdentToken) | 280 if (range.peek().type() != IdentToken) |
281 return nullptr; | 281 return nullptr; |
282 return cssValuePool().createIdentifierValue(range.consumeIncludingWhitespace
().id()); | 282 return cssValuePool().createIdentifierValue(range.consumeIncludingWhitespace
().id()); |
283 } | 283 } |
284 | 284 |
285 RawPtr<CSSPrimitiveValue> consumeIdentRange(CSSParserTokenRange& range, CSSValue
ID lower, CSSValueID upper) | 285 CSSPrimitiveValue* consumeIdentRange(CSSParserTokenRange& range, CSSValueID lowe
r, CSSValueID upper) |
286 { | 286 { |
287 if (range.peek().id() < lower || range.peek().id() > upper) | 287 if (range.peek().id() < lower || range.peek().id() > upper) |
288 return nullptr; | 288 return nullptr; |
289 return consumeIdent(range); | 289 return consumeIdent(range); |
290 } | 290 } |
291 | 291 |
292 RawPtr<CSSCustomIdentValue> consumeCustomIdent(CSSParserTokenRange& range) | 292 CSSCustomIdentValue* consumeCustomIdent(CSSParserTokenRange& range) |
293 { | 293 { |
294 if (range.peek().type() != IdentToken || isCSSWideKeyword(range.peek().id())
) | 294 if (range.peek().type() != IdentToken || isCSSWideKeyword(range.peek().id())
) |
295 return nullptr; | 295 return nullptr; |
296 return CSSCustomIdentValue::create(range.consumeIncludingWhitespace().value(
)); | 296 return CSSCustomIdentValue::create(range.consumeIncludingWhitespace().value(
)); |
297 } | 297 } |
298 | 298 |
299 RawPtr<CSSStringValue> consumeString(CSSParserTokenRange& range) | 299 CSSStringValue* consumeString(CSSParserTokenRange& range) |
300 { | 300 { |
301 if (range.peek().type() != StringToken) | 301 if (range.peek().type() != StringToken) |
302 return nullptr; | 302 return nullptr; |
303 return CSSStringValue::create(range.consumeIncludingWhitespace().value()); | 303 return CSSStringValue::create(range.consumeIncludingWhitespace().value()); |
304 } | 304 } |
305 | 305 |
306 String consumeUrl(CSSParserTokenRange& range) | 306 String consumeUrl(CSSParserTokenRange& range) |
307 { | 307 { |
308 const CSSParserToken& token = range.peek(); | 308 const CSSParserToken& token = range.peek(); |
309 if (token.type() == UrlToken) { | 309 if (token.type() == UrlToken) { |
(...skipping 21 matching lines...) Expand all Loading... |
331 // TODO(timloh): Multiply by 2.55 and round instead of floor. | 331 // TODO(timloh): Multiply by 2.55 and round instead of floor. |
332 if (value.isPercentage()) | 332 if (value.isPercentage()) |
333 result *= 2.56; | 333 result *= 2.56; |
334 return clampTo<int>(result, 0, 255); | 334 return clampTo<int>(result, 0, 255); |
335 } | 335 } |
336 | 336 |
337 static bool parseRGBParameters(CSSParserTokenRange& range, RGBA32& result, bool
parseAlpha) | 337 static bool parseRGBParameters(CSSParserTokenRange& range, RGBA32& result, bool
parseAlpha) |
338 { | 338 { |
339 ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId()
== CSSValueRgba); | 339 ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId()
== CSSValueRgba); |
340 CSSParserTokenRange args = consumeFunction(range); | 340 CSSParserTokenRange args = consumeFunction(range); |
341 RawPtr<CSSPrimitiveValue> colorParameter = consumeInteger(args); | 341 CSSPrimitiveValue* colorParameter = consumeInteger(args); |
342 if (!colorParameter) | 342 if (!colorParameter) |
343 colorParameter = consumePercent(args, ValueRangeAll); | 343 colorParameter = consumePercent(args, ValueRangeAll); |
344 if (!colorParameter) | 344 if (!colorParameter) |
345 return false; | 345 return false; |
346 const bool isPercent = colorParameter->isPercentage(); | 346 const bool isPercent = colorParameter->isPercentage(); |
347 int colorArray[3]; | 347 int colorArray[3]; |
348 colorArray[0] = clampRGBComponent(*colorParameter); | 348 colorArray[0] = clampRGBComponent(*colorParameter); |
349 for (int i = 1; i < 3; i++) { | 349 for (int i = 1; i < 3; i++) { |
350 if (!consumeCommaIncludingWhitespace(args)) | 350 if (!consumeCommaIncludingWhitespace(args)) |
351 return false; | 351 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
367 } else { | 367 } else { |
368 result = makeRGB(colorArray[0], colorArray[1], colorArray[2]); | 368 result = makeRGB(colorArray[0], colorArray[1], colorArray[2]); |
369 } | 369 } |
370 return args.atEnd(); | 370 return args.atEnd(); |
371 } | 371 } |
372 | 372 |
373 static bool parseHSLParameters(CSSParserTokenRange& range, RGBA32& result, bool
parseAlpha) | 373 static bool parseHSLParameters(CSSParserTokenRange& range, RGBA32& result, bool
parseAlpha) |
374 { | 374 { |
375 ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId()
== CSSValueHsla); | 375 ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId()
== CSSValueHsla); |
376 CSSParserTokenRange args = consumeFunction(range); | 376 CSSParserTokenRange args = consumeFunction(range); |
377 RawPtr<CSSPrimitiveValue> hslValue = consumeNumber(args, ValueRangeAll); | 377 CSSPrimitiveValue* hslValue = consumeNumber(args, ValueRangeAll); |
378 if (!hslValue) | 378 if (!hslValue) |
379 return false; | 379 return false; |
380 double colorArray[3]; | 380 double colorArray[3]; |
381 colorArray[0] = (((hslValue->getIntValue() % 360) + 360) % 360) / 360.0; | 381 colorArray[0] = (((hslValue->getIntValue() % 360) + 360) % 360) / 360.0; |
382 for (int i = 1; i < 3; i++) { | 382 for (int i = 1; i < 3; i++) { |
383 if (!consumeCommaIncludingWhitespace(args)) | 383 if (!consumeCommaIncludingWhitespace(args)) |
384 return false; | 384 return false; |
385 hslValue = consumePercent(args, ValueRangeAll); | 385 hslValue = consumePercent(args, ValueRangeAll); |
386 if (!hslValue) | 386 if (!hslValue) |
387 return false; | 387 return false; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 if (functionId < CSSValueRgb || functionId > CSSValueHsla) | 433 if (functionId < CSSValueRgb || functionId > CSSValueHsla) |
434 return false; | 434 return false; |
435 CSSParserTokenRange colorRange = range; | 435 CSSParserTokenRange colorRange = range; |
436 if ((functionId <= CSSValueRgba && !parseRGBParameters(colorRange, result, f
unctionId == CSSValueRgba)) | 436 if ((functionId <= CSSValueRgba && !parseRGBParameters(colorRange, result, f
unctionId == CSSValueRgba)) |
437 || (functionId >= CSSValueHsl && !parseHSLParameters(colorRange, result,
functionId == CSSValueHsla))) | 437 || (functionId >= CSSValueHsl && !parseHSLParameters(colorRange, result,
functionId == CSSValueHsla))) |
438 return false; | 438 return false; |
439 range = colorRange; | 439 range = colorRange; |
440 return true; | 440 return true; |
441 } | 441 } |
442 | 442 |
443 RawPtr<CSSValue> consumeColor(CSSParserTokenRange& range, CSSParserMode cssParse
rMode, bool acceptQuirkyColors) | 443 CSSValue* consumeColor(CSSParserTokenRange& range, CSSParserMode cssParserMode,
bool acceptQuirkyColors) |
444 { | 444 { |
445 CSSValueID id = range.peek().id(); | 445 CSSValueID id = range.peek().id(); |
446 if (CSSPropertyParser::isColorKeyword(id)) { | 446 if (CSSPropertyParser::isColorKeyword(id)) { |
447 if (!isValueAllowedInMode(id, cssParserMode)) | 447 if (!isValueAllowedInMode(id, cssParserMode)) |
448 return nullptr; | 448 return nullptr; |
449 return consumeIdent(range); | 449 return consumeIdent(range); |
450 } | 450 } |
451 RGBA32 color = Color::transparent; | 451 RGBA32 color = Color::transparent; |
452 if (!parseHexColor(range, color, acceptQuirkyColors) && !parseColorFunction(
range, color)) | 452 if (!parseHexColor(range, color, acceptQuirkyColors) && !parseColorFunction(
range, color)) |
453 return nullptr; | 453 return nullptr; |
454 return cssValuePool().createColorValue(color); | 454 return cssValuePool().createColorValue(color); |
455 } | 455 } |
456 | 456 |
457 static RawPtr<CSSPrimitiveValue> consumePositionComponent(CSSParserTokenRange& r
ange, CSSParserMode cssParserMode, UnitlessQuirk unitless) | 457 static CSSPrimitiveValue* consumePositionComponent(CSSParserTokenRange& range, C
SSParserMode cssParserMode, UnitlessQuirk unitless) |
458 { | 458 { |
459 if (range.peek().type() == IdentToken) | 459 if (range.peek().type() == IdentToken) |
460 return consumeIdent<CSSValueLeft, CSSValueTop, CSSValueBottom, CSSValueR
ight, CSSValueCenter>(range); | 460 return consumeIdent<CSSValueLeft, CSSValueTop, CSSValueBottom, CSSValueR
ight, CSSValueCenter>(range); |
461 return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, unitless)
; | 461 return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, unitless)
; |
462 } | 462 } |
463 | 463 |
464 static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value) | 464 static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value) |
465 { | 465 { |
466 return value.isValueID() && (value.getValueID() == CSSValueLeft || value.get
ValueID() == CSSValueRight); | 466 return value.isValueID() && (value.getValueID() == CSSValueLeft || value.get
ValueID() == CSSValueRight); |
467 } | 467 } |
468 | 468 |
469 static bool isVerticalPositionKeywordOnly(const CSSPrimitiveValue& value) | 469 static bool isVerticalPositionKeywordOnly(const CSSPrimitiveValue& value) |
470 { | 470 { |
471 return value.isValueID() && (value.getValueID() == CSSValueTop || value.getV
alueID() == CSSValueBottom); | 471 return value.isValueID() && (value.getValueID() == CSSValueTop || value.getV
alueID() == CSSValueBottom); |
472 } | 472 } |
473 | 473 |
474 static void positionFromOneValue(RawPtr<CSSPrimitiveValue> value, RawPtr<CSSValu
e>& resultX, RawPtr<CSSValue>& resultY) | 474 static void positionFromOneValue(CSSPrimitiveValue* value, CSSValue*& resultX, C
SSValue*& resultY) |
475 { | 475 { |
476 bool valueAppliesToYAxisOnly = isVerticalPositionKeywordOnly(*value); | 476 bool valueAppliesToYAxisOnly = isVerticalPositionKeywordOnly(*value); |
477 resultX = value; | 477 resultX = value; |
478 resultY = cssValuePool().createIdentifierValue(CSSValueCenter); | 478 resultY = cssValuePool().createIdentifierValue(CSSValueCenter); |
479 if (valueAppliesToYAxisOnly) | 479 if (valueAppliesToYAxisOnly) |
480 swap(resultX, resultY); | 480 std::swap(resultX, resultY); |
481 } | 481 } |
482 | 482 |
483 static bool positionFromTwoValues(RawPtr<CSSPrimitiveValue> value1, RawPtr<CSSPr
imitiveValue> value2, | 483 static bool positionFromTwoValues(CSSPrimitiveValue* value1, CSSPrimitiveValue*
value2, |
484 RawPtr<CSSValue>& resultX, RawPtr<CSSValue>& resultY) | 484 CSSValue*& resultX, CSSValue*& resultY) |
485 { | 485 { |
486 bool mustOrderAsXY = isHorizontalPositionKeywordOnly(*value1) || isVerticalP
ositionKeywordOnly(*value2) | 486 bool mustOrderAsXY = isHorizontalPositionKeywordOnly(*value1) || isVerticalP
ositionKeywordOnly(*value2) |
487 || !value1->isValueID() || !value2->isValueID(); | 487 || !value1->isValueID() || !value2->isValueID(); |
488 bool mustOrderAsYX = isVerticalPositionKeywordOnly(*value1) || isHorizontalP
ositionKeywordOnly(*value2); | 488 bool mustOrderAsYX = isVerticalPositionKeywordOnly(*value1) || isHorizontalP
ositionKeywordOnly(*value2); |
489 if (mustOrderAsXY && mustOrderAsYX) | 489 if (mustOrderAsXY && mustOrderAsYX) |
490 return false; | 490 return false; |
491 resultX = value1; | 491 resultX = value1; |
492 resultY = value2; | 492 resultY = value2; |
493 if (mustOrderAsYX) | 493 if (mustOrderAsYX) |
494 swap(resultX, resultY); | 494 std::swap(resultX, resultY); |
495 return true; | 495 return true; |
496 } | 496 } |
497 | 497 |
498 static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, RawPtr<CSS
Value>& resultX, RawPtr<CSSValue>& resultY) | 498 static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, CSSValue*&
resultX, CSSValue*& resultY) |
499 { | 499 { |
500 CSSPrimitiveValue* center = nullptr; | 500 CSSPrimitiveValue* center = nullptr; |
501 for (int i = 0; values[i]; i++) { | 501 for (int i = 0; values[i]; i++) { |
502 CSSPrimitiveValue* currentValue = values[i]; | 502 CSSPrimitiveValue* currentValue = values[i]; |
503 if (!currentValue->isValueID()) | 503 if (!currentValue->isValueID()) |
504 return false; | 504 return false; |
505 CSSValueID id = currentValue->getValueID(); | 505 CSSValueID id = currentValue->getValueID(); |
506 | 506 |
507 if (id == CSSValueCenter) { | 507 if (id == CSSValueCenter) { |
508 if (center) | 508 if (center) |
509 return false; | 509 return false; |
510 center = currentValue; | 510 center = currentValue; |
511 continue; | 511 continue; |
512 } | 512 } |
513 | 513 |
514 RawPtr<CSSValue> result = nullptr; | 514 CSSValue* result = nullptr; |
515 if (values[i + 1] && !values[i + 1]->isValueID()) { | 515 if (values[i + 1] && !values[i + 1]->isValueID()) { |
516 result = CSSValuePair::create(currentValue, values[++i], CSSValuePai
r::KeepIdenticalValues); | 516 result = CSSValuePair::create(currentValue, values[++i], CSSValuePai
r::KeepIdenticalValues); |
517 } else { | 517 } else { |
518 result = currentValue; | 518 result = currentValue; |
519 } | 519 } |
520 | 520 |
521 if (id == CSSValueLeft || id == CSSValueRight) { | 521 if (id == CSSValueLeft || id == CSSValueRight) { |
522 if (resultX) | 522 if (resultX) |
523 return false; | 523 return false; |
524 resultX = result.release(); | 524 resultX = result; |
525 } else { | 525 } else { |
526 ASSERT(id == CSSValueTop || id == CSSValueBottom); | 526 ASSERT(id == CSSValueTop || id == CSSValueBottom); |
527 if (resultY) | 527 if (resultY) |
528 return false; | 528 return false; |
529 resultY = result.release(); | 529 resultY = result; |
530 } | 530 } |
531 } | 531 } |
532 | 532 |
533 if (center) { | 533 if (center) { |
534 ASSERT(resultX || resultY); | 534 ASSERT(resultX || resultY); |
535 if (resultX && resultY) | 535 if (resultX && resultY) |
536 return false; | 536 return false; |
537 if (!resultX) | 537 if (!resultX) |
538 resultX = center; | 538 resultX = center; |
539 else | 539 else |
540 resultY = center; | 540 resultY = center; |
541 } | 541 } |
542 | 542 |
543 ASSERT(resultX && resultY); | 543 ASSERT(resultX && resultY); |
544 return true; | 544 return true; |
545 } | 545 } |
546 | 546 |
547 // TODO(timloh): This may consume from the range upon failure. The background | 547 // TODO(timloh): This may consume from the range upon failure. The background |
548 // shorthand works around it, but we should just fix it here. | 548 // shorthand works around it, but we should just fix it here. |
549 bool consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, Un
itlessQuirk unitless, RawPtr<CSSValue>& resultX, RawPtr<CSSValue>& resultY) | 549 bool consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, Un
itlessQuirk unitless, CSSValue*& resultX, CSSValue*& resultY) |
550 { | 550 { |
551 RawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(range, cssParser
Mode, unitless); | 551 CSSPrimitiveValue* value1 = consumePositionComponent(range, cssParserMode, u
nitless); |
552 if (!value1) | 552 if (!value1) |
553 return false; | 553 return false; |
554 | 554 |
555 RawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParser
Mode, unitless); | 555 CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, u
nitless); |
556 if (!value2) { | 556 if (!value2) { |
557 positionFromOneValue(value1.release(), resultX, resultY); | 557 positionFromOneValue(value1, resultX, resultY); |
558 return true; | 558 return true; |
559 } | 559 } |
560 | 560 |
561 RawPtr<CSSPrimitiveValue> value3 = consumePositionComponent(range, cssParser
Mode, unitless); | 561 CSSPrimitiveValue* value3 = consumePositionComponent(range, cssParserMode, u
nitless); |
562 if (!value3) | 562 if (!value3) |
563 return positionFromTwoValues(value1.release(), value2.release(), resultX
, resultY); | 563 return positionFromTwoValues(value1, value2, resultX, resultY); |
564 | 564 |
565 RawPtr<CSSPrimitiveValue> value4 = consumePositionComponent(range, cssParser
Mode, unitless); | 565 CSSPrimitiveValue* value4 = consumePositionComponent(range, cssParserMode, u
nitless); |
566 CSSPrimitiveValue* values[5]; | 566 CSSPrimitiveValue* values[5]; |
567 values[0] = value1.get(); | 567 values[0] = value1; |
568 values[1] = value2.get(); | 568 values[1] = value2; |
569 values[2] = value3.get(); | 569 values[2] = value3; |
570 values[3] = value4.get(); | 570 values[3] = value4; |
571 values[4] = nullptr; | 571 values[4] = nullptr; |
572 return positionFromThreeOrFourValues(values, resultX, resultY); | 572 return positionFromThreeOrFourValues(values, resultX, resultY); |
573 } | 573 } |
574 | 574 |
575 RawPtr<CSSValuePair> consumePosition(CSSParserTokenRange& range, CSSParserMode c
ssParserMode, UnitlessQuirk unitless) | 575 CSSValuePair* consumePosition(CSSParserTokenRange& range, CSSParserMode cssParse
rMode, UnitlessQuirk unitless) |
576 { | 576 { |
577 RawPtr<CSSValue> resultX = nullptr; | 577 CSSValue* resultX = nullptr; |
578 RawPtr<CSSValue> resultY = nullptr; | 578 CSSValue* resultY = nullptr; |
579 if (consumePosition(range, cssParserMode, unitless, resultX, resultY)) | 579 if (consumePosition(range, cssParserMode, unitless, resultX, resultY)) |
580 return CSSValuePair::create(resultX.release(), resultY.release(), CSSVal
uePair::KeepIdenticalValues); | 580 return CSSValuePair::create(resultX, resultY, CSSValuePair::KeepIdentica
lValues); |
581 return nullptr; | 581 return nullptr; |
582 } | 582 } |
583 | 583 |
584 bool consumeOneOrTwoValuedPosition(CSSParserTokenRange& range, CSSParserMode css
ParserMode, UnitlessQuirk unitless, RawPtr<CSSValue>& resultX, RawPtr<CSSValue>&
resultY) | 584 bool consumeOneOrTwoValuedPosition(CSSParserTokenRange& range, CSSParserMode css
ParserMode, UnitlessQuirk unitless, CSSValue*& resultX, CSSValue*& resultY) |
585 { | 585 { |
586 RawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(range, cssParser
Mode, unitless); | 586 CSSPrimitiveValue* value1 = consumePositionComponent(range, cssParserMode, u
nitless); |
587 if (!value1) | 587 if (!value1) |
588 return false; | 588 return false; |
589 RawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParser
Mode, unitless); | 589 CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, u
nitless); |
590 if (!value2) { | 590 if (!value2) { |
591 positionFromOneValue(value1.release(), resultX, resultY); | 591 positionFromOneValue(value1, resultX, resultY); |
592 return true; | 592 return true; |
593 } | 593 } |
594 return positionFromTwoValues(value1.release(), value2.release(), resultX, re
sultY); | 594 return positionFromTwoValues(value1, value2, resultX, resultY); |
595 } | 595 } |
596 | 596 |
597 } // namespace CSSPropertyParserHelpers | 597 } // namespace CSSPropertyParserHelpers |
598 | 598 |
599 } // namespace blink | 599 } // namespace blink |
OLD | NEW |