Title: [286897] trunk
Revision
286897
Author
[email protected]
Date
2021-12-10 18:45:31 -0800 (Fri, 10 Dec 2021)

Log Message

Don't do simplification for percentage comparison resolution against negative reference values.
https://bugs.webkit.org/show_bug.cgi?id=233987

Reviewed by Darin Adler.

A percentage may be resolved against a negative value, which is allowed only in 'background-position' property.

Currently in CSSCalcExpressionNodeParser::parseCalc,
it creates CSSCalcExpressionNode tree result and does simplification for it.
But during it, e.g. min(50%, 10%) is simplified to min(10%) and max(50%, 10%) is simplified to max(50%),
which is the opposite result what should be done against negative basis.

With this patch, the percentage comparison resolution against nagative basis is done correctly.

The corresponding spec is step 4's note described below in
https://drafts.csswg.org/css-values-4/#simplify-a-calculation-tree.

'If a percentage is left at this point, it will usually block simplification of the node,
since it needs to be resolved against another value using information not currently available.
(Otherwise, it would have been converted to a different value in an earlier step.)
This includes operations such as "min", since percentages might resolve against a negative basis,
and thus end up with an opposite comparative relationship than the raw percentage value would seem to indicate.'

LayoutTests/imported/w3c:

* web-platform-tests/css/css-values/minmax-percentage-serialize-expected.txt:

Source/WebCore:

* css/calc/CSSCalcExpressionNodeParser.cpp:
(WebCore::CSSCalcExpressionNodeParser::parseCalc):
* css/calc/CSSCalcExpressionNodeParser.h:
* css/calc/CSSCalcOperationNode.cpp:
(WebCore::CSSCalcOperationNode::combineChildren):
* css/calc/CSSCalcOperationNode.h:
* css/calc/CSSCalcValue.cpp:
(WebCore::CSSCalcValue::create):
* css/calc/CSSCalcValue.h:
* css/parser/CSSPropertyParser.cpp:
(WebCore::consumeBackgroundPosition):
* css/parser/CSSPropertyParserHelpers.cpp:
(WebCore::CSSPropertyParserHelpers::CalcParser::CalcParser):
(WebCore::CSSPropertyParserHelpers::consumeLengthOrPercent):
(WebCore::CSSPropertyParserHelpers::consumePositionComponent):
(WebCore::CSSPropertyParserHelpers::consumePositionCoordinates):
* css/parser/CSSPropertyParserHelpers.h:

LayoutTests:

* TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (286896 => 286897)


--- trunk/LayoutTests/ChangeLog	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/LayoutTests/ChangeLog	2021-12-11 02:45:31 UTC (rev 286897)
@@ -1,3 +1,30 @@
+2021-12-10  Joonghun Park  <[email protected]>
+
+        Don't do simplification for percentage comparison resolution against negative reference values.
+        https://bugs.webkit.org/show_bug.cgi?id=233987
+
+        Reviewed by Darin Adler.
+
+        A percentage may be resolved against a negative value, which is allowed only in 'background-position' property.
+
+        Currently in CSSCalcExpressionNodeParser::parseCalc,
+        it creates CSSCalcExpressionNode tree result and does simplification for it.
+        But during it, e.g. min(50%, 10%) is simplified to min(10%) and max(50%, 10%) is simplified to max(50%),
+        which is the opposite result what should be done against negative basis.
+
+        With this patch, the percentage comparison resolution against nagative basis is done correctly.
+
+        The corresponding spec is step 4's note described below in
+        https://drafts.csswg.org/css-values-4/#simplify-a-calculation-tree.
+
+        'If a percentage is left at this point, it will usually block simplification of the node,
+        since it needs to be resolved against another value using information not currently available.
+        (Otherwise, it would have been converted to a different value in an earlier step.)
+        This includes operations such as "min", since percentages might resolve against a negative basis,
+        and thus end up with an opposite comparative relationship than the raw percentage value would seem to indicate.'
+
+        * TestExpectations:
+
 2021-12-10  Devin Rousso  <[email protected]>
 
         WKWebView doesn’t respond to -copyFont: and -pasteFont:

Modified: trunk/LayoutTests/TestExpectations (286896 => 286897)


