Skip to content

Commit

Permalink
[anchor-position] Implement anchor functions as tree-scoped CSS values
Browse files Browse the repository at this point in the history
This patch is a follow up and also the major motivation of the
previous patch crrev.com/c/4167268.

It not only rewrites the existing support without ScopedCSSValue,
but also enables CSS transitions with such values, and in particular,
transitions that involve more than onre tree scopes, which is
impossible to support with ScopedCSSValue.

Bug: 1395026
Change-Id: Id5d99024384e0b9d6ab438ae04c3bb36e18b83d9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4185495
Reviewed-by: Anders Hartvoll Ruud <andruud@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1096559}
  • Loading branch information
xiaochengh authored and Chromium LUCI CQ committed Jan 25, 2023
1 parent 264e7d5 commit d9638f2
Show file tree
Hide file tree
Showing 14 changed files with 333 additions and 90 deletions.
6 changes: 0 additions & 6 deletions third_party/blink/renderer/core/css/css_length_resolver.h
Expand Up @@ -15,8 +15,6 @@

namespace blink {

class TreeScope;

class CORE_EXPORT CSSLengthResolver {
public:
explicit CSSLengthResolver(float zoom) : zoom_(zoom) {}
Expand Down Expand Up @@ -49,10 +47,6 @@ class CORE_EXPORT CSSLengthResolver {

virtual WritingMode GetWritingMode() const = 0;

// Some length functions (anchor() and anchor-size()) contain tree-scoped
// name references. Returns that tree scope.
virtual const TreeScope* GetTreeScope() const { return nullptr; }

float Zoom() const { return zoom_; }
void SetZoom(float zoom) {
DCHECK(std::isfinite(zoom));
Expand Down
61 changes: 52 additions & 9 deletions third_party/blink/renderer/core/css/css_math_expression_node.cc
Expand Up @@ -234,7 +234,8 @@ CSSMathExpressionNumericLiteral* CSSMathExpressionNumericLiteral::Create(
CSSMathExpressionNumericLiteral::CSSMathExpressionNumericLiteral(
const CSSNumericLiteralValue* value)
: CSSMathExpressionNode(UnitCategory(value->GetType()),
false /* has_comparisons*/),
false /* has_comparisons*/,
false /* needs_tree_scope_population*/),
value_(value) {}

bool CSSMathExpressionNumericLiteral::IsZero() const {
Expand Down Expand Up @@ -704,7 +705,8 @@ CSSMathExpressionOperation::CSSMathExpressionOperation(
CalculationCategory category)
: CSSMathExpressionNode(
category,
left_side->HasComparisons() || right_side->HasComparisons()),
left_side->HasComparisons() || right_side->HasComparisons(),
!left_side->IsScopedValue() || !right_side->IsScopedValue()),
operands_({left_side, right_side}),
operator_(op) {}

Expand All @@ -718,13 +720,24 @@ static bool AnyOperandHasComparisons(
return false;
}

static bool AnyOperandNeedsTreeScopePopulation(
CSSMathExpressionOperation::Operands& operands) {
for (const CSSMathExpressionNode* operand : operands) {
if (!operand->IsScopedValue()) {
return true;
}
}
return false;
}

CSSMathExpressionOperation::CSSMathExpressionOperation(
CalculationCategory category,
Operands&& operands,
CSSMathOperator op)
: CSSMathExpressionNode(
category,
IsComparison(op) || AnyOperandHasComparisons(operands)),
IsComparison(op) || AnyOperandHasComparisons(operands),
AnyOperandNeedsTreeScopePopulation(operands)),
operands_(std::move(operands)),
operator_(op) {}

Expand Down Expand Up @@ -1196,6 +1209,16 @@ double CSSMathExpressionOperation::EvaluateOperator(
return 0;
}

const CSSMathExpressionNode& CSSMathExpressionOperation::PopulateWithTreeScope(
const TreeScope* tree_scope) const {
Operands populated_operands;
for (const CSSMathExpressionNode* op : operands_) {
populated_operands.push_back(&op->EnsureScopedValue(tree_scope));
}
return *MakeGarbageCollected<CSSMathExpressionOperation>(
Category(), std::move(populated_operands), operator_);
}

#if DCHECK_IS_ON()
bool CSSMathExpressionOperation::InvolvesPercentageComparisons() const {
if (IsMinOrMax() && Category() == kCalcPercent && operands_.size() > 1u) {
Expand All @@ -1219,7 +1242,10 @@ CSSMathExpressionAnchorQuery::CSSMathExpressionAnchorQuery(
const CSSCustomIdentValue* anchor_name,
const CSSValue& value,
const CSSPrimitiveValue* fallback)
: CSSMathExpressionNode(kCalcPercentLength, false /* has_comparisons */),
: CSSMathExpressionNode(kCalcPercentLength,
false /* has_comparisons */,
(anchor_name && !anchor_name->IsScopedValue()) ||
(fallback && !fallback->IsScopedValue())),
type_(type),
anchor_name_(anchor_name),
value_(value),
Expand Down Expand Up @@ -1306,9 +1332,10 @@ AnchorSizeValue CSSValueIDToAnchorSizeValueEnum(CSSValueID value) {
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionAnchorQuery::ToCalculationExpression(
const CSSLengthResolver& length_resolver) const {
DCHECK(IsScopedValue());
ScopedCSSName* anchor_name =
anchor_name_ ? MakeGarbageCollected<ScopedCSSName>(
anchor_name_->Value(), length_resolver.GetTreeScope())
anchor_name_->Value(), anchor_name_->GetTreeScope())
: nullptr;
Length fallback = fallback_ ? fallback_->ConvertToLength(length_resolver)
: Length::Fixed(0);
Expand All @@ -1332,6 +1359,20 @@ CSSMathExpressionAnchorQuery::ToCalculationExpression(
fallback);
}

const CSSMathExpressionNode&
CSSMathExpressionAnchorQuery::PopulateWithTreeScope(
const TreeScope* tree_scope) const {
return *MakeGarbageCollected<CSSMathExpressionAnchorQuery>(
type_,
anchor_name_ ? To<CSSCustomIdentValue>(
&anchor_name_->EnsureScopedValue(tree_scope))
: nullptr,
*value_,
fallback_
? To<CSSPrimitiveValue>(&fallback_->EnsureScopedValue(tree_scope))
: nullptr);
}

void CSSMathExpressionAnchorQuery::Trace(Visitor* visitor) const {
visitor->Trace(anchor_name_);
visitor->Trace(value_);
Expand Down Expand Up @@ -1825,10 +1866,12 @@ CSSMathExpressionNode* CSSMathExpressionNode::Create(
CSSAnchorQueryType type = anchor_query.Type() == AnchorQueryType::kAnchor
? CSSAnchorQueryType::kAnchor
: CSSAnchorQueryType::kAnchorSize;
CSSCustomIdentValue* anchor_name =
anchor_query.AnchorName() ? MakeGarbageCollected<CSSCustomIdentValue>(
anchor_query.AnchorName()->GetName())
: nullptr;
const CSSCustomIdentValue* anchor_name = nullptr;
if (const ScopedCSSName* passed_name = anchor_query.AnchorName()) {
anchor_name = To<CSSCustomIdentValue>(
&MakeGarbageCollected<CSSCustomIdentValue>(passed_name->GetName())
->EnsureScopedValue(passed_name->GetTreeScope()));
}
CSSValue* value = AnchorQueryValueToCSSValue(anchor_query);
CSSPrimitiveValue* fallback = CSSPrimitiveValue::CreateFromLength(
anchor_query.GetFallback(), /* zoom */ 1);
Expand Down
30 changes: 28 additions & 2 deletions third_party/blink/renderer/core/css/css_math_expression_node.h
Expand Up @@ -141,6 +141,17 @@ class CORE_EXPORT CSSMathExpressionNode
void SetIsNestedCalc() { is_nested_calc_ = true; }

bool HasComparisons() const { return has_comparisons_; }
bool IsScopedValue() const { return !needs_tree_scope_population_; }

const CSSMathExpressionNode& EnsureScopedValue(
const TreeScope* tree_scope) const {
if (!needs_tree_scope_population_) {
return *this;
}
return PopulateWithTreeScope(tree_scope);
}
virtual const CSSMathExpressionNode& PopulateWithTreeScope(
const TreeScope*) const = 0;

#if DCHECK_IS_ON()
// There's a subtle issue in comparing two percentages, e.g., min(10%, 20%).
Expand All @@ -153,14 +164,19 @@ class CORE_EXPORT CSSMathExpressionNode
virtual void Trace(Visitor* visitor) const {}

protected:
CSSMathExpressionNode(CalculationCategory category, bool has_comparisons)
: category_(category), has_comparisons_(has_comparisons) {
CSSMathExpressionNode(CalculationCategory category,
bool has_comparisons,
bool needs_tree_scope_population)
: category_(category),
has_comparisons_(has_comparisons),
needs_tree_scope_population_(needs_tree_scope_population) {
DCHECK_NE(category, kCalcOther);
}

CalculationCategory category_;
bool is_nested_calc_ = false;
bool has_comparisons_;
bool needs_tree_scope_population_;
};

class CORE_EXPORT CSSMathExpressionNumericLiteral final
Expand All @@ -178,6 +194,12 @@ class CORE_EXPORT CSSMathExpressionNumericLiteral final

bool IsNumericLiteral() const final { return true; }

const CSSMathExpressionNode& PopulateWithTreeScope(
const TreeScope* tree_scope) const final {
NOTREACHED();
return *this;
}

bool IsZero() const final;
String CustomCSSText() const final;
scoped_refptr<const CalculationExpressionNode> ToCalculationExpression(
Expand Down Expand Up @@ -273,6 +295,8 @@ class CORE_EXPORT CSSMathExpressionOperation final
String CustomCSSText() const final;
bool operator==(const CSSMathExpressionNode& exp) const final;
CSSPrimitiveValue::UnitType ResolvedUnitType() const final;
const CSSMathExpressionNode& PopulateWithTreeScope(
const TreeScope*) const final;
void Trace(Visitor* visitor) const final;

#if DCHECK_IS_ON()
Expand Down Expand Up @@ -365,6 +389,8 @@ class CORE_EXPORT CSSMathExpressionAnchorQuery final
scoped_refptr<const CalculationExpressionNode> ToCalculationExpression(
const CSSLengthResolver&) const final;
bool operator==(const CSSMathExpressionNode& other) const final;
const CSSMathExpressionNode& PopulateWithTreeScope(
const TreeScope*) const final;
void Trace(Visitor* visitor) const final;

#if DCHECK_IS_ON()
Expand Down
11 changes: 10 additions & 1 deletion third_party/blink/renderer/core/css/css_math_function_value.cc
Expand Up @@ -29,7 +29,9 @@ CSSMathFunctionValue::CSSMathFunctionValue(
CSSPrimitiveValue::ValueRange range)
: CSSPrimitiveValue(kMathFunctionClass),
expression_(expression),
value_range_in_target_context_(range) {}
value_range_in_target_context_(range) {
needs_tree_scope_population_ = !expression->IsScopedValue();
}

// static
CSSMathFunctionValue* CSSMathFunctionValue::Create(
Expand Down Expand Up @@ -166,4 +168,11 @@ scoped_refptr<const CalculationValue> CSSMathFunctionValue::ToCalcValue(
AllowsNegativePercentageReference());
}

const CSSValue& CSSMathFunctionValue::PopulateWithTreeScope(
const TreeScope* tree_scope) const {
return *MakeGarbageCollected<CSSMathFunctionValue>(
&expression_->PopulateWithTreeScope(tree_scope),
value_range_in_target_context_);
}

} // namespace blink
2 changes: 2 additions & 0 deletions third_party/blink/renderer/core/css/css_math_function_value.h
Expand Up @@ -87,6 +87,8 @@ class CORE_EXPORT CSSMathFunctionValue : public CSSPrimitiveValue {

bool HasComparisons() const { return expression_->HasComparisons(); }

const CSSValue& PopulateWithTreeScope(const TreeScope*) const;

void TraceAfterDispatch(blink::Visitor* visitor) const;

private:
Expand Down
10 changes: 0 additions & 10 deletions third_party/blink/renderer/core/css/css_properties.json5
Expand Up @@ -2293,7 +2293,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "box-shadow",
Expand Down Expand Up @@ -3008,7 +3007,6 @@
supports_incremental_style: true,
valid_for_formatted_text: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "hyphenate-limit-chars",
Expand Down Expand Up @@ -3132,7 +3130,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "letter-spacing",
Expand Down Expand Up @@ -3400,7 +3397,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "max-width",
Expand All @@ -3418,7 +3414,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "min-height",
Expand All @@ -3435,7 +3430,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "min-width",
Expand All @@ -3452,7 +3446,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "mix-blend-mode",
Expand Down Expand Up @@ -4055,7 +4048,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "r",
Expand Down Expand Up @@ -4977,7 +4969,6 @@
},
supports_incremental_style: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "touch-action",
Expand Down Expand Up @@ -5901,7 +5892,6 @@
supports_incremental_style: true,
valid_for_formatted_text: true,
valid_for_position_fallback: true,
tree_scoped_value: true,
},
{
name: "will-change",
Expand Down
Expand Up @@ -300,20 +300,6 @@ class CORE_EXPORT CSSToLengthConversionData : public CSSLengthResolver {
mutable Flags* flags_ = nullptr;
};

class ScopedCSSToLengthConversionData : public CSSToLengthConversionData {
STACK_ALLOCATED();

public:
ScopedCSSToLengthConversionData(const CSSToLengthConversionData& data,
const TreeScope* scope)
: CSSToLengthConversionData(data), tree_scope_(scope) {}

const TreeScope* GetTreeScope() const override { return tree_scope_; }

private:
const TreeScope* tree_scope_;
};

} // namespace blink

#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_TO_LENGTH_CONVERSION_DATA_H_
2 changes: 2 additions & 0 deletions third_party/blink/renderer/core/css/css_value.cc
Expand Up @@ -464,6 +464,8 @@ const CSSValue& CSSValue::PopulateWithTreeScope(
switch (GetClassType()) {
case kCustomIdentClass:
return To<CSSCustomIdentValue>(this)->PopulateWithTreeScope(tree_scope);
case kMathFunctionClass:
return To<CSSMathFunctionValue>(this)->PopulateWithTreeScope(tree_scope);
default:
NOTREACHED();
return *this;
Expand Down

0 comments on commit d9638f2

Please sign in to comment.