aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-12-03 02:19:48 +0100
committerSimon Sapin <simon.sapin@exyr.org>2019-12-03 15:11:35 +0100
commitc056e5b6b0dcd3a0226c02b6ffbe544a085da567 (patch)
tree27a9a434a4308efb1bddff489691f6c2cbc81fa5 /components
parentda36fcddb05da8a4370c006f937ab43682d057c0 (diff)
downloadservo-c056e5b6b0dcd3a0226c02b6ffbe544a085da567.tar.gz
servo-c056e5b6b0dcd3a0226c02b6ffbe544a085da567.zip
Finish plumbing intrinsic min/max-content through box construction
Diffstat (limited to 'components')
-rw-r--r--components/layout_2020/dom_traversal.rs3
-rw-r--r--components/layout_2020/flow/construct.rs68
-rw-r--r--components/layout_2020/flow/inline.rs11
-rw-r--r--components/layout_2020/formatting_contexts.rs32
-rw-r--r--components/layout_2020/sizing.rs5
5 files changed, 80 insertions, 39 deletions
diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs
index b71395cf1f4..056103d7205 100644
--- a/components/layout_2020/dom_traversal.rs
+++ b/components/layout_2020/dom_traversal.rs
@@ -192,8 +192,7 @@ impl<Node> Contents<Node> {
/// Returns true iff the `try_from` impl below would return `Err(_)`
pub fn is_replaced(&self) -> bool {
match self {
- Contents::OfElement(_) |
- Contents::OfPseudoElement(_) => false,
+ Contents::OfElement(_) | Contents::OfPseudoElement(_) => false,
Contents::Replaced(_) => true,
}
}
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs
index f7490f4c605..80f44b2ff81 100644
--- a/components/layout_2020/flow/construct.rs
+++ b/components/layout_2020/flow/construct.rs
@@ -24,14 +24,17 @@ impl BlockFormattingContext {
context: &LayoutContext,
style: &Arc<ComputedValues>,
contents: NonReplacedContents<impl NodeExt<'dom>>,
- ) -> Self {
- let (contents, contains_floats) = BlockContainer::construct(context, style, contents);
+ request_content_sizes: bool,
+ ) -> (Self, Option<ContentSizes>) {
+ let (contents, contains_floats, content_sizes) =
+ BlockContainer::construct(context, style, contents, request_content_sizes);
// FIXME: add contribution to `content_sizes` of floats in this formatting context
// https://dbaron.org/css/intrinsic/#intrinsic
- Self {
+ let bfc = Self {
contents,
contains_floats: contains_floats == ContainsFloats::Yes,
- }
+ };
+ (bfc, content_sizes)
}
}
@@ -130,9 +133,8 @@ impl BlockContainer {
context: &LayoutContext,
block_container_style: &Arc<ComputedValues>,
contents: NonReplacedContents<impl NodeExt<'dom>>,
- //request_content_sizes: bool,
- ) -> (BlockContainer, ContainsFloats) {
- let request_content_sizes = false; // FIXME
+ request_content_sizes: bool,
+ ) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) {
let mut builder = BlockContainerBuilder {
context,
block_container_style,
@@ -153,10 +155,19 @@ impl BlockContainer {
.is_empty()
{
if builder.block_level_boxes.is_empty() {
+ let content_sizes = if request_content_sizes {
+ Some(
+ builder
+ .ongoing_inline_formatting_context
+ .inline_content_sizes(context),
+ )
+ } else {
+ None
+ };
let container = BlockContainer::InlineFormattingContext(
builder.ongoing_inline_formatting_context,
);
- return (container, builder.contains_floats);
+ return (container, builder.contains_floats, content_sizes);
}
builder.end_ongoing_inline_formatting_context();
}
@@ -204,7 +215,12 @@ impl BlockContainer {
},
);
let container = BlockContainer::BlockLevelBoxes(iter.collect());
- (container, target.contains_floats)
+ let content_sizes = if request_content_sizes {
+ Some(target.outer_content_sizes_of_children)
+ } else {
+ None
+ };
+ (container, target.contains_floats, content_sizes)
}
}
@@ -367,7 +383,9 @@ where
});
// `unwrap` doesn’t panic here because `is_replaced` returned `false`.
- NonReplacedContents::try_from(contents).unwrap().traverse(&style, self.context, self);
+ NonReplacedContents::try_from(contents)
+ .unwrap()
+ .traverse(&style, self.context, self);
let mut inline_box = self
.ongoing_inline_boxes_stack
@@ -575,13 +593,12 @@ where
) -> (Arc<BlockLevelBox>, ContainsFloats) {
match self {
IntermediateBlockLevelBox::SameFormattingContextBlock { style, contents } => {
- let request_content_sizes =
- max_assign_in_flow_outer_content_sizes_to.is_some() &&
+ let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() &&
style.inline_size_is_auto();
- let (contents, contains_floats) = contents.finish(context, &style, request_content_sizes);
+ let (contents, contains_floats, content_sizes) =
+ contents.finish(context, &style, request_content_sizes);
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
- let get_content_size = || todo!();
- to.max_assign(&outer_inline_content_sizes(&style, get_content_size()))
+ to.max_assign(&outer_inline_content_sizes(&style, &content_sizes))
}
let block_level_box =
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style });
@@ -592,8 +609,7 @@ where
display_inside,
contents,
} => {
- let request_content_sizes =
- max_assign_in_flow_outer_content_sizes_to.is_some() &&
+ let request_content_sizes = max_assign_in_flow_outer_content_sizes_to.is_some() &&
style.inline_size_is_auto();
let contents = IndependentFormattingContext::construct(
context,
@@ -603,8 +619,10 @@ where
request_content_sizes,
);
if let Some(to) = max_assign_in_flow_outer_content_sizes_to {
- let get_content_size = || todo!();
- to.max_assign(&outer_inline_content_sizes(&contents.style, get_content_size()))
+ to.max_assign(&outer_inline_content_sizes(
+ &contents.style,
+ &contents.inline_content_sizes,
+ ))
}
(
Arc::new(BlockLevelBox::Independent(contents)),
@@ -643,19 +661,25 @@ where
self,
context: &LayoutContext,
style: &Arc<ComputedValues>,
- _request_content_sizes: bool,
- ) -> (BlockContainer, ContainsFloats) {
+ request_content_sizes: bool,
+ ) -> (BlockContainer, ContainsFloats, Option<ContentSizes>) {
match self {
IntermediateBlockContainer::Deferred { contents } => {
- BlockContainer::construct(context, style, contents)
+ BlockContainer::construct(context, style, contents, request_content_sizes)
},
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
+ let content_sizes = if request_content_sizes {
+ Some(ifc.inline_content_sizes(context))
+ } else {
+ None
+ };
// If that inline formatting context contained any float, those
// were already taken into account during the first phase of
// box construction.
(
BlockContainer::InlineFormattingContext(ifc),
ContainsFloats::No,
+ content_sizes,
)
},
}
diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs
index 605b87e3699..53cc3ad2ec2 100644
--- a/components/layout_2020/flow/inline.rs
+++ b/components/layout_2020/flow/inline.rs
@@ -84,8 +84,7 @@ impl InlineFormattingContext {
// This works on an already-constructed `InlineFormattingContext`,
// Which would have to change if/when
// `BlockContainer::construct` parallelize their construction.
- #[allow(unused)]
- pub(super) fn content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes {
+ pub(super) fn inline_content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes {
struct Computation {
paragraph: ContentSizes,
current_line: ContentSizes,
@@ -147,12 +146,10 @@ impl InlineFormattingContext {
}
},
InlineLevelBox::Atomic(atomic) => {
- let inner = || {
- // &atomic.inline_content_sizes
- todo!()
- };
let (outer, pc) = outer_inline_content_sizes_and_percentages(
- &atomic.style, inner());
+ &atomic.style,
+ &atomic.inline_content_sizes,
+ );
self.current_line.min_content += outer.min_content;
self.current_line.max_content += outer.max_content;
self.current_line_percentages += pc;
diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs
index 9b11c28246c..c6e4611db56 100644
--- a/components/layout_2020/formatting_contexts.rs
+++ b/components/layout_2020/formatting_contexts.rs
@@ -8,6 +8,7 @@ use crate::flow::BlockFormattingContext;
use crate::fragments::Fragment;
use crate::positioned::AbsolutelyPositionedFragment;
use crate::replaced::ReplacedContent;
+use crate::sizing::ContentSizes;
use crate::style_ext::DisplayInside;
use crate::ContainingBlock;
use servo_arc::Arc;
@@ -19,6 +20,10 @@ use style::values::computed::Length;
#[derive(Debug)]
pub(crate) struct IndependentFormattingContext {
pub style: Arc<ComputedValues>,
+
+ /// If it was requested during construction
+ pub inline_content_sizes: Option<ContentSizes>,
+
contents: IndependentFormattingContextContents,
}
@@ -50,18 +55,31 @@ impl IndependentFormattingContext {
style: Arc<ComputedValues>,
display_inside: DisplayInside,
contents: Contents<impl NodeExt<'dom>>,
- _request_content_sizes: bool, // Ignored for replaced content
+ request_content_sizes: bool,
) -> Self {
use self::IndependentFormattingContextContents as Contents;
- let contents = match contents.try_into() {
+ let (contents, inline_content_sizes) = match contents.try_into() {
Ok(non_replaced) => match display_inside {
- DisplayInside::Flow | DisplayInside::FlowRoot => Contents::Flow(
- BlockFormattingContext::construct(context, &style, non_replaced),
- ),
+ DisplayInside::Flow | DisplayInside::FlowRoot => {
+ let (bfc, content_sizes) = BlockFormattingContext::construct(
+ context,
+ &style,
+ non_replaced,
+ request_content_sizes,
+ );
+ (Contents::Flow(bfc), content_sizes)
+ },
+ },
+ Err(replaced) => {
+ let content_sizes = None; // Unused by layout code
+ (Contents::Replaced(replaced), content_sizes)
},
- Err(replaced) => Contents::Replaced(replaced),
};
- Self { style, contents }
+ Self {
+ style,
+ contents,
+ inline_content_sizes,
+ }
}
pub fn as_replaced(&self) -> Result<&ReplacedContent, NonReplacedIFC> {
diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs
index 998c2e2b419..a58602d23fd 100644
--- a/components/layout_2020/sizing.rs
+++ b/components/layout_2020/sizing.rs
@@ -65,7 +65,10 @@ pub(crate) fn outer_inline_content_sizes_and_percentages(
let specified = specified.map(|lp| lp.as_length());
// The (inner) min/max-content are only used for 'auto'
let mut outer = match specified.non_auto().flatten() {
- None => inner_content_sizes.as_ref().expect("Accessing content size that was not requested").clone(),
+ None => inner_content_sizes
+ .as_ref()
+ .expect("Accessing content size that was not requested")
+ .clone(),
Some(length) => ContentSizes {
min_content: length,
max_content: length,