mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Flex items in the box tree
This commit is contained in:
parent
64124f7a5e
commit
ec548e849c
3 changed files with 121 additions and 25 deletions
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
|
use crate::flexbox::FlexLevelBox;
|
||||||
use crate::flow::inline::InlineLevelBox;
|
use crate::flow::inline::InlineLevelBox;
|
||||||
use crate::flow::BlockLevelBox;
|
use crate::flow::BlockLevelBox;
|
||||||
|
|
||||||
|
@ -17,4 +18,5 @@ pub(super) enum LayoutBox {
|
||||||
DisplayContents,
|
DisplayContents,
|
||||||
BlockLevel(ArcRefCell<BlockLevelBox>),
|
BlockLevel(ArcRefCell<BlockLevelBox>),
|
||||||
InlineLevel(ArcRefCell<InlineLevelBox>),
|
InlineLevel(ArcRefCell<InlineLevelBox>),
|
||||||
|
FlexLevel(ArcRefCell<FlexLevelBox>),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,33 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use crate::cell::ArcRefCell;
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom_traversal::{NodeExt, NonReplacedContents};
|
use crate::dom_traversal::{BoxSlot, Contents, NodeExt, NonReplacedContents, TraversalHandler};
|
||||||
use crate::formatting_contexts::IndependentLayout;
|
use crate::element_data::LayoutBox;
|
||||||
use crate::positioned::PositioningContext;
|
use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout};
|
||||||
use crate::sizing::{BoxContentSizes, ContentSizesRequest};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
|
use crate::sizing::{BoxContentSizes, ContentSizes, ContentSizesRequest};
|
||||||
|
use crate::style_ext::DisplayGeneratingBox;
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
|
use std::borrow::Cow;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
|
use style::values::computed::Length;
|
||||||
use style::values::specified::text::TextDecorationLine;
|
use style::values::specified::text::TextDecorationLine;
|
||||||
|
use style::Zero;
|
||||||
|
|
||||||
// FIXME: `min-width: auto` is not zero: https://drafts.csswg.org/css-flexbox/#min-size-auto
|
// FIXME: `min-width: auto` is not zero: https://drafts.csswg.org/css-flexbox/#min-size-auto
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub(crate) struct FlexContainer {
|
pub(crate) struct FlexContainer {
|
||||||
unimplemented_fallback: crate::flow::BlockFormattingContext,
|
children: Vec<ArcRefCell<FlexLevelBox>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
pub(crate) enum FlexLevelBox {
|
||||||
|
FlexItem(IndependentFormattingContext),
|
||||||
|
OutOfFlowAbsolutelyPositionedBox(Arc<AbsolutelyPositionedBox>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlexContainer {
|
impl FlexContainer {
|
||||||
|
@ -28,23 +40,86 @@ impl FlexContainer {
|
||||||
content_sizes: ContentSizesRequest,
|
content_sizes: ContentSizesRequest,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_text_decoration_line: TextDecorationLine,
|
||||||
) -> (Self, BoxContentSizes) {
|
) -> (Self, BoxContentSizes) {
|
||||||
let (unimplemented_fallback, content_sizes) =
|
let text_decoration_line =
|
||||||
crate::flow::BlockFormattingContext::construct(
|
propagated_text_decoration_line | style.clone_text_decoration_line();
|
||||||
context,
|
let mut builder = FlexContainerBuilder {
|
||||||
node,
|
context,
|
||||||
style,
|
text_decoration_line,
|
||||||
contents,
|
flex_container: Self {
|
||||||
content_sizes,
|
children: Vec::new(),
|
||||||
propagated_text_decoration_line,
|
|
||||||
);
|
|
||||||
(
|
|
||||||
Self {
|
|
||||||
unimplemented_fallback,
|
|
||||||
},
|
},
|
||||||
content_sizes,
|
};
|
||||||
)
|
contents.traverse(context, node, style, &mut builder);
|
||||||
|
let content_sizes = content_sizes.compute(|| {
|
||||||
|
// FIXME
|
||||||
|
ContentSizes::zero()
|
||||||
|
});
|
||||||
|
(builder.flex_container, content_sizes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FlexContainerBuilder<'context> {
|
||||||
|
context: &'context LayoutContext<'context>,
|
||||||
|
text_decoration_line: TextDecorationLine,
|
||||||
|
flex_container: FlexContainer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'context, 'dom, Node: 'dom> TraversalHandler<'dom, Node> for FlexContainerBuilder<'context>
|
||||||
|
where
|
||||||
|
Node: NodeExt<'dom>,
|
||||||
|
{
|
||||||
|
fn handle_text(
|
||||||
|
&mut self,
|
||||||
|
node: Node,
|
||||||
|
text: Cow<'dom, str>,
|
||||||
|
parent_style: &Arc<ComputedValues>,
|
||||||
|
) {
|
||||||
|
// FIXME
|
||||||
|
let _ = node;
|
||||||
|
let _ = text;
|
||||||
|
let _ = parent_style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Or pseudo-element
|
||||||
|
fn handle_element(
|
||||||
|
&mut self,
|
||||||
|
node: Node,
|
||||||
|
style: &Arc<ComputedValues>,
|
||||||
|
display: DisplayGeneratingBox,
|
||||||
|
contents: Contents,
|
||||||
|
box_slot: BoxSlot<'dom>,
|
||||||
|
) {
|
||||||
|
let display_inside = match display {
|
||||||
|
DisplayGeneratingBox::OutsideInside { inside, .. } => inside,
|
||||||
|
};
|
||||||
|
let box_ = if style.get_box().position.is_absolutely_positioned() {
|
||||||
|
// https://drafts.csswg.org/css-flexbox/#abspos-items
|
||||||
|
ArcRefCell::new(FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new(
|
||||||
|
AbsolutelyPositionedBox::construct(
|
||||||
|
self.context,
|
||||||
|
node,
|
||||||
|
style.clone(),
|
||||||
|
display_inside,
|
||||||
|
contents,
|
||||||
|
),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
ArcRefCell::new(FlexLevelBox::FlexItem(IndependentFormattingContext::construct(
|
||||||
|
self.context,
|
||||||
|
node,
|
||||||
|
style.clone(),
|
||||||
|
display_inside,
|
||||||
|
contents,
|
||||||
|
ContentSizesRequest::None, // FIXME: request sizes when we start using them
|
||||||
|
self.text_decoration_line,
|
||||||
|
)))
|
||||||
|
};
|
||||||
|
self.flex_container.children.push(box_.clone());
|
||||||
|
box_slot.set(LayoutBox::FlexLevel(box_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlexContainer {
|
||||||
pub(crate) fn layout(
|
pub(crate) fn layout(
|
||||||
&self,
|
&self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
|
@ -52,11 +127,14 @@ impl FlexContainer {
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
tree_rank: usize,
|
tree_rank: usize,
|
||||||
) -> IndependentLayout {
|
) -> IndependentLayout {
|
||||||
self.unimplemented_fallback.layout(
|
// FIXME
|
||||||
layout_context,
|
let _ = layout_context;
|
||||||
positioning_context,
|
let _ = positioning_context;
|
||||||
containing_block,
|
let _ = containing_block;
|
||||||
tree_rank,
|
let _ = tree_rank;
|
||||||
)
|
IndependentLayout {
|
||||||
|
fragments: Vec::new(),
|
||||||
|
content_block_size: Length::zero(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::display_list::stacking_context::{
|
||||||
};
|
};
|
||||||
use crate::dom_traversal::{iter_child_nodes, Contents, NodeExt};
|
use crate::dom_traversal::{iter_child_nodes, Contents, NodeExt};
|
||||||
use crate::element_data::LayoutBox;
|
use crate::element_data::LayoutBox;
|
||||||
|
use crate::flexbox::FlexLevelBox;
|
||||||
use crate::flow::construct::ContainsFloats;
|
use crate::flow::construct::ContainsFloats;
|
||||||
use crate::flow::float::FloatBox;
|
use crate::flow::float::FloatBox;
|
||||||
use crate::flow::inline::InlineLevelBox;
|
use crate::flow::inline::InlineLevelBox;
|
||||||
|
@ -119,6 +120,7 @@ impl BoxTree {
|
||||||
enum UpdatePoint {
|
enum UpdatePoint {
|
||||||
AbsolutelyPositionedBlockLevelBox(ArcRefCell<BlockLevelBox>),
|
AbsolutelyPositionedBlockLevelBox(ArcRefCell<BlockLevelBox>),
|
||||||
AbsolutelyPositionedInlineLevelBox(ArcRefCell<InlineLevelBox>),
|
AbsolutelyPositionedInlineLevelBox(ArcRefCell<InlineLevelBox>),
|
||||||
|
AbsolutelyPositionedFlexLevelBox(ArcRefCell<FlexLevelBox>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_point<'dom, Node>(
|
fn update_point<'dom, Node>(
|
||||||
|
@ -188,6 +190,14 @@ impl BoxTree {
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
},
|
},
|
||||||
|
LayoutBox::FlexLevel(flex_level_box) => match &*flex_level_box.borrow() {
|
||||||
|
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(_)
|
||||||
|
if box_style.position.is_absolutely_positioned() =>
|
||||||
|
{
|
||||||
|
UpdatePoint::AbsolutelyPositionedFlexLevelBox(flex_level_box.clone())
|
||||||
|
},
|
||||||
|
_ => return None,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
Some((primary_style.clone(), display_inside, update_point))
|
Some((primary_style.clone(), display_inside, update_point))
|
||||||
}
|
}
|
||||||
|
@ -217,6 +227,12 @@ impl BoxTree {
|
||||||
out_of_flow_absolutely_positioned_box,
|
out_of_flow_absolutely_positioned_box,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
UpdatePoint::AbsolutelyPositionedFlexLevelBox(flex_level_box) => {
|
||||||
|
*flex_level_box.borrow_mut() =
|
||||||
|
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
||||||
|
out_of_flow_absolutely_positioned_box,
|
||||||
|
);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue