Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "config.h" | 5 #include "config.h" |
| 6 #include "core/css/parser/CSSPropertyParser.h" | 6 #include "core/css/parser/CSSPropertyParser.h" |
| 7 | 7 |
| 8 #include "core/StylePropertyShorthand.h" | 8 #include "core/StylePropertyShorthand.h" |
| 9 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
| 10 #include "core/css/CSSCustomIdentValue.h" | 10 #include "core/css/CSSCustomIdentValue.h" |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 return nullptr; | 351 return nullptr; |
| 352 } | 352 } |
| 353 CalcParser calcParser(range, valueRange); | 353 CalcParser calcParser(range, valueRange); |
| 354 if (const CSSCalcValue* calculation = calcParser.value()) { | 354 if (const CSSCalcValue* calculation = calcParser.value()) { |
| 355 if (calculation->category() == CalcTime) | 355 if (calculation->category() == CalcTime) |
| 356 return calcParser.consumeValue(); | 356 return calcParser.consumeValue(); |
| 357 } | 357 } |
| 358 return nullptr; | 358 return nullptr; |
| 359 } | 359 } |
| 360 | 360 |
| 361 static inline int colorIntFromValue(double value, bool isPercent) | |
| 362 { | |
|
Timothy Loh
2015/10/26 05:23:09
Both IE and FF round instead of truncating, and mu
rwlbuis
2015/10/26 22:21:24
Done.
| |
| 363 if (value <= 0.0) | |
| 364 return 0; | |
| 365 | |
| 366 if (isPercent) { | |
| 367 if (value >= 100.0) | |
| 368 return 255; | |
| 369 return static_cast<int>(value * 256.0 / 100.0); | |
| 370 } | |
| 371 | |
| 372 if (value >= 255.0) | |
| 373 return 255; | |
| 374 | |
| 375 return static_cast<int>(value); | |
| 376 } | |
| 377 | |
| 378 static bool parseColorParameters(CSSParserTokenRange& range, int* colorArray, bo ol parseAlpha) | |
| 379 { | |
| 380 ASSERT(range.peek().type() == FunctionToken); | |
|
Timothy Loh
2015/10/26 05:23:09
I think consumeFunction asserts this
rwlbuis
2015/10/26 22:21:24
Done.
| |
| 381 CSSParserTokenRange args = consumeFunction(range); | |
| 382 // Get the first value and its type | |
| 383 RefPtrWillBeRawPtr<CSSPrimitiveValue> colorParameter = consumeInteger(args); | |
| 384 if (!colorParameter) | |
| 385 colorParameter = consumePercent(args, ValueRangeAll); | |
| 386 if (!colorParameter) | |
| 387 return false; | |
| 388 | |
| 389 const bool isPercent = colorParameter->isPercentage(); | |
| 390 colorArray[0] = colorIntFromValue(colorParameter->getDoubleValue(), isPercen t); | |
| 391 for (int i = 1; i < 3; i++) { | |
| 392 if (!consumeCommaIncludingWhitespace(args)) | |
| 393 return false; | |
| 394 colorParameter = consumeInteger(args); | |
|
Timothy Loh
2015/10/26 05:23:09
I'd prefer:
= isPercent ? consumePercent(args, Va
rwlbuis
2015/10/26 22:21:24
Way better, done.
| |
| 395 if (!colorParameter) | |
| 396 colorParameter = consumePercent(args, ValueRangeAll); | |
| 397 if (!colorParameter || colorParameter->isPercentage() != isPercent) | |
| 398 return false; | |
| 399 colorArray[i] = colorIntFromValue(colorParameter->getDoubleValue(), isPe rcent); | |
| 400 } | |
| 401 if (parseAlpha) { | |
| 402 if (!consumeCommaIncludingWhitespace(args)) | |
| 403 return false; | |
| 404 RefPtrWillBeRawPtr<CSSPrimitiveValue> alphaValue = consumeNumber(args, V alueRangeAll); | |
| 405 if (!alphaValue) | |
| 406 return false; | |
| 407 double doubleValue = alphaValue->getDoubleValue(); | |
| 408 // Convert the floating pointer number of alpha to an integer in the ran ge [0, 256), | |
| 409 // with an equal distribution across all 256 values. | |
| 410 colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, doubleValue )) * nextafter(256.0, 0.0)); | |
| 411 } | |
| 412 return args.atEnd(); | |
| 413 } | |
| 414 | |
| 415 static bool parseHSLParameters(CSSParserTokenRange& range, double* colorArray, b ool parseAlpha) | |
| 416 { | |
| 417 // Get the first value | |
|
Timothy Loh
2015/10/26 05:23:09
I don't think this comment is useful
rwlbuis
2015/10/26 22:21:24
Done.
| |
| 418 ASSERT(range.peek().type() == FunctionToken); | |
| 419 CSSParserTokenRange args = consumeFunction(range); | |
| 420 RefPtrWillBeRawPtr<CSSPrimitiveValue> hslValue = consumeNumber(args, ValueRa ngeAll); | |
| 421 if (!hslValue) | |
| 422 return false; | |
| 423 // normalize the Hue value and change it to be between 0 and 1.0 | |
|
Timothy Loh
2015/10/26 05:23:09
I don't think this comment is useful either
rwlbuis
2015/10/26 22:21:24
Done.
| |
| 424 colorArray[0] = (((static_cast<int>(hslValue->getDoubleValue()) % 360) + 360 ) % 360) / 360.0; | |
|
Timothy Loh
2015/10/26 05:23:09
we can probably drop the static_cast here
rwlbuis
2015/10/26 22:21:24
You mean using getIntValue right? Done.
| |
| 425 for (int i = 1; i < 3; i++) { | |
| 426 if (!consumeCommaIncludingWhitespace(args)) | |
| 427 return false; | |
| 428 hslValue = consumePercent(args, ValueRangeAll); | |
| 429 if (!hslValue) | |
| 430 return false; | |
| 431 double doubleValue = hslValue->getDoubleValue(); | |
| 432 colorArray[i] = std::max(0.0, std::min(100.0, doubleValue)) / 100.0; // needs to be value between 0 and 1.0 | |
| 433 } | |
| 434 if (parseAlpha) { | |
| 435 if (!consumeCommaIncludingWhitespace(args)) | |
| 436 return false; | |
| 437 hslValue = consumeNumber(args, ValueRangeAll); | |
| 438 if (!hslValue) | |
| 439 return false; | |
| 440 double doubleValue = hslValue->getDoubleValue(); | |
| 441 colorArray[3] = std::max(0.0, std::min(1.0, doubleValue)); | |
| 442 } | |
| 443 return args.atEnd(); | |
| 444 } | |
| 445 | |
| 446 static bool parseColorFromValue(CSSParserTokenRange& range, RGBA32& result, bool acceptQuirkyColors) | |
| 447 { | |
| 448 const CSSParserToken& token = range.peek(); | |
| 449 if (acceptQuirkyColors && token.type() == NumberToken && token.numericValueT ype() == IntegerValueType | |
| 450 && token.numericValue() >= 0. && token.numericValue() < 1000000.) { | |
| 451 String str = String::format("%06d", static_cast<int>(token.numericValue( ))); | |
| 452 if (!Color::parseHexColor(str, result)) | |
| 453 return false; | |
| 454 range.consumeIncludingWhitespace(); | |
| 455 return true; | |
| 456 } | |
| 457 if (acceptQuirkyColors && token.type() == DimensionToken) { | |
| 458 String color = token.value(); | |
|
Timothy Loh
2015/10/26 05:23:09
Don't we need to prepend the numeric value to this
rwlbuis
2015/10/26 22:21:24
Yeah, sorry. I changes color-quirk.html test to ca
| |
| 459 if (color.length() > 6) | |
| 460 return false; | |
| 461 while (color.length() < 6) | |
| 462 color = "0" + color; | |
| 463 range.consumeIncludingWhitespace(); | |
| 464 return Color::parseHexColor(color, result); | |
| 465 } | |
| 466 if (token.type() == IdentToken) { | |
| 467 Color color; | |
| 468 if (color.setNamedColor(token.value())) | |
|
Timothy Loh
2015/10/26 05:23:09
isn't this covered by isColorKeyword in the callin
rwlbuis
2015/10/26 22:21:24
Well spotted! I guess the original code has the sa
| |
| 469 result = color.rgb(); | |
| 470 else if (!acceptQuirkyColors || !Color::parseHexColor(token.value(), res ult)) | |
| 471 return false; | |
| 472 range.consumeIncludingWhitespace(); | |
| 473 return true; | |
| 474 } | |
| 475 if (token.type() == HashToken) { | |
| 476 CSSParserString string = range.consumeIncludingWhitespace().value(); | |
| 477 if (string.is8Bit()) | |
| 478 return Color::parseHexColor(string.characters8(), string.length(), r esult); | |
| 479 return Color::parseHexColor(string.characters16(), string.length(), resu lt); | |
| 480 } | |
| 481 if (token.functionId() == CSSValueRgb) { | |
| 482 int colorValues[3]; | |
| 483 if (!parseColorParameters(range, colorValues, false)) | |
| 484 return false; | |
| 485 result = makeRGB(colorValues[0], colorValues[1], colorValues[2]); | |
| 486 } else if (token.functionId() == CSSValueRgba) { | |
| 487 int colorValues[4]; | |
| 488 if (!parseColorParameters(range, colorValues, true)) | |
| 489 return false; | |
| 490 result = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorV alues[3]); | |
| 491 } else if (token.functionId() == CSSValueHsl) { | |
| 492 double colorValues[3]; | |
| 493 if (!parseHSLParameters(range, colorValues, false)) | |
| 494 return false; | |
| 495 result = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2] , 1.0); | |
| 496 } else if (token.functionId() == CSSValueHsla) { | |
| 497 double colorValues[4]; | |
| 498 if (!parseHSLParameters(range, colorValues, true)) | |
| 499 return false; | |
| 500 result = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2] , colorValues[3]); | |
| 501 } else { | |
| 502 return false; | |
| 503 } | |
| 504 | |
| 505 return true; | |
| 506 } | |
| 507 | |
| 508 static PassRefPtrWillBeRawPtr<CSSValue> consumeColor(CSSParserTokenRange& range, const CSSParserContext& context, bool acceptQuirkyColors = false) | |
| 509 { | |
| 510 CSSValueID id = range.peek().id(); | |
| 511 if (CSSPropertyParser::isColorKeyword(id)) { | |
| 512 if (!isValueAllowedInMode(id, context.mode())) | |
| 513 return nullptr; | |
| 514 return consumeIdent(range); | |
| 515 } | |
| 516 RGBA32 c = Color::transparent; | |
| 517 if (!parseColorFromValue(range, c, acceptQuirkyColors)) | |
|
Timothy Loh
2015/10/26 05:23:09
There are a few places where we're updating the ra
rwlbuis
2015/10/26 22:21:24
Done.
| |
| 518 return nullptr; | |
| 519 return cssValuePool().createColorValue(c); | |
| 520 } | |
| 521 | |
| 361 static inline bool isCSSWideKeyword(const CSSValueID& id) | 522 static inline bool isCSSWideKeyword(const CSSValueID& id) |
| 362 { | 523 { |
| 363 return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; | 524 return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; |
| 364 } | 525 } |
| 365 | 526 |
| 366 // Methods for consuming non-shorthand properties starts here. | 527 // Methods for consuming non-shorthand properties starts here. |
| 367 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r ange) | 528 static PassRefPtrWillBeRawPtr<CSSValue> consumeWillChange(CSSParserTokenRange& r ange) |
| 368 { | 529 { |
| 369 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 530 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
| 370 if (range.peek().id() == CSSValueAuto) { | 531 if (range.peek().id() == CSSValueAuto) { |
| (...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1300 case CSSPropertyAnimationIterationCount: | 1461 case CSSPropertyAnimationIterationCount: |
| 1301 case CSSPropertyAnimationName: | 1462 case CSSPropertyAnimationName: |
| 1302 case CSSPropertyAnimationPlayState: | 1463 case CSSPropertyAnimationPlayState: |
| 1303 case CSSPropertyTransitionProperty: | 1464 case CSSPropertyTransitionProperty: |
| 1304 case CSSPropertyAnimationTimingFunction: | 1465 case CSSPropertyAnimationTimingFunction: |
| 1305 case CSSPropertyTransitionTimingFunction: | 1466 case CSSPropertyTransitionTimingFunction: |
| 1306 return consumeAnimationPropertyList(property, m_range, m_context, unreso lvedProperty == CSSPropertyAliasWebkitAnimationName); | 1467 return consumeAnimationPropertyList(property, m_range, m_context, unreso lvedProperty == CSSPropertyAliasWebkitAnimationName); |
| 1307 case CSSPropertyOrphans: | 1468 case CSSPropertyOrphans: |
| 1308 case CSSPropertyWidows: | 1469 case CSSPropertyWidows: |
| 1309 return consumeWidowsOrOrphans(m_range); | 1470 return consumeWidowsOrOrphans(m_range); |
| 1471 case CSSPropertyWebkitTextFillColor: | |
| 1472 case CSSPropertyWebkitTapHighlightColor: | |
| 1473 return consumeColor(m_range, m_context); | |
| 1474 case CSSPropertyColor: | |
| 1475 return consumeColor(m_range, m_context, inQuirksMode()); | |
| 1310 default: | 1476 default: |
| 1311 return nullptr; | 1477 return nullptr; |
| 1312 } | 1478 } |
| 1313 } | 1479 } |
| 1314 | 1480 |
| 1315 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) | 1481 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) |
| 1316 { | 1482 { |
| 1317 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 1483 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
| 1318 | 1484 |
| 1319 do { | 1485 do { |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1730 m_currentShorthand = oldShorthand; | 1896 m_currentShorthand = oldShorthand; |
| 1731 return consumeColumns(important); | 1897 return consumeColumns(important); |
| 1732 } | 1898 } |
| 1733 default: | 1899 default: |
| 1734 m_currentShorthand = oldShorthand; | 1900 m_currentShorthand = oldShorthand; |
| 1735 return false; | 1901 return false; |
| 1736 } | 1902 } |
| 1737 } | 1903 } |
| 1738 | 1904 |
| 1739 } // namespace blink | 1905 } // namespace blink |
| OLD | NEW |