Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (282808 => 282809)
--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-09-21 09:22:55 UTC (rev 282808)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp 2021-09-21 09:28:00 UTC (rev 282809)
@@ -207,25 +207,6 @@
return { { m_calcValue->primitiveType(), m_calcValue->doubleValue() } };
}
- std::optional<LengthOrPercentRaw> consumeLengthOrPercentRaw()
- {
- if (!m_calcValue)
- return std::nullopt;
-
- switch (m_calcValue->category()) {
- case CalculationCategory::Length:
- m_sourceRange = m_range;
- return { LengthRaw({ m_calcValue->primitiveType(), m_calcValue->doubleValue() }) };
- case CalculationCategory::Percent:
- case CalculationCategory::PercentLength:
- case CalculationCategory::PercentNumber:
- m_sourceRange = m_range;
- return { { m_calcValue->doubleValue() } };
- default:
- return std::nullopt;
- }
- }
-
private:
CSSParserTokenRange& m_sourceRange;
CSSParserTokenRange m_range;
@@ -235,16 +216,32 @@
// MARK: - Primitive value consumers for callers that know the token type.
+static RefPtr<CSSCalcValue> consumeCalcRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, CalculationCategory category, const CSSCalcSymbolTable& symbolTable = { }, ValueRange valueRange = ValueRange::All)
+{
+ ASSERT(range.peek().type() == FunctionToken);
+
+ const auto& token = range.peek();
+ auto functionId = token.functionId();
+ if (!CSSCalcValue::isCalcFunction(functionId))
+ return nullptr;
+
+ auto calcValue = CSSCalcValue::create(functionId, consumeFunction(range), category, valueRange, symbolTable);
+ if (calcValue && calcValue->category() == category)
+ return calcValue;
+
+ return nullptr;
+}
+
// MARK: Integer (Raw)
-template<typename IntType> static std::optional<IntType> consumeIntegerTypeRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, double minimumValue)
+template<typename IntType> static std::optional<IntType> consumeIntegerTypeRawWithKnownTokenTypeFunction(CSSParserTokenRange& sourceRange, double minimumValue)
{
- ASSERT(range.peek().type() == FunctionToken);
+ auto range = sourceRange;
+ if (auto value = consumeCalcRawWithKnownTokenTypeFunction(range, CalculationCategory::Number, { }, ValueRange::All)) {
+ sourceRange = range;
+ return clampTo<IntType>(std::round(std::max(value->doubleValue(), minimumValue)));
+ }
- CalcParser parser(range, CalculationCategory::Number);
- if (auto calculation = parser.value(); calculation && calculation->category() == CalculationCategory::Number)
- return parser.consumeIntegerTypeRaw<IntType>(minimumValue);
-
return std::nullopt;
}
@@ -286,12 +283,17 @@
return value;
}
-static std::optional<double> consumeNumberRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange)
+static std::optional<double> consumeNumberRawWithKnownTokenTypeFunction(CSSParserTokenRange& sourceRange, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange)
{
- ASSERT(range.peek().type() == FunctionToken);
+ auto range = sourceRange;
+ if (auto value = consumeCalcRawWithKnownTokenTypeFunction(range, CalculationCategory::Number, symbolTable, valueRange)) {
+ if (auto validatedValue = validatedNumberRaw(value->doubleValue(), valueRange)) {
+ sourceRange = range;
+ return validatedValue;
+ }
+ }
- CalcParser parser(range, CalculationCategory::Number, valueRange, symbolTable);
- return parser.consumeNumberRaw();
+ return std::nullopt;
}
static std::optional<double> consumeNumberRawWithKnownTokenTypeNumber(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange)
@@ -361,12 +363,23 @@
return value;
}
-static std::optional<double> consumePercentRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange)
+static std::optional<double> consumePercentRawWithKnownTokenTypeFunction(CSSParserTokenRange& sourceRange, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange)
{
- ASSERT(range.peek().type() == FunctionToken);
+ ASSERT(sourceRange.peek().type() == FunctionToken);
- CalcParser parser(range, CalculationCategory::Percent, valueRange, symbolTable);
- return parser.consumePercentRaw();
+ const auto& token = sourceRange.peek();
+ auto functionId = token.functionId();
+ if (!CSSCalcValue::isCalcFunction(functionId))
+ return std::nullopt;
+
+ auto range = sourceRange;
+ auto calcValue = CSSCalcValue::create(functionId, consumeFunction(range), CalculationCategory::Percent, valueRange, symbolTable);
+ if (calcValue && calcValue->category() == CalculationCategory::Percent) {
+ sourceRange = range;
+ return calcValue->doubleValue();
+ }
+
+ return std::nullopt;
}
static std::optional<double> consumePercentRawWithKnownTokenTypePercentage(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange)
@@ -433,12 +446,14 @@
return value;
}
-static std::optional<LengthRaw> consumeLengthRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk)
+static std::optional<LengthRaw> consumeLengthRawWithKnownTokenTypeFunction(CSSParserTokenRange& sourceRange, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk)
{
- ASSERT(range.peek().type() == FunctionToken);
-
- CalcParser parser(range, CalculationCategory::Length, valueRange, symbolTable);
- return parser.consumeLengthRaw();
+ auto range = sourceRange;
+ if (auto value = consumeCalcRawWithKnownTokenTypeFunction(range, CalculationCategory::Length, symbolTable, valueRange)) {
+ sourceRange = range;
+ return { { value->primitiveType(), value->doubleValue() } };
+ }
+ return std::nullopt;
}
static std::optional<LengthRaw> consumeLengthRawWithKnownTokenTypeDimension(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange valueRange, CSSParserMode parserMode, UnitlessQuirk)
@@ -528,12 +543,14 @@
// MARK: Angle (raw)
-static std::optional<AngleRaw> consumeAngleRawWithKnownTokenTypeFunction(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
+static std::optional<AngleRaw> consumeAngleRawWithKnownTokenTypeFunction(CSSParserTokenRange& sourceRange, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
{
- ASSERT(range.peek().type() == FunctionToken);
-
- CalcParser parser(range, CalculationCategory::Angle, valueRange, symbolTable);
- return parser.consumeAngleRaw();
+ auto range = sourceRange;
+ if (auto value = consumeCalcRawWithKnownTokenTypeFunction(range, CalculationCategory::Angle, symbolTable, valueRange)) {
+ sourceRange = range;
+ return { { value->primitiveType(), value->doubleValue() } };
+ }
+ return std::nullopt;
}
static std::optional<AngleRaw> consumeAngleRawWithKnownTokenTypeDimension(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk)
@@ -943,10 +960,10 @@
switch (token.type()) {
case FunctionToken: {
- // FIXME: Should this be using trying to generate the calc with both Length and Percent destination category types?
- CalcParser parser(range, CalculationCategory::Length, valueRange);
- if (auto calculation = parser.value(); calculation && canConsumeCalcValue(calculation->category(), parserMode))
- return parser.consumeLengthOrPercentRaw();
+ if (auto length = consumeLengthRawWithKnownTokenTypeFunction(range, { }, valueRange, parserMode, unitless))
+ return convertToLengthOrPercentRaw(length);
+ if (auto percent = consumePercentRawWithKnownTokenTypeFunction(range, { }, valueRange))
+ return convertToLengthOrPercentRaw(percent);
break;
}