Skip to content
Permalink
Browse files
[@Property] Support <time> and <dimension> syntax
https://bugs.webkit.org/show_bug.cgi?id=249096
rdar://103229229

Reviewed by Alan Baradlay.

This patch also adds support for calc() in for dimension values. It was missing.

* LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/register-property-syntax-parsing-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-computation-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/registered-property-initial-expected.txt:
* LayoutTests/imported/w3c/web-platform-tests/css/css-properties-values-api/typedom-expected.txt:
* Source/WebCore/css/CSSPrimitiveValue.cpp:
(WebCore::CSSPrimitiveValue::primitiveType const):
* Source/WebCore/css/calc/CSSCalcCategoryMapping.cpp:
(WebCore::calcUnitCategory):
(WebCore::calculationCategoryForCombination):
(WebCore::canonicalUnitTypeForCalculationCategory):
* Source/WebCore/css/calc/CSSCalcOperationNode.cpp:
(WebCore::resolvedTypeForMinOrMaxOrClamp):
(WebCore::sortingCategoryForType):
(WebCore::CSSCalcOperationNode::primitiveType const):
* Source/WebCore/css/calc/CSSCalcPrimitiveValueNode.cpp:
(WebCore::CSSCalcPrimitiveValueNode::createCalcExpression const):
(WebCore::CSSCalcPrimitiveValueNode::computeLengthPx const):
* Source/WebCore/css/parser/CSSPropertyParser.cpp:
(WebCore::CSSPropertyParser::parseCustomPropertyValueWithSyntaxDefinition):
(WebCore::CSSPropertyParser::parseTypedCustomPropertyValue):
* Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::ResolutionCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer::consume):
(WebCore::CSSPropertyParserHelpers::ResolutionCSSPrimitiveValueWithKnownTokenTypeDimensionConsumer::consume): Deleted.
* Source/WebCore/css/parser/CSSPropertySyntax.cpp:
(WebCore::CSSPropertySyntax::parseComponent):
* Source/WebCore/css/parser/CSSPropertySyntax.h:
* Source/WebCore/platform/calc/CalculationCategory.cpp:
(WebCore::operator<<):
* Source/WebCore/platform/calc/CalculationCategory.h:

Canonical link: https://commits.webkit.org/257706@main
  • Loading branch information
anttijk committed Dec 11, 2022
1 parent bf6ec0b commit a122428d84a49b6ac58a94321170579a681519ce
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 54 deletions.
@@ -42,11 +42,11 @@ PASS syntax:'<integer>', initialValue:'calc(3.1415 + 3.1415)' is valid
PASS syntax:'<angle>', initialValue:'10deg' is valid
PASS syntax:'<angle>', initialValue:'20.5rad' is valid
PASS syntax:'<angle>', initialValue:'calc(50grad + 3.14159rad)' is valid
FAIL syntax:'<time>', initialValue:'2s' is valid The given initial value does not parse for the given syntax.
FAIL syntax:'<time>', initialValue:'calc(2s - 9ms)' is valid The given initial value does not parse for the given syntax.
FAIL syntax:'<resolution>', initialValue:'10dpi' is valid The given initial value does not parse for the given syntax.
FAIL syntax:'<resolution>', initialValue:'3dPpX' is valid The given initial value does not parse for the given syntax.
FAIL syntax:'<resolution>', initialValue:'-5.3dpcm' is valid The given initial value does not parse for the given syntax.
PASS syntax:'<time>', initialValue:'2s' is valid
PASS syntax:'<time>', initialValue:'calc(2s - 9ms)' is valid
PASS syntax:'<resolution>', initialValue:'10dpi' is valid
PASS syntax:'<resolution>', initialValue:'3dPpX' is valid
PASS syntax:'<resolution>', initialValue:'-5.3dpcm' is valid
FAIL syntax:'<transform-function>', initialValue:'translateX(2px)' is valid The given initial value does not parse for the given syntax.
PASS syntax:'<transform-function>|<integer>', initialValue:'5' is valid
FAIL syntax:'<transform-function>|<integer>', initialValue:'scale(2)' is valid The given initial value does not parse for the given syntax.
@@ -53,12 +53,12 @@ PASS <angle> values are computed correctly [180deg]
PASS <angle> values are computed correctly [400grad]
PASS <angle> values are computed correctly [calc(360deg + 400grad)]
PASS * values are computed correctly [50s]
FAIL <time> values are computed correctly [1s] The given initial value does not parse for the given syntax.
FAIL <time> values are computed correctly [1000ms] The given initial value does not parse for the given syntax.
FAIL <time> values are computed correctly [calc(1000ms + 1s)] The given initial value does not parse for the given syntax.
PASS <time> values are computed correctly [1s]
PASS <time> values are computed correctly [1000ms]
PASS <time> values are computed correctly [calc(1000ms + 1s)]
PASS * values are computed correctly [50dpi]
FAIL <resolution> values are computed correctly [1dppx] The given initial value does not parse for the given syntax.
FAIL <resolution> values are computed correctly [96dpi] The given initial value does not parse for the given syntax.
FAIL <resolution> values are computed correctly [calc(1dppx + 96dpi)] The given initial value does not parse for the given syntax.
PASS <resolution> values are computed correctly [1dppx]
PASS <resolution> values are computed correctly [96dpi]
PASS <resolution> values are computed correctly [calc(1dppx + 96dpi)]
PASS * values are computed correctly [url(why)]

