Bug 1942715: Part 3 - Remove old & now-unused anchor resolution infrastructure in CalcNode. r=firefox-style-system-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D237096
This commit is contained in:
@@ -91,9 +91,7 @@ impl<ValueType: ColorComponentType> ColorComponent<ValueType> {
|
||||
} else {
|
||||
ValueType::units()
|
||||
});
|
||||
let node = GenericCalcNode::parse(context, input, function, allow)?;
|
||||
debug_assert!(!node.has_anchor_function, "Anchor function used for color?");
|
||||
let mut node = node.node;
|
||||
let mut node = GenericCalcNode::parse(context, input, function, allow)?;
|
||||
|
||||
// TODO(tlouw): We only have to simplify the node when we have to store it, but we
|
||||
// only know if we have to store it much later when the whole color
|
||||
|
||||
@@ -30,10 +30,7 @@ use crate::gecko_bindings::structs::GeckoFontMetrics;
|
||||
use crate::logical_geometry::PhysicalSide;
|
||||
use crate::values::animated::{Animate, Context as AnimatedContext, Procedure, ToAnimatedValue, ToAnimatedZero};
|
||||
use crate::values::distance::{ComputeSquaredDistance, SquaredDistance};
|
||||
use crate::values::generics::calc::{
|
||||
AnchorPositioningResolver, CalcUnits, GenericCalcAnchorFunction, GenericCalcAnchorSizeFunction,
|
||||
PositivePercentageBasis,
|
||||
};
|
||||
use crate::values::generics::calc::{CalcUnits, PositivePercentageBasis};
|
||||
use crate::values::generics::length::AnchorResolutionResult;
|
||||
use crate::values::generics::{calc, NonNegative};
|
||||
use crate::values::resolved::{Context as ResolvedContext, ToResolvedValue};
|
||||
@@ -231,12 +228,6 @@ enum Serializable {
|
||||
Percentage(Percentage),
|
||||
}
|
||||
|
||||
impl From<CalcLengthPercentage> for LengthPercentage {
|
||||
fn from(value: CalcLengthPercentage) -> Self {
|
||||
Self::new_calc(value.node, value.clamping_mode, value.has_anchor_function)
|
||||
}
|
||||
}
|
||||
|
||||
impl LengthPercentage {
|
||||
/// 1px length value for SVG defaults
|
||||
#[inline]
|
||||
@@ -250,14 +241,11 @@ impl LengthPercentage {
|
||||
Self::new_percent(Percentage::zero())
|
||||
}
|
||||
|
||||
fn to_calc_node(&self) -> (CalcNode, bool) {
|
||||
fn to_calc_node(&self) -> CalcNode {
|
||||
match self.unpack() {
|
||||
Unpacked::Length(l) => (CalcNode::Leaf(CalcLengthPercentageLeaf::Length(l)), false),
|
||||
Unpacked::Percentage(p) => (
|
||||
CalcNode::Leaf(CalcLengthPercentageLeaf::Percentage(p)),
|
||||
false,
|
||||
),
|
||||
Unpacked::Calc(p) => (p.node.clone(), p.has_anchor_function),
|
||||
Unpacked::Length(l) => CalcNode::Leaf(CalcLengthPercentageLeaf::Length(l)),
|
||||
Unpacked::Percentage(p) => CalcNode::Leaf(CalcLengthPercentageLeaf::Percentage(p)),
|
||||
Unpacked::Calc(p) => p.node.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,9 +255,10 @@ impl LengthPercentage {
|
||||
Unpacked::Percentage(p) => Self::new_percent(p),
|
||||
Unpacked::Calc(lp) => Self::new_calc_unchecked(Box::new(CalcLengthPercentage {
|
||||
clamping_mode: lp.clamping_mode,
|
||||
has_anchor_function: lp.has_anchor_function,
|
||||
node: lp.node.map_leaves(|leaf| match *leaf {
|
||||
CalcLengthPercentageLeaf::Length(ref l) => CalcLengthPercentageLeaf::Length(map_fn(*l)),
|
||||
CalcLengthPercentageLeaf::Length(ref l) => {
|
||||
CalcLengthPercentageLeaf::Length(map_fn(*l))
|
||||
},
|
||||
ref l => l.clone(),
|
||||
}),
|
||||
})),
|
||||
@@ -307,7 +296,7 @@ impl LengthPercentage {
|
||||
pub fn hundred_percent_minus(v: Self, clamping_mode: AllowedNumericType) -> Self {
|
||||
// TODO: This could in theory take ownership of the calc node in `v` if
|
||||
// possible instead of cloning.
|
||||
let (mut node, has_anchor_function) = v.to_calc_node();
|
||||
let mut node = v.to_calc_node();
|
||||
node.negate();
|
||||
|
||||
let new_node = CalcNode::Sum(
|
||||
@@ -318,7 +307,7 @@ impl LengthPercentage {
|
||||
.into(),
|
||||
);
|
||||
|
||||
Self::new_calc(new_node, clamping_mode, has_anchor_function)
|
||||
Self::new_calc(new_node, clamping_mode)
|
||||
}
|
||||
|
||||
/// Given a list of `LengthPercentage` values, construct the value representing
|
||||
@@ -328,38 +317,18 @@ impl LengthPercentage {
|
||||
Percentage::hundred(),
|
||||
))];
|
||||
|
||||
let mut has_anchor_function = false;
|
||||
for lp in list.iter() {
|
||||
let (mut node, node_has_anchor_function) = lp.to_calc_node();
|
||||
has_anchor_function |= node_has_anchor_function;
|
||||
let mut node = lp.to_calc_node();
|
||||
node.negate();
|
||||
new_list.push(node)
|
||||
}
|
||||
|
||||
Self::new_calc(
|
||||
CalcNode::Sum(new_list.into()),
|
||||
clamping_mode,
|
||||
has_anchor_function,
|
||||
)
|
||||
}
|
||||
|
||||
/// Construct a new `calc()` value from `CalcLengthPercentage`.
|
||||
#[inline]
|
||||
pub fn new_calc_from(calc_length_percentage: CalcLengthPercentage) -> Self {
|
||||
Self::new_calc(
|
||||
calc_length_percentage.node,
|
||||
calc_length_percentage.clamping_mode,
|
||||
calc_length_percentage.has_anchor_function,
|
||||
)
|
||||
Self::new_calc(CalcNode::Sum(new_list.into()), clamping_mode)
|
||||
}
|
||||
|
||||
/// Constructs a `calc()` value.
|
||||
#[inline]
|
||||
pub fn new_calc(
|
||||
mut node: CalcNode,
|
||||
clamping_mode: AllowedNumericType,
|
||||
has_anchor_function: bool,
|
||||
) -> Self {
|
||||
pub fn new_calc(mut node: CalcNode, clamping_mode: AllowedNumericType) -> Self {
|
||||
node.simplify_and_sort();
|
||||
|
||||
match node {
|
||||
@@ -383,7 +352,6 @@ impl LengthPercentage {
|
||||
_ => Self::new_calc_unchecked(Box::new(CalcLengthPercentage {
|
||||
clamping_mode,
|
||||
node,
|
||||
has_anchor_function,
|
||||
})),
|
||||
}
|
||||
}
|
||||
@@ -918,11 +886,6 @@ impl calc::CalcNodeLeaf for CalcLengthPercentageLeaf {
|
||||
}
|
||||
}
|
||||
|
||||
/// Computed `anchor()` function in math functions.
|
||||
pub type CalcAnchorFunction = GenericCalcAnchorFunction<CalcLengthPercentageLeaf>;
|
||||
/// Computed `anchor-size()` function in math functions.
|
||||
pub type CalcAnchorSizeFunction = GenericCalcAnchorSizeFunction<CalcLengthPercentageLeaf>;
|
||||
|
||||
/// The computed version of a calc() node for `<length-percentage>` values.
|
||||
pub type CalcNode = calc::GenericCalcNode<CalcLengthPercentageLeaf>;
|
||||
|
||||
@@ -935,10 +898,6 @@ pub struct CalcLengthPercentage {
|
||||
#[animation(constant)]
|
||||
#[css(skip)]
|
||||
clamping_mode: AllowedNumericType,
|
||||
/// See documentation for field of the same name in `specified::CalcLengthPercentage`.
|
||||
#[animation(constant)]
|
||||
#[css(skip)]
|
||||
has_anchor_function: bool,
|
||||
node: CalcNode,
|
||||
}
|
||||
|
||||
@@ -1109,56 +1068,6 @@ impl CalcLengthPercentage {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves anchor positioning functions. This is separate from percentage length resolution, as
|
||||
/// it's valid to ask "Is a given inset auto?" without having to resolve the full length value.
|
||||
/// Note(dshin): When interleaving is implemented, and if the anchor function resolves to a percentage
|
||||
/// fallback value, percentage values probably be left as-is, for animation.
|
||||
#[inline]
|
||||
pub fn resolve_anchor_functions(
|
||||
&self,
|
||||
side: PhysicalSide,
|
||||
prop: PositionProperty,
|
||||
) -> Result<Self, ()> {
|
||||
let result = self.node.resolve_anchor(side, prop, &Resolver)?;
|
||||
Ok(Self {
|
||||
clamping_mode: self.clamping_mode,
|
||||
// TODO(dshin): When the interleaving is implemented, we need to mark anchor-resolved
|
||||
// values somehow so that we know this value need to be animated when the anchor element or
|
||||
// the absolute containing block is changed.
|
||||
has_anchor_function: false,
|
||||
node: result,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Resolver;
|
||||
|
||||
impl AnchorPositioningResolver<CalcLengthPercentageLeaf> for Resolver {
|
||||
fn resolve_anchor(
|
||||
&self,
|
||||
f: &CalcAnchorFunction,
|
||||
side: PhysicalSide,
|
||||
position: PositionProperty,
|
||||
) -> Result<CalcNode, ()> {
|
||||
match f.resolve(side, position) {
|
||||
AnchorResolutionResult::Resolved(v) => Ok(*v),
|
||||
AnchorResolutionResult::Fallback(v) => Ok(*v.clone()),
|
||||
AnchorResolutionResult::Invalid => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_anchor_size(
|
||||
&self,
|
||||
f: &CalcAnchorSizeFunction,
|
||||
position: PositionProperty,
|
||||
) -> Result<CalcNode, ()> {
|
||||
match f.resolve(position) {
|
||||
AnchorResolutionResult::Resolved(v) => Ok(*v),
|
||||
AnchorResolutionResult::Fallback(v) => Ok(*v.clone()),
|
||||
AnchorResolutionResult::Invalid => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(emilio): We don't compare `clamping_mode` since we want to preserve the
|
||||
@@ -1210,7 +1119,7 @@ impl specified::CalcLengthPercentage {
|
||||
},
|
||||
});
|
||||
|
||||
LengthPercentage::new_calc(node, self.clamping_mode, self.has_anchor_function)
|
||||
LengthPercentage::new_calc(node, self.clamping_mode)
|
||||
}
|
||||
|
||||
/// Compute font-size or line-height taking into account text-zoom if necessary.
|
||||
@@ -1289,7 +1198,6 @@ impl specified::CalcLengthPercentage {
|
||||
CalcLengthPercentageLeaf::Percentage(ref p) => Leaf::Percentage(p.0),
|
||||
CalcLengthPercentageLeaf::Number(n) => Leaf::Number(*n),
|
||||
}),
|
||||
has_anchor_function: computed.has_anchor_function,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1320,15 +1228,12 @@ impl Animate for LengthPercentage {
|
||||
}
|
||||
|
||||
let (l, r) = procedure.weights();
|
||||
let (one, one_has_anchor_function) = self.to_calc_node();
|
||||
let (other, other_has_anchor_function) = other.to_calc_node();
|
||||
let one = product_with(one, l as f32);
|
||||
let other = product_with(other, r as f32);
|
||||
let one = product_with(self.to_calc_node(), l as f32);
|
||||
let other = product_with(other.to_calc_node(), r as f32);
|
||||
|
||||
Self::new_calc(
|
||||
CalcNode::Sum(vec![one, other].into()),
|
||||
AllowedNumericType::All,
|
||||
one_has_anchor_function || other_has_anchor_function,
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
//!
|
||||
//! [calc]: https://drafts.csswg.org/css-values/#calc-notation
|
||||
|
||||
use crate::logical_geometry::PhysicalSide;
|
||||
use crate::values::generics::box_::PositionProperty;
|
||||
use crate::values::generics::length::GenericAnchorSizeFunction;
|
||||
use crate::values::generics::position::{AnchorSide, GenericAnchorFunction};
|
||||
use num_traits::Zero;
|
||||
@@ -442,24 +440,6 @@ enum ArgumentLevel {
|
||||
Nested,
|
||||
}
|
||||
|
||||
/// Trait for resolving anchor positioning functions in math functions.
|
||||
pub trait AnchorPositioningResolver<L: CalcNodeLeaf> {
|
||||
/// Resolve `anchor()` function to a value.
|
||||
fn resolve_anchor(
|
||||
&self,
|
||||
f: &GenericCalcAnchorFunction<L>,
|
||||
side: PhysicalSide,
|
||||
position: PositionProperty,
|
||||
) -> Result<GenericCalcNode<L>, ()>;
|
||||
|
||||
/// Resolve `anchor-size()` function to a value.
|
||||
fn resolve_anchor_size(
|
||||
&self,
|
||||
f: &GenericCalcAnchorSizeFunction<L>,
|
||||
position: PositionProperty,
|
||||
) -> Result<GenericCalcNode<L>, ()>;
|
||||
}
|
||||
|
||||
impl<L: CalcNodeLeaf> CalcNode<L> {
|
||||
/// Create a dummy CalcNode that can be used to do replacements of other nodes.
|
||||
fn dummy() -> Self {
|
||||
@@ -1214,135 +1194,6 @@ impl<L: CalcNodeLeaf> CalcNode<L> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve anchor functions, returning the reduced node as a result of it.
|
||||
/// This returns a cloned node, so callers should ideally keep track of
|
||||
/// the node's usage of anchor functions and skip calling this.
|
||||
/// Returns `Err(())` if the anchor function used resolves to an invalid
|
||||
/// anchor and there is no fallback available.
|
||||
pub fn resolve_anchor<R>(
|
||||
&self,
|
||||
side: PhysicalSide,
|
||||
position_property: PositionProperty,
|
||||
anchor_function_resolver: &R,
|
||||
) -> Result<Self, ()>
|
||||
where
|
||||
R: AnchorPositioningResolver<L>,
|
||||
{
|
||||
fn resolve_anchor_internal<L: CalcNodeLeaf, R>(
|
||||
node: &mut CalcNode<L>,
|
||||
side: PhysicalSide,
|
||||
position_property: PositionProperty,
|
||||
anchor_positioning_resolver: &R,
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
R: AnchorPositioningResolver<L>,
|
||||
{
|
||||
match node {
|
||||
CalcNode::Leaf(_) => Ok(()),
|
||||
CalcNode::Negate(child) |
|
||||
CalcNode::Invert(child) |
|
||||
CalcNode::Abs(child) |
|
||||
CalcNode::Sign(child) => resolve_anchor_internal(
|
||||
child,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
),
|
||||
CalcNode::Sum(children) |
|
||||
CalcNode::Product(children) |
|
||||
CalcNode::MinMax(children, _) |
|
||||
CalcNode::Hypot(children) => {
|
||||
for child in children.iter_mut() {
|
||||
resolve_anchor_internal(
|
||||
child,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
},
|
||||
CalcNode::Clamp { min, center, max } => {
|
||||
resolve_anchor_internal(
|
||||
min,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)?;
|
||||
resolve_anchor_internal(
|
||||
center,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)?;
|
||||
resolve_anchor_internal(
|
||||
max,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)
|
||||
},
|
||||
CalcNode::Round {
|
||||
value,
|
||||
step,
|
||||
..
|
||||
} => {
|
||||
resolve_anchor_internal(
|
||||
value,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)?;
|
||||
resolve_anchor_internal(
|
||||
step,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)
|
||||
},
|
||||
CalcNode::ModRem {
|
||||
dividend,
|
||||
divisor,
|
||||
op: _,
|
||||
} => {
|
||||
resolve_anchor_internal(
|
||||
dividend,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)?;
|
||||
resolve_anchor_internal(
|
||||
divisor,
|
||||
side,
|
||||
position_property,
|
||||
anchor_positioning_resolver,
|
||||
)
|
||||
},
|
||||
CalcNode::Anchor(f) => {
|
||||
*node =
|
||||
anchor_positioning_resolver.resolve_anchor(f, side, position_property)?;
|
||||
Ok(())
|
||||
},
|
||||
CalcNode::AnchorSize(f) => {
|
||||
*node =
|
||||
anchor_positioning_resolver.resolve_anchor_size(f, position_property)?;
|
||||
Ok(())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(dshin, Bug 1924225): When interleaving for anchor positioning happens, we can
|
||||
// mutate the node in place.
|
||||
let mut cloned = self.clone();
|
||||
resolve_anchor_internal(
|
||||
&mut cloned,
|
||||
side,
|
||||
position_property,
|
||||
anchor_function_resolver,
|
||||
)?;
|
||||
Ok(cloned)
|
||||
}
|
||||
|
||||
fn is_negative_leaf(&self) -> Result<bool, ()> {
|
||||
Ok(match *self {
|
||||
Self::Leaf(ref l) => l.is_negative()?,
|
||||
|
||||
@@ -129,11 +129,6 @@ impl ToCss for Leaf {
|
||||
pub struct CalcLengthPercentage {
|
||||
#[css(skip)]
|
||||
pub clamping_mode: AllowedNumericType,
|
||||
/// Flag indicating if any anchor function is part of this node.
|
||||
/// This can be used to skip the traversal of calc node tree for
|
||||
/// math functions not using any anchor function.
|
||||
#[css(skip)]
|
||||
pub has_anchor_function: bool,
|
||||
pub node: CalcNode,
|
||||
}
|
||||
|
||||
@@ -494,9 +489,11 @@ impl AnchorSide<Box<CalcNode>> {
|
||||
if let Ok(k) = input.try_parse(|i| AnchorSideKeyword::parse(i)) {
|
||||
return Ok(Self::Keyword(k));
|
||||
}
|
||||
Ok(Self::Percentage(Box::new(
|
||||
CalcNode::parse_argument(context, input, AllowParse::new(CalcUnits::PERCENTAGE))?.node,
|
||||
)))
|
||||
Ok(Self::Percentage(Box::new(CalcNode::parse_argument(
|
||||
context,
|
||||
input,
|
||||
AllowParse::new(CalcUnits::PERCENTAGE),
|
||||
)?)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,8 +520,7 @@ impl GenericAnchorFunction<Box<CalcNode>, Box<CalcNode>> {
|
||||
context,
|
||||
i,
|
||||
AllowParse::new(CalcUnits::LENGTH_PERCENTAGE),
|
||||
)?
|
||||
.node;
|
||||
)?;
|
||||
Ok::<Box<CalcNode>, ParseError<'i>>(Box::new(node))
|
||||
})
|
||||
.ok();
|
||||
@@ -547,7 +543,7 @@ impl GenericAnchorSizeFunction<Box<CalcNode>> {
|
||||
}
|
||||
GenericAnchorSizeFunction::parse_inner(context, input, |i| {
|
||||
CalcNode::parse_argument(context, i, AllowParse::new(CalcUnits::LENGTH_PERCENTAGE))
|
||||
.map(|r| Box::new(r.node))
|
||||
.map(|r| Box::new(r))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -559,73 +555,6 @@ pub type CalcAnchorSizeFunction = generic::GenericCalcAnchorSizeFunction<Leaf>;
|
||||
|
||||
/// A calc node representation for specified values.
|
||||
pub type CalcNode = generic::GenericCalcNode<Leaf>;
|
||||
|
||||
/// Result of parsing the calc node.
|
||||
pub struct ParsedCalcNode {
|
||||
/// The parsed calc node.
|
||||
pub node: CalcNode,
|
||||
/// See documentation for the field of the same name in `CalcLengthPercentage`.
|
||||
pub has_anchor_function: bool,
|
||||
}
|
||||
|
||||
impl ParsedCalcNode {
|
||||
#[inline]
|
||||
fn new(node: CalcNode, has_anchor_function: bool) -> Self {
|
||||
Self {
|
||||
node,
|
||||
has_anchor_function,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn into_length_or_percentage(
|
||||
self,
|
||||
clamping_mode: AllowedNumericType,
|
||||
) -> Result<CalcLengthPercentage, ()> {
|
||||
self.node
|
||||
.into_length_or_percentage(clamping_mode, self.has_anchor_function)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_time(&self, clamping_mode: Option<AllowedNumericType>) -> Result<Time, ()> {
|
||||
debug_assert!(!self.has_anchor_function, "Anchor function used for time?");
|
||||
self.node.to_time(clamping_mode)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_resolution(&self) -> Result<Resolution, ()> {
|
||||
debug_assert!(
|
||||
!self.has_anchor_function,
|
||||
"Anchor function used for resolution?"
|
||||
);
|
||||
self.node.to_resolution()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_angle(&self) -> Result<Angle, ()> {
|
||||
debug_assert!(!self.has_anchor_function, "Anchor function used for angle?");
|
||||
self.node.to_angle()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_number(&self) -> Result<CSSFloat, ()> {
|
||||
debug_assert!(
|
||||
!self.has_anchor_function,
|
||||
"Anchor function used for number?"
|
||||
);
|
||||
self.node.to_number()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_percentage(&self) -> Result<CSSFloat, ()> {
|
||||
debug_assert!(
|
||||
!self.has_anchor_function,
|
||||
"Anchor function used for percentage?"
|
||||
);
|
||||
self.node.to_percentage()
|
||||
}
|
||||
}
|
||||
|
||||
impl CalcNode {
|
||||
/// Tries to parse a single element in the expression, that is, a
|
||||
/// `<length>`, `<angle>`, `<time>`, `<percentage>`, `<resolution>`, etc.
|
||||
@@ -636,44 +565,38 @@ impl CalcNode {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allowed: AllowParse,
|
||||
) -> Result<ParsedCalcNode, ParseError<'i>> {
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let location = input.current_source_location();
|
||||
match input.next()? {
|
||||
&Token::Number { value, .. } => Ok(ParsedCalcNode::new(
|
||||
CalcNode::Leaf(Leaf::Number(value)),
|
||||
false,
|
||||
)),
|
||||
&Token::Number { value, .. } => Ok(CalcNode::Leaf(Leaf::Number(value))),
|
||||
&Token::Dimension {
|
||||
value, ref unit, ..
|
||||
} => {
|
||||
if allowed.includes(CalcUnits::LENGTH) {
|
||||
if let Ok(l) = NoCalcLength::parse_dimension(context, value, unit) {
|
||||
return Ok(ParsedCalcNode::new(CalcNode::Leaf(Leaf::Length(l)), false));
|
||||
return Ok(CalcNode::Leaf(Leaf::Length(l)));
|
||||
}
|
||||
}
|
||||
if allowed.includes(CalcUnits::ANGLE) {
|
||||
if let Ok(a) = Angle::parse_dimension(value, unit, /* from_calc = */ true) {
|
||||
return Ok(ParsedCalcNode::new(CalcNode::Leaf(Leaf::Angle(a)), false));
|
||||
return Ok(CalcNode::Leaf(Leaf::Angle(a)));
|
||||
}
|
||||
}
|
||||
if allowed.includes(CalcUnits::TIME) {
|
||||
if let Ok(t) = Time::parse_dimension(value, unit) {
|
||||
return Ok(ParsedCalcNode::new(CalcNode::Leaf(Leaf::Time(t)), false));
|
||||
return Ok(CalcNode::Leaf(Leaf::Time(t)));
|
||||
}
|
||||
}
|
||||
if allowed.includes(CalcUnits::RESOLUTION) {
|
||||
if let Ok(t) = Resolution::parse_dimension(value, unit) {
|
||||
return Ok(ParsedCalcNode::new(
|
||||
CalcNode::Leaf(Leaf::Resolution(t)),
|
||||
false,
|
||||
));
|
||||
return Ok(CalcNode::Leaf(Leaf::Resolution(t)));
|
||||
}
|
||||
}
|
||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
},
|
||||
&Token::Percentage { unit_value, .. } if allowed.includes(CalcUnits::PERCENTAGE) => Ok(
|
||||
ParsedCalcNode::new(CalcNode::Leaf(Leaf::Percentage(unit_value)), false),
|
||||
),
|
||||
&Token::Percentage { unit_value, .. } if allowed.includes(CalcUnits::PERCENTAGE) => {
|
||||
Ok(CalcNode::Leaf(Leaf::Percentage(unit_value)))
|
||||
},
|
||||
&Token::ParenthesisBlock => {
|
||||
input.parse_nested_block(|input| CalcNode::parse_argument(context, input, allowed))
|
||||
},
|
||||
@@ -684,10 +607,7 @@ impl CalcNode {
|
||||
name.eq_ignore_ascii_case("anchor") =>
|
||||
{
|
||||
let anchor_function = GenericAnchorFunction::parse_in_calc(context, input)?;
|
||||
Ok(ParsedCalcNode::new(
|
||||
CalcNode::Anchor(Box::new(anchor_function)),
|
||||
true,
|
||||
))
|
||||
Ok(CalcNode::Anchor(Box::new(anchor_function)))
|
||||
},
|
||||
&Token::Function(ref name)
|
||||
if allowed
|
||||
@@ -697,10 +617,7 @@ impl CalcNode {
|
||||
{
|
||||
let anchor_size_function =
|
||||
GenericAnchorSizeFunction::parse_in_calc(context, input)?;
|
||||
Ok(ParsedCalcNode::new(
|
||||
CalcNode::AnchorSize(Box::new(anchor_size_function)),
|
||||
true,
|
||||
))
|
||||
Ok(CalcNode::AnchorSize(Box::new(anchor_size_function)))
|
||||
},
|
||||
&Token::Function(ref name) => {
|
||||
let function = CalcNode::math_function(context, name, location)?;
|
||||
@@ -730,7 +647,7 @@ impl CalcNode {
|
||||
}
|
||||
},
|
||||
};
|
||||
Ok(ParsedCalcNode::new(CalcNode::Leaf(leaf), false))
|
||||
Ok(CalcNode::Leaf(leaf))
|
||||
},
|
||||
t => Err(location.new_unexpected_token_error(t.clone())),
|
||||
}
|
||||
@@ -744,7 +661,7 @@ impl CalcNode {
|
||||
input: &mut Parser<'i, 't>,
|
||||
function: MathFunction,
|
||||
allowed: AllowParse,
|
||||
) -> Result<ParsedCalcNode, ParseError<'i>> {
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.parse_nested_block(|input| {
|
||||
match function {
|
||||
MathFunction::Calc => Self::parse_argument(context, input, allowed),
|
||||
@@ -754,15 +671,10 @@ impl CalcNode {
|
||||
let center = Self::parse_argument(context, input, allowed)?;
|
||||
input.expect_comma()?;
|
||||
let max = Self::parse_argument(context, input, allowed)?;
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Clamp {
|
||||
min: Box::new(min.node),
|
||||
center: Box::new(center.node),
|
||||
max: Box::new(max.node),
|
||||
},
|
||||
has_anchor_function: min.has_anchor_function ||
|
||||
center.has_anchor_function ||
|
||||
max.has_anchor_function,
|
||||
Ok(Self::Clamp {
|
||||
min: Box::new(min),
|
||||
center: Box::new(center),
|
||||
max: Box::new(max),
|
||||
})
|
||||
},
|
||||
MathFunction::Round => {
|
||||
@@ -794,17 +706,12 @@ impl CalcNode {
|
||||
Self::parse_argument(context, input, allowed)
|
||||
});
|
||||
|
||||
let (step, step_has_anchor_function) = step
|
||||
.map(|s| (s.node, s.has_anchor_function))
|
||||
.unwrap_or((Self::Leaf(Leaf::Number(1.0)), false));
|
||||
let step = step.unwrap_or(Self::Leaf(Leaf::Number(1.0)));
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Round {
|
||||
Ok(Self::Round {
|
||||
strategy: strategy.unwrap_or(RoundingStrategy::Nearest),
|
||||
value: Box::new(value.node),
|
||||
value: Box::new(value),
|
||||
step: Box::new(step),
|
||||
},
|
||||
has_anchor_function: value.has_anchor_function || step_has_anchor_function,
|
||||
})
|
||||
},
|
||||
MathFunction::Mod | MathFunction::Rem => {
|
||||
@@ -817,14 +724,10 @@ impl CalcNode {
|
||||
MathFunction::Rem => ModRemOp::Rem,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::ModRem {
|
||||
dividend: Box::new(dividend.node),
|
||||
divisor: Box::new(divisor.node),
|
||||
Ok(Self::ModRem {
|
||||
dividend: Box::new(dividend),
|
||||
divisor: Box::new(divisor),
|
||||
op,
|
||||
},
|
||||
has_anchor_function: dividend.has_anchor_function ||
|
||||
divisor.has_anchor_function,
|
||||
})
|
||||
},
|
||||
MathFunction::Min | MathFunction::Max => {
|
||||
@@ -833,11 +736,9 @@ impl CalcNode {
|
||||
//
|
||||
// Consider adding an API to cssparser to specify the
|
||||
// initial vector capacity?
|
||||
let mut has_anchor_function = false;
|
||||
let arguments = input.parse_comma_separated(|input| {
|
||||
let result = Self::parse_argument(context, input, allowed)?;
|
||||
has_anchor_function |= result.has_anchor_function;
|
||||
Ok(result.node)
|
||||
Ok(result)
|
||||
})?;
|
||||
|
||||
let op = match function {
|
||||
@@ -846,10 +747,7 @@ impl CalcNode {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::MinMax(arguments.into(), op),
|
||||
has_anchor_function,
|
||||
})
|
||||
Ok(Self::MinMax(arguments.into(), op))
|
||||
},
|
||||
MathFunction::Sin | MathFunction::Cos | MathFunction::Tan => {
|
||||
let a = Self::parse_angle_argument(context, input)?;
|
||||
@@ -863,10 +761,7 @@ impl CalcNode {
|
||||
},
|
||||
};
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Number(number)),
|
||||
has_anchor_function: false,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Number(number)))
|
||||
},
|
||||
MathFunction::Asin | MathFunction::Acos | MathFunction::Atan => {
|
||||
let a = Self::parse_number_argument(context, input)?;
|
||||
@@ -880,18 +775,13 @@ impl CalcNode {
|
||||
},
|
||||
};
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Angle(Angle::from_radians(radians))),
|
||||
has_anchor_function: false,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Angle(Angle::from_radians(radians))))
|
||||
},
|
||||
MathFunction::Atan2 => {
|
||||
let allow_all = allowed.new_including(CalcUnits::ALL);
|
||||
let a = Self::parse_argument(context, input, allow_all)?;
|
||||
let (a, a_has_anchor_function) = (a.node, a.has_anchor_function);
|
||||
input.expect_comma()?;
|
||||
let b = Self::parse_argument(context, input, allow_all)?;
|
||||
let (b, b_has_anchor_function) = (b.node, b.has_anchor_function);
|
||||
|
||||
let radians = Self::try_resolve(input, || {
|
||||
if let Ok(a) = a.to_number() {
|
||||
@@ -919,23 +809,14 @@ impl CalcNode {
|
||||
return Ok(a.dppx().atan2(b.dppx()));
|
||||
}
|
||||
|
||||
let a = a.into_length_or_percentage(
|
||||
AllowedNumericType::All,
|
||||
a_has_anchor_function,
|
||||
)?;
|
||||
let b = b.into_length_or_percentage(
|
||||
AllowedNumericType::All,
|
||||
b_has_anchor_function,
|
||||
)?;
|
||||
let a = a.into_length_or_percentage(AllowedNumericType::All)?;
|
||||
let b = b.into_length_or_percentage(AllowedNumericType::All)?;
|
||||
let (a, b) = CalcLengthPercentage::same_unit_length_as(&a, &b).ok_or(())?;
|
||||
|
||||
Ok(a.atan2(b))
|
||||
})?;
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Angle(Angle::from_radians(radians))),
|
||||
has_anchor_function: a_has_anchor_function || b_has_anchor_function,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Angle(Angle::from_radians(radians))))
|
||||
},
|
||||
MathFunction::Pow => {
|
||||
let a = Self::parse_number_argument(context, input)?;
|
||||
@@ -944,33 +825,22 @@ impl CalcNode {
|
||||
|
||||
let number = a.powf(b);
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Number(number)),
|
||||
has_anchor_function: false,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Number(number)))
|
||||
},
|
||||
MathFunction::Sqrt => {
|
||||
let a = Self::parse_number_argument(context, input)?;
|
||||
|
||||
let number = a.sqrt();
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Number(number)),
|
||||
has_anchor_function: false,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Number(number)))
|
||||
},
|
||||
MathFunction::Hypot => {
|
||||
let mut has_anchor_function = false;
|
||||
let arguments = input.parse_comma_separated(|input| {
|
||||
let result = Self::parse_argument(context, input, allowed)?;
|
||||
has_anchor_function |= result.has_anchor_function;
|
||||
Ok(result.node)
|
||||
Ok(result)
|
||||
})?;
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Hypot(arguments.into()),
|
||||
has_anchor_function,
|
||||
})
|
||||
Ok(Self::Hypot(arguments.into()))
|
||||
},
|
||||
MathFunction::Log => {
|
||||
let a = Self::parse_number_argument(context, input)?;
|
||||
@@ -986,25 +856,16 @@ impl CalcNode {
|
||||
None => a.ln(),
|
||||
};
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Number(number)),
|
||||
has_anchor_function: false,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Number(number)))
|
||||
},
|
||||
MathFunction::Exp => {
|
||||
let a = Self::parse_number_argument(context, input)?;
|
||||
let number = a.exp();
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Leaf(Leaf::Number(number)),
|
||||
has_anchor_function: false,
|
||||
})
|
||||
Ok(Self::Leaf(Leaf::Number(number)))
|
||||
},
|
||||
MathFunction::Abs => {
|
||||
let node = Self::parse_argument(context, input, allowed)?;
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Abs(Box::new(node.node)),
|
||||
has_anchor_function: node.has_anchor_function,
|
||||
})
|
||||
Ok(Self::Abs(Box::new(node)))
|
||||
},
|
||||
MathFunction::Sign => {
|
||||
// The sign of a percentage is dependent on the percentage basis, so if
|
||||
@@ -1015,10 +876,7 @@ impl CalcNode {
|
||||
input,
|
||||
allowed.new_including(CalcUnits::ALL - CalcUnits::PERCENTAGE),
|
||||
)?;
|
||||
Ok(ParsedCalcNode {
|
||||
node: Self::Sign(Box::new(node.node)),
|
||||
has_anchor_function: node.has_anchor_function,
|
||||
})
|
||||
Ok(Self::Sign(Box::new(node)))
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -1028,8 +886,7 @@ impl CalcNode {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CSSFloat, ParseError<'i>> {
|
||||
let argument =
|
||||
Self::parse_argument(context, input, AllowParse::new(CalcUnits::ANGLE))?.node;
|
||||
let argument = Self::parse_argument(context, input, AllowParse::new(CalcUnits::ANGLE))?;
|
||||
argument
|
||||
.to_number()
|
||||
.or_else(|()| Ok(argument.to_angle()?.radians()))
|
||||
@@ -1041,7 +898,6 @@ impl CalcNode {
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<CSSFloat, ParseError<'i>> {
|
||||
Self::parse_argument(context, input, AllowParse::new(CalcUnits::empty()))?
|
||||
.node
|
||||
.to_number()
|
||||
.map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||
}
|
||||
@@ -1050,11 +906,10 @@ impl CalcNode {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allowed: AllowParse,
|
||||
) -> Result<ParsedCalcNode, ParseError<'i>> {
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut sum = SmallVec::<[CalcNode; 1]>::new();
|
||||
let first = Self::parse_product(context, input, allowed)?;
|
||||
sum.push(first.node);
|
||||
let mut has_anchor_function = first.has_anchor_function;
|
||||
sum.push(first);
|
||||
loop {
|
||||
let start = input.state();
|
||||
match input.next_including_whitespace() {
|
||||
@@ -1065,18 +920,15 @@ impl CalcNode {
|
||||
match *input.next()? {
|
||||
Token::Delim('+') => {
|
||||
let rhs = Self::parse_product(context, input, allowed)?;
|
||||
has_anchor_function |= rhs.has_anchor_function;
|
||||
if sum.last_mut().unwrap().try_sum_in_place(&rhs.node).is_err() {
|
||||
// TODO(dshin): need to combine
|
||||
sum.push(rhs.node);
|
||||
if sum.last_mut().unwrap().try_sum_in_place(&rhs).is_err() {
|
||||
sum.push(rhs);
|
||||
}
|
||||
},
|
||||
Token::Delim('-') => {
|
||||
let mut rhs = Self::parse_product(context, input, allowed)?;
|
||||
has_anchor_function |= rhs.has_anchor_function;
|
||||
rhs.node.negate();
|
||||
if sum.last_mut().unwrap().try_sum_in_place(&rhs.node).is_err() {
|
||||
sum.push(rhs.node);
|
||||
rhs.negate();
|
||||
if sum.last_mut().unwrap().try_sum_in_place(&rhs).is_err() {
|
||||
sum.push(rhs);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
@@ -1092,13 +944,10 @@ impl CalcNode {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: if sum.len() == 1 {
|
||||
Ok(if sum.len() == 1 {
|
||||
sum.drain(..).next().unwrap()
|
||||
} else {
|
||||
Self::Sum(sum.into_boxed_slice().into())
|
||||
},
|
||||
has_anchor_function,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1115,33 +964,25 @@ impl CalcNode {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
allowed: AllowParse,
|
||||
) -> Result<ParsedCalcNode, ParseError<'i>> {
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let mut product = SmallVec::<[CalcNode; 1]>::new();
|
||||
let first = Self::parse_one(context, input, allowed)?;
|
||||
product.push(first.node);
|
||||
let mut has_anchor_function = first.has_anchor_function;
|
||||
product.push(first);
|
||||
|
||||
loop {
|
||||
let start = input.state();
|
||||
match input.next() {
|
||||
Ok(&Token::Delim('*')) => {
|
||||
let mut rhs = Self::parse_one(context, input, allowed)?;
|
||||
has_anchor_function |= rhs.has_anchor_function;
|
||||
|
||||
// We can unwrap here, becuase we start the function by adding a node to
|
||||
// the list.
|
||||
if !product
|
||||
.last_mut()
|
||||
.unwrap()
|
||||
.try_product_in_place(&mut rhs.node)
|
||||
{
|
||||
// TODO(dshin): need to combine
|
||||
product.push(rhs.node);
|
||||
if !product.last_mut().unwrap().try_product_in_place(&mut rhs) {
|
||||
product.push(rhs);
|
||||
}
|
||||
},
|
||||
Ok(&Token::Delim('/')) => {
|
||||
let rhs = Self::parse_one(context, input, allowed)?;
|
||||
has_anchor_function |= rhs.has_anchor_function;
|
||||
|
||||
enum InPlaceDivisionResult {
|
||||
/// The right was merged into the left.
|
||||
@@ -1183,10 +1024,10 @@ impl CalcNode {
|
||||
// already resolve it, then merge it with the last node on the product list.
|
||||
// We can unwrap here, becuase we start the function by adding a node to
|
||||
// the list.
|
||||
match try_division_in_place(&mut product.last_mut().unwrap(), &rhs.node) {
|
||||
match try_division_in_place(&mut product.last_mut().unwrap(), &rhs) {
|
||||
InPlaceDivisionResult::Merged => {},
|
||||
InPlaceDivisionResult::Unchanged => {
|
||||
product.push(Self::Invert(Box::new(rhs.node)))
|
||||
product.push(Self::Invert(Box::new(rhs)))
|
||||
},
|
||||
InPlaceDivisionResult::Invalid => {
|
||||
return Err(
|
||||
@@ -1202,13 +1043,10 @@ impl CalcNode {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ParsedCalcNode {
|
||||
node: if product.len() == 1 {
|
||||
Ok(if product.len() == 1 {
|
||||
product.drain(..).next().unwrap()
|
||||
} else {
|
||||
Self::Product(product.into_boxed_slice().into())
|
||||
},
|
||||
has_anchor_function,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1227,7 +1065,6 @@ impl CalcNode {
|
||||
pub fn into_length_or_percentage(
|
||||
mut self,
|
||||
clamping_mode: AllowedNumericType,
|
||||
has_anchor_function: bool,
|
||||
) -> Result<CalcLengthPercentage, ()> {
|
||||
self.simplify_and_sort();
|
||||
|
||||
@@ -1240,7 +1077,6 @@ impl CalcNode {
|
||||
Ok(CalcLengthPercentage {
|
||||
clamping_mode,
|
||||
node: self,
|
||||
has_anchor_function,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1649,7 +1649,6 @@ impl From<Percentage> for LengthPercentage {
|
||||
if let Some(clamping_mode) = pc.calc_clamping_mode() {
|
||||
LengthPercentage::Calc(Box::new(CalcLengthPercentage {
|
||||
clamping_mode,
|
||||
has_anchor_function: false,
|
||||
node: CalcNode::Leaf(calc::Leaf::Percentage(pc.get())),
|
||||
}))
|
||||
} else {
|
||||
@@ -1812,11 +1811,11 @@ impl LengthPercentage {
|
||||
/// Returns self as specified::calc::CalcNode.
|
||||
/// Note that this expect the clamping_mode is AllowedNumericType::All for Calc. The caller
|
||||
/// should take care about it when using this function.
|
||||
fn to_calc_node(self) -> (CalcNode, bool) {
|
||||
fn to_calc_node(self) -> CalcNode {
|
||||
match self {
|
||||
LengthPercentage::Length(l) => (CalcNode::Leaf(calc::Leaf::Length(l)), false),
|
||||
LengthPercentage::Percentage(p) => (CalcNode::Leaf(calc::Leaf::Percentage(p.0)), false),
|
||||
LengthPercentage::Calc(p) => (p.node, p.has_anchor_function),
|
||||
LengthPercentage::Length(l) => CalcNode::Leaf(calc::Leaf::Length(l)),
|
||||
LengthPercentage::Percentage(p) => CalcNode::Leaf(calc::Leaf::Percentage(p.0)),
|
||||
LengthPercentage::Calc(p) => p.node,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1825,14 +1824,13 @@ impl LengthPercentage {
|
||||
let mut sum = smallvec::SmallVec::<[CalcNode; 2]>::new();
|
||||
sum.push(CalcNode::Leaf(calc::Leaf::Percentage(1.0)));
|
||||
|
||||
let (mut node, has_anchor_function) = self.to_calc_node();
|
||||
let mut node = self.to_calc_node();
|
||||
node.negate();
|
||||
sum.push(node);
|
||||
|
||||
let calc = CalcNode::Sum(sum.into_boxed_slice().into());
|
||||
LengthPercentage::Calc(Box::new(
|
||||
calc.into_length_or_percentage(clamping_mode, has_anchor_function)
|
||||
.unwrap(),
|
||||
calc.into_length_or_percentage(clamping_mode).unwrap(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9812,29 +9812,3 @@ pub extern "C" fn Servo_ResolveAnchorSizeFunction(
|
||||
) {
|
||||
*out = AnchorPositioningFunctionResolution::new(func.resolve(prop));
|
||||
}
|
||||
|
||||
/// Result of resolving a math function node potentially containing
|
||||
/// anchor positioning function.
|
||||
#[repr(u8)]
|
||||
pub enum CalcAnchorPositioningFunctionResolution {
|
||||
/// Anchor positioning function is used, but at least one of them
|
||||
/// did not resolve to a valid reference - Property using this
|
||||
/// expression is now invalid at computed time.
|
||||
Invalid,
|
||||
/// Anchor positioning function is used, and all of them resolved
|
||||
/// to valid references, or specified a fallback.
|
||||
Valid(computed::LengthPercentage),
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ResolveAnchorPositioningFunctionInCalc(
|
||||
calc: &computed::length_percentage::CalcLengthPercentage,
|
||||
side: PhysicalSide,
|
||||
prop: PositionProperty,
|
||||
out: &mut CalcAnchorPositioningFunctionResolution,
|
||||
) {
|
||||
*out = match calc.resolve_anchor_functions(side, prop) {
|
||||
Ok(l) => CalcAnchorPositioningFunctionResolution::Valid(l.into()),
|
||||
Err(_) => CalcAnchorPositioningFunctionResolution::Invalid,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user