Bug 1964122: Work with side, not axis, when resolving anchor() r=firefox-style-system-reviewers,emilio
Previously, we mapped left: anchor(left); to "Resolve anchor(left) with in horizontal axis" - However, this doesn't work for two reasons: 1. `left: anchor(left)` and `right: anchor(left)` have to return 2 different values to produce the identical result 2. We need side data for `left: anchor(inside)` and `right: anchor(outside)` Differential Revision: https://phabricator.services.mozilla.com/D247663
This commit is contained in:
committed by
dshin@mozilla.com
parent
b7d69dd476
commit
1a41596bbf
@@ -27,7 +27,7 @@
|
||||
use super::{Context, Length, Percentage, PositionProperty, ToComputedValue};
|
||||
#[cfg(feature = "gecko")]
|
||||
use crate::gecko_bindings::structs::GeckoFontMetrics;
|
||||
use crate::logical_geometry::PhysicalAxis;
|
||||
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::{CalcUnits, PositivePercentageBasis};
|
||||
@@ -915,10 +915,10 @@ fn resolve_anchor_functions(
|
||||
) -> Result<Option<CalcNode>, ()> {
|
||||
let resolution = match node {
|
||||
CalcNode::Anchor(f) => {
|
||||
let axis = info.axis.expect("Unexpected anchor()");
|
||||
let side = info.side.expect("Unexpected anchor()");
|
||||
// Invalid use of `anchor()` (i.e. Outside of inset properties) should've been
|
||||
// caught at parse time.
|
||||
f.resolve(axis, info.position_property)
|
||||
f.resolve(side, info.position_property)
|
||||
},
|
||||
CalcNode::AnchorSize(f) => f.resolve(info.position_property),
|
||||
_ => return Ok(None),
|
||||
@@ -938,14 +938,13 @@ fn resolve_anchor_functions(
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct CalcAnchorFunctionResolutionInfo {
|
||||
/// Which axis we're resolving anchor functions for.
|
||||
/// Which side we're resolving anchor functions for.
|
||||
/// This is only relevant for `anchor()`, which requires
|
||||
/// the property using the function to be in the same axis
|
||||
/// as the specified side [1]. `None` if we aren't expecting
|
||||
/// `anchor()`, like in size properties, where only `anchor-size()`
|
||||
/// is allowed.
|
||||
/// the property using the function to be in the side[1].
|
||||
/// `None` if we aren't expecting `anchor()`, like in size
|
||||
/// properties, where only `anchor-size()` is allowed.
|
||||
/// [1]: https://drafts.csswg.org/css-anchor-position-1/#anchor-valid
|
||||
pub axis: Option<PhysicalAxis>,
|
||||
pub side: Option<PhysicalSide>,
|
||||
/// `position` property of the box for which this style is being resolved.
|
||||
pub position_property: PositionProperty,
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use style_traits::CssWriter;
|
||||
use style_traits::SpecifiedValueInfo;
|
||||
use style_traits::ToCss;
|
||||
|
||||
use crate::logical_geometry::PhysicalAxis;
|
||||
use crate::logical_geometry::PhysicalSide;
|
||||
use crate::values::animated::ToAnimatedZero;
|
||||
use crate::values::generics::box_::PositionProperty;
|
||||
use crate::values::generics::length::{AnchorResolutionResult, GenericAnchorSizeFunction};
|
||||
@@ -391,14 +391,14 @@ impl<Percentage, LengthPercentage> GenericAnchorFunction<Percentage, LengthPerce
|
||||
/// Resolve the anchor function. On failure, return reference to fallback, if exists.
|
||||
pub fn resolve<'a>(
|
||||
&'a self,
|
||||
axis: PhysicalAxis,
|
||||
side: PhysicalSide,
|
||||
position_property: PositionProperty,
|
||||
) -> AnchorResolutionResult<'a, LengthPercentage> {
|
||||
if !position_property.is_absolutely_positioned() {
|
||||
return AnchorResolutionResult::new_anchor_invalid(self.fallback.as_ref());
|
||||
}
|
||||
|
||||
if !self.side.valid_for_axis(axis) {
|
||||
if !self.side.valid_for(side) {
|
||||
return AnchorResolutionResult::new_anchor_invalid(self.fallback.as_ref());
|
||||
}
|
||||
|
||||
@@ -456,10 +456,10 @@ pub enum AnchorSideKeyword {
|
||||
}
|
||||
|
||||
impl AnchorSideKeyword {
|
||||
fn valid_for_axis(&self, axis: PhysicalAxis) -> bool {
|
||||
fn valid_for(&self, side: PhysicalSide) -> bool {
|
||||
match self {
|
||||
Self::Left | Self::Right => axis == PhysicalAxis::Horizontal,
|
||||
Self::Top | Self::Bottom => axis == PhysicalAxis::Vertical,
|
||||
Self::Left | Self::Right => matches!(side, PhysicalSide::Left | PhysicalSide::Right),
|
||||
Self::Top | Self::Bottom => matches!(side, PhysicalSide::Top | PhysicalSide::Bottom),
|
||||
Self::Inside |
|
||||
Self::Outside |
|
||||
Self::Start |
|
||||
@@ -500,10 +500,10 @@ pub enum AnchorSide<P> {
|
||||
}
|
||||
|
||||
impl<P> AnchorSide<P> {
|
||||
/// Is this anchor side valid for a given axis?
|
||||
pub fn valid_for_axis(&self, axis: PhysicalAxis) -> bool {
|
||||
/// Is this anchor side valid for a given side?
|
||||
pub fn valid_for(&self, side: PhysicalSide) -> bool {
|
||||
match self {
|
||||
Self::Keyword(k) => k.valid_for_axis(axis),
|
||||
Self::Keyword(k) => k.valid_for(side),
|
||||
Self::Percentage(_) => true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,6 +331,7 @@ include = [
|
||||
"Margin",
|
||||
"PositionProperty",
|
||||
"PhysicalAxis",
|
||||
"PhysicalSide",
|
||||
"QueryFontMetricsFlags",
|
||||
]
|
||||
item_types = [
|
||||
|
||||
@@ -103,7 +103,7 @@ use style::invalidation::element::relative_selector::{
|
||||
};
|
||||
use style::invalidation::element::restyle_hints::RestyleHint;
|
||||
use style::invalidation::stylesheets::RuleChangeKind;
|
||||
use style::logical_geometry::PhysicalAxis;
|
||||
use style::logical_geometry::PhysicalSide;
|
||||
use style::media_queries::MediaList;
|
||||
use style::parser::{Parse, ParserContext};
|
||||
#[cfg(feature = "gecko_debug")]
|
||||
@@ -8447,12 +8447,12 @@ pub enum CalcAnchorPositioningFunctionResolution {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ResolveAnchorFunctionsInCalcPercentage(
|
||||
calc: &computed::length_percentage::CalcLengthPercentage,
|
||||
axis: Option<&PhysicalAxis>,
|
||||
side: Option<&PhysicalSide>,
|
||||
position_property: PositionProperty,
|
||||
out: &mut CalcAnchorPositioningFunctionResolution,
|
||||
) {
|
||||
let resolved = calc.resolve_anchor(CalcAnchorFunctionResolutionInfo {
|
||||
axis: axis.copied(),
|
||||
side: side.copied(),
|
||||
position_property,
|
||||
});
|
||||
|
||||
@@ -9869,11 +9869,11 @@ impl AnchorPositioningFunctionResolution {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ResolveAnchorFunction(
|
||||
func: &AnchorFunction,
|
||||
axis: PhysicalAxis,
|
||||
side: PhysicalSide,
|
||||
prop: PositionProperty,
|
||||
out: &mut AnchorPositioningFunctionResolution,
|
||||
) {
|
||||
*out = AnchorPositioningFunctionResolution::new(func.resolve(axis, prop));
|
||||
*out = AnchorPositioningFunctionResolution::new(func.resolve(side, prop));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
Reference in New Issue
Block a user