--- trunk/LayoutTests/TestExpectations	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/LayoutTests/TestExpectations	2021-12-11 02:45:31 UTC (rev 286897)
@@ -3765,7 +3765,6 @@
 webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-6.html [ ImageOnlyFailure ]
 webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-attachment-local/attachment-local-positioning-3.html [ ImageOnlyFailure ]
 webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-attachment-local/attachment-local-positioning-4.html [ ImageOnlyFailure ]
-webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-position-negative-percentage-comparison.html [ ImageOnlyFailure ]
 webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-size-cover-003.html [ ImageOnlyFailure ]
 webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-size/background-size-cover-svg.html [ ImageOnlyFailure ]
 webkit.org/b/206753 imported/w3c/web-platform-tests/css/css-backgrounds/background-size/vector/background-size-vector-003.html [ ImageOnlyFailure ]

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (286896 => 286897)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-12-11 02:45:31 UTC (rev 286897)
@@ -1,3 +1,30 @@
+2021-12-10  Joonghun Park  <[email protected]>
+
+        Don't do simplification for percentage comparison resolution against negative reference values.
+        https://bugs.webkit.org/show_bug.cgi?id=233987
+
+        Reviewed by Darin Adler.
+
+        A percentage may be resolved against a negative value, which is allowed only in 'background-position' property.
+
+        Currently in CSSCalcExpressionNodeParser::parseCalc,
+        it creates CSSCalcExpressionNode tree result and does simplification for it.
+        But during it, e.g. min(50%, 10%) is simplified to min(10%) and max(50%, 10%) is simplified to max(50%),
+        which is the opposite result what should be done against negative basis.
+
+        With this patch, the percentage comparison resolution against nagative basis is done correctly.
+
+        The corresponding spec is step 4's note described below in
+        https://drafts.csswg.org/css-values-4/#simplify-a-calculation-tree.
+
+        'If a percentage is left at this point, it will usually block simplification of the node,
+        since it needs to be resolved against another value using information not currently available.
+        (Otherwise, it would have been converted to a different value in an earlier step.)
+        This includes operations such as "min", since percentages might resolve against a negative basis,
+        and thus end up with an opposite comparative relationship than the raw percentage value would seem to indicate.'
+
+        * web-platform-tests/css/css-values/minmax-percentage-serialize-expected.txt:
+
 2021-12-10  Alexey Shvayka  <[email protected]>
 
         Some WebIDL operations / attributes incorrectly use _current_ realm instead of _relevant_

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/minmax-percentage-serialize-expected.txt (286896 => 286897)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/minmax-percentage-serialize-expected.txt	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-values/minmax-percentage-serialize-expected.txt	2021-12-11 02:45:31 UTC (rev 286897)
@@ -17,7 +17,7 @@
 FAIL 'max(3%, 2%, 1%)' as a specified value should serialize as 'max(3%, 2%, 1%)'. assert_equals: 'max(3%, 2%, 1%)' should round-trip exactly in specified values. expected "max(3%, 2%, 1%)" but got "max(3%)"
 FAIL 'max(3%, 2%, 1%)' as a computed value should serialize as 'max(3%, 2%, 1%)'. assert_equals: 'max(3%, 2%, 1%)' should round-trip exactly in computed values. expected "max(3%, 2%, 1%)" but got "max(3%)"
 PASS 'max(3%, 2%, 1%)' as a used value should serialize as '3px'.
-FAIL 'min(1%, 2%, 3%) 0px' as a specified value should serialize as 'min(1%, 2%, 3%) 0px'. assert_equals: 'min(1%, 2%, 3%) 0px' should round-trip exactly in specified values. expected "min(1%, 2%, 3%) 0px" but got "min(1%) 0px"
+PASS 'min(1%, 2%, 3%) 0px' as a specified value should serialize as 'min(1%, 2%, 3%) 0px'.
 FAIL 'min(1%, 2%, 3%) 0px' as a computed value should serialize as 'min(1%, 2%, 3%) 0px'. assert_equals: 'min(1%, 2%, 3%) 0px' should round-trip exactly in computed values. expected "min(1%, 2%, 3%) 0px" but got "min(1%) 0px"
 PASS 'calc(min(1%, 2%) + max(3%, 4%) + 10%)' as a specified value should serialize as 'calc(15%)'.
 PASS 'calc(min(1%, 2%) + max(3%, 4%) + 10%)' as a computed value should serialize as '15%'.

Modified: trunk/Source/WebCore/ChangeLog (286896 => 286897)


--- trunk/Source/WebCore/ChangeLog	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/ChangeLog	2021-12-11 02:45:31 UTC (rev 286897)
@@ -1,3 +1,46 @@
+2021-12-10  Joonghun Park  <[email protected]>
+
+        Don't do simplification for percentage comparison resolution against negative reference values.
+        https://bugs.webkit.org/show_bug.cgi?id=233987
+
+        Reviewed by Darin Adler.
+
+        A percentage may be resolved against a negative value, which is allowed only in 'background-position' property.
+
+        Currently in CSSCalcExpressionNodeParser::parseCalc,
+        it creates CSSCalcExpressionNode tree result and does simplification for it.
+        But during it, e.g. min(50%, 10%) is simplified to min(10%) and max(50%, 10%) is simplified to max(50%),
+        which is the opposite result what should be done against negative basis.
+
+        With this patch, the percentage comparison resolution against nagative basis is done correctly.
+
+        The corresponding spec is step 4's note described below in
+        https://drafts.csswg.org/css-values-4/#simplify-a-calculation-tree.
+
+        'If a percentage is left at this point, it will usually block simplification of the node,
+        since it needs to be resolved against another value using information not currently available.
+        (Otherwise, it would have been converted to a different value in an earlier step.)
+        This includes operations such as "min", since percentages might resolve against a negative basis,
+        and thus end up with an opposite comparative relationship than the raw percentage value would seem to indicate.'
+
+        * css/calc/CSSCalcExpressionNodeParser.cpp:
+        (WebCore::CSSCalcExpressionNodeParser::parseCalc):
+        * css/calc/CSSCalcExpressionNodeParser.h:
+        * css/calc/CSSCalcOperationNode.cpp:
+        (WebCore::CSSCalcOperationNode::combineChildren):
+        * css/calc/CSSCalcOperationNode.h:
+        * css/calc/CSSCalcValue.cpp:
+        (WebCore::CSSCalcValue::create):
+        * css/calc/CSSCalcValue.h:
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumeBackgroundPosition):
+        * css/parser/CSSPropertyParserHelpers.cpp:
+        (WebCore::CSSPropertyParserHelpers::CalcParser::CalcParser):
+        (WebCore::CSSPropertyParserHelpers::consumeLengthOrPercent):
+        (WebCore::CSSPropertyParserHelpers::consumePositionComponent):
+        (WebCore::CSSPropertyParserHelpers::consumePositionCoordinates):
+        * css/parser/CSSPropertyParserHelpers.h:
+
 2021-12-10  Michael Saboff  <[email protected]>
 
         https://bugs.webkit.org/show_bug.cgi?id=234173

Modified: trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp (286896 => 286897)


--- trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.cpp	2021-12-11 02:45:31 UTC (rev 286897)
@@ -61,8 +61,19 @@
 // <calc-sum> = <calc-product> [ [ '+' | '-' ] <calc-product> ]*
 // <calc-product> = <calc-value> [ [ '*' | '/' ] <calc-value> ]*
 // <calc-value> = <number> | <dimension> | <percentage> | ( <calc-sum> )
-RefPtr<CSSCalcExpressionNode> CSSCalcExpressionNodeParser::parseCalc(CSSParserTokenRange tokens, CSSValueID function)
+RefPtr<CSSCalcExpressionNode> CSSCalcExpressionNodeParser::parseCalc(CSSParserTokenRange tokens, CSSValueID function, bool allowsNegativePercentage)
 {
+    std::function<void(CSSCalcExpressionNode&)> setAllowsNegativePercentageReferenceIfNeeded = [&](CSSCalcExpressionNode& _expression_) {
+        if (is<CSSCalcOperationNode>(_expression_)) {
+            auto& operationNode = downcast<CSSCalcOperationNode>(_expression_);
+            if (operationNode.isMinOrMaxNode())
+                operationNode.setAllowsNegativePercentageReference();
+
+            for (auto& child : operationNode.children())
+                setAllowsNegativePercentageReferenceIfNeeded(child);
+        }
+    };
+
     tokens.consumeWhitespace();
 
     RefPtr<CSSCalcExpressionNode> result;
@@ -75,6 +86,9 @@
 
     LOG_WITH_STREAM(Calc, stream << "CSSCalcExpressionNodeParser::parseCalc " << prettyPrintNode(*result));
 
+    if (allowsNegativePercentage)
+        setAllowsNegativePercentageReferenceIfNeeded(*result);
+
     result = CSSCalcOperationNode::simplify(result.releaseNonNull());
 
     LOG_WITH_STREAM(Calc, stream << "CSSCalcExpressionNodeParser::parseCalc - after simplification " << prettyPrintNode(*result));

Modified: trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.h (286896 => 286897)


--- trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.h	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/calc/CSSCalcExpressionNodeParser.h	2021-12-11 02:45:31 UTC (rev 286897)
@@ -44,7 +44,7 @@
     {
     }
 
-    RefPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange, CSSValueID function);
+    RefPtr<CSSCalcExpressionNode> parseCalc(CSSParserTokenRange, CSSValueID function, bool allowsNegativePercentage);
     
 private:
     char operatorValue(const CSSParserToken&);

Modified: trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp (286896 => 286897)


--- trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/calc/CSSCalcOperationNode.cpp	2021-12-11 02:45:31 UTC (rev 286897)
@@ -828,6 +828,13 @@
 
     if ((isMinOrMaxNode() || isHypotNode()) && canCombineAllChildren()) {
         auto combinedUnitType = m_children[0]->primitiveType();
+        auto involvesPercentageComparisons = [&]() {
+            return combinedUnitType == CSSUnitType::CSS_PERCENTAGE && m_children.size() > 1;
+        };
+
+        if (isMinOrMaxNode() && allowsNegativePercentageReference() && involvesPercentageComparisons())
+            return;
+
         auto category = calculationCategoryForCombination(combinedUnitType);
         if (category != CalculationCategory::Other)
             combinedUnitType = canonicalUnitTypeForCalculationCategory(category);

Modified: trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h (286896 => 286897)


--- trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/calc/CSSCalcOperationNode.h	2021-12-11 02:45:31 UTC (rev 286897)
@@ -73,6 +73,9 @@
     
     bool canCombineAllChildren() const;
 
+    bool allowsNegativePercentageReference() { return m_allowsNegativePercentageReference; }
+    void setAllowsNegativePercentageReference() { m_allowsNegativePercentageReference = true; }
+
     bool isIdentity() const { return m_children.size() == 1 && (m_operator == CalcOperator::Min || m_operator == CalcOperator::Max || m_operator == CalcOperator::Add || m_operator == CalcOperator::Multiply); }
 
     const Vector<Ref<CSSCalcExpressionNode>>& children() const { return m_children; }
@@ -141,6 +144,7 @@
 
     CalcOperator m_operator;
     Vector<Ref<CSSCalcExpressionNode>> m_children;
+    bool m_allowsNegativePercentageReference = false;
 };
 
 }

Modified: trunk/Source/WebCore/css/calc/CSSCalcValue.cpp (286896 => 286897)


--- trunk/Source/WebCore/css/calc/CSSCalcValue.cpp	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/calc/CSSCalcValue.cpp	2021-12-11 02:45:31 UTC (rev 286897)
@@ -390,10 +390,10 @@
     ts << ")\n";
 }
 
