diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index f71187e1118..9f98174e2cd 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -12,7 +12,10 @@ use crate::fragments::{ DebugId, Fragment, TextFragment, }; use crate::geom::flow_relative::{Rect, Sides, Vec2}; -use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext}; +use crate::positioned::{ + relative_adjustement, AbsolutelyPositionedBox, HoistedAbsolutelyPositionedBox, + PositioningContext, +}; use crate::sizing::ContentSizes; use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside}; use crate::ContainingBlock; @@ -64,6 +67,7 @@ struct InlineNestingLevelState<'box_tree> { fragments_so_far: Vec, inline_start: Length, max_block_size_of_fragments_so_far: Length, + positioning_context: Option, } struct PartialInlineBoxFragment<'box_tree> { @@ -86,6 +90,31 @@ struct InlineFormattingContextState<'box_tree, 'a, 'b> { current_nesting_level: InlineNestingLevelState<'box_tree>, } +impl<'box_tree, 'a, 'b> InlineFormattingContextState<'box_tree, 'a, 'b> { + fn push_hoisted_box_to_positioning_context( + &mut self, + hoisted_box: HoistedAbsolutelyPositionedBox, + ) { + if let Some(context) = self.current_nesting_level.positioning_context.as_mut() { + context.push(hoisted_box); + return; + } + + for nesting_level in self.partial_inline_boxes_stack.iter_mut().rev() { + if let Some(context) = nesting_level + .parent_nesting_level + .positioning_context + .as_mut() + { + context.push(hoisted_box); + return; + } + } + + self.positioning_context.push(hoisted_box); + } +} + struct Lines { // One anonymous fragment per line fragments: Vec, @@ -226,6 +255,7 @@ impl InlineFormattingContext { fragments_so_far: Vec::with_capacity(self.inline_level_boxes.len()), inline_start: Length::zero(), max_block_size_of_fragments_so_far: Length::zero(), + positioning_context: None, }, }; loop { @@ -257,15 +287,14 @@ impl InlineFormattingContext { panic!("display:none does not generate an abspos box") }, }; - let hoisted_fragment = - box_.clone().to_hoisted(initial_start_corner, tree_rank); - let hoisted_fragment_id = hoisted_fragment.fragment_id; - ifc.positioning_context.push(hoisted_fragment); - ifc.lines - .fragments - .push(Fragment::AbsoluteOrFixedPositioned( - AbsoluteOrFixedPositionedFragment(hoisted_fragment_id), - )); + let hoisted_box = box_.clone().to_hoisted(initial_start_corner, tree_rank); + let hoisted_fragment_id = hoisted_box.fragment_id; + ifc.push_hoisted_box_to_positioning_context(hoisted_box); + ifc.current_nesting_level.fragments_so_far.push( + Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment( + hoisted_fragment_id, + )), + ); }, InlineLevelBox::OutOfFlowFloatBox(_box_) => { // TODO @@ -275,6 +304,7 @@ impl InlineFormattingContext { // Reached the end of ifc.remaining_boxes if let Some(mut partial) = ifc.partial_inline_boxes_stack.pop() { partial.finish_layout( + layout_context, &mut ifc.current_nesting_level, &mut ifc.inline_position, false, @@ -392,6 +422,7 @@ impl InlineBox { if style.clone_position().is_relative() { start_corner += &relative_adjustement(&style, ifc.containing_block) } + let positioning_context = PositioningContext::new_for_style(&style); PartialInlineBoxFragment { tag: self.tag, style, @@ -409,6 +440,7 @@ impl InlineBox { fragments_so_far: Vec::with_capacity(self.children.len()), inline_start: ifc.inline_position, max_block_size_of_fragments_so_far: Length::zero(), + positioning_context, }, ), } @@ -418,6 +450,7 @@ impl InlineBox { impl<'box_tree> PartialInlineBoxFragment<'box_tree> { fn finish_layout( &mut self, + layout_context: &LayoutContext, nesting_level: &mut InlineNestingLevelState, inline_position: &mut Length, at_line_break: bool, @@ -459,6 +492,11 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> { fragment.border.block_sum() + fragment.margin.block_sum(), ); + + if let Some(context) = nesting_level.positioning_context.as_mut() { + context.layout_collected_children(layout_context, &mut fragment); + } + self.parent_nesting_level .fragments_so_far .push(Fragment::Box(fragment)); @@ -748,7 +786,12 @@ impl TextRun { ifc.current_nesting_level.inline_start = Length::zero(); let mut nesting_level = &mut ifc.current_nesting_level; for partial in ifc.partial_inline_boxes_stack.iter_mut().rev() { - partial.finish_layout(nesting_level, &mut ifc.inline_position, true); + partial.finish_layout( + layout_context, + nesting_level, + &mut ifc.inline_position, + true, + ); partial.start_corner.inline = Length::zero(); partial.padding.inline_start = Length::zero(); partial.border.inline_start = Length::zero(); diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index b9dca32db12..a0216ec296c 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -172,7 +172,7 @@ impl PositioningContext { self.for_nearest_positioned_ancestor.is_some() } - fn new_for_style(style: &ComputedValues) -> Option { + pub(crate) fn new_for_style(style: &ComputedValues) -> Option { if style.establishes_containing_block_for_all_descendants() { Some(Self::new_for_containing_block_for_all_descendants()) } else if style.establishes_containing_block() { @@ -243,7 +243,7 @@ impl PositioningContext { // Lay out the hoisted boxes collected into this `PositioningContext` and add them // to the given `BoxFragment`. - fn layout_collected_children( + pub fn layout_collected_children( &mut self, layout_context: &LayoutContext, new_fragment: &mut BoxFragment, diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index 7ed41d1cd91..cdde69a7866 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -245,7 +245,9 @@ impl ComputedValuesExt for ComputedValues { /// Returns true if this style establishes a containing block for all descendants /// including fixed and absolutely positioned ones. fn establishes_containing_block_for_all_descendants(&self) -> bool { - if self.has_transform_or_perspective() { + if self.get_box().display.outside() != stylo::DisplayOutside::Inline && + self.has_transform_or_perspective() + { return true; } diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/positioning/abspos-inline-008.xht.ini b/tests/wpt/metadata-layout-2020/css/CSS2/positioning/abspos-inline-008.xht.ini deleted file mode 100644 index f77c2c83d5d..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/positioning/abspos-inline-008.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[abspos-inline-008.xht] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/positioning/toogle-abspos-on-relpos-inline-child.html.ini b/tests/wpt/metadata-layout-2020/css/CSS2/positioning/toogle-abspos-on-relpos-inline-child.html.ini deleted file mode 100644 index 928300474c1..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/positioning/toogle-abspos-on-relpos-inline-child.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[toogle-abspos-on-relpos-inline-child.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/css-transforms/preserve3d-button.html.ini b/tests/wpt/metadata-layout-2020/css/css-transforms/preserve3d-button.html.ini deleted file mode 100644 index 0c6784a80ed..00000000000 --- a/tests/wpt/metadata-layout-2020/css/css-transforms/preserve3d-button.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[preserve3d-button.html] - expected: FAIL diff --git a/tests/wpt/metadata-layout-2020/css/filter-effects/filtered-inline-is-container.html.ini b/tests/wpt/metadata-layout-2020/css/filter-effects/filtered-inline-is-container.html.ini deleted file mode 100644 index b41a8df9ac0..00000000000 --- a/tests/wpt/metadata-layout-2020/css/filter-effects/filtered-inline-is-container.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[filtered-inline-is-container.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta-layout-2020/css/absolute_inline_containing_block_a.html.ini b/tests/wpt/mozilla/meta-layout-2020/css/absolute_inline_containing_block_a.html.ini deleted file mode 100644 index eb5471a558b..00000000000 --- a/tests/wpt/mozilla/meta-layout-2020/css/absolute_inline_containing_block_a.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute_inline_containing_block_a.html] - expected: FAIL