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.
|
//! Generic types for CSS values related to length.
|
||||||
|
|
||||||
use crate::parser::{Parse, ParserContext};
|
use crate::parser::{Parse, ParserContext};
|
||||||
|
use crate::values::generics::box_::PositionProperty;
|
||||||
use crate::values::generics::Optional;
|
use crate::values::generics::Optional;
|
||||||
use crate::values::DashedIdent;
|
use crate::values::DashedIdent;
|
||||||
#[cfg(feature = "gecko")]
|
#[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>
|
impl<LengthPercentage> GenericAnchorSizeFunction<LengthPercentage>
|
||||||
{
|
{
|
||||||
/// Parse the inner part of `anchor-size()`, after the parser has consumed "anchor-size(".
|
/// 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.
|
/// Keyword values for the anchor size function.
|
||||||
|
|||||||
@@ -11,8 +11,10 @@ use style_traits::CssWriter;
|
|||||||
use style_traits::SpecifiedValueInfo;
|
use style_traits::SpecifiedValueInfo;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
|
||||||
|
use crate::logical_geometry::PhysicalSide;
|
||||||
use crate::values::animated::ToAnimatedZero;
|
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::ratio::Ratio;
|
||||||
use crate::values::generics::Optional;
|
use crate::values::generics::Optional;
|
||||||
use crate::values::DashedIdent;
|
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.
|
/// Keyword values for the anchor positioning function.
|
||||||
#[derive(
|
#[derive(
|
||||||
Animate,
|
Animate,
|
||||||
@@ -423,6 +445,22 @@ pub enum AnchorSideKeyword {
|
|||||||
Center,
|
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.
|
/// Anchor side for the anchor positioning function.
|
||||||
#[derive(
|
#[derive(
|
||||||
Animate,
|
Animate,
|
||||||
@@ -450,3 +488,13 @@ pub enum AnchorSide<P> {
|
|||||||
/// Percentage value between the `start` and `end` sides.
|
/// Percentage value between the `start` and `end` sides.
|
||||||
Percentage(P),
|
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",
|
"AnchorSizeFunction",
|
||||||
"Margin",
|
"Margin",
|
||||||
"PositionProperty",
|
"PositionProperty",
|
||||||
|
"PhysicalSide",
|
||||||
]
|
]
|
||||||
item_types = [
|
item_types = [
|
||||||
"enums",
|
"enums",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use selectors::matching::{ElementSelectorFlags, MatchingForInvalidation, Selecto
|
|||||||
use selectors::{Element, OpaqueElement};
|
use selectors::{Element, OpaqueElement};
|
||||||
use servo_arc::{Arc, ArcBorrow};
|
use servo_arc::{Arc, ArcBorrow};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use style::values::generics::length::AnchorResolutionResult;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
@@ -103,6 +104,7 @@ use style::invalidation::element::relative_selector::{
|
|||||||
};
|
};
|
||||||
use style::invalidation::element::restyle_hints::RestyleHint;
|
use style::invalidation::element::restyle_hints::RestyleHint;
|
||||||
use style::invalidation::stylesheets::RuleChangeKind;
|
use style::invalidation::stylesheets::RuleChangeKind;
|
||||||
|
use style::logical_geometry::PhysicalSide;
|
||||||
use style::media_queries::MediaList;
|
use style::media_queries::MediaList;
|
||||||
use style::parser::{Parse, ParserContext};
|
use style::parser::{Parse, ParserContext};
|
||||||
#[cfg(feature = "gecko_debug")]
|
#[cfg(feature = "gecko_debug")]
|
||||||
@@ -149,7 +151,9 @@ use style::values::computed::effects::Filter;
|
|||||||
use style::values::computed::font::{
|
use style::values::computed::font::{
|
||||||
FamilyName, FontFamily, FontFamilyList, FontStretch, FontStyle, FontWeight, GenericFontFamily,
|
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::distance::ComputeSquaredDistance;
|
||||||
use style::values::generics::color::ColorMixFlags;
|
use style::values::generics::color::ColorMixFlags;
|
||||||
use style::values::generics::easing::BeforeFlag;
|
use style::values::generics::easing::BeforeFlag;
|
||||||
@@ -9735,3 +9739,45 @@ pub unsafe extern "C" fn Servo_CSSParser_NextToken(
|
|||||||
|
|
||||||
return true;
|
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