-RefPtr<CSSCalcValue> CSSCalcValue::create(CSSValueID function, const CSSParserTokenRange& tokens, CalculationCategory destinationCategory, ValueRange range, const CSSCalcSymbolTable& symbolTable)
+RefPtr<CSSCalcValue> CSSCalcValue::create(CSSValueID function, const CSSParserTokenRange& tokens, CalculationCategory destinationCategory, ValueRange range, const CSSCalcSymbolTable& symbolTable, bool allowsNegativePercentage)
 {
     CSSCalcExpressionNodeParser parser(destinationCategory, symbolTable);
-    auto _expression_ = parser.parseCalc(tokens, function);
+    auto _expression_ = parser.parseCalc(tokens, function, allowsNegativePercentage);
     if (!_expression_)
         return nullptr;
     auto result = adoptRef(new CSSCalcValue(_expression_.releaseNonNull(), range != ValueRange::All));

Modified: trunk/Source/WebCore/css/calc/CSSCalcValue.h (286896 => 286897)


--- trunk/Source/WebCore/css/calc/CSSCalcValue.h	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/calc/CSSCalcValue.h	2021-12-11 02:45:31 UTC (rev 286897)
@@ -50,7 +50,7 @@
 
 class CSSCalcValue final : public CSSValue {
 public:
-    static RefPtr<CSSCalcValue> create(CSSValueID function, const CSSParserTokenRange&, CalculationCategory destinationCategory, ValueRange, const CSSCalcSymbolTable&);
+    static RefPtr<CSSCalcValue> create(CSSValueID function, const CSSParserTokenRange&, CalculationCategory destinationCategory, ValueRange, const CSSCalcSymbolTable&, bool allowsNegativePercentage = false);
     static RefPtr<CSSCalcValue> create(CSSValueID function, const CSSParserTokenRange&, CalculationCategory destinationCategory, ValueRange);
     static RefPtr<CSSCalcValue> create(const CalculationValue&, const RenderStyle&);
     ~CSSCalcValue();

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (286896 => 286897)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2021-12-11 02:45:31 UTC (rev 286897)
@@ -5575,7 +5575,7 @@
 static bool consumeBackgroundPosition(CSSParserTokenRange& range, const CSSParserContext& context, CSSPropertyID property, RefPtr<CSSValue>& resultX, RefPtr<CSSValue>& resultY)
 {
     do {
-        auto position = consumePositionCoordinates(range, context.mode, UnitlessQuirk::Allow, property == CSSPropertyMaskPosition ? PositionSyntax::Position : PositionSyntax::BackgroundPosition);
+        auto position = consumePositionCoordinates(range, context.mode, UnitlessQuirk::Allow, property == CSSPropertyMaskPosition ? PositionSyntax::Position : PositionSyntax::BackgroundPosition, NegativePercentagePolicy::Allow);
         if (!position)
             return false;
         addBackgroundValue(resultX, WTFMove(position->x));

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp (286896 => 286897)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.cpp	2021-12-11 02:45:31 UTC (rev 286897)
@@ -118,7 +118,7 @@
 // FIXME: consider pulling in the parsing logic from CSSCalcExpressionNodeParser.
 class CalcParser {
 public:
-    explicit CalcParser(CSSParserTokenRange& range, CalculationCategory destinationCategory, ValueRange valueRange = ValueRange::All, const CSSCalcSymbolTable& symbolTable = { }, CSSValuePool& pool = CSSValuePool::singleton())
+    explicit CalcParser(CSSParserTokenRange& range, CalculationCategory destinationCategory, ValueRange valueRange = ValueRange::All, const CSSCalcSymbolTable& symbolTable = { }, CSSValuePool& pool = CSSValuePool::singleton(), bool allowsNegativePercentage = false)
         : m_sourceRange(range)
         , m_range(range)
         , m_pool(pool)
@@ -126,7 +126,7 @@
         const CSSParserToken& token = range.peek();
         auto functionId = token.functionId();
         if (CSSCalcValue::isCalcFunction(functionId))
-            m_calcValue = CSSCalcValue::create(functionId, consumeFunction(m_range), destinationCategory, valueRange, symbolTable);
+            m_calcValue = CSSCalcValue::create(functionId, consumeFunction(m_range), destinationCategory, valueRange, symbolTable, allowsNegativePercentage);
     }
 
     const CSSCalcValue* value() const { return m_calcValue.get(); }
@@ -1008,7 +1008,7 @@
     return std::nullopt;
 }
 
-RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless)
+RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange& range, CSSParserMode parserMode, ValueRange valueRange, UnitlessQuirk unitless, bool allowsNegativePercentage)
 {
     auto& token = range.peek();
 
@@ -1015,7 +1015,7 @@
     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);
+        CalcParser parser(range, CalculationCategory::Length, valueRange, { }, CSSValuePool::singleton(), allowsNegativePercentage);
         if (auto calculation = parser.value(); calculation && canConsumeCalcValue(calculation->category(), parserMode))
             return parser.consumeValue();
         break;
@@ -2661,11 +2661,11 @@
     return CSSValuePool::singleton().createValue(color);
 }
 
