#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/css/css_math_expression_node.h"
#include <algorithm>
#include <cfloat>
#include <numeric>
#include <tuple>
#include "base/memory/values_equivalent.h"
#include "third_party/blink/renderer/core/css/css_custom_ident_value.h"
#include "third_party/blink/renderer/core/css/css_math_function_value.h"
#include "third_party/blink/renderer/core/css/css_math_operator.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/css_value_clamping_utils.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/try_tactic_transform.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/style/anchor_specifier_value.h"
#include "third_party/blink/renderer/platform/geometry/calculation_expression_node.h"
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/geometry/math_functions.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
#include "ui/gfx/geometry/sin_cos_degrees.h"
namespace blink {
static CalculationResultCategory UnitCategory(
CSSPrimitiveValue::UnitType type) { … }
CSSMathOperator CSSValueIDToCSSMathOperator(CSSValueID id) { … }
static bool HasDoubleValue(CSSPrimitiveValue::UnitType type) { … }
namespace {
double TanDegrees(double degrees) { … }
const PixelsAndPercent CreateClampedSamePixelsAndPercent(float value) { … }
bool IsNaN(PixelsAndPercent value, bool allows_negative_percentage_reference) { … }
std::optional<PixelsAndPercent> EvaluateValueIfNaNorInfinity(
scoped_refptr<const blink::CalculationExpressionNode> value,
bool allows_negative_percentage_reference) { … }
bool IsAllowedMediaFeature(const CSSValueID& id) { … }
bool IsAllowedContainerFeature(const CSSValueID& id) { … }
bool CheckProgressFunctionTypes(
CSSValueID function_id,
const CSSMathExpressionOperation::Operands& nodes) { … }
bool CanEagerlySimplify(const CSSMathExpressionNode* operand) { … }
bool CanEagerlySimplify(const CSSMathExpressionOperation::Operands& operands) { … }
enum class ProgressArgsSimplificationStatus { … };
ProgressArgsSimplificationStatus CanEagerlySimplifyProgressArgs(
const CSSMathExpressionOperation::Operands& operands) { … }
UnitsHashMap;
struct CSSMathExpressionNodeWithOperator { … };
UnitsVector;
UnitsVectorHashMap;
bool IsNumericNodeWithDoubleValue(const CSSMathExpressionNode* node) { … }
const CSSMathExpressionNode* MaybeNegateFirstNode(
CSSMathOperator op,
const CSSMathExpressionNode* node) { … }
CSSMathOperator MaybeChangeOperatorSignIfNesting(bool is_in_nesting,
CSSMathOperator outer_op,
CSSMathOperator current_op) { … }
CSSMathExpressionNodeWithOperator MaybeReplaceNodeWithCombined(
const CSSMathExpressionNode* node,
CSSMathOperator op,
const UnitsHashMap& units_map) { … }
void CombineNumericChildrenFromNode(const CSSMathExpressionNode* root,
CSSMathOperator op,
UnitsHashMap& numeric_children,
UnitsVector& all_children,
bool is_in_nesting = false) { … }
void CollectNumericChildrenFromNode(const CSSMathExpressionNode* root,
CSSMathOperator op,
UnitsVectorHashMap& numeric_children,
UnitsVector& complex_children,
bool is_in_nesting = false) { … }
CSSMathExpressionNode* AddNodeToSumNode(CSSMathExpressionNode* sum_node,
const CSSMathExpressionNode* node,
CSSMathOperator op) { … }
CSSMathExpressionNode* AddNodesVectorToSumNode(CSSMathExpressionNode* sum_node,
const UnitsVector& vector) { … }
CSSMathExpressionNode* MaybeSortSumNode(
const CSSMathExpressionOperation* root) { … }
CSSMathExpressionNode* MaybeSimplifySumNode(
const CSSMathExpressionOperation* root) { … }
CSSMathExpressionNode* MaybeDistributeArithmeticOperation(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side,
CSSMathOperator op) { … }
}
CSSMathExpressionNumericLiteral* CSSMathExpressionNumericLiteral::Create(
const CSSNumericLiteralValue* value) { … }
CSSMathExpressionNumericLiteral* CSSMathExpressionNumericLiteral::Create(
double value,
CSSPrimitiveValue::UnitType type) { … }
CSSMathExpressionNumericLiteral::CSSMathExpressionNumericLiteral(
const CSSNumericLiteralValue* value)
: … { … }
CSSPrimitiveValue::BoolStatus CSSMathExpressionNumericLiteral::ResolvesTo(
double value) const { … }
CSSPrimitiveValue::BoolStatus CSSMathExpressionNumericLiteral::IsNegative()
const { … }
String CSSMathExpressionNumericLiteral::CustomCSSText() const { … }
std::optional<PixelsAndPercent>
CSSMathExpressionNumericLiteral::ToPixelsAndPercent(
const CSSLengthResolver& length_resolver) const { … }
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionNumericLiteral::ToCalculationExpression(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionNumericLiteral::DoubleValue() const { … }
std::optional<double>
CSSMathExpressionNumericLiteral::ComputeValueInCanonicalUnit() const { … }
std::optional<double>
CSSMathExpressionNumericLiteral::ComputeValueInCanonicalUnit(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionNumericLiteral::ComputeDouble(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionNumericLiteral::ComputeLengthPx(
const CSSLengthResolver& length_resolver) const { … }
bool CSSMathExpressionNumericLiteral::AccumulateLengthArray(
CSSLengthArray& length_array,
double multiplier) const { … }
void CSSMathExpressionNumericLiteral::AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const { … }
bool CSSMathExpressionNumericLiteral::operator==(
const CSSMathExpressionNode& other) const { … }
CSSPrimitiveValue::UnitType CSSMathExpressionNumericLiteral::ResolvedUnitType()
const { … }
bool CSSMathExpressionNumericLiteral::IsComputationallyIndependent() const { … }
void CSSMathExpressionNumericLiteral::Trace(Visitor* visitor) const { … }
#if DCHECK_IS_ON()
bool CSSMathExpressionNumericLiteral::InvolvesPercentageComparisons() const { … }
#endif
static const CalculationResultCategory
kAddSubtractResult[kCalcOther][kCalcOther] = …;
static CalculationResultCategory DetermineCategory(
const CSSMathExpressionNode& left_side,
const CSSMathExpressionNode& right_side,
CSSMathOperator op) { … }
static CalculationResultCategory DetermineComparisonCategory(
const CSSMathExpressionOperation::Operands& operands) { … }
static CalculationResultCategory DetermineCalcSizeCategory(
const CSSMathExpressionNode& left_side,
const CSSMathExpressionNode& right_side,
CSSMathOperator op) { … }
CSSMathExpressionIdentifierLiteral::CSSMathExpressionIdentifierLiteral(
AtomicString identifier)
: … { … }
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionIdentifierLiteral::ToCalculationExpression(
const CSSLengthResolver&) const { … }
namespace {
CalculationExpressionSizingKeywordNode::Keyword CSSValueIDToSizingKeyword(
CSSValueID keyword) { … }
CSSValueID SizingKeywordToCSSValueID(
CalculationExpressionSizingKeywordNode::Keyword keyword) { … }
CalculationResultCategory DetermineKeywordCategory(
CSSValueID keyword,
CSSMathExpressionKeywordLiteral::Context context) { … }
}
CSSMathExpressionKeywordLiteral::CSSMathExpressionKeywordLiteral(
CSSValueID keyword,
Context context)
: … { … }
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionKeywordLiteral::ToCalculationExpression(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionKeywordLiteral::ComputeDouble(
const CSSLengthResolver& length_resolver) const { … }
std::optional<PixelsAndPercent>
CSSMathExpressionKeywordLiteral::ToPixelsAndPercent(
const CSSLengthResolver& length_resolver) const { … }
bool CSSMathExpressionOperation::AllOperandsAreNumeric() const { … }
CSSMathExpressionNode* CSSMathExpressionOperation::CreateArithmeticOperation(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side,
CSSMathOperator op) { … }
CSSMathExpressionNode* CSSMathExpressionOperation::CreateCalcSizeOperation(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side) { … }
CSSMathExpressionNode* CSSMathExpressionOperation::CreateComparisonFunction(
Operands&& operands,
CSSMathOperator op) { … }
CSSMathExpressionNode*
CSSMathExpressionOperation::CreateComparisonFunctionSimplified(
Operands&& operands,
CSSMathOperator op) { … }
static double ValueAsNumber(const CSSMathExpressionNode* node, bool& error) { … }
static bool SupportedCategoryForAtan2(
const CalculationResultCategory category) { … }
static bool IsRelativeLength(CSSPrimitiveValue::UnitType type) { … }
static double ResolveAtan2(const CSSMathExpressionNode* y_node,
const CSSMathExpressionNode* x_node,
bool& error) { … }
static double ValueAsDegrees(const CSSMathExpressionNode* node, bool& error) { … }
static bool CanonicalizeRoundArguments(
CSSMathExpressionOperation::Operands& nodes) { … }
static bool ShouldSerializeRoundingStep(
const CSSMathExpressionOperation::Operands& operands) { … }
CSSMathExpressionNode*
CSSMathExpressionOperation::CreateTrigonometricFunctionSimplified(
Operands&& operands,
CSSValueID function_id) { … }
CSSMathExpressionNode* CSSMathExpressionOperation::CreateSteppedValueFunction(
Operands&& operands,
CSSMathOperator op) { … }
CSSMathExpressionNode* CSSMathExpressionOperation::CreateExponentialFunction(
Operands&& operands,
CSSValueID function_id) { … }
CSSMathExpressionNode* CSSMathExpressionOperation::CreateSignRelatedFunction(
Operands&& operands,
CSSValueID function_id) { … }
namespace {
inline const CSSMathExpressionOperation* DynamicToCalcSize(
const CSSMathExpressionNode* node) { … }
inline bool CanArithmeticOperationBeSimplified(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side) { … }
}
CSSMathExpressionNode*
CSSMathExpressionOperation::CreateArithmeticOperationSimplified(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side,
CSSMathOperator op) { … }
namespace {
std::tuple<const CSSMathExpressionNode*, wtf_size_t> SubstituteForSizeKeyword(
const CSSMathExpressionNode* source,
const CSSMathExpressionNode* size_substitution,
wtf_size_t count_in_substitution) { … }
const CSSMathExpressionNode* SubstituteForPercentages(
const CSSMathExpressionNode* source) { … }
bool BasisIsCanonical(const CSSMathExpressionNode* basis) { … }
const CSSMathExpressionOperation* MakeBasisCanonical(
const CSSMathExpressionOperation* calc_size_input) { … }
}
CSSMathExpressionNode*
CSSMathExpressionOperation::CreateArithmeticOperationAndSimplifyCalcSize(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side,
CSSMathOperator op) { … }
CSSMathExpressionOperation::CSSMathExpressionOperation(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side,
CSSMathOperator op,
CalculationResultCategory category)
: … { … }
bool CSSMathExpressionOperation::HasPercentage() const { … }
bool CSSMathExpressionOperation::InvolvesLayout() const { … }
static bool AnyOperandHasComparisons(
CSSMathExpressionOperation::Operands& operands) { … }
static bool AnyOperandHasAnchorFunctions(
CSSMathExpressionOperation::Operands& operands) { … }
static bool AnyOperandNeedsTreeScopePopulation(
CSSMathExpressionOperation::Operands& operands) { … }
CSSMathExpressionOperation::CSSMathExpressionOperation(
CalculationResultCategory category,
Operands&& operands,
CSSMathOperator op)
: … { … }
CSSMathExpressionOperation::CSSMathExpressionOperation(
CalculationResultCategory category,
CSSMathOperator op)
: … { … }
CSSPrimitiveValue::BoolStatus CSSMathExpressionOperation::ResolvesTo(
double value) const { … }
CSSPrimitiveValue::BoolStatus CSSMathExpressionOperation::IsNegative() const { … }
std::optional<PixelsAndPercent> CSSMathExpressionOperation::ToPixelsAndPercent(
const CSSLengthResolver& length_resolver) const { … }
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionOperation::ToCalculationExpression(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionOperation::DoubleValue() const { … }
static bool HasCanonicalUnit(CalculationResultCategory category) { … }
std::optional<double> CSSMathExpressionOperation::ComputeValueInCanonicalUnit()
const { … }
std::optional<double> CSSMathExpressionOperation::ComputeValueInCanonicalUnit(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionOperation::ComputeDouble(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionOperation::ComputeLengthPx(
const CSSLengthResolver& length_resolver) const { … }
bool CSSMathExpressionOperation::AccumulateLengthArray(
CSSLengthArray& length_array,
double multiplier) const { … }
void CSSMathExpressionOperation::AccumulateLengthUnitTypes(
CSSPrimitiveValue::LengthTypeFlags& types) const { … }
bool CSSMathExpressionOperation::IsComputationallyIndependent() const { … }
String CSSMathExpressionOperation::CustomCSSText() const { … }
bool CSSMathExpressionOperation::operator==(
const CSSMathExpressionNode& exp) const { … }
CSSPrimitiveValue::UnitType CSSMathExpressionOperation::ResolvedUnitType()
const { … }
void CSSMathExpressionOperation::Trace(Visitor* visitor) const { … }
const CSSMathExpressionNode* CSSMathExpressionOperation::GetNumericLiteralSide(
const CSSMathExpressionNode* left_side,
const CSSMathExpressionNode* right_side) { … }
double CSSMathExpressionOperation::EvaluateOperator(
const Vector<double>& operands,
CSSMathOperator op) { … }
const CSSMathExpressionNode& CSSMathExpressionOperation::PopulateWithTreeScope(
const TreeScope* tree_scope) const { … }
const CSSMathExpressionNode* CSSMathExpressionOperation::TransformAnchors(
LogicalAxis logical_axis,
const TryTacticTransform& transform,
const WritingDirectionMode& writing_direction) const { … }
bool CSSMathExpressionOperation::HasInvalidAnchorFunctions(
const CSSLengthResolver& length_resolver) const { … }
#if DCHECK_IS_ON()
bool CSSMathExpressionOperation::InvolvesPercentageComparisons() const { … }
#endif
namespace {
double EvaluateContainerSize(const CSSIdentifierValue* size_feature,
const CSSCustomIdentValue* container_name,
const CSSLengthResolver& length_resolver) { … }
}
CSSMathExpressionContainerFeature::CSSMathExpressionContainerFeature(
const CSSIdentifierValue* size_feature,
const CSSCustomIdentValue* container_name)
: … { … }
String CSSMathExpressionContainerFeature::CustomCSSText() const { … }
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionContainerFeature::ToCalculationExpression(
const CSSLengthResolver& length_resolver) const { … }
std::optional<PixelsAndPercent>
CSSMathExpressionContainerFeature::ToPixelsAndPercent(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionContainerFeature::ComputeDouble(
const CSSLengthResolver& length_resolver) const { … }
namespace {
CalculationResultCategory AnchorQueryCategory(
const CSSPrimitiveValue* fallback) { … }
}
CSSMathExpressionAnchorQuery::CSSMathExpressionAnchorQuery(
CSSAnchorQueryType type,
const CSSValue* anchor_specifier,
const CSSValue* value,
const CSSPrimitiveValue* fallback)
: … { … }
double CSSMathExpressionAnchorQuery::DoubleValue() const { … }
double CSSMathExpressionAnchorQuery::ComputeLengthPx(
const CSSLengthResolver& length_resolver) const { … }
double CSSMathExpressionAnchorQuery::ComputeDouble(
const CSSLengthResolver& length_resolver) const { … }
String CSSMathExpressionAnchorQuery::CustomCSSText() const { … }
bool CSSMathExpressionAnchorQuery::operator==(
const CSSMathExpressionNode& other) const { … }
namespace {
CSSAnchorValue CSSValueIDToAnchorValueEnum(CSSValueID value) { … }
CSSAnchorSizeValue CSSValueIDToAnchorSizeValueEnum(CSSValueID value) { … }
}
scoped_refptr<const CalculationExpressionNode>
CSSMathExpressionAnchorQuery::ToCalculationExpression(
const CSSLengthResolver& length_resolver) const { … }
std::optional<LayoutUnit> CSSMathExpressionAnchorQuery::EvaluateQuery(
const AnchorQuery& query,
const CSSLengthResolver& length_resolver) const { … }
AnchorQuery CSSMathExpressionAnchorQuery::ToQuery(
const CSSLengthResolver& length_resolver) const { … }
const CSSMathExpressionNode&
CSSMathExpressionAnchorQuery::PopulateWithTreeScope(
const TreeScope* tree_scope) const { … }
namespace {
bool FlipLogical(LogicalAxis logical_axis,
const TryTacticTransform& transform) { … }
CSSValueID TransformAnchorCSSValueID(
CSSValueID from,
LogicalAxis logical_axis,
const TryTacticTransform& transform,
const WritingDirectionMode& writing_direction) { … }
float TransformAnchorPercentage(float from,
LogicalAxis logical_axis,
const TryTacticTransform& transform) { … }
}
const CSSMathExpressionNode* CSSMathExpressionAnchorQuery::TransformAnchors(
LogicalAxis logical_axis,
const TryTacticTransform& transform,
const WritingDirectionMode& writing_direction) const { … }
bool CSSMathExpressionAnchorQuery::HasInvalidAnchorFunctions(
const CSSLengthResolver& length_resolver) const { … }
void CSSMathExpressionAnchorQuery::Trace(Visitor* visitor) const { … }
class CSSMathExpressionNodeParser { … };
scoped_refptr<const CalculationValue> CSSMathExpressionNode::ToCalcValue(
const CSSLengthResolver& length_resolver,
Length::ValueRange range,
bool allows_negative_percentage_reference) const { … }
CSSMathExpressionNode* CSSMathExpressionNode::Create(
const CalculationValue& calc) { … }
CSSMathExpressionNode* CSSMathExpressionNode::Create(PixelsAndPercent value) { … }
CSSMathExpressionNode* CSSMathExpressionNode::Create(
const CalculationExpressionNode& node) { … }
CSSMathExpressionNode* CSSMathExpressionNode::ParseMathFunction(
CSSValueID function_id,
CSSParserTokenRange tokens,
const CSSParserContext& context,
const Flags parsing_flags,
CSSAnchorQueryTypes allowed_anchor_queries,
const CSSColorChannelMap& color_channel_map) { … }
}
WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(…)