commit 99598e4feb20b2b8283d64777df889c36e1985b2
parent 570ec34c7ace0099bc87b3c2c1fa71588c0fbcc6
Author: Jonathan Watt <jwatt@jwatt.org>
Date: Wed, 3 Dec 2025 17:44:42 +0000
Bug 1991929 p1. Apply <position-area> values for `position-try-fallbacks` into computed style. r=emilio,firefox-style-system-reviewers,layout-anchor-positioning-reviewers
We already do this for [<dashed-ident> || <try-tactic>] values, but currently
try to pass position-area values through to functions that need it in an effort
to avoid creating a new ComputedValues for this case. Unfortunately we're not
passing it through to all the places that need it, and doing so would be very
messy.
Removal of the current code that passes position-area values will come in a
later patch.
Differential Revision: https://phabricator.services.mozilla.com/D274931
Diffstat:
6 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/layout/generic/AbsoluteContainingBlock.cpp b/layout/generic/AbsoluteContainingBlock.cpp
@@ -1147,17 +1147,15 @@ void AbsoluteContainingBlock::ReflowAbsoluteFrame(
RefPtr<ComputedStyle> nextFallbackStyle;
while (true) {
nextFallback = &fallbacks[aIndex];
- if (nextFallback->IsIdentAndOrTactic()) {
- nextFallbackStyle = aPresContext->StyleSet()->ResolvePositionTry(
- *aKidFrame->GetContent()->AsElement(), *aKidFrame->Style(),
- nextFallback->AsIdentAndOrTactic());
- if (!nextFallbackStyle) {
- // No @position-try rule for this name was found, per spec we should
- // skip it.
- aIndex++;
- if (aIndex >= fallbacks.Length()) {
- return false;
- }
+ nextFallbackStyle = aPresContext->StyleSet()->ResolvePositionTry(
+ *aKidFrame->GetContent()->AsElement(), *aKidFrame->Style(),
+ *nextFallback);
+ if (!nextFallbackStyle) {
+ // No @position-try rule for this name was found, per spec we should
+ // skip it.
+ aIndex++;
+ if (aIndex >= fallbacks.Length()) {
+ return false;
}
}
break;
diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp
@@ -611,7 +611,7 @@ already_AddRefed<ComputedStyle> ServoStyleSet::ResolveStartingStyle(
already_AddRefed<ComputedStyle> ServoStyleSet::ResolvePositionTry(
dom::Element& aElement, ComputedStyle& aStyle,
- const StyleDashedIdentAndOrTryTactic& aFallback) {
+ const StylePositionTryFallbacksItem& aFallback) {
return Servo_ComputedValues_GetForPositionTry(mRawData.get(), &aStyle,
&aElement, &aFallback)
.Consume();
diff --git a/layout/style/ServoStyleSet.h b/layout/style/ServoStyleSet.h
@@ -32,7 +32,7 @@ enum class MediaFeatureChangeReason : uint8_t;
enum class StylePageSizeOrientation : uint8_t;
enum class StyleRuleChangeKind : uint32_t;
enum class StyleRelativeSelectorNthEdgeInvalidateFor : uint8_t;
-struct StyleDashedIdentAndOrTryTactic;
+union StylePositionTryFallbacksItem;
struct StyleRuleChange;
class ErrorResult;
@@ -267,7 +267,7 @@ class ServoStyleSet {
already_AddRefed<ComputedStyle> ResolvePositionTry(
dom::Element& aElement, ComputedStyle& aStyle,
- const StyleDashedIdentAndOrTryTactic&);
+ const StylePositionTryFallbacksItem&);
size_t SheetCount(Origin) const;
StyleSheet* SheetAt(Origin, size_t aIndex) const;
diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs
@@ -2488,7 +2488,7 @@ impl<'a> StyleBuilder<'a> {
///
/// Do _not_ actually call this to construct a style, this should mostly be
/// used for animations.
- pub fn for_animation(
+ pub fn for_derived_style(
device: &'a Device,
stylist: Option<&'a Stylist>,
style_to_derive_from: &'a ComputedValues,
diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs
@@ -22,8 +22,10 @@ use crate::invalidation::media_queries::{
};
use crate::invalidation::stylesheets::RuleChangeKind;
use crate::media_queries::Device;
-use crate::properties::{self, CascadeMode, ComputedValues, FirstLineReparenting};
-use crate::properties::{AnimationDeclarations, PropertyDeclarationBlock};
+use crate::properties::{
+ self, AnimationDeclarations, CascadeMode, ComputedValues, FirstLineReparenting,
+ PropertyDeclarationBlock, StyleBuilder,
+};
use crate::properties_and_values::registry::{
PropertyRegistration, PropertyRegistrationData, ScriptRegistry as CustomPropertyScriptRegistry,
};
@@ -56,7 +58,7 @@ use crate::stylesheets::{
PerOriginIter, StylesheetContents, StylesheetInDocument,
};
use crate::stylesheets::{CustomMediaEvaluator, CustomMediaMap};
-use crate::values::computed::DashedIdentAndOrTryTactic;
+use crate::values::specified::position::PositionTryFallbacksItem;
use crate::values::specified::position::PositionTryFallbacksTryTactic;
use crate::values::{computed, AtomIdent};
use crate::AllocErr;
@@ -1307,11 +1309,26 @@ impl Stylist {
style: &ComputedValues,
guards: &StylesheetGuards,
element: E,
- name_and_try_tactic: &DashedIdentAndOrTryTactic,
+ fallback_item: &PositionTryFallbacksItem,
) -> Option<Arc<ComputedValues>>
where
E: TElement,
{
+ let name_and_try_tactic = match *fallback_item {
+ PositionTryFallbacksItem::PositionArea(area) => {
+ // We don't bother passing the parent_style argument here since
+ // we probably don't need it. If we do, we could wrap this up in
+ // a style_resolver::with_default_parent_styles call, as below.
+ let mut builder =
+ StyleBuilder::for_derived_style(&self.device, Some(self), style, None);
+ builder.mutate_position().set_position_area(area);
+ return Some(builder.build());
+ },
+ PositionTryFallbacksItem::IdentAndOrTactic(ref name_and_try_tactic) => {
+ name_and_try_tactic
+ },
+ };
+
let fallback_rule = if !name_and_try_tactic.ident.is_empty() {
Some(self.lookup_position_try(&name_and_try_tactic.ident.0, element)?)
} else {
diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs
@@ -174,7 +174,7 @@ use style::values::generics::length::GenericAnchorSizeFunction;
use style::values::resolved;
use style::values::specified::align::AlignFlags;
use style::values::specified::intersection_observer::IntersectionObserverMargin;
-use style::values::specified::position::DashedIdentAndOrTryTactic;
+use style::values::specified::position::PositionTryFallbacksItem;
use style::values::specified::source_size_list::SourceSizeList;
use style::values::specified::svg_path::PathCommand;
use style::values::specified::{AbsoluteLength, NoCalcLength};
@@ -4452,7 +4452,7 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForPositionTry(
raw_data: &PerDocumentStyleData,
style: &ComputedValues,
element: &RawGeckoElement,
- name_and_try_tactic: &DashedIdentAndOrTryTactic,
+ fallback_item: &PositionTryFallbacksItem,
) -> Strong<ComputedValues> {
let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
@@ -4460,7 +4460,7 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForPositionTry(
let element = GeckoElement(element);
let data = raw_data.borrow();
data.stylist
- .resolve_position_try(style, &guards, element, name_and_try_tactic)
+ .resolve_position_try(style, &guards, element, fallback_item)
.into()
}
@@ -6946,7 +6946,7 @@ fn create_context_for_animation<'a>(
container_size_query: ContainerSizeQuery<'a>,
) -> Context<'a> {
Context::new_for_animation(
- StyleBuilder::for_animation(
+ StyleBuilder::for_derived_style(
per_doc_data.stylist.device(),
Some(&per_doc_data.stylist),
style,