Commit 86c916bd authored by timloh's avatar timloh Committed by Commit bot

Move consumeColor and consumePosition to CSSPropertyParserHelpers

This patch moves the routines for consuming <color> and <position> out
of CSSPropertyParser.cpp and into CSSPropertyParserHelpers. We expect
that we'll require these routines for various Houdini APIs.

BUG=499780

Review URL: https://codereview.chromium.org/1802673003

Cr-Commit-Position: refs/heads/master@{#381865}
parent 04dfd7b7
......@@ -5,6 +5,7 @@
#include "core/animation/CSSColorInterpolationType.h"
#include "core/animation/ColorPropertyFunctions.h"
#include "core/css/CSSColorValue.h"
#include "core/css/parser/CSSPropertyParser.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/layout/LayoutTheme.h"
......
......@@ -279,274 +279,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;
......
......@@ -23,7 +23,6 @@
#ifndef CSSPropertyParser_h
#define CSSPropertyParser_h
#include "core/css/CSSColorValue.h"
#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/StyleRule.h"
#include "core/css/parser/CSSParserTokenRange.h"
......@@ -74,6 +73,7 @@ public:
// Parses a non-shorthand CSS property
static PassRefPtrWillBeRawPtr<CSSValue> parseSingleValue(CSSPropertyID, const CSSParserTokenRange&, const CSSParserContext&);
// TODO(timloh): This doesn't seem like the right place for these
static bool isSystemColor(CSSValueID);
static bool isColorKeyword(CSSValueID);
static bool isValidNumericValue(double);
......
......@@ -6,6 +6,9 @@
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSStringValue.h"
#include "core/css/CSSValuePair.h"
// TODO(timloh): Remove this dependency
#include "core/css/parser/CSSPropertyParser.h"
namespace blink {
......@@ -322,6 +325,275 @@ String consumeUrl(CSSParserTokenRange& range)
return String();
}
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
// TODO(timloh): This should check the numericValueType flag
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;
}
PassRefPtrWillBeRawPtr<CSSValue> consumeColor(CSSParserTokenRange& range, CSSParserMode cssParserMode, bool acceptQuirkyColors)
{
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;
}
// TODO(timloh): This may consume from the range upon failure. The background
// shorthand works around it, but we should just fix it here.
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);
}
PassRefPtrWillBeRawPtr<CSSValuePair> 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;
}
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);
}
} // namespace CSSPropertyParserHelpers
} // namespace blink
......@@ -14,6 +14,7 @@
namespace blink {
class CSSStringValue;
class CSSValuePair;
// When these functions are successful, they will consume all the relevant
// tokens from the range and also consume any whitespace which follows. When
......@@ -51,7 +52,13 @@ PassRefPtrWillBeRawPtr<CSSCustomIdentValue> consumeCustomIdent(CSSParserTokenRan
PassRefPtrWillBeRawPtr<CSSStringValue> consumeString(CSSParserTokenRange&);
String consumeUrl(CSSParserTokenRange&);
// TODO(timloh): Move across consumeColor, consumeImage and consumePosition
PassRefPtrWillBeRawPtr<CSSValue> consumeColor(CSSParserTokenRange&, CSSParserMode, bool acceptQuirkyColors = false);
PassRefPtrWillBeRawPtr<CSSValuePair> consumePosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk);
bool consumePosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY);
bool consumeOneOrTwoValuedPosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, RefPtrWillBeRawPtr<CSSValue>& resultX, RefPtrWillBeRawPtr<CSSValue>& resultY);
// TODO(timloh): Move across consumeImage
// Template implementations are at the bottom of the file for readability.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment