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

Unified Diff: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp

Issue 1603193002: Move two shape related properties into CSSPropertyParser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments Created 4 years, 11 months 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: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 0d0289de215d787aff3cce61cc940094fc764aff..e13ebebdc9da4990a27d59308295605921767dbb 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -5,6 +5,7 @@
#include "core/css/parser/CSSPropertyParser.h"
#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSBasicShapeValues.h"
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSCounterValue.h"
#include "core/css/CSSCrossfadeValue.h"
@@ -2741,6 +2742,8 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeGeneratedImage(CSSParserTokenRang
if (context.useCounter())
context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLinearGradient);
result = consumeLinearGradient(args, context.mode(), Repeating, CSSPrefixedLinearGradient);
+ } else if (id == CSSValueRepeatingLinearGradient) {
+ result = consumeLinearGradient(args, context.mode(), Repeating, CSSLinearGradient);
} else if (id == CSSValueLinearGradient) {
result = consumeLinearGradient(args, context.mode(), NonRepeating, CSSLinearGradient);
} else if (id == CSSValueWebkitGradient) {
@@ -2934,6 +2937,216 @@ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeVerticalAlign(CSSParserT
return parsedValue.release();
}
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> consumeShapeRadius(CSSParserTokenRange& args, CSSParserMode cssParserMode)
+{
+ if (identMatches<CSSValueClosestSide, CSSValueFarthestSide>(args.peek().id()))
+ return consumeIdent(args);
+ return consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
+}
+
+static PassRefPtrWillBeRawPtr<CSSBasicShapeCircleValue> consumeBasicShapeCircle(CSSParserTokenRange& args, const CSSParserContext& context)
+{
+ // spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes
+ // circle( [<shape-radius>]? [at <position>]? )
+ RefPtrWillBeRawPtr<CSSBasicShapeCircleValue> shape = CSSBasicShapeCircleValue::create();
+ if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = consumeShapeRadius(args, context.mode()))
+ shape->setRadius(radius.release());
+ if (consumeIdent<CSSValueAt>(args)) {
+ RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
+ if (!consumePosition(args, context.mode(), UnitlessQuirk::Forbid, centerX, centerY))
+ return nullptr;
+ shape->setCenterX(centerX);
+ shape->setCenterY(centerY);
+ }
+ return shape.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSBasicShapeEllipseValue> consumeBasicShapeEllipse(CSSParserTokenRange& args, const CSSParserContext& context)
+{
+ // spec: https://drafts.csswg.org/css-shapes/#supported-basic-shapes
+ // ellipse( [<shape-radius>{2}]? [at <position>]? )
+ RefPtrWillBeRawPtr<CSSBasicShapeEllipseValue> shape = CSSBasicShapeEllipseValue::create();
+ if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX = consumeShapeRadius(args, context.mode())) {
+ shape->setRadiusX(radiusX);
+ if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY = consumeShapeRadius(args, context.mode()))
+ shape->setRadiusY(radiusY);
+ }
+ if (consumeIdent<CSSValueAt>(args)) {
+ RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
+ if (!consumePosition(args, context.mode(), UnitlessQuirk::Forbid, centerX, centerY))
+ return nullptr;
+ shape->setCenterX(centerX);
+ shape->setCenterY(centerY);
+ }
+ return shape.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSBasicShapePolygonValue> consumeBasicShapePolygon(CSSParserTokenRange& args, const CSSParserContext& context)
+{
+ RefPtrWillBeRawPtr<CSSBasicShapePolygonValue> shape = CSSBasicShapePolygonValue::create();
+ if (identMatches<CSSValueEvenodd, CSSValueNonzero>(args.peek().id())) {
+ shape->setWindRule(args.consumeIncludingWhitespace().id() == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
+ if (!consumeCommaIncludingWhitespace(args))
+ return nullptr;
+ }
+
+ do {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> xLength = consumeLengthOrPercent(args, context.mode(), ValueRangeAll);
+ if (!xLength)
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = consumeLengthOrPercent(args, context.mode(), ValueRangeAll);
+ if (!yLength)
+ return nullptr;
+ shape->appendPoint(xLength.release(), yLength.release());
+ } while (consumeCommaIncludingWhitespace(args));
+ return shape.release();
+}
+
+static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4])
+{
+ if (radii[3])
+ return;
+ if (!radii[2]) {
+ if (!radii[1])
+ radii[1] = radii[0];
+ radii[2] = radii[0];
+ }
+ radii[3] = radii[1];
+}
+
+static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4], RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4], CSSParserTokenRange& range, CSSParserMode cssParserMode, bool useLegacyParsing)
+{
+#if ENABLE(OILPAN)
+ // Unconditionally zero initialize the arrays of raw pointers.
+ memset(horizontalRadii, 0, 4 * sizeof(horizontalRadii[0]));
+ memset(verticalRadii, 0, 4 * sizeof(verticalRadii[0]));
+#endif
+ unsigned i = 0;
+ for (; i < 4 && !range.atEnd() && range.peek().type() != DelimiterToken; ++i) {
+ horizontalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative);
+ if (!horizontalRadii[i])
+ return false;
+ }
+ if (!horizontalRadii[0])
+ return false;
+ if (range.atEnd()) {
+ // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
+ if (useLegacyParsing && i == 2) {
+ verticalRadii[0] = horizontalRadii[1];
+ horizontalRadii[1] = nullptr;
+ } else {
+ completeBorderRadii(horizontalRadii);
+ for (unsigned i = 0; i < 4; ++i)
+ verticalRadii[i] = horizontalRadii[i];
+ return true;
+ }
+ } else {
+ if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '/')
+ return false;
+ range.consumeIncludingWhitespace();
+ for (i = 0; i < 4 && !range.atEnd(); ++i) {
+ verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative);
+ if (!verticalRadii[i])
+ return false;
+ }
+ if (!verticalRadii[0] || !range.atEnd())
+ return false;
+ }
+ completeBorderRadii(horizontalRadii);
+ completeBorderRadii(verticalRadii);
+ return true;
+}
+
+static PassRefPtrWillBeRawPtr<CSSBasicShapeInsetValue> consumeBasicShapeInset(CSSParserTokenRange& args, const CSSParserContext& context)
+{
+ RefPtrWillBeRawPtr<CSSBasicShapeInsetValue> shape = CSSBasicShapeInsetValue::create();
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> top = consumeLengthOrPercent(args, context.mode(), ValueRangeAll);
+ if (!top)
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> right = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> bottom = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> left = nullptr;
+ if ((right = consumeLengthOrPercent(args, context.mode(), ValueRangeAll))) {
+ if ((bottom = consumeLengthOrPercent(args, context.mode(), ValueRangeAll)))
+ left = consumeLengthOrPercent(args, context.mode(), ValueRangeAll);
+ }
+ if (left)
+ shape->updateShapeSize4Values(top.get(), right.get(), bottom.get(), left.get());
+ else if (bottom)
+ shape->updateShapeSize3Values(top.get(), right.get(), bottom.get());
+ else if (right)
+ shape->updateShapeSize2Values(top.get(), right.get());
+ else
+ shape->updateShapeSize1Value(top.get());
+
+ if (consumeIdent<CSSValueRound>(args)) {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4];
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4];
+ if (!consumeRadii(horizontalRadii, verticalRadii, args, context.mode(), false))
+ return nullptr;
+ shape->setTopLeftRadius(CSSValuePair::create(horizontalRadii[0].release(), verticalRadii[0].release(), CSSValuePair::DropIdenticalValues));
+ shape->setTopRightRadius(CSSValuePair::create(horizontalRadii[1].release(), verticalRadii[1].release(), CSSValuePair::DropIdenticalValues));
+ shape->setBottomRightRadius(CSSValuePair::create(horizontalRadii[2].release(), verticalRadii[2].release(), CSSValuePair::DropIdenticalValues));
+ shape->setBottomLeftRadius(CSSValuePair::create(horizontalRadii[3].release(), verticalRadii[3].release(), CSSValuePair::DropIdenticalValues));
+ }
+ return shape.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumeBasicShape(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ RefPtrWillBeRawPtr<CSSValue> shape = nullptr;
+ if (range.peek().type() != FunctionToken)
+ return nullptr;
+ CSSValueID id = range.peek().functionId();
+ CSSParserTokenRange rangeCopy = range;
+ CSSParserTokenRange args = consumeFunction(rangeCopy);
+ if (id == CSSValueCircle)
+ shape = consumeBasicShapeCircle(args, context);
+ else if (id == CSSValueEllipse)
+ shape = consumeBasicShapeEllipse(args, context);
+ else if (id == CSSValuePolygon)
+ shape = consumeBasicShapePolygon(args, context);
+ else if (id == CSSValueInset)
+ shape = consumeBasicShapeInset(args, context);
+ if (!shape || !args.atEnd())
+ return nullptr;
+ range = rangeCopy;
+ return shape.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumeClipPath(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ if (range.peek().id() == CSSValueNone)
+ return consumeIdent(range);
+ String url = consumeUrl(range);
+ if (!url.isNull())
+ return CSSURIValue::create(url);
+ return consumeBasicShape(range, context);
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> consumeShapeOutside(CSSParserTokenRange& range, const CSSParserContext& context)
+{
+ if (range.peek().id() == CSSValueNone)
+ return consumeIdent(range);
+ if (RefPtrWillBeRawPtr<CSSValue> imageValue = consumeImage(range, context))
+ return imageValue.release();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ if (RefPtrWillBeRawPtr<CSSValue> boxValue = consumeIdent<CSSValueContentBox, CSSValuePaddingBox, CSSValueBorderBox, CSSValueMarginBox>(range))
+ list->append(boxValue.release());
+ if (RefPtrWillBeRawPtr<CSSValue> shapeValue = consumeBasicShape(range, context)) {
+ list->append(shapeValue.release());
+ if (list->length() < 2) {
+ if (RefPtrWillBeRawPtr<CSSValue> boxValue = consumeIdent<CSSValueContentBox, CSSValuePaddingBox, CSSValueBorderBox, CSSValueMarginBox>(range))
+ list->append(boxValue.release());
+ }
+ }
+ if (!list->length())
+ return nullptr;
+ return list.release();
+}
+
PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty)
{
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -3230,6 +3443,10 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
return consumeIdent<CSSValueAuto, CSSValueUnder>(m_range);
case CSSPropertyVerticalAlign:
return consumeVerticalAlign(m_range, m_context.mode());
+ case CSSPropertyShapeOutside:
+ return consumeShapeOutside(m_range, m_context);
+ case CSSPropertyWebkitClipPath:
+ return consumeClipPath(m_range, m_context);
default:
CSSParserValueList valueList(m_range);
if (valueList.size()) {
@@ -3748,49 +3965,6 @@ bool CSSPropertyParser::consume4Values(const StylePropertyShorthand& shorthand,
return m_range.atEnd();
}
-static bool consumeRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRadii[4], RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRadii[4], CSSParserTokenRange& range, CSSParserMode cssParserMode, bool useLegacyParsing)
-{
-#if ENABLE(OILPAN)
- // Unconditionally zero initialize the arrays of raw pointers.
- memset(horizontalRadii, 0, 4 * sizeof(horizontalRadii[0]));
- memset(verticalRadii, 0, 4 * sizeof(verticalRadii[0]));
-#endif
- unsigned i = 0;
- for (; i < 4 && !range.atEnd() && range.peek().type() != DelimiterToken; ++i) {
- horizontalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative);
- if (!horizontalRadii[i])
- return false;
- }
- if (!horizontalRadii[0])
- return false;
- if (range.atEnd()) {
- // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
- if (useLegacyParsing && i == 2) {
- verticalRadii[0] = horizontalRadii[1];
- horizontalRadii[1] = nullptr;
- } else {
- completeBorderRadii(horizontalRadii);
- for (unsigned i = 0; i < 4; ++i)
- verticalRadii[i] = horizontalRadii[i];
- return true;
- }
- } else {
- if (range.peek().type() != DelimiterToken || range.peek().delimiter() != '/')
- return false;
- range.consumeIncludingWhitespace();
- for (i = 0; i < 4 && !range.atEnd(); ++i) {
- verticalRadii[i] = consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative);
- if (!verticalRadii[i])
- return false;
- }
- if (!verticalRadii[0] || !range.atEnd())
- return false;
- }
- completeBorderRadii(horizontalRadii);
- completeBorderRadii(verticalRadii);
- return true;
-}
-
bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important)
{
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);

Powered by Google App Engine
This is Rietveld 408576698