accessibility_tree/layout/flow/
root.rs1use super::*;
2
3impl crate::dom::Document {
4 pub fn layout(
5 &self,
6 viewport: crate::primitives::Size<crate::primitives::CssPx>,
7 ) -> Vec<Fragment> {
8 BoxTreeRoot::construct(self).layout(viewport)
9 }
10}
11
12struct BoxTreeRoot(BlockFormattingContext);
13
14impl BoxTreeRoot {
15 pub fn construct(document: &dom::Document) -> Self {
16 let author_styles = &document.parse_stylesheets();
17 let context = Context {
18 document,
19 author_styles,
20 };
21 let root_element = document.root_element();
22 let style = style_for_element(context.author_styles, context.document, root_element, None);
23 let (contains_floats, boxes) = construct_for_root_element(&context, root_element, style);
24 Self(BlockFormattingContext {
25 contains_floats: contains_floats == ContainsFloats::Yes,
26 contents: BlockContainer::BlockLevelBoxes(boxes),
27 })
28 }
29}
30
31fn construct_for_root_element(
32 context: &Context,
33 root_element: dom::NodeId,
34 style: Arc<ComputedValues>,
35) -> (ContainsFloats, Vec<Arc<BlockLevelBox>>) {
36 let replaced = ReplacedContent::for_element(root_element, context);
37
38 let display_inside = match style.box_.display {
39 Display::None => return (ContainsFloats::No, Vec::new()),
40 Display::Contents if replaced.is_some() => {
41 return (ContainsFloats::No, Vec::new());
43 }
44 Display::Contents => DisplayInside::Flow,
46 Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside,
48 };
49
50 if let Some(replaced) = replaced {
51 let _box = match replaced {};
52 #[allow(unreachable_code)]
53 {
54 return (ContainsFloats::No, vec![Arc::new(_box)]);
55 }
56 }
57
58 let contents = IndependentFormattingContext::construct(
59 context,
60 &style,
61 display_inside,
62 Contents::OfElement(root_element),
63 );
64 if style.box_.position.is_absolutely_positioned() {
65 (
66 ContainsFloats::No,
67 vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
68 AbsolutelyPositionedBox { style, contents },
69 ))],
70 )
71 } else if style.box_.float.is_floating() {
72 (
73 ContainsFloats::Yes,
74 vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox {
75 contents,
76 style,
77 }))],
78 )
79 } else {
80 (
81 ContainsFloats::No,
82 vec![Arc::new(BlockLevelBox::Independent { style, contents })],
83 )
84 }
85}
86
87impl BoxTreeRoot {
88 fn layout(&self, viewport: crate::primitives::Size<crate::primitives::CssPx>) -> Vec<Fragment> {
89 let initial_containing_block_size = Vec2 {
90 inline: Length { px: viewport.width },
91 block: Length {
92 px: viewport.height,
93 },
94 };
95
96 let initial_containing_block = ContainingBlock {
97 inline_size: initial_containing_block_size.inline,
98 block_size: LengthOrAuto::Length(initial_containing_block_size.block),
99 mode: (WritingMode::HorizontalTb, Direction::Ltr),
102 };
103 let dummy_tree_rank = 0;
104 let mut absolutely_positioned_fragments = vec![];
105 let mut flow_children = self.0.layout(
106 &initial_containing_block,
107 dummy_tree_rank,
108 &mut absolutely_positioned_fragments,
109 );
110
111 let initial_containing_block = DefiniteContainingBlock {
112 size: initial_containing_block_size,
113 mode: initial_containing_block.mode,
114 };
115 flow_children.fragments.par_extend(
116 absolutely_positioned_fragments
117 .par_iter()
118 .map(|a| a.layout(&initial_containing_block)),
119 );
120 flow_children.fragments
121 }
122}