@@ -25,7 +25,7 @@ PASS Initial non-inherited value can be substituted [ calc(13% + 37px), --x]
PASS Initial non-inherited value can be substituted [calc(10px + 15px), --x]
PASS Initial non-inherited value can be substituted [calc(13 + 37), --x]
PASS Initial non-inherited value can be substituted [calc(13% + 37%), --x]
FAIL Initial non-inherited value can be substituted [2000ms, --x] The given initial value does not parse for the given syntax.
PASS Initial non-inherited value can be substituted [2000ms, --x]
FAIL Initial non-inherited value can be substituted [scale(calc(2 + 2)), --x] The given initial value does not parse for the given syntax.
FAIL Initial non-inherited value can be substituted [scale(calc(2 + 2)) translateX(calc(3px + 1px)), --x] The given initial value does not parse for the given syntax.

Large diffs are not rendered by default.

@@ -280,6 +280,7 @@ CSSUnitType CSSPrimitiveValue::primitiveType() const
case CalculationCategory::Angle:
case CalculationCategory::Time:
case CalculationCategory::Frequency:
case CalculationCategory::Resolution:
return m_value.calc->primitiveType();
case CalculationCategory::Other:
return CSSUnitType::CSS_UNKNOWN;
@@ -95,6 +95,10 @@ CalculationCategory calcUnitCategory(CSSUnitType type)
case CSSUnitType::CSS_HZ:
case CSSUnitType::CSS_KHZ:
return CalculationCategory::Frequency;
case CSSUnitType::CSS_DPPX:
case CSSUnitType::CSS_DPI:
case CSSUnitType::CSS_DPCM:
return CalculationCategory::Resolution;
default:
return CalculationCategory::Other;
}
@@ -127,6 +131,10 @@ CalculationCategory calculationCategoryForCombination(CSSUnitType type)
case CSSUnitType::CSS_HZ:
case CSSUnitType::CSS_KHZ:
return CalculationCategory::Frequency;
case CSSUnitType::CSS_DPPX:
case CSSUnitType::CSS_DPI:
case CSSUnitType::CSS_DPCM:
return CalculationCategory::Resolution;
case CSSUnitType::CSS_EMS:
case CSSUnitType::CSS_EXS:
case CSSUnitType::CSS_LHS:
@@ -178,6 +186,7 @@ CSSUnitType canonicalUnitTypeForCalculationCategory(CalculationCategory category
case CalculationCategory::Angle: return CSSUnitType::CSS_DEG;
case CalculationCategory::Time: return CSSUnitType::CSS_S;
case CalculationCategory::Frequency: return CSSUnitType::CSS_HZ;
case CalculationCategory::Resolution: return CSSUnitType::CSS_DPPX;
case CalculationCategory::Other:
case CalculationCategory::PercentNumber:
case CalculationCategory::PercentLength:
@@ -164,6 +164,7 @@ static CalculationCategory resolvedTypeForMinOrMaxOrClamp(CalculationCategory ca
case CalculationCategory::Angle:
case CalculationCategory::Time:
case CalculationCategory::Frequency:
case CalculationCategory::Resolution:
case CalculationCategory::Other:
return category;

@@ -201,6 +202,7 @@ static SortingCategory sortingCategoryForType(CSSUnitType unitType)
SortingCategory::Dimension, // CalculationCategory::Angle,
SortingCategory::Dimension, // CalculationCategory::Time,
SortingCategory::Dimension, // CalculationCategory::Frequency,
SortingCategory::Dimension, // CalculationCategory::Resolution,
SortingCategory::Other, // UOther
};

@@ -1006,6 +1008,7 @@ CSSUnitType CSSCalcOperationNode::primitiveType() const
case CalculationCategory::Angle:
case CalculationCategory::Time:
case CalculationCategory::Frequency:
case CalculationCategory::Resolution:
if (m_children.size() == 1 && !isInverseTrigNode())
return m_children.first()->primitiveType();
return canonicalUnitTypeForCalculationCategory(unitCategory);
@@ -158,6 +158,7 @@ std::unique_ptr<CalcExpressionNode> CSSCalcPrimitiveValueNode::createCalcExpress
case CalculationCategory::Angle:
case CalculationCategory::Time:
case CalculationCategory::Frequency:
case CalculationCategory::Resolution:
case CalculationCategory::Other:
ASSERT_NOT_REACHED();
}
@@ -193,6 +194,7 @@ double CSSCalcPrimitiveValueNode::computeLengthPx(const CSSToLengthConversionDat
case CalculationCategory::Angle:
case CalculationCategory::Time:
case CalculationCategory::Frequency:
case CalculationCategory::Resolution:
case CalculationCategory::Other:
ASSERT_NOT_REACHED();
break;
@@ -358,6 +358,10 @@ std::pair<RefPtr<CSSValue>, CSSPropertySyntax::Type> CSSPropertyParser::parseCus
return consumeNumber(m_range, ValueRange::All);
case CSSPropertySyntax::Type::Angle:
return consumeAngle(m_range, m_context.mode);
case CSSPropertySyntax::Type::Time:
return consumeTime(m_range, m_context.mode, ValueRange::All);
case CSSPropertySyntax::Type::Resolution:
return consumeResolution(m_range);
case CSSPropertySyntax::Type::Color:
return consumeColor(m_range, m_context);
case CSSPropertySyntax::Type::Image:
@@ -448,6 +452,10 @@ RefPtr<CSSCustomPropertyValue> CSSPropertyParser::parseTypedCustomPropertyValue(
return CSSCustomPropertyValue::createForNumericSyntax(name, primitiveValue->doubleValue(), CSSUnitType::CSS_NUMBER);
case CSSPropertySyntax::Type::Angle:
return CSSCustomPropertyValue::createForNumericSyntax(name, primitiveValue->computeDegrees(), CSSUnitType::CSS_DEG);
case CSSPropertySyntax::Type::Time:
return CSSCustomPropertyValue::createForNumericSyntax(name, primitiveValue->doubleValue(CSSUnitType::CSS_S), CSSUnitType::CSS_S);
case CSSPropertySyntax::Type::Resolution:
return CSSCustomPropertyValue::createForNumericSyntax(name, primitiveValue->doubleValue(CSSUnitType::CSS_DPPX), CSSUnitType::CSS_DPPX);
case CSSPropertySyntax::Type::Color: {
auto color = builderState.colorFromPrimitiveValue(*primitiveValue, Style::ForVisitedLink::No);
return CSSCustomPropertyValue::createForColorSyntax(name, color);
@@ -785,9 +785,20 @@ struct TimeCSSPrimitiveValueWithCalcWithKnownTokenTypeNumberConsumer {
}
};

// MARK: Resolution (CSSPrimitiveValue - no calc)
// MARK: Resolution (CSSPrimitiveValue - maintaining calc)

struct ResolutionCSSPrimitiveValueWithKnownTokenTypeDimensionConsumer {
struct ResolutionCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer {
static constexpr CSSParserTokenType tokenType = FunctionToken;
static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable& symbolTable, ValueRange valueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
{
ASSERT(range.peek().type() == FunctionToken);

CalcParser parser(range, CalculationCategory::Resolution, valueRange, symbolTable, pool);
return parser.consumeValueIfCategory(CalculationCategory::Resolution);
}
};

struct ResolutionCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer {
static constexpr CSSParserTokenType tokenType = DimensionToken;
static RefPtr<CSSPrimitiveValue> consume(CSSParserTokenRange& range, const CSSCalcSymbolTable&, ValueRange, CSSParserMode, UnitlessQuirk, UnitlessZeroQuirk, CSSValuePool& pool)
{
@@ -1204,8 +1215,8 @@ struct TimeConsumer {
struct ResolutionConsumer {
using Result = RefPtr<CSSPrimitiveValue>;

// NOTE: Unlike the other types, calc() does not work with <resolution>.
using DimensionToken = ResolutionCSSPrimitiveValueWithKnownTokenTypeDimensionConsumer;
using FunctionToken = ResolutionCSSPrimitiveValueWithCalcWithKnownTokenTypeFunctionConsumer;
using DimensionToken = ResolutionCSSPrimitiveValueWithCalcWithKnownTokenTypeDimensionConsumer;
};

// MARK: - Combination consumer definitions.
@@ -70,6 +70,10 @@ auto CSSPropertySyntax::parseComponent(StringParsingBuffer<CharacterType> buffer
return Component { Type::Number, multiplier };
if (dataTypeName == "angle"_s)
return Component { Type::Angle, multiplier };
if (dataTypeName == "time"_s)
return Component { Type::Time, multiplier };
if (dataTypeName == "resolution"_s)
return Component { Type::Resolution, multiplier };
if (dataTypeName == "color"_s)
return Component { Type::Color, multiplier };
if (dataTypeName == "image"_s)
@@ -39,6 +39,8 @@ class CSSPropertySyntax {
Integer,
Number,
Angle,
Time,
Resolution,
Color,
Image,
URL,
@@ -41,6 +41,7 @@ TextStream& operator<<(TextStream& ts, CalculationCategory category)
case CalculationCategory::Angle: ts << "angle"; break;
case CalculationCategory::Time: ts << "time"; break;
case CalculationCategory::Frequency: ts << "frequency"; break;
case CalculationCategory::Resolution: ts << "resolution"; break;
case CalculationCategory::Other: ts << "other"; break;
}

@@ -39,6 +39,7 @@ enum class CalculationCategory : uint8_t {
Angle,
Time,
Frequency,
Resolution,
Other
};

0 comments on commit a122428

Please sign in to comment.