diff --git a/components/layout/flow/construct.rs b/components/layout/flow/construct.rs index 68e7f1178d0..48493eceade 100644 --- a/components/layout/flow/construct.rs +++ b/components/layout/flow/construct.rs @@ -290,7 +290,7 @@ impl<'dom, 'style> BlockContainerBuilder<'dom, 'style> { if inline_table { self.ensure_inline_formatting_context_builder() - .push_atomic(ifc); + .push_atomic(|| ArcRefCell::new(ifc), None); } else { let table_block = ArcRefCell::new(BlockLevelBox::Independent(ifc)); @@ -472,15 +472,20 @@ impl<'dom> BlockContainerBuilder<'dom, '_> { // If this inline element is an atomic, handle it and return. let context = self.context; let propagated_data = self.propagated_data; - let atomic = self.ensure_inline_formatting_context_builder().push_atomic( - IndependentFormattingContext::construct( + + let construction_callback = || { + ArcRefCell::new(IndependentFormattingContext::construct( context, info, display_inside, contents, propagated_data, - ), - ); + )) + }; + let old_layout_box = box_slot.take_layout_box_if_undamaged(info.damage); + let atomic = self + .ensure_inline_formatting_context_builder() + .push_atomic(construction_callback, old_layout_box); box_slot.set(LayoutBox::InlineLevel(vec![atomic])); return; }, diff --git a/components/layout/flow/inline/construct.rs b/components/layout/flow/inline/construct.rs index 5acc10754fc..1b4fe869416 100644 --- a/components/layout/flow/inline/construct.rs +++ b/components/layout/flow/inline/construct.rs @@ -18,6 +18,7 @@ use super::{ }; use crate::cell::ArcRefCell; use crate::context::LayoutContext; +use crate::dom::LayoutBox; use crate::dom_traversal::NodeAndStyleInfo; use crate::flow::float::FloatBox; use crate::formatting_contexts::IndependentFormattingContext; @@ -153,10 +154,30 @@ impl InlineFormattingContextBuilder { pub(crate) fn push_atomic( &mut self, - independent_formatting_context: IndependentFormattingContext, + independent_formatting_context_creator: impl FnOnce() + -> ArcRefCell, + old_layout_box: Option, ) -> ArcRefCell { + // If there is an existing undamaged layout box that's compatible, use that. + let independent_formatting_context = old_layout_box + .and_then(|layout_box| { + let LayoutBox::InlineLevel(inline_level_boxes) = layout_box else { + return None; + }; + + // If there's an existing box, it should be a compatible atomic inline and should + // not have been subject to inline-block splitting. + assert_eq!(inline_level_boxes.len(), 1); + let first_box = inline_level_boxes.into_iter().next()?; + match &*first_box.borrow() { + InlineItem::Atomic(atomic, ..) => Some(atomic.clone()), + _ => None, + } + }) + .unwrap_or_else(independent_formatting_context_creator); + let inline_level_box = ArcRefCell::new(InlineItem::Atomic( - ArcRefCell::new(independent_formatting_context), + independent_formatting_context, self.current_text_offset, Level::ltr(), /* This will be assigned later if necessary. */ ));