From 89855afa4daed56907b84daeb674066524e4352c Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Fri, 5 Jun 2020 12:06:25 +0200 Subject: 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. --- components/layout_2020/flow/construct.rs | 169 +++++++++++++------------------ 1 file changed, 70 insertions(+), 99 deletions(-) (limited to 'components/layout_2020/flow/construct.rs') 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, + info: &NodeAndStyleInfo, 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, box_slot: BoxSlot<'dom>, - style: Arc, kind: BlockLevelCreator, } @@ -116,9 +119,9 @@ enum IntermediateBlockContainer { struct BlockContainerBuilder<'dom, 'style, Node> { context: &'style LayoutContext<'style>, - root: Node, - - block_container_style: &'style Arc, + /// This NodeAndStyleInfo contains the root node, the corresponding pseudo + /// content designator, and the block container style. + info: &'style NodeAndStyleInfo, /// 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, + info: &NodeAndStyleInfo, 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, + info: &NodeAndStyleInfo, 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, - ) { + fn handle_text(&mut self, info: &NodeAndStyleInfo, 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, + info: &NodeAndStyleInfo, display_inside: DisplayInside, contents: Contents, ) -> ArcRefCell { + 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, + info: &NodeAndStyleInfo, 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, + info: &NodeAndStyleInfo, 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, + info: &NodeAndStyleInfo, 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::( &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, 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, + info: &NodeAndStyleInfo, 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, -- cgit v1.2.3