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 6f247e4fabba6906dbe62ae6d183200e54bd65fe..d53005dbd499c618559629d8999fb2a42a8461df 100644 |
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
@@ -278,274 +278,6 @@ bool CSSPropertyParser::consumeCSSWideKeyword(CSSPropertyID unresolvedProperty, |
return true; |
} |
-// Helper methods for consuming tokens starts here. |
-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 parseRGBParameters(CSSParserTokenRange& range, RGBA32& result, bool parseAlpha) |
-{ |
- ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId() == CSSValueRgba); |
- CSSParserTokenRange args = consumeFunction(range); |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> colorParameter = consumeInteger(args); |
- if (!colorParameter) |
- colorParameter = consumePercent(args, ValueRangeAll); |
- if (!colorParameter) |
- return false; |
- const bool isPercent = colorParameter->isPercentage(); |
- int colorArray[3]; |
- 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; |
- double alpha; |
- if (!consumeNumberRaw(args, alpha)) |
- return false; |
- // Convert the floating pointer number of alpha to an integer in the range [0, 256), |
- // with an equal distribution across all 256 values. |
- int alphaComponent = static_cast<int>(clampTo<double>(alpha, 0.0, 1.0) * nextafter(256.0, 0.0)); |
- result = makeRGBA(colorArray[0], colorArray[1], colorArray[2], alphaComponent); |
- } else { |
- result = makeRGB(colorArray[0], colorArray[1], colorArray[2]); |
- } |
- return args.atEnd(); |
-} |
- |
-static bool parseHSLParameters(CSSParserTokenRange& range, RGBA32& result, bool parseAlpha) |
-{ |
- ASSERT(range.peek().functionId() == CSSValueHsl || range.peek().functionId() == CSSValueHsla); |
- CSSParserTokenRange args = consumeFunction(range); |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> hslValue = consumeNumber(args, ValueRangeAll); |
- if (!hslValue) |
- return false; |
- double colorArray[3]; |
- 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. |
- } |
- double alpha = 1.0; |
- if (parseAlpha) { |
- if (!consumeCommaIncludingWhitespace(args)) |
- return false; |
- if (!consumeNumberRaw(args, alpha)) |
- return false; |
- alpha = clampTo<double>(alpha, 0.0, 1.0); |
- } |
- result = makeRGBAFromHSLA(colorArray[0], colorArray[1], colorArray[2], alpha); |
- return args.atEnd(); |
-} |
- |
-static bool parseHexColor(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::parseHexColor(color, result)) |
- return false; |
- range.consumeIncludingWhitespace(); |
- return true; |
-} |
- |
-static bool parseColorFunction(CSSParserTokenRange& range, RGBA32& result) |
-{ |
- CSSValueID functionId = range.peek().functionId(); |
- if (functionId < CSSValueRgb || functionId > CSSValueHsla) |
- return false; |
- CSSParserTokenRange colorRange = range; |
- if ((functionId <= CSSValueRgba && !parseRGBParameters(colorRange, result, functionId == CSSValueRgba)) |
- || (functionId >= CSSValueHsl && !parseHSLParameters(colorRange, result, functionId == CSSValueHsla))) |
- return false; |
- range = colorRange; |
- return true; |
-} |
- |
-static PassRefPtrWillBeRawPtr<CSSValue> consumeColor(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool acceptQuirkyColors = false) |
-{ |
- CSSValueID id = range.peek().id(); |
- if (CSSPropertyParser::isColorKeyword(id)) { |
- if (!isValueAllowedInMode(id, cssParserMode)) |
- return nullptr; |
- return consumeIdent(range); |
- } |
- RGBA32 color = Color::transparent; |
- if (!parseHexColor(range, color, acceptQuirkyColors) && !parseColorFunction(range, color)) |
- return nullptr; |
- return cssValuePool().createColorValue(color); |
-} |
- |
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumePositionComponent(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless) |
-{ |
- if (range.peek().type() == IdentToken) |
- return consumeIdent<CSSValueLeft, CSSValueTop, CSSValueBottom, CSSValueRight, CSSValueCenter>(range); |
- return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, unitless); |
-} |
- |
-static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value) |
-{ |
- return value.isValueID() && (value.getValueID() == CSSValueLeft || value.getValueID() == CSSValueRight); |
-} |
- |
-static bool isVerticalPositionKeywordOnly(const CSSPrimitiveValue& value) |
-{ |
- return value.isValueID() && (value.getValueID() == CSSValueTop || value.getValueID() == CSSValueBottom); |
-} |
- |
-static void positionFromOneValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) |
-{ |
- bool valueAppliesToYAxisOnly = isVerticalPositionKeywordOnly(*value); |
- resultX = value; |
- resultY = cssValuePool().createIdentifierValue(CSSValueCenter); |
- if (valueAppliesToYAxisOnly) |
- swap(resultX, resultY); |
-} |
- |
-static bool positionFromTwoValues(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value2, |
- RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) |
-{ |
- bool mustOrderAsXY = isHorizontalPositionKeywordOnly(*value1) || isVerticalPositionKeywordOnly(*value2) |
- || !value1->isValueID() || !value2->isValueID(); |
- bool mustOrderAsYX = isVerticalPositionKeywordOnly(*value1) || isHorizontalPositionKeywordOnly(*value2); |
- if (mustOrderAsXY && mustOrderAsYX) |
- return false; |
- resultX = value1; |
- resultY = value2; |
- if (mustOrderAsYX) |
- swap(resultX, resultY); |
- return true; |
-} |
- |
-static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) |
-{ |
- CSSPrimitiveValue* center = nullptr; |
- for (int i = 0; values[i]; i++) { |
- CSSPrimitiveValue* currentValue = values[i]; |
- if (!currentValue->isValueID()) |
- return false; |
- CSSValueID id = currentValue->getValueID(); |
- |
- if (id == CSSValueCenter) { |
- if (center) |
- return false; |
- center = currentValue; |
- continue; |
- } |
- |
- RefPtrWillBeRawPtr<CSSValue> result = nullptr; |
- if (values[i + 1] && !values[i + 1]->isValueID()) { |
- result = CSSValuePair::create(currentValue, values[++i], CSSValuePair::KeepIdenticalValues); |
- } else { |
- result = currentValue; |
- } |
- |
- if (id == CSSValueLeft || id == CSSValueRight) { |
- if (resultX) |
- return false; |
- resultX = result.release(); |
- } else { |
- ASSERT(id == CSSValueTop || id == CSSValueBottom); |
- if (resultY) |
- return false; |
- resultY = result.release(); |
- } |
- } |
- |
- if (center) { |
- ASSERT(resultX || resultY); |
- if (resultX && resultY) |
- return false; |
- if (!resultX) |
- resultX = center; |
- else |
- resultY = center; |
- } |
- |
- ASSERT(resultX && resultY); |
- return true; |
-} |
- |
-// This may consume from the range upon failure since no caller needs the stricter behaviour. |
-static bool consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) |
-{ |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(range, cssParserMode, unitless); |
- if (!value1) |
- return false; |
- |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParserMode, unitless); |
- if (!value2) { |
- positionFromOneValue(value1.release(), resultX, resultY); |
- return true; |
- } |
- |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = consumePositionComponent(range, cssParserMode, unitless); |
- if (!value3) |
- return positionFromTwoValues(value1.release(), value2.release(), resultX, resultY); |
- |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> value4 = consumePositionComponent(range, cssParserMode, unitless); |
- CSSPrimitiveValue* values[5]; |
- values[0] = value1.get(); |
- values[1] = value2.get(); |
- values[2] = value3.get(); |
- values[3] = value4.get(); |
- values[4] = nullptr; |
- return positionFromThreeOrFourValues(values, resultX, resultY); |
-} |
- |
-static PassRefPtrWillBeRawPtr<CSSValue> consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless) |
-{ |
- RefPtrWillBeRawPtr<CSSValue> resultX = nullptr; |
- RefPtrWillBeRawPtr<CSSValue> resultY = nullptr; |
- if (consumePosition(range, cssParserMode, unitless, resultX, resultY)) |
- return CSSValuePair::create(resultX.release(), resultY.release(), CSSValuePair::KeepIdenticalValues); |
- return nullptr; |
-} |
- |
-static bool consumeOneOrTwoValuedPosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY) |
-{ |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> value1 = consumePositionComponent(range, cssParserMode, unitless); |
- if (!value1) |
- return false; |
- RefPtrWillBeRawPtr<CSSPrimitiveValue> value2 = consumePositionComponent(range, cssParserMode, unitless); |
- if (!value2) { |
- positionFromOneValue(value1.release(), resultX, resultY); |
- return true; |
- } |
- return positionFromTwoValues(value1.release(), value2.release(), resultX, resultY); |
-} |
- |
static PassRefPtrWillBeRawPtr<CSSValueList> consumeTransformOrigin(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless) |
{ |
RefPtrWillBeRawPtr<CSSValue> resultX = nullptr; |