Make IndependentFormattingContext a struct that owns styles

… and has a private enum for its contents.

Privacy forces the rest of the code to go through methods
rather than matching on the enum,
reducing accidental layout-mode-specific behavior.
This commit is contained in:
Simon Sapin 2019-11-26 11:22:23 +01:00
parent 799057f1e6
commit b2b3ea992c
9 changed files with 149 additions and 123 deletions

View file

@ -7,9 +7,10 @@ use crate::element_data::LayoutBox;
use crate::flow::float::FloatBox;
use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox, TextRun};
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::formatting_contexts::IndependentFormattingContext;
use crate::positioned::AbsolutelyPositionedBox;
use crate::style_ext::{DisplayGeneratingBox, DisplayInside, DisplayOutside};
use crate::{take, IndependentFormattingContext};
use crate::take;
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
@ -450,11 +451,10 @@ where
AbsolutelyPositionedBox {
contents: IndependentFormattingContext::construct(
unimplemented!(),
&style,
style,
display_inside,
contents,
),
style,
},
));
self.current_inline_level_boxes().push(box_.clone());
@ -482,11 +482,10 @@ where
let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox {
contents: IndependentFormattingContext::construct(
self.context,
&style,
style,
display_inside,
contents,
),
style,
}));
self.current_inline_level_boxes().push(box_.clone());
box_slot.set(LayoutBox::InlineLevel(box_))
@ -562,12 +561,12 @@ where
} => {
let contents = IndependentFormattingContext::construct(
context,
&style,
style,
display_inside,
contents,
);
(
Arc::new(BlockLevelBox::Independent { style, contents }),
Arc::new(BlockLevelBox::Independent(contents)),
ContainsFloats::No,
)
},
@ -580,11 +579,10 @@ where
AbsolutelyPositionedBox {
contents: IndependentFormattingContext::construct(
context,
&style,
style,
display_inside,
contents,
),
style: style,
},
));
(block_level_box, ContainsFloats::No)
@ -596,14 +594,12 @@ where
} => {
let contents = IndependentFormattingContext::construct(
context,
&style,
style,
display_inside,
contents,
);
let block_level_box = Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox {
contents,
style,
}));
let block_level_box =
Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox { contents }));
(block_level_box, ContainsFloats::Yes)
},
}

View file

@ -2,13 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::IndependentFormattingContext;
use crate::formatting_contexts::IndependentFormattingContext;
use servo_arc::Arc;
use style::properties::ComputedValues;
#[derive(Debug)]
pub(crate) struct FloatBox {
pub style: Arc<ComputedValues>,
pub contents: IndependentFormattingContext,
}

View file

@ -118,7 +118,7 @@ impl InlineFormattingContext {
},
InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
let initial_start_corner =
match Display::from(box_.style.get_box().original_display) {
match Display::from(box_.contents.style.get_box().original_display) {
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside {
outside,
inside: _,

View file

@ -7,6 +7,7 @@
use crate::context::LayoutContext;
use crate::flow::float::{FloatBox, FloatContext};
use crate::flow::inline::InlineFormattingContext;
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::{
AnonymousFragment, BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment,
};
@ -15,7 +16,7 @@ use crate::positioned::{
adjust_static_positions, AbsolutelyPositionedBox, AbsolutelyPositionedFragment,
};
use crate::style_ext::{ComputedValuesExt, Position};
use crate::{relative_adjustement, ContainingBlock, IndependentFormattingContext};
use crate::{relative_adjustement, ContainingBlock};
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc;
@ -50,10 +51,7 @@ pub(crate) enum BlockLevelBox {
},
OutOfFlowAbsolutelyPositionedBox(AbsolutelyPositionedBox),
OutOfFlowFloatBox(FloatBox),
Independent {
style: Arc<ComputedValues>,
contents: IndependentFormattingContext,
},
Independent(IndependentFormattingContext),
}
pub(super) struct FlowChildren {
@ -292,19 +290,24 @@ impl BlockLevelBox {
},
))
},
BlockLevelBox::Independent { style, contents } => match contents.as_replaced() {
BlockLevelBox::Independent(contents) => match contents.as_replaced() {
Ok(replaced) => {
// FIXME
match *replaced {}
},
Err(contents) => Fragment::Box(layout_in_flow_non_replaced_block_level(
Err(non_replaced) => Fragment::Box(layout_in_flow_non_replaced_block_level(
layout_context,
containing_block,
absolutely_positioned_fragments,
style,
&contents.style,
BlockLevelKind::EstablishesAnIndependentFormattingContext,
|containing_block, nested_abspos, _| {
contents.layout(layout_context, containing_block, tree_rank, nested_abspos)
non_replaced.layout(
layout_context,
containing_block,
tree_rank,
nested_abspos,
)
},
)),
},

View file

@ -8,6 +8,7 @@ use crate::dom_traversal::{Contents, NodeExt};
use crate::flow::construct::ContainsFloats;
use crate::flow::float::FloatBox;
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Fragment;
use crate::geom;
use crate::geom::flow_relative::Vec2;
@ -16,7 +17,7 @@ use crate::replaced::ReplacedContent;
use crate::style_ext::{
Direction, Display, DisplayGeneratingBox, DisplayInside, DisplayOutside, WritingMode,
};
use crate::{ContainingBlock, DefiniteContainingBlock, IndependentFormattingContext};
use crate::{ContainingBlock, DefiniteContainingBlock};
use rayon::iter::{IntoParallelRefIterator, ParallelExtend, ParallelIterator};
use servo_arc::Arc;
use style::context::SharedStyleContext;
@ -69,31 +70,32 @@ fn construct_for_root_element<'dom>(
}
}
let position = box_style.position;
let float = box_style.float;
let contents = IndependentFormattingContext::construct(
context,
&style,
style,
display_inside,
Contents::OfElement(root_element),
);
if box_style.position.is_absolutely_positioned() {
if position.is_absolutely_positioned() {
(
ContainsFloats::No,
vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
AbsolutelyPositionedBox { style, contents },
AbsolutelyPositionedBox { contents },
))],
)
} else if box_style.float.is_floating() {
} else if float.is_floating() {
(
ContainsFloats::Yes,
vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox {
contents,
style,
}))],
)
} else {
(
ContainsFloats::No,
vec![Arc::new(BlockLevelBox::Independent { style, contents })],
vec![Arc::new(BlockLevelBox::Independent(contents))],
)
}
}