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

Side by Side 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/) 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo bile.com/)
8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
9 * Copyright (C) 2012 Intel Corporation. All rights reserved. 9 * Copyright (C) 2012 Intel Corporation. All rights reserved.
10 * 10 *
(...skipping 5152 matching lines...) Expand 10 before | Expand all | Expand 10 after
5163 argument = args->next(); 5163 argument = args->next();
5164 } 5164 }
5165 argumentNumber++; 5165 argumentNumber++;
5166 } 5166 }
5167 5167
5168 if (argumentNumber < 4) 5168 if (argumentNumber < 4)
5169 return 0; 5169 return 0;
5170 return shape; 5170 return shape;
5171 } 5171 }
5172 5172
5173 PassRefPtr<CSSPrimitiveValue> CSSParser::parseShapeRadius(CSSParserValue* value)
5174 {
5175 if (value->id == CSSValueClosestSide && value->id == CSSValueFarthestSide)
bemjb 2013/12/07 00:05:32 This should be a ||, not &&.
5176 return cssValuePool().createIdentifierValue(value->id);
5177
5178 if (!validUnit(value, FLength | FPercent | FNonNeg))
5179 return 0;
5180
5181 return createPrimitiveNumericValue(value);
5182 }
5183
5173 PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeCircle(CSSParserValueList* a rgs) 5184 PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeCircle(CSSParserValueList* a rgs)
5174 { 5185 {
5175 ASSERT(args); 5186 ASSERT(args);
5176 5187
5188 // circle(radius)
5189 // circle(radius at <position>
5190 // circle(at <position>)
5191 // where position defines centerX and centerY using a CSS <position> data ty pe.
5192 RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create();
5193
5194 for (CSSParserValue* argument = args->current(); argument; argument = args-> next()) {
5195 // The call to parseFillPosition below should consume all of the
5196 // arguments except the first two. Thus, and index greater than one
5197 // indicates an invalid production.
5198 if (args->currentIndex() > 1)
5199 return 0;
5200
5201 if (!args->currentIndex() && argument->id != CSSValueAt) {
5202 if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
5203 shape->setRadius(radius);
5204 continue;
5205 }
5206
5207 return 0;
5208 }
5209
5210 if (argument->id == CSSValueAt) {
5211 RefPtr<CSSValue> centerX;
5212 RefPtr<CSSValue> centerY;
5213 args->next(); // set list to start of position center
5214 parseFillPosition(args, centerX, centerY);
5215 if (centerX && centerY) {
5216 ASSERT(centerX->isPrimitiveValue());
5217 ASSERT(centerY->isPrimitiveValue());
5218 shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
5219 shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
5220 } else {
5221 return 0;
5222 }
5223 } else {
5224 return 0;
5225 }
5226 }
5227
5228 return shape;
5229 }
5230
5231 PassRefPtr<CSSBasicShape> CSSParser::parseDeprecatedBasicShapeCircle(CSSParserVa lueList* args)
5232 {
5233 ASSERT(args);
5234
5177 // circle(centerX, centerY, radius) 5235 // circle(centerX, centerY, radius)
5178 if (args->size() != 5) 5236 if (args->size() != 5)
5179 return 0; 5237 return 0;
5180 5238
5181 RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create(); 5239 RefPtr<CSSDeprecatedBasicShapeCircle> shape = CSSDeprecatedBasicShapeCircle: :create();
5182 5240
5183 unsigned argumentNumber = 0; 5241 unsigned argumentNumber = 0;
5184 CSSParserValue* argument = args->current(); 5242 CSSParserValue* argument = args->current();
5185 while (argument) { 5243 while (argument) {
5186 Units unitFlags = FLength | FPercent; 5244 Units unitFlags = FLength | FPercent;
5187 if (argumentNumber == 2) { 5245 if (argumentNumber == 2) {
5188 // Argument radius cannot be negative. 5246 // Argument radius cannot be negative.
5189 unitFlags = unitFlags | FNonNeg; 5247 unitFlags = unitFlags | FNonNeg;
5190 } 5248 }
5191 5249
(...skipping 25 matching lines...) Expand all
5217 5275
5218 if (argumentNumber < 3) 5276 if (argumentNumber < 3)
5219 return 0; 5277 return 0;
5220 return shape; 5278 return shape;
5221 } 5279 }
5222 5280
5223 PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList* args) 5281 PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList* args)
5224 { 5282 {
5225 ASSERT(args); 5283 ASSERT(args);
5226 5284
5285 // ellipse(radiusX)
5286 // ellipse(radiusX at <position>
5287 // ellipse(radiusX radiusY)
5288 // ellipse(radiusX radiusY at <position>
5289 // ellipse(at <position>)
5290 // where position defines centerX and centerY using a CSS <position> data ty pe.
5291 RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create();
5292
5293 for (CSSParserValue* argument = args->current(); argument; argument = args-> next()) {
5294 // The call to parseFillPosition below should consume all of the
5295 // arguments except the first three. Thus, an index greater than two
5296 // indicates an invalid production.
5297 if (args->currentIndex() > 2)
5298 return 0;
5299
5300 if (args->currentIndex() < 2 && argument->id != CSSValueAt) {
5301 if (RefPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
5302 if (!shape->radiusX())
5303 shape->setRadiusX(radius);
5304 else
5305 shape->setRadiusY(radius);
5306 continue;
5307 }
5308
5309 return 0;
5310 }
5311
5312 if (argument->id != CSSValueAt)
5313 return 0;
5314 RefPtr<CSSValue> centerX;
5315 RefPtr<CSSValue> centerY;
5316 args->next(); // set list to start of position center
5317 parseFillPosition(args, centerX, centerY);
5318 if (!centerX || !centerY)
5319 return 0;
5320
5321 ASSERT(centerX->isPrimitiveValue());
5322 ASSERT(centerY->isPrimitiveValue());
5323 shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
5324 shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
5325 }
5326
5327 return shape;
5328 }
5329
5330 PassRefPtr<CSSBasicShape> CSSParser::parseDeprecatedBasicShapeEllipse(CSSParserV alueList* args)
5331 {
5332 ASSERT(args);
5333
5227 // ellipse(centerX, centerY, radiusX, radiusY) 5334 // ellipse(centerX, centerY, radiusX, radiusY)
5228 if (args->size() != 7) 5335 if (args->size() != 7)
5229 return 0; 5336 return 0;
5230 5337
5231 RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create(); 5338 RefPtr<CSSDeprecatedBasicShapeEllipse> shape = CSSDeprecatedBasicShapeEllips e::create();
5232 unsigned argumentNumber = 0; 5339 unsigned argumentNumber = 0;
5233 CSSParserValue* argument = args->current(); 5340 CSSParserValue* argument = args->current();
5234 while (argument) { 5341 while (argument) {
5235 Units unitFlags = FLength | FPercent; 5342 Units unitFlags = FLength | FPercent;
5236 if (argumentNumber > 1) { 5343 if (argumentNumber > 1) {
5237 // Arguments radiusX and radiusY cannot be negative. 5344 // Arguments radiusX and radiusY cannot be negative.
5238 unitFlags = unitFlags | FNonNeg; 5345 unitFlags = unitFlags | FNonNeg;
5239 } 5346 }
5240 if (!validUnit(argument, unitFlags)) 5347 if (!validUnit(argument, unitFlags))
5241 return 0; 5348 return 0;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5315 argumentX = 0; 5422 argumentX = 0;
5316 else if (!isComma(commaOrNull)) 5423 else if (!isComma(commaOrNull))
5317 return 0; 5424 return 0;
5318 else 5425 else
5319 argumentX = args->next(); 5426 argumentX = args->next();
5320 } 5427 }
5321 5428
5322 return shape; 5429 return shape;
5323 } 5430 }
5324 5431
5432 // FIXME This function is temporary to allow for an orderly transition between
5433 // the new CSS Shapes circle and ellipse syntax. It will be removed when the
5434 // old syntax is removed.
5435 static bool isDeprecatedBasicShape(CSSParserValueList* args)
5436 {
5437 for (unsigned i = args->currentIndex(); i < args->size(); ++i) {
5438 CSSParserValue* value = args->valueAt(i);
5439 if (isComma(value))
5440 return true;
5441 }
5442
5443 return false;
5444 }
5445
5325 bool CSSParser::parseBasicShape(CSSPropertyID propId, bool important) 5446 bool CSSParser::parseBasicShape(CSSPropertyID propId, bool important)
5326 { 5447 {
5327 CSSParserValue* value = m_valueList->current(); 5448 CSSParserValue* value = m_valueList->current();
5328 ASSERT(value->unit == CSSParserValue::Function); 5449 ASSERT(value->unit == CSSParserValue::Function);
5329 CSSParserValueList* args = value->function->args.get(); 5450 CSSParserValueList* args = value->function->args.get();
5330 5451
5331 if (!args) 5452 if (!args)
5332 return false; 5453 return false;
5333 5454
5334 RefPtr<CSSBasicShape> shape; 5455 RefPtr<CSSBasicShape> shape;
5335 if (equalIgnoringCase(value->function->name, "rectangle(")) 5456 if (equalIgnoringCase(value->function->name, "rectangle("))
5336 shape = parseBasicShapeRectangle(args); 5457 shape = parseBasicShapeRectangle(args);
5337 else if (equalIgnoringCase(value->function->name, "circle(")) 5458 else if (equalIgnoringCase(value->function->name, "circle("))
5338 shape = parseBasicShapeCircle(args); 5459 if (isDeprecatedBasicShape(args))
5460 shape = parseDeprecatedBasicShapeCircle(args);
5461 else
5462 shape = parseBasicShapeCircle(args);
5339 else if (equalIgnoringCase(value->function->name, "ellipse(")) 5463 else if (equalIgnoringCase(value->function->name, "ellipse("))
5340 shape = parseBasicShapeEllipse(args); 5464 if (isDeprecatedBasicShape(args))
5465 shape = parseDeprecatedBasicShapeEllipse(args);
5466 else
5467 shape = parseBasicShapeEllipse(args);
5341 else if (equalIgnoringCase(value->function->name, "polygon(")) 5468 else if (equalIgnoringCase(value->function->name, "polygon("))
5342 shape = parseBasicShapePolygon(args); 5469 shape = parseBasicShapePolygon(args);
5343 else if (equalIgnoringCase(value->function->name, "inset-rectangle(")) 5470 else if (equalIgnoringCase(value->function->name, "inset-rectangle("))
5344 shape = parseBasicShapeInsetRectangle(args); 5471 shape = parseBasicShapeInsetRectangle(args);
5345 5472
5346 if (!shape) 5473 if (!shape)
5347 return false; 5474 return false;
5348 5475
5349 addProperty(propId, cssValuePool().createValue(shape.release()), important); 5476 addProperty(propId, cssValuePool().createValue(shape.release()), important);
5350 m_valueList->next(); 5477 m_valueList->next();
(...skipping 5063 matching lines...) Expand 10 before | Expand all | Expand 10 after
10414 { 10541 {
10415 // The tokenizer checks for the construct of an+b. 10542 // The tokenizer checks for the construct of an+b.
10416 // However, since the {ident} rule precedes the {nth} rule, some of those 10543 // However, since the {ident} rule precedes the {nth} rule, some of those
10417 // tokens are identified as string literal. Furthermore we need to accept 10544 // tokens are identified as string literal. Furthermore we need to accept
10418 // "odd" and "even" which does not match to an+b. 10545 // "odd" and "even" which does not match to an+b.
10419 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even") 10546 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
10420 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n"); 10547 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
10421 } 10548 }
10422 10549
10423 } 10550 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698