aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/layout_2020/positioned.rs62
1 files changed, 42 insertions, 20 deletions
diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs
index f9e5671e9db..7c3c2588d7c 100644
--- a/components/layout_2020/positioned.rs
+++ b/components/layout_2020/positioned.rs
@@ -833,7 +833,11 @@ impl<'a> AbsoluteAxisSolver<'a> {
self.box_offsets.end.non_auto(),
) {
(None, None) => solve_for_anchor(if self.flip_anchor {
- Anchor::End(self.containing_size - self.static_position_rect_axis.origin)
+ Anchor::End(
+ self.containing_size -
+ self.static_position_rect_axis.origin -
+ self.static_position_rect_axis.length,
+ )
} else {
Anchor::Start(self.static_position_rect_axis.origin)
}),
@@ -911,40 +915,58 @@ impl<'a> AbsoluteAxisSolver<'a> {
}
fn origin_for_alignment_or_justification(&self, margin_box_axis: RectAxis) -> Option<Au> {
- let alignment_container = match (
+ let (alignment_container, flip_anchor) = match (
self.box_offsets.start.non_auto(),
self.box_offsets.end.non_auto(),
) {
- (None, None) => self.static_position_rect_axis,
+ (None, None) => (self.static_position_rect_axis, self.flip_anchor),
(Some(start), Some(end)) => {
let start = start.to_used_value(self.containing_size);
let end = end.to_used_value(self.containing_size);
-
- RectAxis {
+ let alignment_container = RectAxis {
origin: start,
length: self.containing_size - (end + start),
- }
+ };
+ (alignment_container, false)
},
_ => return None,
};
- let mut value_after_safety = self.alignment.value();
- if self.alignment.flags() == AlignFlags::SAFE &&
- margin_box_axis.length > alignment_container.length
+ // Here we resolve the alignment to either start, center, or end.
+ // Note we need to handle both self-alignment values (when some inset isn't auto)
+ // and distributed alignment values (when both insets are auto).
+ // The latter are treated as their fallback alignment.
+ let alignment = match self.alignment.value() {
+ // https://drafts.csswg.org/css-align/#valdef-self-position-end
+ // https://drafts.csswg.org/css-align/#valdef-self-position-flex-end
+ AlignFlags::END | AlignFlags::FLEX_END => AlignFlags::END,
+ // https://drafts.csswg.org/css-align/#valdef-self-position-center
+ // https://drafts.csswg.org/css-align/#valdef-align-content-space-around
+ // https://drafts.csswg.org/css-align/#valdef-align-content-space-evenly
+ AlignFlags::CENTER | AlignFlags::SPACE_AROUND | AlignFlags::SPACE_EVENLY => {
+ AlignFlags::CENTER
+ },
+ // TODO(#34282): handle missing values: self-start, self-end, left, right.
+ _ => AlignFlags::START,
+ };
+
+ if alignment == AlignFlags::START ||
+ self.alignment.flags() == AlignFlags::SAFE &&
+ margin_box_axis.length > alignment_container.length
{
- value_after_safety = AlignFlags::START;
+ // Aligning to start is no-op, so just return `None`. This should be equivalent
+ // to returning `Some(alignment_container.origin + free_space)` if `flip_anchor`,
+ // or `Some(alignment_container.origin)` otherwise.
+ return None;
}
- match value_after_safety {
- AlignFlags::CENTER | AlignFlags::SPACE_AROUND | AlignFlags::SPACE_EVENLY => Some(
- alignment_container.origin +
- ((alignment_container.length - margin_box_axis.length) / 2),
- ),
- AlignFlags::FLEX_END | AlignFlags::END => Some(
- alignment_container.origin + alignment_container.length - margin_box_axis.length,
- ),
- _ => None,
- }
+ let free_space = alignment_container.length - margin_box_axis.length;
+ Some(match alignment {
+ AlignFlags::CENTER => alignment_container.origin + free_space / 2,
+ AlignFlags::END if flip_anchor => alignment_container.origin,
+ AlignFlags::END => alignment_container.origin + free_space,
+ _ => unreachable!(),
+ })
}
fn solve_alignment(