1use std::marker::PhantomData;
6
7use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
8use html5ever::{local_name, ns};
9use layout_api::wrapper_traits::{LayoutDataTrait, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
10use layout_api::{
11 GenericLayoutDataTrait, LayoutElementType, LayoutNodeType as ScriptLayoutNodeType,
12 SVGElementData,
13};
14use malloc_size_of_derive::MallocSizeOf;
15use script::layout_dom::ServoThreadSafeLayoutNode;
16use servo_arc::Arc as ServoArc;
17use smallvec::SmallVec;
18use style::context::SharedStyleContext;
19use style::properties::ComputedValues;
20use style::selector_parser::PseudoElement;
21use style::values::specified::box_::DisplayOutside as StyloDisplayOutside;
22
23use crate::cell::{ArcRefCell, WeakRefCell};
24use crate::context::LayoutContext;
25use crate::dom_traversal::{Contents, NodeAndStyleInfo};
26use crate::flexbox::FlexLevelBox;
27use crate::flow::inline::{InlineItem, SharedInlineStyles, WeakInlineItem};
28use crate::flow::{BlockLevelBox, BlockLevelCreator};
29use crate::fragment_tree::{Fragment, FragmentFlags};
30use crate::geom::PhysicalSize;
31use crate::layout_box_base::LayoutBoxBase;
32use crate::replaced::{CanvasInfo, IFrameInfo, ImageInfo, VideoInfo};
33use crate::style_ext::{
34 ComputedValuesExt, Display, DisplayGeneratingBox, DisplayLayoutInternal, DisplayOutside,
35};
36use crate::table::{TableLevelBox, WeakTableLevelBox};
37use crate::taffy::TaffyItemBox;
38
39#[derive(MallocSizeOf)]
40pub struct PseudoLayoutData {
41 pseudo: PseudoElement,
42 data: ArcRefCell<InnerDOMLayoutData>,
43}
44
45#[derive(Default, MallocSizeOf)]
47pub struct InnerDOMLayoutData {
48 pub(super) self_box: ArcRefCell<Option<LayoutBox>>,
49 pub(super) pseudo_boxes: SmallVec<[PseudoLayoutData; 2]>,
50}
51
52impl InnerDOMLayoutData {
53 fn pseudo_layout_data(
54 &self,
55 pseudo_element: PseudoElement,
56 ) -> Option<ArcRefCell<InnerDOMLayoutData>> {
57 for pseudo_layout_data in self.pseudo_boxes.iter() {
58 if pseudo_element == pseudo_layout_data.pseudo {
59 return Some(pseudo_layout_data.data.clone());
60 }
61 }
62 None
63 }
64
65 fn create_pseudo_layout_data(
66 &mut self,
67 pseudo_element: PseudoElement,
68 ) -> ArcRefCell<InnerDOMLayoutData> {
69 let data: ArcRefCell<InnerDOMLayoutData> = Default::default();
70 self.pseudo_boxes.push(PseudoLayoutData {
71 pseudo: pseudo_element,
72 data: data.clone(),
73 });
74 data
75 }
76
77 fn fragments(&self) -> Vec<Fragment> {
78 self.self_box
79 .borrow()
80 .as_ref()
81 .and_then(|layout_box| layout_box.with_base(LayoutBoxBase::fragments))
82 .unwrap_or_default()
83 }
84
85 fn repair_style(&self, node: &ServoThreadSafeLayoutNode, context: &SharedStyleContext) {
86 if let Some(layout_object) = &*self.self_box.borrow() {
87 layout_object.repair_style(context, node, &node.style(context));
88 }
89
90 for pseudo_layout_data in self.pseudo_boxes.iter() {
91 let Some(node_with_pseudo) = node.with_pseudo(pseudo_layout_data.pseudo) else {
92 continue;
93 };
94 pseudo_layout_data
95 .data
96 .borrow()
97 .repair_style(&node_with_pseudo, context);
98 }
99 }
100
101 fn with_layout_box_base(&self, callback: impl Fn(&LayoutBoxBase)) {
102 if let Some(data) = self.self_box.borrow().as_ref() {
103 data.with_base(callback);
104 }
105 }
106
107 fn with_layout_box_base_including_pseudos(&self, callback: impl Fn(&LayoutBoxBase)) {
108 self.with_layout_box_base(&callback);
109 for pseudo_layout_data in self.pseudo_boxes.iter() {
110 pseudo_layout_data
111 .data
112 .borrow()
113 .with_layout_box_base(&callback);
114 }
115 }
116}
117
118#[derive(Debug, MallocSizeOf)]
120pub(super) enum LayoutBox {
121 DisplayContents(SharedInlineStyles),
122 BlockLevel(ArcRefCell<BlockLevelBox>),
123 InlineLevel(InlineItem),
124 FlexLevel(ArcRefCell<FlexLevelBox>),
125 TableLevelBox(TableLevelBox),
126 TaffyItemBox(ArcRefCell<TaffyItemBox>),
127}
128
129impl LayoutBox {
130 pub(crate) fn with_base<T>(&self, callback: impl FnOnce(&LayoutBoxBase) -> T) -> Option<T> {
131 Some(match self {
132 LayoutBox::DisplayContents(..) => return None,
133 LayoutBox::BlockLevel(block_level_box) => block_level_box.borrow().with_base(callback),
134 LayoutBox::InlineLevel(inline_item) => inline_item.with_base(callback),
135 LayoutBox::FlexLevel(flex_level_box) => flex_level_box.borrow().with_base(callback),
136 LayoutBox::TaffyItemBox(taffy_item_box) => taffy_item_box.borrow().with_base(callback),
137 LayoutBox::TableLevelBox(table_box) => table_box.with_base(callback),
138 })
139 }
140
141 pub(crate) fn with_base_mut<T>(
142 &mut self,
143 callback: impl FnOnce(&mut LayoutBoxBase) -> T,
144 ) -> Option<T> {
145 Some(match self {
146 LayoutBox::DisplayContents(..) => return None,
147 LayoutBox::BlockLevel(block_level_box) => {
148 block_level_box.borrow_mut().with_base_mut(callback)
149 },
150 LayoutBox::InlineLevel(inline_item) => inline_item.with_base_mut(callback),
151 LayoutBox::FlexLevel(flex_level_box) => {
152 flex_level_box.borrow_mut().with_base_mut(callback)
153 },
154 LayoutBox::TaffyItemBox(taffy_item_box) => {
155 taffy_item_box.borrow_mut().with_base_mut(callback)
156 },
157 LayoutBox::TableLevelBox(table_box) => table_box.with_base_mut(callback),
158 })
159 }
160
161 fn repair_style(
162 &self,
163 context: &SharedStyleContext,
164 node: &ServoThreadSafeLayoutNode,
165 new_style: &ServoArc<ComputedValues>,
166 ) {
167 match self {
168 LayoutBox::DisplayContents(inline_shared_styles) => {
169 *inline_shared_styles.style.borrow_mut() = new_style.clone();
170 *inline_shared_styles.selected.borrow_mut() = node.selected_style(context);
171 },
172 LayoutBox::BlockLevel(block_level_box) => {
173 block_level_box
174 .borrow_mut()
175 .repair_style(context, node, new_style);
176 },
177 LayoutBox::InlineLevel(inline_item) => {
178 inline_item.repair_style(context, node, new_style);
179 },
180 LayoutBox::FlexLevel(flex_level_box) => flex_level_box
181 .borrow_mut()
182 .repair_style(context, node, new_style),
183 LayoutBox::TableLevelBox(table_level_box) => {
184 table_level_box.repair_style(context, node, new_style)
185 },
186 LayoutBox::TaffyItemBox(taffy_item_box) => taffy_item_box
187 .borrow_mut()
188 .repair_style(context, node, new_style),
189 }
190 }
191
192 fn attached_to_tree(&self, layout_box: WeakLayoutBox) {
193 match self {
194 Self::DisplayContents(_) => {
195 },
198 Self::BlockLevel(block_level_box) => {
199 block_level_box.borrow().attached_to_tree(layout_box)
200 },
201 Self::InlineLevel(inline_item) => inline_item.attached_to_tree(layout_box),
202 Self::FlexLevel(flex_level_box) => flex_level_box.borrow().attached_to_tree(layout_box),
203 Self::TableLevelBox(table_level_box) => table_level_box.attached_to_tree(layout_box),
204 Self::TaffyItemBox(taffy_item_box) => {
205 taffy_item_box.borrow().attached_to_tree(layout_box)
206 },
207 }
208 }
209
210 fn downgrade(&self) -> WeakLayoutBox {
211 match self {
212 Self::DisplayContents(inline_shared_styles) => {
213 WeakLayoutBox::DisplayContents(inline_shared_styles.clone())
214 },
215 Self::BlockLevel(block_level_box) => {
216 WeakLayoutBox::BlockLevel(block_level_box.downgrade())
217 },
218 Self::InlineLevel(inline_item) => WeakLayoutBox::InlineLevel(inline_item.downgrade()),
219 Self::FlexLevel(flex_level_box) => WeakLayoutBox::FlexLevel(flex_level_box.downgrade()),
220 Self::TableLevelBox(table_level_box) => {
221 WeakLayoutBox::TableLevelBox(table_level_box.downgrade())
222 },
223 Self::TaffyItemBox(taffy_item_box) => {
224 WeakLayoutBox::TaffyItemBox(taffy_item_box.downgrade())
225 },
226 }
227 }
228}
229
230#[derive(Clone, Debug, MallocSizeOf)]
231pub(super) enum WeakLayoutBox {
232 DisplayContents(SharedInlineStyles),
233 BlockLevel(WeakRefCell<BlockLevelBox>),
234 InlineLevel(WeakInlineItem),
235 FlexLevel(WeakRefCell<FlexLevelBox>),
236 TableLevelBox(WeakTableLevelBox),
237 TaffyItemBox(WeakRefCell<TaffyItemBox>),
238}
239
240impl WeakLayoutBox {
241 pub(crate) fn upgrade(&self) -> Option<LayoutBox> {
242 Some(match self {
243 Self::DisplayContents(inline_shared_styles) => {
244 LayoutBox::DisplayContents(inline_shared_styles.clone())
245 },
246 Self::BlockLevel(block_level_box) => LayoutBox::BlockLevel(block_level_box.upgrade()?),
247 Self::InlineLevel(inline_item) => LayoutBox::InlineLevel(inline_item.upgrade()?),
248 Self::FlexLevel(flex_level_box) => LayoutBox::FlexLevel(flex_level_box.upgrade()?),
249 Self::TableLevelBox(table_level_box) => {
250 LayoutBox::TableLevelBox(table_level_box.upgrade()?)
251 },
252 Self::TaffyItemBox(taffy_item_box) => {
253 LayoutBox::TaffyItemBox(taffy_item_box.upgrade()?)
254 },
255 })
256 }
257}
258
259#[derive(Default, MallocSizeOf)]
263pub struct DOMLayoutData(AtomicRefCell<InnerDOMLayoutData>);
264
265impl LayoutDataTrait for DOMLayoutData {}
267impl GenericLayoutDataTrait for DOMLayoutData {
268 fn as_any(&self) -> &dyn std::any::Any {
269 self
270 }
271}
272
273pub struct BoxSlot<'dom> {
274 pub(crate) slot: ArcRefCell<Option<LayoutBox>>,
275 pub(crate) marker: PhantomData<&'dom ()>,
276}
277
278impl From<ArcRefCell<Option<LayoutBox>>> for BoxSlot<'_> {
279 fn from(slot: ArcRefCell<Option<LayoutBox>>) -> Self {
280 Self {
281 slot,
282 marker: PhantomData,
283 }
284 }
285}
286
287impl BoxSlot<'_> {
289 pub(crate) fn set(self, layout_box: LayoutBox) {
290 layout_box.attached_to_tree(layout_box.downgrade());
291 *self.slot.borrow_mut() = Some(layout_box);
292 }
293
294 pub(crate) fn take_layout_box(&self) -> Option<LayoutBox> {
295 self.slot.borrow_mut().take()
296 }
297}
298
299impl Drop for BoxSlot<'_> {
300 fn drop(&mut self) {
301 if !std::thread::panicking() {
302 assert!(self.slot.borrow().is_some(), "failed to set a layout box");
303 }
304 }
305}
306
307pub(crate) trait NodeExt<'dom> {
308 fn as_image(&self) -> Option<(ImageInfo, PhysicalSize<f64>)>;
310 fn as_canvas(&self) -> Option<(CanvasInfo, PhysicalSize<f64>)>;
311 fn as_iframe(&self) -> Option<IFrameInfo>;
312 fn as_video(&self) -> Option<(VideoInfo, Option<PhysicalSize<f64>>)>;
313 fn as_svg(&self) -> Option<SVGElementData<'dom>>;
314 fn as_typeless_object_with_data_attribute(&self) -> Option<String>;
315
316 fn ensure_inner_layout_data(&self) -> AtomicRefMut<'dom, InnerDOMLayoutData>;
317 fn inner_layout_data(&self) -> Option<AtomicRef<'dom, InnerDOMLayoutData>>;
318 fn inner_layout_data_mut(&self) -> Option<AtomicRefMut<'dom, InnerDOMLayoutData>>;
319 fn box_slot(&self) -> BoxSlot<'dom>;
320
321 fn unset_all_boxes(&self);
323
324 fn fragments_for_pseudo(&self, pseudo_element: Option<PseudoElement>) -> Vec<Fragment>;
325 fn with_layout_box_base_including_pseudos(&self, callback: impl Fn(&LayoutBoxBase));
326
327 fn repair_style(&self, context: &SharedStyleContext);
328
329 fn isolates_damage_for_damage_propagation(&self) -> bool;
340
341 fn rebuild_box_tree_from_independent_formatting_context(
348 &self,
349 layout_context: &LayoutContext,
350 ) -> bool;
351}
352
353impl<'dom> NodeExt<'dom> for ServoThreadSafeLayoutNode<'dom> {
354 fn as_image(&self) -> Option<(ImageInfo, PhysicalSize<f64>)> {
355 let (resource, metadata) = self.image_data()?;
356 let width = metadata.map(|metadata| metadata.width).unwrap_or_default();
357 let height = metadata.map(|metadata| metadata.height).unwrap_or_default();
358 let (mut width, mut height) = (width as f64, height as f64);
359 if let Some(density) = self.image_density().filter(|density| *density != 1.) {
361 width /= density;
362 height /= density;
363 }
364 Some((
365 ImageInfo {
366 image: resource,
367 showing_broken_image_icon: self.showing_broken_image_icon(),
368 url: self.image_url(),
369 },
370 PhysicalSize::new(width, height),
371 ))
372 }
373
374 fn as_svg(&self) -> Option<SVGElementData<'dom>> {
375 self.svg_data()
376 }
377
378 fn as_video(&self) -> Option<(VideoInfo, Option<PhysicalSize<f64>>)> {
379 let data = self.media_data()?;
380 let natural_size = if let Some(frame) = data.current_frame {
381 Some(PhysicalSize::new(frame.width.into(), frame.height.into()))
382 } else {
383 data.metadata
384 .map(|meta| PhysicalSize::new(meta.width.into(), meta.height.into()))
385 };
386 Some((
387 VideoInfo {
388 image_key: data.current_frame.map(|frame| frame.image_key),
389 },
390 natural_size,
391 ))
392 }
393
394 fn as_canvas(&self) -> Option<(CanvasInfo, PhysicalSize<f64>)> {
395 let canvas_data = self.canvas_data()?;
396 let source = canvas_data.image_key;
397 Some((
398 CanvasInfo { source },
399 PhysicalSize::new(canvas_data.width.into(), canvas_data.height.into()),
400 ))
401 }
402
403 fn as_iframe(&self) -> Option<IFrameInfo> {
404 match (self.iframe_pipeline_id(), self.iframe_browsing_context_id()) {
405 (Some(pipeline_id), Some(browsing_context_id)) => Some(IFrameInfo {
406 pipeline_id,
407 browsing_context_id,
408 }),
409 _ => None,
410 }
411 }
412
413 fn as_typeless_object_with_data_attribute(&self) -> Option<String> {
414 if self.type_id() !=
415 Some(ScriptLayoutNodeType::Element(
416 LayoutElementType::HTMLObjectElement,
417 ))
418 {
419 return None;
420 }
421
422 let element = self.as_element()?;
426 if element.get_attr(&ns!(), &local_name!("type")).is_some() {
427 return None;
428 }
429 element
430 .get_attr(&ns!(), &local_name!("data"))
431 .map(|string| string.to_owned())
432 }
433
434 fn ensure_inner_layout_data(&self) -> AtomicRefMut<'dom, InnerDOMLayoutData> {
435 if self.layout_data().is_none() {
436 self.initialize_layout_data::<DOMLayoutData>();
437 }
438 self.layout_data()
439 .unwrap()
440 .as_any()
441 .downcast_ref::<DOMLayoutData>()
442 .unwrap()
443 .0
444 .borrow_mut()
445 }
446
447 fn inner_layout_data(&self) -> Option<AtomicRef<'dom, InnerDOMLayoutData>> {
448 self.layout_data().map(|data| {
449 data.as_any()
450 .downcast_ref::<DOMLayoutData>()
451 .unwrap()
452 .0
453 .borrow()
454 })
455 }
456
457 fn inner_layout_data_mut(&self) -> Option<AtomicRefMut<'dom, InnerDOMLayoutData>> {
458 self.layout_data().map(|data| {
459 data.as_any()
460 .downcast_ref::<DOMLayoutData>()
461 .unwrap()
462 .0
463 .borrow_mut()
464 })
465 }
466
467 fn box_slot(&self) -> BoxSlot<'dom> {
468 let pseudo_element_chain = self.pseudo_element_chain();
469 let Some(primary) = pseudo_element_chain.primary else {
470 return self.ensure_inner_layout_data().self_box.clone().into();
471 };
472
473 let Some(secondary) = pseudo_element_chain.secondary else {
474 let primary_layout_data = self
475 .ensure_inner_layout_data()
476 .create_pseudo_layout_data(primary);
477 return primary_layout_data.borrow().self_box.clone().into();
478 };
479
480 let primary_layout_data = self
487 .inner_layout_data()
488 .expect("Should already have element InnerLayoutData here.")
489 .pseudo_layout_data(primary)
490 .expect("Should already have primary pseudo-element InnerLayoutData here");
491 let secondary_layout_data = primary_layout_data
492 .borrow_mut()
493 .create_pseudo_layout_data(secondary);
494 secondary_layout_data.borrow().self_box.clone().into()
495 }
496
497 fn unset_all_boxes(&self) {
498 let mut layout_data = self.ensure_inner_layout_data();
499 *layout_data.self_box.borrow_mut() = None;
500 layout_data.pseudo_boxes.clear();
501
502 }
505
506 fn with_layout_box_base_including_pseudos(&self, callback: impl Fn(&LayoutBoxBase)) {
507 if let Some(inner_layout_data) = self.inner_layout_data() {
508 inner_layout_data.with_layout_box_base_including_pseudos(callback);
509 }
510 }
511
512 fn fragments_for_pseudo(&self, pseudo_element: Option<PseudoElement>) -> Vec<Fragment> {
513 let Some(layout_data) = self.inner_layout_data() else {
514 return vec![];
515 };
516 match pseudo_element {
517 Some(pseudo_element) => layout_data
518 .pseudo_layout_data(pseudo_element)
519 .map(|pseudo_layout_data| pseudo_layout_data.borrow().fragments())
520 .unwrap_or_default(),
521 None => layout_data.fragments(),
522 }
523 }
524
525 fn repair_style(&self, context: &SharedStyleContext) {
526 if let Some(layout_data) = self.inner_layout_data() {
527 layout_data.repair_style(self, context);
528 }
529 }
530
531 fn isolates_damage_for_damage_propagation(&self) -> bool {
532 if self.as_element().is_some_and(|element| {
536 element.is_body_element_of_html_element_root() || element.is_root()
537 }) {
538 return false;
539 }
540
541 let Some(inner_layout_data) = self.inner_layout_data() else {
542 return false;
543 };
544 let self_box = inner_layout_data.self_box.borrow();
545 let Some(self_box) = &*self_box else {
546 return false;
547 };
548
549 match self_box {
550 LayoutBox::DisplayContents(..) => false,
551 LayoutBox::BlockLevel(block_level) => matches!(
552 &*block_level.borrow(),
553 BlockLevelBox::Independent(..) |
554 BlockLevelBox::OutOfFlowFloatBox(..) |
555 BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(..)
556 ),
557 LayoutBox::InlineLevel(inline_level) => matches!(
558 inline_level,
559 InlineItem::OutOfFlowAbsolutelyPositionedBox(..) | InlineItem::Atomic(..)
560 ),
561 LayoutBox::FlexLevel(..) => true,
562 LayoutBox::TableLevelBox(table_level_box) => matches!(
563 table_level_box,
564 TableLevelBox::Cell(..) | TableLevelBox::Caption(..),
565 ),
566 LayoutBox::TaffyItemBox(..) => true,
567 }
568 }
569
570 fn rebuild_box_tree_from_independent_formatting_context(
571 &self,
572 layout_context: &LayoutContext,
573 ) -> bool {
574 if self.as_element().is_some_and(|element| {
578 element.is_body_element_of_html_element_root() || element.is_root()
579 }) {
580 return false;
581 }
582
583 let layout_box = {
584 let Some(mut inner_layout_data) = self.inner_layout_data_mut() else {
585 return false;
586 };
587 inner_layout_data.pseudo_boxes.clear();
588 inner_layout_data.self_box.clone()
589 };
590
591 let layout_box = layout_box.borrow();
592 let Some(layout_box) = &*layout_box else {
593 return false;
594 };
595
596 let info = NodeAndStyleInfo::new(*self, self.style(&layout_context.style_context));
597 let box_style = info.style.get_box();
598 let Display::GeneratingBox(display) = box_style.display.into() else {
599 return false;
600 };
601 let contents = || {
602 assert!(
603 self.pseudo_element_chain().is_empty(),
604 "Shouldn't try to rebuild box tree from a pseudo-element"
605 );
606 Contents::for_element(info.node, layout_context)
607 };
608 match layout_box {
609 LayoutBox::DisplayContents(..) => false,
610 LayoutBox::BlockLevel(block_level) => {
611 let mut block_level = block_level.borrow_mut();
612 match &mut *block_level {
613 BlockLevelBox::Independent(independent_formatting_context) => {
614 let DisplayGeneratingBox::OutsideInside {
615 outside: DisplayOutside::Block,
616 inside: display_inside,
617 } = display
618 else {
619 return false;
620 };
621 if !matches!(
622 BlockLevelCreator::new_for_inflow_block_level_element(
623 &info,
624 display_inside,
625 contents(),
626 independent_formatting_context.propagated_data,
627 ),
628 BlockLevelCreator::Independent { .. }
629 ) {
630 return false;
631 }
632 independent_formatting_context.rebuild(layout_context, &info);
633 true
634 },
635 BlockLevelBox::OutOfFlowFloatBox(float_box) => {
636 if !info.style.clone_float().is_floating() {
637 return false;
638 }
639 float_box.contents.rebuild(layout_context, &info);
640 true
641 },
642 BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
643 if !info.style.clone_position().is_absolutely_positioned() ||
648 box_style.original_display.outside() != StyloDisplayOutside::Block
649 {
650 return false;
651 }
652 positioned_box
653 .borrow_mut()
654 .context
655 .rebuild(layout_context, &info);
656 true
657 },
658 _ => false,
659 }
660 },
661 LayoutBox::InlineLevel(inline_level) => match inline_level {
662 InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
663 if !info.style.clone_position().is_absolutely_positioned() {
664 return false;
665 }
666 positioned_box
667 .borrow_mut()
668 .context
669 .rebuild(layout_context, &info);
670 true
671 },
672 InlineItem::Atomic(atomic_box, _, _) => {
673 let flags = match contents() {
674 Contents::NonReplaced(_) => FragmentFlags::empty(),
675 Contents::Replaced(_) => FragmentFlags::IS_REPLACED,
676 Contents::Widget(_) => FragmentFlags::IS_WIDGET,
677 };
678 if !info.style.is_atomic_inline_level(flags) {
679 return false;
680 }
681 atomic_box.borrow_mut().rebuild(layout_context, &info);
682 true
683 },
684 _ => false,
685 },
686 LayoutBox::FlexLevel(flex_level_box) => {
687 let mut flex_level_box = flex_level_box.borrow_mut();
688 match &mut *flex_level_box {
689 FlexLevelBox::FlexItem(flex_item_box) => {
690 if info.style.clone_position().is_absolutely_positioned() ||
691 flex_item_box.style().clone_order() != info.style.clone_order()
692 {
693 return false;
694 }
695 flex_item_box
696 .independent_formatting_context
697 .rebuild(layout_context, &info)
698 },
699 FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
700 if !info.style.clone_position().is_absolutely_positioned() {
701 return false;
702 }
703 positioned_box
704 .borrow_mut()
705 .context
706 .rebuild(layout_context, &info);
707 },
708 }
709 true
710 },
711 LayoutBox::TableLevelBox(table_level_box) => match table_level_box {
712 TableLevelBox::Caption(caption) => {
713 if display !=
714 DisplayGeneratingBox::LayoutInternal(DisplayLayoutInternal::TableCaption)
715 {
716 return false;
717 }
718 caption.borrow_mut().context.rebuild(layout_context, &info);
719 true
720 },
721 TableLevelBox::Cell(table_cell) => {
722 if display !=
723 DisplayGeneratingBox::LayoutInternal(DisplayLayoutInternal::TableCell)
724 {
725 return false;
726 }
727 table_cell
728 .borrow_mut()
729 .context
730 .rebuild(layout_context, &info);
731 true
732 },
733 _ => false,
734 },
735 LayoutBox::TaffyItemBox(..) => false,
736 }
737 }
738}