Bug 1923763: Part 2 - Implement Anchor function resolution functions from Rust side. r=firefox-style-system-reviewers,emilio
Differential Revision: https://phabricator.services.mozilla.com/D231256
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
//! Generic types for CSS values related to length.
|
||||
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::generics::box_::PositionProperty;
|
||||
use crate::values::generics::Optional;
|
||||
use crate::values::DashedIdent;
|
||||
#[cfg(feature = "gecko")]
|
||||
@@ -450,6 +451,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Result of resolving an anchor function.
|
||||
pub enum AnchorResolutionResult<'a, LengthPercentage> {
|
||||
/// Function resolved to a valid anchor.
|
||||
Resolved(LengthPercentage),
|
||||
/// Referenced anchor is invalid, but fallback is used.
|
||||
Fallback(&'a LengthPercentage),
|
||||
/// Referenced anchor is invalid.
|
||||
Invalid,
|
||||
}
|
||||
|
||||
impl<'a, LengthPercentage> AnchorResolutionResult<'a, LengthPercentage> {
|
||||
/// Return result for an invalid anchor function, depending on if it has any fallback.
|
||||
pub fn new_anchor_invalid(fallback: Option<&'a LengthPercentage>) -> Self {
|
||||
if let Some(fb) = fallback {
|
||||
return Self::Fallback(fb);
|
||||
}
|
||||
Self::Invalid
|
||||
}
|
||||
}
|
||||
|
||||
impl<LengthPercentage> GenericAnchorSizeFunction<LengthPercentage>
|
||||
{
|
||||
/// Parse the inner part of `anchor-size()`, after the parser has consumed "anchor-size(".
|
||||
@@ -487,6 +508,19 @@ impl<LengthPercentage> GenericAnchorSizeFunction<LengthPercentage>
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Resolve the anchor size function. On failure, return reference to fallback, if exists.
|
||||
pub fn resolve<'a>(
|
||||
&'a self,
|
||||
position_property: PositionProperty,
|
||||
) -> AnchorResolutionResult<'a, LengthPercentage> {
|
||||
if !position_property.is_absolutely_positioned() {
|
||||
return AnchorResolutionResult::new_anchor_invalid(self.fallback.as_ref());
|
||||
}
|
||||
|
||||
// TODO(dshin): Do the actual anchor resolution here.
|
||||
AnchorResolutionResult::new_anchor_invalid(self.fallback.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// Keyword values for the anchor size function.
|
||||
|
||||
@@ -11,8 +11,10 @@ use style_traits::CssWriter;
|
||||
use style_traits::SpecifiedValueInfo;
|
||||
use style_traits::ToCss;
|
||||
|
||||
use crate::logical_geometry::PhysicalSide;
|
||||
use crate::values::animated::ToAnimatedZero;
|
||||
use crate::values::generics::length::GenericAnchorSizeFunction;
|
||||
use crate::values::generics::box_::PositionProperty;
|
||||
use crate::values::generics::length::{AnchorResolutionResult, GenericAnchorSizeFunction};
|
||||
use crate::values::generics::ratio::Ratio;
|
||||
use crate::values::generics::Optional;
|
||||
use crate::values::DashedIdent;
|
||||
@@ -375,6 +377,26 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<Percentage, LengthPercentage> GenericAnchorFunction<Percentage, LengthPercentage> {
|
||||
/// Resolve the anchor function. On failure, return reference to fallback, if exists.
|
||||
pub fn resolve<'a>(
|
||||
&'a self,
|
||||
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_side(side) {
|
||||
return AnchorResolutionResult::new_anchor_invalid(self.fallback.as_ref());
|
||||
}
|
||||
|
||||
// TODO(dshin): Do the actual anchor resolution here.
|
||||
AnchorResolutionResult::new_anchor_invalid(self.fallback.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// Keyword values for the anchor positioning function.
|
||||
#[derive(
|
||||
Animate,
|
||||
@@ -423,6 +445,22 @@ pub enum AnchorSideKeyword {
|
||||
Center,
|
||||
}
|
||||
|
||||
impl AnchorSideKeyword {
|
||||
fn valid_for_side(&self, side: PhysicalSide) -> bool {
|
||||
match self {
|
||||
Self::Left | Self::Right => side == PhysicalSide::Left || side == PhysicalSide::Right,
|
||||
Self::Top | Self::Bottom => side == PhysicalSide::Top || side == PhysicalSide::Bottom,
|
||||
Self::Inside |
|
||||
Self::Outside |
|
||||
Self::Start |
|
||||
Self::End |
|
||||
Self::SelfStart |
|
||||
Self::SelfEnd |
|
||||
Self::Center => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Anchor side for the anchor positioning function.
|
||||
#[derive(
|
||||
Animate,
|
||||
@@ -450,3 +488,13 @@ pub enum AnchorSide<P> {
|
||||
/// Percentage value between the `start` and `end` sides.
|
||||
Percentage(P),
|
||||
}
|
||||
|
||||
impl<P> AnchorSide<P> {
|
||||
/// Is this anchor side valid for a given side?
|
||||
pub fn valid_for_side(&self, side: PhysicalSide) -> bool {
|
||||
match self {
|
||||
Self::Keyword(k) => k.valid_for_side(side),
|
||||
Self::Percentage(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,6 +326,7 @@ include = [
|
||||
"AnchorSizeFunction",
|
||||
"Margin",
|
||||
"PositionProperty",
|
||||
"PhysicalSide",
|
||||
]
|
||||
item_types = [
|
||||
"enums",
|
||||
|
||||
@@ -16,6 +16,7 @@ use selectors::matching::{ElementSelectorFlags, MatchingForInvalidation, Selecto
|
||||
use selectors::{Element, OpaqueElement};
|
||||
use servo_arc::{Arc, ArcBorrow};
|
||||
use smallvec::SmallVec;
|
||||
use style::values::generics::length::AnchorResolutionResult;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::Write;
|
||||
use std::iter;
|
||||
@@ -103,6 +104,7 @@ use style::invalidation::element::relative_selector::{
|
||||
};
|
||||
use style::invalidation::element::restyle_hints::RestyleHint;
|
||||
use style::invalidation::stylesheets::RuleChangeKind;
|
||||
use style::logical_geometry::PhysicalSide;
|
||||
use style::media_queries::MediaList;
|
||||
use style::parser::{Parse, ParserContext};
|
||||
#[cfg(feature = "gecko_debug")]
|
||||
@@ -149,7 +151,9 @@ use style::values::computed::effects::Filter;
|
||||
use style::values::computed::font::{
|
||||
FamilyName, FontFamily, FontFamilyList, FontStretch, FontStyle, FontWeight, GenericFontFamily,
|
||||
};
|
||||
use style::values::computed::{self, Context, ToComputedValue};
|
||||
use style::values::computed::length::AnchorSizeFunction;
|
||||
use style::values::computed::position::AnchorFunction;
|
||||
use style::values::computed::{self, Context, PositionProperty, ToComputedValue};
|
||||
use style::values::distance::ComputeSquaredDistance;
|
||||
use style::values::generics::color::ColorMixFlags;
|
||||
use style::values::generics::easing::BeforeFlag;
|
||||
@@ -9735,3 +9739,45 @@ pub unsafe extern "C" fn Servo_CSSParser_NextToken(
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Result of resolving an anchor positioning function.
|
||||
#[repr(u8)]
|
||||
pub enum AnchorPositioningFunctionResolution {
|
||||
/// Anchor function invalid.
|
||||
Invalid,
|
||||
/// Anchor function resolved to a reference to fallback.
|
||||
ResolvedReference(*const computed::LengthPercentage),
|
||||
/// Anchor function resolved to a value.
|
||||
Resolved(computed::LengthPercentage),
|
||||
}
|
||||
|
||||
impl AnchorPositioningFunctionResolution {
|
||||
fn new(result: AnchorResolutionResult<'_, computed::LengthPercentage>) -> Self {
|
||||
match result {
|
||||
AnchorResolutionResult::Resolved(l) => AnchorPositioningFunctionResolution::Resolved(l),
|
||||
AnchorResolutionResult::Fallback(l) => {
|
||||
AnchorPositioningFunctionResolution::ResolvedReference(l as *const _)
|
||||
},
|
||||
AnchorResolutionResult::Invalid => AnchorPositioningFunctionResolution::Invalid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ResolveAnchorFunction(
|
||||
func: &AnchorFunction,
|
||||
side: PhysicalSide,
|
||||
prop: PositionProperty,
|
||||
out: &mut AnchorPositioningFunctionResolution,
|
||||
) {
|
||||
*out = AnchorPositioningFunctionResolution::new(func.resolve(side, prop));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_ResolveAnchorSizeFunction(
|
||||
func: &AnchorSizeFunction,
|
||||
prop: PositionProperty,
|
||||
out: &mut AnchorPositioningFunctionResolution,
|
||||
) {
|
||||
*out = AnchorPositioningFunctionResolution::new(func.resolve(prop));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user