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

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

Issue 2247773004: [WIP] CSS Motion Path: offset-anchor and offset-position Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: offsetAnchor Created 4 years, 4 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/CSSPropertyParserHelpers.cpp
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParserHelpers.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParserHelpers.cpp
index 6ee13b885bf0ed761aba96a92f91b0b31f7c45b4..c4dafc3a74957260a00076a92d15b6c99e22df1a 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParserHelpers.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParserHelpers.cpp
@@ -488,11 +488,24 @@ CSSValue* consumeColor(CSSParserTokenRange& range, CSSParserMode cssParserMode,
return CSSColorValue::create(color);
}
-static CSSPrimitiveValue* consumePositionComponent(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
+static CSSPrimitiveValue* consumePositionComponent(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, bool& horizontalEdge, bool& verticalEdge)
{
- if (range.peek().type() == IdentToken)
- return consumeIdent<CSSValueLeft, CSSValueTop, CSSValueBottom, CSSValueRight, CSSValueCenter>(range);
- return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, unitless);
+ if (range.peek().type() != IdentToken)
+ return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, unitless);
+
+ CSSValueID id = range.peek().id();
+ if (id == CSSValueLeft || id == CSSValueRight) {
+ if (horizontalEdge)
+ return nullptr;
+ horizontalEdge = true;
+ } else if (id == CSSValueTop || id == CSSValueBottom) {
+ if (verticalEdge)
+ return nullptr;
+ verticalEdge = true;
+ } else if (id != CSSValueCenter) {
+ return nullptr;
+ }
+ return consumeIdent(range);
}
static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value)
@@ -514,33 +527,29 @@ static void positionFromOneValue(CSSPrimitiveValue* value, CSSValue*& resultX, C
std::swap(resultX, resultY);
}
-static bool positionFromTwoValues(CSSPrimitiveValue* value1, CSSPrimitiveValue* value2,
+static void positionFromTwoValues(CSSPrimitiveValue* value1, CSSPrimitiveValue* value2,
CSSValue*& resultX, CSSValue*& resultY)
{
bool mustOrderAsXY = isHorizontalPositionKeywordOnly(*value1) || isVerticalPositionKeywordOnly(*value2)
|| !value1->isValueID() || !value2->isValueID();
bool mustOrderAsYX = isVerticalPositionKeywordOnly(*value1) || isHorizontalPositionKeywordOnly(*value2);
- if (mustOrderAsXY && mustOrderAsYX)
- return false;
+ DCHECK(!mustOrderAsXY || !mustOrderAsYX);
resultX = value1;
resultY = value2;
if (mustOrderAsYX)
std::swap(resultX, resultY);
- return true;
}
-static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, CSSValue*& resultX, CSSValue*& resultY)
+static void positionFromThreeOrFourValues(CSSPrimitiveValue** values, CSSValue*& resultX, CSSValue*& resultY)
{
CSSPrimitiveValue* center = nullptr;
for (int i = 0; values[i]; i++) {
CSSPrimitiveValue* currentValue = values[i];
- if (!currentValue->isValueID())
- return false;
+ DCHECK(currentValue->isValueID());
CSSValueID id = currentValue->getValueID();
if (id == CSSValueCenter) {
- if (center)
- return false;
+ DCHECK(!center);
center = currentValue;
continue;
}
@@ -553,57 +562,69 @@ static bool positionFromThreeOrFourValues(CSSPrimitiveValue** values, CSSValue*&
}
if (id == CSSValueLeft || id == CSSValueRight) {
- if (resultX)
- return false;
+ DCHECK(!resultX);
resultX = result;
} else {
- ASSERT(id == CSSValueTop || id == CSSValueBottom);
- if (resultY)
- return false;
+ DCHECK(id == CSSValueTop || id == CSSValueBottom);
+ DCHECK(!resultY);
resultY = result;
}
}
if (center) {
- ASSERT(resultX || resultY);
- if (resultX && resultY)
- return false;
+ DCHECK(!!resultX != !!resultY);
if (!resultX)
resultX = center;
else
resultY = center;
}
- ASSERT(resultX && resultY);
- return true;
+ DCHECK(resultX && resultY);
}
-// TODO(timloh): This may consume from the range upon failure. The background
-// shorthand works around it, but we should just fix it here.
bool consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, CSSValue*& resultX, CSSValue*& resultY)
{
- CSSPrimitiveValue* value1 = consumePositionComponent(range, cssParserMode, unitless);
+ bool horizontalEdge = false;
+ bool verticalEdge = false;
+ CSSPrimitiveValue* value1 = consumePositionComponent(range, cssParserMode, unitless, horizontalEdge, verticalEdge);
if (!value1)
return false;
+ if (!value1->isValueID())
+ horizontalEdge = true;
- CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, unitless);
+ CSSParserTokenRange rangeAfterFirstConsume = range;
+ CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, unitless, horizontalEdge, verticalEdge);
if (!value2) {
positionFromOneValue(value1, resultX, resultY);
return true;
}
- CSSPrimitiveValue* value3 = consumePositionComponent(range, cssParserMode, unitless);
- if (!value3)
- return positionFromTwoValues(value1, value2, resultX, resultY);
+ CSSPrimitiveValue* value3 = nullptr;
+ if (value1->isValueID()
+ && value2->isValueID() != (range.peek().type() == IdentToken)
+ && (value2->isValueID() ? value2->getValueID() : value1->getValueID()) != CSSValueCenter)
+ value3 = consumePositionComponent(range, cssParserMode, unitless, horizontalEdge, verticalEdge);
+ if (!value3) {
+ if (verticalEdge && !value2->isValueID()) {
+ range = rangeAfterFirstConsume;
+ positionFromOneValue(value1, resultX, resultY);
+ return true;
+ }
+ positionFromTwoValues(value1, value2, resultX, resultY);
+ return true;
+ }
- CSSPrimitiveValue* value4 = consumePositionComponent(range, cssParserMode, unitless);
+ CSSPrimitiveValue* value4 = nullptr;
+ if (value3->isValueID() && value3->getValueID() != CSSValueCenter && range.peek().type() != IdentToken)
+ value4 = consumePositionComponent(range, cssParserMode, unitless, horizontalEdge, verticalEdge);
CSSPrimitiveValue* values[5];
values[0] = value1;
values[1] = value2;
values[2] = value3;
values[3] = value4;
values[4] = nullptr;
- return positionFromThreeOrFourValues(values, resultX, resultY);
+ positionFromThreeOrFourValues(values, resultX, resultY);
+ return true;
}
CSSValuePair* consumePosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless)
@@ -617,15 +638,23 @@ CSSValuePair* consumePosition(CSSParserTokenRange& range, CSSParserMode cssParse
bool consumeOneOrTwoValuedPosition(CSSParserTokenRange& range, CSSParserMode cssParserMode, UnitlessQuirk unitless, CSSValue*& resultX, CSSValue*& resultY)
{
- CSSPrimitiveValue* value1 = consumePositionComponent(range, cssParserMode, unitless);
+ bool horizontalEdge = false;
+ bool verticalEdge = false;
+ CSSPrimitiveValue* value1 = consumePositionComponent(range, cssParserMode, unitless, horizontalEdge, verticalEdge);
if (!value1)
return false;
- CSSPrimitiveValue* value2 = consumePositionComponent(range, cssParserMode, unitless);
+ if (!value1->isValueID())
+ horizontalEdge = true;
+
+ CSSPrimitiveValue* value2 = nullptr;
+ if (!verticalEdge || range.peek().type() == IdentToken)
+ value2 = consumePositionComponent(range, cssParserMode, unitless, horizontalEdge, verticalEdge);
if (!value2) {
positionFromOneValue(value1, resultX, resultY);
return true;
}
- return positionFromTwoValues(value1, value2, resultX, resultY);
+ positionFromTwoValues(value1, value2, resultX, resultY);
+ return true;
}
// This should go away once we drop support for -webkit-gradient

Powered by Google App Engine
This is Rietveld 408576698