diff options
author | Martin Robinson <mrobinson@igalia.com> | 2020-06-05 12:06:25 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2020-06-06 17:25:08 +0200 |
commit | 89855afa4daed56907b84daeb674066524e4352c (patch) | |
tree | a80dfbaa99b44bfcb049cd6182d70bf397ac04d0 /components/layout_2020/flow/construct.rs | |
parent | 7df4655b604683aee5763696589b041024b264ce (diff) | |
download | servo-89855afa4daed56907b84daeb674066524e4352c.tar.gz servo-89855afa4daed56907b84daeb674066524e4352c.zip |
layout_2020: Tag fragments with their pseudo content type
This will allow us to answer queries and properly handle animations in
the future for fragments generated for pseudo content.
Diffstat (limited to 'components/layout_2020/flow/construct.rs')
-rw-r--r-- | components/layout_2020/flow/construct.rs | 169 |
1 files changed, 70 insertions, 99 deletions
diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index f91330f45fb..4219bc7bf47 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -4,12 +4,15 @@ use crate::cell::ArcRefCell; use crate::context::LayoutContext; -use crate::dom_traversal::{BoxSlot, Contents, NodeExt, NonReplacedContents, TraversalHandler}; +use crate::dom_traversal::{ + BoxSlot, Contents, NodeAndStyleInfo, NodeExt, NonReplacedContents, TraversalHandler, +}; 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::fragments::Tag; use crate::positioned::AbsolutelyPositionedBox; use crate::sizing::{BoxContentSizes, ContentSizes, ContentSizesRequest}; use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside}; @@ -23,18 +26,19 @@ use style::selector_parser::PseudoElement; use style::values::specified::text::TextDecorationLine; impl BlockFormattingContext { - pub fn construct<'dom>( + pub fn construct<'dom, Node>( context: &LayoutContext, - node: impl NodeExt<'dom>, - style: &Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, contents: NonReplacedContents, content_sizes: ContentSizesRequest, propagated_text_decoration_line: TextDecorationLine, - ) -> (Self, BoxContentSizes) { + ) -> (Self, BoxContentSizes) + where + Node: NodeExt<'dom>, + { let (contents, contains_floats, inline_content_sizes) = BlockContainer::construct( context, - node, - style, + info, contents, content_sizes, propagated_text_decoration_line, @@ -74,9 +78,8 @@ impl BlockFormattingContext { } struct BlockLevelJob<'dom, Node> { - node: Node, + info: NodeAndStyleInfo<Node>, box_slot: BoxSlot<'dom>, - style: Arc<ComputedValues>, kind: BlockLevelCreator, } @@ -116,9 +119,9 @@ enum IntermediateBlockContainer { struct BlockContainerBuilder<'dom, 'style, Node> { context: &'style LayoutContext<'style>, - root: Node, - - block_container_style: &'style Arc<ComputedValues>, + /// This NodeAndStyleInfo contains the root node, the corresponding pseudo + /// content designator, and the block container style. + info: &'style NodeAndStyleInfo<Node>, /// The list of block-level boxes to be built for the final block container. /// @@ -168,20 +171,21 @@ struct BlockContainerBuilder<'dom, 'style, Node> { } impl BlockContainer { - pub fn construct<'dom>( + pub fn construct<'dom, Node>( context: &LayoutContext, - root: impl NodeExt<'dom>, - block_container_style: &Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, contents: NonReplacedContents, content_sizes: ContentSizesRequest, propagated_text_decoration_line: TextDecorationLine, - ) -> (BlockContainer, ContainsFloats, BoxContentSizes) { + ) -> (BlockContainer, ContainsFloats, BoxContentSizes) + where + Node: NodeExt<'dom>, + { let text_decoration_line = - propagated_text_decoration_line | block_container_style.clone_text_decoration_line(); + propagated_text_decoration_line | info.style.clone_text_decoration_line(); let mut builder = BlockContainerBuilder { context, - root, - block_container_style, + info, block_level_boxes: Vec::new(), ongoing_inline_formatting_context: InlineFormattingContext::new(text_decoration_line), ongoing_inline_boxes_stack: Vec::new(), @@ -189,7 +193,7 @@ impl BlockContainer { contains_floats: ContainsFloats::No, }; - contents.traverse(context, root, block_container_style, &mut builder); + contents.traverse(context, info, &mut builder); debug_assert!(builder.ongoing_inline_boxes_stack.is_empty()); @@ -272,8 +276,7 @@ where { fn handle_element( &mut self, - node: Node, - style: Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, display: DisplayGeneratingBox, contents: Contents, box_slot: BoxSlot<'dom>, @@ -281,32 +284,25 @@ where match display { DisplayGeneratingBox::OutsideInside { outside, inside } => match outside { DisplayOutside::Inline => box_slot.set(LayoutBox::InlineLevel( - self.handle_inline_level_element(node, style, inside, contents), + self.handle_inline_level_element(info, inside, contents), )), DisplayOutside::Block => { - let box_style = style.get_box(); + let box_style = info.style.get_box(); // Floats and abspos cause blockification, so they only happen in this case. // https://drafts.csswg.org/css2/visuren.html#dis-pos-flo if box_style.position.is_absolutely_positioned() { - self.handle_absolutely_positioned_element( - node, style, inside, contents, box_slot, - ) + self.handle_absolutely_positioned_element(info, inside, contents, box_slot) } else if box_style.float.is_floating() { - self.handle_float_element(node, style, inside, contents, box_slot) + self.handle_float_element(info, inside, contents, box_slot) } else { - self.handle_block_level_element(node, style, inside, contents, box_slot) + self.handle_block_level_element(info, inside, contents, box_slot) } }, }, } } - fn handle_text( - &mut self, - node: Node, - input: Cow<'dom, str>, - parent_style: Arc<ComputedValues>, - ) { + fn handle_text(&mut self, info: &NodeAndStyleInfo<Node>, input: Cow<'dom, str>) { let (leading_whitespace, mut input) = self.handle_leading_whitespace(&input); if leading_whitespace || !input.is_empty() { // This text node should be pushed either to the next ongoing @@ -356,8 +352,8 @@ where if let Some(text) = new_text_run_contents { inlines.push(ArcRefCell::new(InlineLevelBox::TextRun(TextRun { - tag: node.as_opaque(), - parent_style, + tag: Tag::from_node_and_style_info(info), + parent_style: Arc::clone(&info.style), text, }))) } @@ -430,30 +426,27 @@ where fn handle_inline_level_element( &mut self, - node: Node, - style: Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, display_inside: DisplayInside, contents: Contents, ) -> ArcRefCell<InlineLevelBox> { + let style = &info.style; let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() { // We found un inline box. // Whatever happened before, all we need to do before recurring // is to remember this ongoing inline level box. self.ongoing_inline_boxes_stack.push(InlineBox { - tag: node.as_opaque(), - style: style.clone(), + tag: Tag::from_node_and_style_info(info), + style: info.style.clone(), first_fragment: true, last_fragment: false, children: vec![], }); // `unwrap` doesn’t panic here because `is_replaced` returned `false`. - NonReplacedContents::try_from(contents).unwrap().traverse( - self.context, - node, - &style, - self, - ); + NonReplacedContents::try_from(contents) + .unwrap() + .traverse(self.context, info, self); let mut inline_box = self .ongoing_inline_boxes_stack @@ -466,8 +459,7 @@ where ArcRefCell::new(InlineLevelBox::Atomic( IndependentFormattingContext::construct( self.context, - node, - style, + info, display_inside, contents, content_sizes, @@ -482,8 +474,7 @@ where fn handle_block_level_element( &mut self, - node: Node, - style: Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, display_inside: DisplayInside, contents: Contents, box_slot: BoxSlot<'dom>, @@ -556,17 +547,15 @@ where }, }; self.block_level_boxes.push(BlockLevelJob { - node, + info: info.clone(), box_slot, - style, kind, }); } fn handle_absolutely_positioned_element( &mut self, - node: Node, - style: Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, display_inside: DisplayInside, contents: Contents, box_slot: BoxSlot<'dom>, @@ -577,20 +566,13 @@ where display_inside, }; self.block_level_boxes.push(BlockLevelJob { - node, + info: info.clone(), box_slot, - style, kind, }); } else { let box_ = ArcRefCell::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new( - AbsolutelyPositionedBox::construct( - self.context, - node, - style, - display_inside, - contents, - ), + AbsolutelyPositionedBox::construct(self.context, info, display_inside, contents), ))); self.current_inline_level_boxes().push(box_.clone()); box_slot.set(LayoutBox::InlineLevel(box_)) @@ -599,8 +581,7 @@ where fn handle_float_element( &mut self, - node: Node, - style: Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, display_inside: DisplayInside, contents: Contents, box_slot: BoxSlot<'dom>, @@ -613,16 +594,14 @@ where display_inside, }; self.block_level_boxes.push(BlockLevelJob { - node, + info: info.clone(), box_slot, - style, kind, }); } else { let box_ = ArcRefCell::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct( self.context, - node, - style, + info, display_inside, contents, ))); @@ -642,7 +621,7 @@ where } let context = self.context; - let block_container_style = self.block_container_style; + let block_container_style = &self.info.style; let anonymous_style = self.anonymous_style.get_or_insert_with(|| { context .shared_context() @@ -650,7 +629,7 @@ where .style_for_anonymous::<Node::ConcreteElement>( &context.shared_context().guards, &PseudoElement::ServoText, - &block_container_style, + block_container_style, ) }); @@ -659,11 +638,11 @@ where &mut self.ongoing_inline_formatting_context, )), ); + let info = self.info.new_replacing_style(anonymous_style.clone()); self.block_level_boxes.push(BlockLevelJob { - node: self.root, + info, // FIXME(nox): We should be storing this somewhere. box_slot: BoxSlot::dummy(), - style: anonymous_style.clone(), kind, }); } @@ -693,26 +672,24 @@ where context: &LayoutContext, max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>, ) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) { - let node = self.node; - let style = self.style; + let info = &self.info; let (block_level_box, contains_floats) = match self.kind { BlockLevelCreator::SameFormattingContextBlock(contents) => { let (contents, contains_floats, box_content_sizes) = contents.finish( context, - node, - &style, + info, ContentSizesRequest::inline_if( max_assign_in_flow_outer_content_sizes_to.is_some() && - !style.inline_size_is_length(), + !info.style.inline_size_is_length(), ), ); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { - to.max_assign(&box_content_sizes.outer_inline(&style)) + to.max_assign(&box_content_sizes.outer_inline(&info.style)) } let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock { - tag: node.as_opaque(), + tag: Tag::from_node_and_style_info(info), contents, - style, + style: Arc::clone(&info.style), }); (block_level_box, contains_floats) }, @@ -723,12 +700,11 @@ where } => { let content_sizes = ContentSizesRequest::inline_if( max_assign_in_flow_outer_content_sizes_to.is_some() && - !style.inline_size_is_length(), + !info.style.inline_size_is_length(), ); let contents = IndependentFormattingContext::construct( context, - node, - style, + info, display_inside, contents, content_sizes, @@ -748,13 +724,7 @@ where } => { let block_level_box = ArcRefCell::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new( - AbsolutelyPositionedBox::construct( - context, - node, - style, - display_inside, - contents, - ), + AbsolutelyPositionedBox::construct(context, info, display_inside, contents), ))); (block_level_box, ContainsFloats::No) }, @@ -763,7 +733,7 @@ where contents, } => { let block_level_box = ArcRefCell::new(BlockLevelBox::OutOfFlowFloatBox( - FloatBox::construct(context, node, style, display_inside, contents), + FloatBox::construct(context, info, display_inside, contents), )); (block_level_box, ContainsFloats::Yes) }, @@ -775,19 +745,20 @@ where } impl IntermediateBlockContainer { - fn finish<'dom>( + fn finish<'dom, Node>( self, context: &LayoutContext, - node: impl NodeExt<'dom>, - style: &Arc<ComputedValues>, + info: &NodeAndStyleInfo<Node>, content_sizes: ContentSizesRequest, - ) -> (BlockContainer, ContainsFloats, BoxContentSizes) { + ) -> (BlockContainer, ContainsFloats, BoxContentSizes) + where + Node: NodeExt<'dom>, + { match self { IntermediateBlockContainer::Deferred(contents, propagated_text_decoration_line) => { BlockContainer::construct( context, - node, - style, + info, contents, content_sizes, propagated_text_decoration_line, |