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(")) |