Chromium Code Reviews| Index: Source/core/css/CSSParser-in.cpp |
| diff --git a/Source/core/css/CSSParser-in.cpp b/Source/core/css/CSSParser-in.cpp |
| index 93bd837a1bb627eaff132ff3e1c959a2eb140f8d..96ab82488494d5ec8bc3198452c04afc582f5862 100644 |
| --- a/Source/core/css/CSSParser-in.cpp |
| +++ b/Source/core/css/CSSParser-in.cpp |
| @@ -5170,15 +5170,73 @@ PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeInsetRectangle(CSSParserValu |
| return shape; |
| } |
| +PassRefPtr<CSSPrimitiveValue> CSSParser::parseShapeRadius(CSSParserValue* value) |
| +{ |
| + if (value->id == CSSValueClosestSide && value->id == CSSValueFarthestSide) |
|
bemjb
2013/12/07 00:05:32
This should be a ||, not &&.
|
| + return cssValuePool().createIdentifierValue(value->id); |
| + |
| + if (!validUnit(value, FLength | FPercent | FNonNeg)) |
| + return 0; |
| + |
| + return createPrimitiveNumericValue(value); |
| +} |
| + |
| PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeCircle(CSSParserValueList* args) |
| { |
| ASSERT(args); |
| + // circle(radius) |
| + // circle(radius at <position> |
| + // circle(at <position>) |
| + // where position defines centerX and centerY using a CSS <position> data type. |
| + RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create(); |
| + |
| + for (CSSParserValue* argument = args->current(); argument; argument = args->next()) { |
| + // The call to parseFillPosition below should consume all of the |
| + // arguments except the first two. Thus, and index greater than one |
| + // indicates an invalid production. |
| + if (args->currentIndex() > 1) |
| + return 0; |
| + |
| + if (!args->currentIndex() && argument->id != CSSValueAt) { |
| + if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) { |
| + shape->setRadius(radius); |
| + continue; |
| + } |
| + |
| + return 0; |
| + } |
| + |
| + if (argument->id == CSSValueAt) { |
| + RefPtr<CSSValue> centerX; |
| + RefPtr<CSSValue> centerY; |
| + args->next(); // set list to start of position center |
| + parseFillPosition(args, centerX, centerY); |
| + if (centerX && centerY) { |
| + ASSERT(centerX->isPrimitiveValue()); |
| + ASSERT(centerY->isPrimitiveValue()); |
| + shape->setCenterX(toCSSPrimitiveValue(centerX.get())); |
| + shape->setCenterY(toCSSPrimitiveValue(centerY.get())); |
| + } else { |
| + return 0; |
| + } |
| + } else { |
| + return 0; |
| + } |
| + } |
| + |
| + return shape; |
| +} |
| + |
| +PassRefPtr<CSSBasicShape> CSSParser::parseDeprecatedBasicShapeCircle(CSSParserValueList* args) |
| +{ |
| + ASSERT(args); |
| + |
| // circle(centerX, centerY, radius) |
| if (args->size() != 5) |
| return 0; |
| - RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create(); |
| + RefPtr<CSSDeprecatedBasicShapeCircle> shape = CSSDeprecatedBasicShapeCircle::create(); |
| unsigned argumentNumber = 0; |
| CSSParserValue* argument = args->current(); |
| @@ -5224,11 +5282,60 @@ PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList* |
| { |
| ASSERT(args); |
| + // ellipse(radiusX) |
| + // ellipse(radiusX at <position> |
| + // ellipse(radiusX radiusY) |
| + // ellipse(radiusX radiusY at <position> |
| + // ellipse(at <position>) |
| + // where position defines centerX and centerY using a CSS <position> data type. |
| + RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create(); |
| + |
| + for (CSSParserValue* argument = args->current(); argument; argument = args->next()) { |
| + // The call to parseFillPosition below should consume all of the |
| + // arguments except the first three. Thus, an index greater than two |
| + // indicates an invalid production. |
| + if (args->currentIndex() > 2) |
| + return 0; |
| + |
| + if (args->currentIndex() < 2 && argument->id != CSSValueAt) { |
| + if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) { |
| + if (!shape->radiusX()) |
| + shape->setRadiusX(radius); |
| + else |
| + shape->setRadiusY(radius); |
| + continue; |
| + } |
| + |
| + return 0; |
| + } |
| + |
| + if (argument->id != CSSValueAt) |
| + return 0; |
| + RefPtr<CSSValue> centerX; |
| + RefPtr<CSSValue> centerY; |
| + args->next(); // set list to start of position center |
| + parseFillPosition(args, centerX, centerY); |
| + if (!centerX || !centerY) |
| + return 0; |
| + |
| + ASSERT(centerX->isPrimitiveValue()); |
| + ASSERT(centerY->isPrimitiveValue()); |
| + shape->setCenterX(toCSSPrimitiveValue(centerX.get())); |
| + shape->setCenterY(toCSSPrimitiveValue(centerY.get())); |
| + } |
| + |
| + return shape; |
| +} |
| + |
| +PassRefPtr<CSSBasicShape> CSSParser::parseDeprecatedBasicShapeEllipse(CSSParserValueList* args) |
| +{ |
| + ASSERT(args); |
| + |
| // ellipse(centerX, centerY, radiusX, radiusY) |
| if (args->size() != 7) |
| return 0; |
| - RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create(); |
| + RefPtr<CSSDeprecatedBasicShapeEllipse> shape = CSSDeprecatedBasicShapeEllipse::create(); |
| unsigned argumentNumber = 0; |
| CSSParserValue* argument = args->current(); |
| while (argument) { |
| @@ -5322,6 +5429,20 @@ PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapePolygon(CSSParserValueList* |
| return shape; |
| } |
| +// FIXME This function is temporary to allow for an orderly transition between |
| +// the new CSS Shapes circle and ellipse syntax. It will be removed when the |
| +// old syntax is removed. |
| +static bool isDeprecatedBasicShape(CSSParserValueList* args) |
| +{ |
| + for (unsigned i = args->currentIndex(); i < args->size(); ++i) { |
| + CSSParserValue* value = args->valueAt(i); |
| + if (isComma(value)) |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| bool CSSParser::parseBasicShape(CSSPropertyID propId, bool important) |
| { |
| CSSParserValue* value = m_valueList->current(); |
| @@ -5335,9 +5456,15 @@ bool CSSParser::parseBasicShape(CSSPropertyID propId, bool important) |
| if (equalIgnoringCase(value->function->name, "rectangle(")) |
| shape = parseBasicShapeRectangle(args); |
| else if (equalIgnoringCase(value->function->name, "circle(")) |
| - shape = parseBasicShapeCircle(args); |
| + if (isDeprecatedBasicShape(args)) |
| + shape = parseDeprecatedBasicShapeCircle(args); |
| + else |
| + shape = parseBasicShapeCircle(args); |
| else if (equalIgnoringCase(value->function->name, "ellipse(")) |
| - shape = parseBasicShapeEllipse(args); |
| + if (isDeprecatedBasicShape(args)) |
| + shape = parseDeprecatedBasicShapeEllipse(args); |
| + else |
| + shape = parseBasicShapeEllipse(args); |
| else if (equalIgnoringCase(value->function->name, "polygon(")) |
| shape = parseBasicShapePolygon(args); |
| else if (equalIgnoringCase(value->function->name, "inset-rectangle(")) |