Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(576)

Unified Diff: Source/core/css/CSSParser-in.cpp

Issue 103413006: Implement parsing of the new ellipse shape syntax. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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("))

Powered by Google App Engine
This is Rietveld 408576698