diff --git a/components/layout/dom.rs b/components/layout/dom.rs index 56daa77dc21..6a1aab4e7a6 100644 --- a/components/layout/dom.rs +++ b/components/layout/dom.rs @@ -180,6 +180,10 @@ impl BoxSlot<'_> { *slot.borrow_mut() = Some(box_); } } + + pub(crate) fn take_layout_box(&self) -> Option { + self.slot.as_ref().and_then(|slot| slot.borrow_mut().take()) + } } impl Drop for BoxSlot<'_> { diff --git a/components/layout/flow/construct.rs b/components/layout/flow/construct.rs index 71dbdcbc19b..68e7f1178d0 100644 --- a/components/layout/flow/construct.rs +++ b/components/layout/flow/construct.rs @@ -700,7 +700,6 @@ impl BlockLevelJob<'_> { }, None => None, } { - block_level_box.borrow().invalidate_cached_fragment(); return block_level_box; } } diff --git a/components/layout/table/construct.rs b/components/layout/table/construct.rs index 0ef39537e35..aa5c97c8107 100644 --- a/components/layout/table/construct.rs +++ b/components/layout/table/construct.rs @@ -854,21 +854,37 @@ impl<'dom> TraversalHandler<'dom> for TableBuilderTraversal<'_, 'dom> { let Contents::NonReplaced(non_replaced_contents) = contents else { unreachable!("Replaced should not have a LayoutInternal display type."); }; - let contents = - IndependentNonReplacedContents::Flow(BlockFormattingContext::construct( - self.context, - info, - non_replaced_contents, - self.current_propagated_data, - false, /* is_list_item */ - )); - let caption = ArcRefCell::new(TableCaption { - context: IndependentFormattingContext { - base: LayoutBoxBase::new(info.into(), info.style.clone()), - contents: IndependentFormattingContextContents::NonReplaced(contents), - }, + let old_caption = (!info.damage.has_box_damage()) + .then(|| match box_slot.take_layout_box() { + Some(LayoutBox::TableLevelBox(TableLevelBox::Caption(caption))) => { + Some(caption) + }, + _ => None, + }) + .flatten(); + + let caption = old_caption.unwrap_or_else(|| { + let contents = IndependentNonReplacedContents::Flow( + BlockFormattingContext::construct( + self.context, + info, + non_replaced_contents, + self.current_propagated_data, + false, /* is_list_item */ + ), + ); + + ArcRefCell::new(TableCaption { + context: IndependentFormattingContext { + base: LayoutBoxBase::new(info.into(), info.style.clone()), + contents: IndependentFormattingContextContents::NonReplaced( + contents, + ), + }, + }) }); + self.builder.table.captions.push(caption.clone()); box_slot.set(LayoutBox::TableLevelBox(TableLevelBox::Caption(caption))); }, diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index ff2a3c155d5..9a2e97f3162 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -145,6 +145,10 @@ pub(crate) fn compute_damage_and_repair_style_inner( element_data.borrow_mut().damage.insert(element_damage); } + if element_damage.contains(LayoutDamage::recollect_box_tree_children()) { + node.invalidate_cached_fragment(); + } + // Only propagate up layout phases from children, as other types of damage are // incorporated into `element_damage` above. element_damage | (damage_from_children & RestyleDamage::RELAYOUT)