Index: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
index 5774399e232491a1d0095b3ba8f4f89fa9240981..75dc2260b05189d791fe7707ba8387fdb74b9db0 100644 |
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
@@ -358,6 +358,148 @@ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeTime(CSSParserTokenRange |
return nullptr; |
} |
+static int clampRGBComponent(const CSSPrimitiveValue& value) |
+{ |
+ double result = value.getDoubleValue(); |
+ // TODO(timloh): Multiply by 2.55 and round instead of floor. |
+ if (value.isPercentage()) |
+ result *= 2.56; |
+ return clampTo<int>(result, 0, 255); |
+} |
+ |
+static bool parseColorParameters(CSSParserTokenRange& range, int* colorArray, bool parseAlpha) |
Timothy Loh
2015/10/27 03:52:21
parseColorParameters -> parseRGBParameters?
IMO t
rwlbuis
2015/10/27 20:07:50
Done.
|
+{ |
+ CSSParserTokenRange args = consumeFunction(range); |
+ // Get the first value and its type. |
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> colorParameter = consumeInteger(args); |
+ if (!colorParameter) |
+ colorParameter = consumePercent(args, ValueRangeAll); |
+ if (!colorParameter) |
+ return false; |
+ |
+ const bool isPercent = colorParameter->isPercentage(); |
+ colorArray[0] = clampRGBComponent(*colorParameter); |
+ for (int i = 1; i < 3; i++) { |
+ if (!consumeCommaIncludingWhitespace(args)) |
+ return false; |
+ colorParameter = isPercent ? consumePercent(args, ValueRangeAll) : consumeInteger(args); |
+ if (!colorParameter) |
+ return false; |
+ colorArray[i] = clampRGBComponent(*colorParameter); |
+ } |
+ if (parseAlpha) { |
+ if (!consumeCommaIncludingWhitespace(args)) |
+ return false; |
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> alphaValue = consumeNumber(args, ValueRangeAll); |
+ if (!alphaValue) |
+ return false; |
+ double doubleValue = alphaValue->getDoubleValue(); |
+ // Convert the floating pointer number of alpha to an integer in the range [0, 256), |
+ // with an equal distribution across all 256 values. |
+ colorArray[3] = static_cast<int>(clampTo<double>(doubleValue, 0.0, 1.0) * nextafter(256.0, 0.0)); |
+ } |
+ return args.atEnd(); |
+} |
+ |
+static bool parseHSLParameters(CSSParserTokenRange& range, double* colorArray, bool parseAlpha) |
+{ |
+ CSSParserTokenRange args = consumeFunction(range); |
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> hslValue = consumeNumber(args, ValueRangeAll); |
+ if (!hslValue) |
+ return false; |
+ colorArray[0] = (((hslValue->getIntValue() % 360) + 360) % 360) / 360.0; |
+ for (int i = 1; i < 3; i++) { |
+ if (!consumeCommaIncludingWhitespace(args)) |
+ return false; |
+ hslValue = consumePercent(args, ValueRangeAll); |
+ if (!hslValue) |
+ return false; |
+ double doubleValue = hslValue->getDoubleValue(); |
+ colorArray[i] = clampTo<double>(doubleValue, 0.0, 100.0) / 100.0; // Needs to be value between 0 and 1.0. |
+ } |
+ if (parseAlpha) { |
+ if (!consumeCommaIncludingWhitespace(args)) |
+ return false; |
+ hslValue = consumeNumber(args, ValueRangeAll); |
+ if (!hslValue) |
+ return false; |
+ double doubleValue = hslValue->getDoubleValue(); |
+ colorArray[3] = clampTo<double>(doubleValue, 0.0, 1.0); |
+ } |
+ return args.atEnd(); |
+} |
+ |
+static bool parseColorFromValue(CSSParserTokenRange& range, RGBA32& result, bool acceptQuirkyColors) |
+{ |
+ const CSSParserToken& token = range.peek(); |
+ String color; |
+ if (acceptQuirkyColors) { |
+ if (token.type() == NumberToken && token.numericValueType() == IntegerValueType |
+ && token.numericValue() >= 0. && token.numericValue() < 1000000.) { // e.g. 112233 |
+ color = String::format("%06d", static_cast<int>(token.numericValue())); |
+ } else if (token.type() == DimensionToken) { // e.g. 0001FF |
+ color = String::number(static_cast<int>(token.numericValue())) + String(token.value()); |
+ if (color.length() > 6) |
+ return false; |
+ while (color.length() < 6) |
+ color = "0" + color; |
+ } else if (token.type() == IdentToken) { // e.g. FF0000 |
+ color = token.value(); |
+ } |
+ } |
+ if (token.type() == HashToken) |
+ color = token.value(); |
+ if (!color.isNull()) { |
+ if (!Color::parseHexColor(color, result)) |
+ return false; |
+ range.consumeIncludingWhitespace(); |
+ return true; |
+ } |
+ if (token.type() != FunctionToken) |
+ return false; |
+ CSSParserTokenRange colorRange = range; |
+ if (token.functionId() == CSSValueRgb) { |
+ int colorValues[3]; |
+ if (!parseColorParameters(colorRange, colorValues, false)) |
+ return false; |
+ result = makeRGB(colorValues[0], colorValues[1], colorValues[2]); |
+ } else if (token.functionId() == CSSValueRgba) { |
+ int colorValues[4]; |
+ if (!parseColorParameters(colorRange, colorValues, true)) |
+ return false; |
+ result = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); |
+ } else if (token.functionId() == CSSValueHsl) { |
+ double colorValues[3]; |
+ if (!parseHSLParameters(colorRange, colorValues, false)) |
+ return false; |
+ result = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0); |
+ } else if (token.functionId() == CSSValueHsla) { |
+ double colorValues[4]; |
+ if (!parseHSLParameters(colorRange, colorValues, true)) |
+ return false; |
+ result = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]); |
+ } else { |
+ return false; |
+ } |
+ |
+ range = colorRange; |
+ return true; |
+} |
+ |
+static PassRefPtrWillBeRawPtr<CSSValue> consumeColor(CSSParserTokenRange& range, const CSSParserContext& context, bool acceptQuirkyColors = false) |
+{ |
+ CSSValueID id = range.peek().id(); |
+ if (CSSPropertyParser::isColorKeyword(id)) { |
+ if (!isValueAllowedInMode(id, context.mode())) |
+ return nullptr; |
+ return consumeIdent(range); |
+ } |
+ RGBA32 color = Color::transparent; |
+ if (!parseColorFromValue(range, color, acceptQuirkyColors)) |
Timothy Loh
2015/10/27 03:52:21
I don't think the current split makes sense here.
rwlbuis
2015/10/27 20:07:50
Sounds good, done.
|
+ return nullptr; |
+ return cssValuePool().createColorValue(color); |
+} |
+ |
static inline bool isCSSWideKeyword(const CSSValueID& id) |
{ |
return id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset || id == CSSValueDefault; |
@@ -1301,6 +1443,11 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
case CSSPropertyOrphans: |
case CSSPropertyWidows: |
return consumeWidowsOrOrphans(m_range); |
+ case CSSPropertyWebkitTextFillColor: |
+ case CSSPropertyWebkitTapHighlightColor: |
+ return consumeColor(m_range, m_context); |
+ case CSSPropertyColor: |
+ return consumeColor(m_range, m_context, inQuirksMode()); |
default: |
return nullptr; |
} |