diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 0d1f2199597..f71187e1118 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -60,7 +60,7 @@ pub(crate) struct TextRun { } struct InlineNestingLevelState<'box_tree> { - remaining_boxes: std::slice::Iter<'box_tree, ArcRefCell>, + remaining_boxes: InlineBoxChildIter<'box_tree>, fragments_so_far: Vec, inline_start: Length, max_block_size_of_fragments_so_far: Length, @@ -222,7 +222,7 @@ impl InlineFormattingContext { }, inline_position: Length::zero(), current_nesting_level: InlineNestingLevelState { - remaining_boxes: self.inline_level_boxes.iter(), + remaining_boxes: InlineBoxChildIter::from_formatting_context(self), fragments_so_far: Vec::with_capacity(self.inline_level_boxes.len()), inline_start: Length::zero(), max_block_size_of_fragments_so_far: Length::zero(), @@ -232,7 +232,7 @@ impl InlineFormattingContext { if let Some(child) = ifc.current_nesting_level.remaining_boxes.next() { match &*child.borrow() { InlineLevelBox::InlineBox(inline) => { - let partial = inline.start_layout(&mut ifc); + let partial = inline.start_layout(child.clone(), &mut ifc); ifc.partial_inline_boxes_stack.push(partial) }, InlineLevelBox::TextRun(run) => run.layout(layout_context, &mut ifc), @@ -257,7 +257,8 @@ impl InlineFormattingContext { panic!("display:none does not generate an abspos box") }, }; - let hoisted_fragment = box_.to_hoisted(initial_start_corner, tree_rank); + 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 @@ -365,7 +366,8 @@ impl Lines { impl InlineBox { fn start_layout<'box_tree>( - &'box_tree self, + &self, + this_inline_level_box: ArcRefCell, ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>, ) -> PartialInlineBoxFragment<'box_tree> { let style = self.style.clone(); @@ -401,7 +403,9 @@ impl InlineBox { parent_nesting_level: std::mem::replace( &mut ifc.current_nesting_level, InlineNestingLevelState { - remaining_boxes: self.children.iter(), + remaining_boxes: InlineBoxChildIter::from_inline_level_box( + this_inline_level_box, + ), fragments_so_far: Vec::with_capacity(self.children.len()), inline_start: ifc.inline_position, max_block_size_of_fragments_so_far: Length::zero(), @@ -461,10 +465,10 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> { } } -fn layout_atomic<'box_tree>( +fn layout_atomic( layout_context: &LayoutContext, - ifc: &mut InlineFormattingContextState<'box_tree, '_, '_>, - atomic: &'box_tree IndependentFormattingContext, + ifc: &mut InlineFormattingContextState, + atomic: &IndependentFormattingContext, ) { let cbis = ifc.containing_block.inline_size; let padding = atomic.style.padding().percentages_relative_to(cbis); @@ -759,3 +763,54 @@ impl TextRun { } } } + +enum InlineBoxChildIter<'box_tree> { + InlineFormattingContext(std::slice::Iter<'box_tree, ArcRefCell>), + InlineBox { + inline_level_box: ArcRefCell, + child_index: usize, + }, +} + +impl<'box_tree> InlineBoxChildIter<'box_tree> { + fn from_formatting_context( + inline_formatting_context: &'box_tree InlineFormattingContext, + ) -> InlineBoxChildIter<'box_tree> { + InlineBoxChildIter::InlineFormattingContext( + inline_formatting_context.inline_level_boxes.iter(), + ) + } + + fn from_inline_level_box( + inline_level_box: ArcRefCell, + ) -> InlineBoxChildIter<'box_tree> { + InlineBoxChildIter::InlineBox { + inline_level_box, + child_index: 0, + } + } +} + +impl<'box_tree> Iterator for InlineBoxChildIter<'box_tree> { + type Item = ArcRefCell; + fn next(&mut self) -> Option> { + match *self { + InlineBoxChildIter::InlineFormattingContext(ref mut iter) => iter.next().cloned(), + InlineBoxChildIter::InlineBox { + ref inline_level_box, + ref mut child_index, + } => match *inline_level_box.borrow() { + InlineLevelBox::InlineBox(ref inline_box) => { + if *child_index >= inline_box.children.len() { + return None; + } + + let kid = inline_box.children[*child_index].clone(); + *child_index += 1; + Some(kid) + }, + _ => unreachable!(), + }, + } + } +} diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index fa0ed0b7c00..6aab3ba2be6 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -315,7 +315,7 @@ impl BlockLevelBox { )) }, BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { - let hoisted_fragment = box_.to_hoisted(Vec2::zero(), tree_rank); + let hoisted_fragment = box_.clone().to_hoisted(Vec2::zero(), tree_rank); let hoisted_fragment_id = hoisted_fragment.fragment_id.clone(); positioning_context.push(hoisted_fragment); Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment(