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 {