-static RefPtr<CSSPrimitiveValue> consumePositionComponent(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless)
+static RefPtr<CSSPrimitiveValue> consumePositionComponent(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, bool allowsNegativePercentage = false)
 {
     if (range.peek().type() == IdentToken)
         return consumeIdent<CSSValueLeft, CSSValueTop, CSSValueBottom, CSSValueRight, CSSValueCenter>(range);
-    return consumeLengthOrPercent(range, parserMode, ValueRange::All, unitless);
+    return consumeLengthOrPercent(range, parserMode, ValueRange::All, unitless, allowsNegativePercentage);
 }
 
 static bool isHorizontalPositionKeywordOnly(const CSSPrimitiveValue& value)
@@ -2814,21 +2814,23 @@
 
 // FIXME: This may consume from the range upon failure. The background
 // shorthand works around it, but we should just fix it here.
-std::optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax)
+std::optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange& range, CSSParserMode parserMode, UnitlessQuirk unitless, PositionSyntax positionSyntax, NegativePercentagePolicy policy)
 {
-    auto value1 = consumePositionComponent(range, parserMode, unitless);
+    bool allowsNegative = policy == NegativePercentagePolicy::Allow;
+
+    auto value1 = consumePositionComponent(range, parserMode, unitless, allowsNegative);
     if (!value1)
         return std::nullopt;
 
-    auto value2 = consumePositionComponent(range, parserMode, unitless);
+    auto value2 = consumePositionComponent(range, parserMode, unitless, allowsNegative);
     if (!value2)
         return positionFromOneValue(*value1);
     
-    auto value3 = consumePositionComponent(range, parserMode, unitless);
+    auto value3 = consumePositionComponent(range, parserMode, unitless, allowsNegative);
     if (!value3)
         return positionFromTwoValues(*value1, *value2);
     
-    auto value4 = consumePositionComponent(range, parserMode, unitless);
+    auto value4 = consumePositionComponent(range, parserMode, unitless, allowsNegative);
     
     std::array<CSSPrimitiveValue*, 5> values {
         value1.get(),

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h (286896 => 286897)


--- trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h	2021-12-11 02:32:03 UTC (rev 286896)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParserHelpers.h	2021-12-11 02:45:31 UTC (rev 286897)
@@ -61,6 +61,8 @@
 // consumeFunction expects the range starts with a FunctionToken.
 CSSParserTokenRange consumeFunction(CSSParserTokenRange&);
 
+enum class NegativePercentagePolicy : bool { Forbid, Allow };
+
 enum class UnitlessQuirk { Allow, Forbid };
 enum class UnitlessZeroQuirk { Allow, Forbid };
 
@@ -92,7 +94,7 @@
 RefPtr<CSSPrimitiveValue> consumePercent(CSSParserTokenRange&, ValueRange);
 RefPtr<CSSPrimitiveValue> consumePercentWorkerSafe(CSSParserTokenRange&, ValueRange, CSSValuePool&);
 std::optional<LengthOrPercentRaw> consumeLengthOrPercentRaw(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
-RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid);
+RefPtr<CSSPrimitiveValue> consumeLengthOrPercent(CSSParserTokenRange&, CSSParserMode, ValueRange, UnitlessQuirk = UnitlessQuirk::Forbid, bool allowsNegativePercentage = false);
 std::optional<AngleRaw> consumeAngleRaw(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid, UnitlessZeroQuirk = UnitlessZeroQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeAngle(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk = UnitlessQuirk::Forbid, UnitlessZeroQuirk = UnitlessZeroQuirk::Forbid);
 RefPtr<CSSPrimitiveValue> consumeAngleWorkerSafe(CSSParserTokenRange&, CSSParserMode, CSSValuePool&, UnitlessQuirk = UnitlessQuirk::Forbid, UnitlessZeroQuirk = UnitlessZeroQuirk::Forbid);
@@ -130,7 +132,7 @@
 
 RefPtr<CSSPrimitiveValue> consumePosition(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax);
 RefPtr<CSSPrimitiveValue> consumeSingleAxisPosition(CSSParserTokenRange&, CSSParserMode, BoxOrient);
-std::optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax);
+std::optional<PositionCoordinates> consumePositionCoordinates(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk, PositionSyntax, NegativePercentagePolicy = NegativePercentagePolicy::Forbid);
 std::optional<PositionCoordinates> consumeOneOrTwoValuedPositionCoordinates(CSSParserTokenRange&, CSSParserMode, UnitlessQuirk);
 
 enum class AllowedImageType : uint8_t {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to