From 47944a39fcfc8344d22a79a5531706fb8be4408f Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Thu, 12 Dec 2019 11:33:28 +0100 Subject: [PATCH] Remove the Node type parameter from Contents We now pass the Node as an argument during DOM traversal in layout. --- components/layout_2020/dom_traversal.rs | 54 ++++----- components/layout_2020/flow/construct.rs | 104 ++++++++++++------ components/layout_2020/flow/float.rs | 4 +- components/layout_2020/flow/root.rs | 7 +- components/layout_2020/formatting_contexts.rs | 4 +- components/layout_2020/positioned.rs | 4 +- 6 files changed, 114 insertions(+), 63 deletions(-) diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index 22b0661cb6d..947cf3aa5ec 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -24,9 +24,9 @@ pub enum WhichPseudoElement { After, } -pub(super) enum Contents { +pub(super) enum Contents { /// Refers to a DOM subtree, plus `::before` and `::after` pseudo-elements. - OfElement(Node), + OfElement, /// Example: an `` element. /// @@ -37,8 +37,8 @@ pub(super) enum Contents { OfPseudoElement(Vec), } -pub(super) enum NonReplacedContents { - OfElement(Node), +pub(super) enum NonReplacedContents { + OfElement, OfPseudoElement(Vec), } @@ -56,9 +56,10 @@ where /// Or pseudo-element fn handle_element( &mut self, + node: Node, style: &ServoArc, display: DisplayGeneratingBox, - contents: Contents, + contents: Contents, box_slot: BoxSlot<'dom>, ); } @@ -108,9 +109,10 @@ fn traverse_element<'dom, Node>( }, Display::GeneratingBox(display) => { handler.handle_element( + element, &style, display, - replaced.map_or(Contents::OfElement(element), Contents::Replaced), + replaced.map_or(Contents::OfElement, Contents::Replaced), element.element_box_slot(), ); }, @@ -131,19 +133,20 @@ fn traverse_pseudo_element<'dom, Node>( Display::Contents => { element.unset_pseudo_element_box(which); let items = generate_pseudo_element_content(&style, element, context); - traverse_pseudo_element_contents(&style, context, handler, items); + traverse_pseudo_element_contents(element, &style, context, handler, items); }, Display::GeneratingBox(display) => { let items = generate_pseudo_element_content(&style, element, context); let contents = Contents::OfPseudoElement(items); let box_slot = element.pseudo_element_box_slot(which); - handler.handle_element(&style, display, contents, box_slot); + handler.handle_element(element, &style, display, contents, box_slot); }, } } } fn traverse_pseudo_element_contents<'dom, Node>( + node: Node, pseudo_element_style: &ServoArc, context: &LayoutContext, handler: &mut impl TraversalHandler<'dom, Node>, @@ -176,6 +179,7 @@ fn traverse_pseudo_element_contents<'dom, Node>( Display::GeneratingBox(display_inline) ); handler.handle_element( + node, item_style, display_inline, Contents::Replaced(contents), @@ -187,51 +191,51 @@ fn traverse_pseudo_element_contents<'dom, Node>( } } -impl Contents { +impl Contents { /// 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, } } } -impl std::convert::TryFrom> for NonReplacedContents { +impl std::convert::TryFrom for NonReplacedContents { type Error = ReplacedContent; - fn try_from(contents: Contents) -> Result { + fn try_from(contents: Contents) -> Result { match contents { - Contents::OfElement(node) => Ok(NonReplacedContents::OfElement(node)), + Contents::OfElement => Ok(NonReplacedContents::OfElement), Contents::OfPseudoElement(items) => Ok(NonReplacedContents::OfPseudoElement(items)), Contents::Replaced(replaced) => Err(replaced), } } } -impl std::convert::From> for Contents { - fn from(contents: NonReplacedContents) -> Self { +impl From for Contents { + fn from(contents: NonReplacedContents) -> Self { match contents { - NonReplacedContents::OfElement(node) => Contents::OfElement(node), + NonReplacedContents::OfElement => Contents::OfElement, NonReplacedContents::OfPseudoElement(items) => Contents::OfPseudoElement(items), } } } -impl<'dom, Node> NonReplacedContents -where - Node: NodeExt<'dom>, -{ - pub(crate) fn traverse( +impl NonReplacedContents { + pub(crate) fn traverse<'dom, Node>( self, - inherited_style: &ServoArc, context: &LayoutContext, + node: Node, + inherited_style: &ServoArc, handler: &mut impl TraversalHandler<'dom, Node>, - ) { + ) where + Node: NodeExt<'dom>, + { match self { - NonReplacedContents::OfElement(node) => traverse_children_of(node, context, handler), + NonReplacedContents::OfElement => traverse_children_of(node, context, handler), NonReplacedContents::OfPseudoElement(items) => { - traverse_pseudo_element_contents(inherited_style, context, handler, items) + traverse_pseudo_element_contents(node, inherited_style, context, handler, items) }, } } diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 6f67fcca045..80de8c0135d 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -22,12 +22,13 @@ use style::selector_parser::PseudoElement; impl BlockFormattingContext { pub fn construct<'dom>( context: &LayoutContext, + node: impl NodeExt<'dom>, style: &Arc, - contents: NonReplacedContents>, + contents: NonReplacedContents, content_sizes: ContentSizesRequest, ) -> (Self, BoxContentSizes) { let (contents, contains_floats, inline_content_sizes) = - BlockContainer::construct(context, style, contents, content_sizes); + BlockContainer::construct(context, node, style, contents, content_sizes); // FIXME: add contribution to `inline_content_sizes` of floats in this formatting context // https://dbaron.org/css/intrinsic/#intrinsic let bfc = Self { @@ -39,24 +40,25 @@ impl BlockFormattingContext { } struct BlockLevelJob<'dom, Node> { + node: Node, box_slot: BoxSlot<'dom>, style: Arc, - kind: BlockLevelCreator, + kind: BlockLevelCreator, } -enum BlockLevelCreator { - SameFormattingContextBlock(IntermediateBlockContainer), +enum BlockLevelCreator { + SameFormattingContextBlock(IntermediateBlockContainer), Independent { display_inside: DisplayInside, - contents: Contents, + contents: Contents, }, OutOfFlowAbsolutelyPositionedBox { display_inside: DisplayInside, - contents: Contents, + contents: Contents, }, OutOfFlowFloatBox { display_inside: DisplayInside, - contents: Contents, + contents: Contents, }, } @@ -67,9 +69,9 @@ enum BlockLevelCreator { /// of a given element. /// /// Deferring allows using rayon’s `into_par_iter`. -enum IntermediateBlockContainer { +enum IntermediateBlockContainer { InlineFormattingContext(InlineFormattingContext), - Deferred(NonReplacedContents), + Deferred(NonReplacedContents), } /// A builder for a block container. @@ -79,6 +81,8 @@ enum IntermediateBlockContainer { struct BlockContainerBuilder<'dom, 'style, Node> { context: &'style LayoutContext<'style>, + root: Node, + block_container_style: &'style Arc, /// The list of block-level boxes to be built for the final block container. @@ -131,12 +135,14 @@ struct BlockContainerBuilder<'dom, 'style, Node> { impl BlockContainer { pub fn construct<'dom>( context: &LayoutContext, + root: impl NodeExt<'dom>, block_container_style: &Arc, - contents: NonReplacedContents>, + contents: NonReplacedContents, content_sizes: ContentSizesRequest, ) -> (BlockContainer, ContainsFloats, BoxContentSizes) { let mut builder = BlockContainerBuilder { context, + root, block_container_style, block_level_boxes: Vec::new(), ongoing_inline_formatting_context: InlineFormattingContext::default(), @@ -145,7 +151,7 @@ impl BlockContainer { contains_floats: ContainsFloats::No, }; - contents.traverse(block_container_style, context, &mut builder); + contents.traverse(context, root, block_container_style, &mut builder); debug_assert!(builder.ongoing_inline_boxes_stack.is_empty()); @@ -228,15 +234,16 @@ where { fn handle_element( &mut self, + node: Node, style: &Arc, display: DisplayGeneratingBox, - contents: Contents, + contents: Contents, box_slot: BoxSlot<'dom>, ) { match display { DisplayGeneratingBox::OutsideInside { outside, inside } => match outside { DisplayOutside::Inline => box_slot.set(LayoutBox::InlineLevel( - self.handle_inline_level_element(style, inside, contents), + self.handle_inline_level_element(node, style, inside, contents), )), DisplayOutside::Block => { let box_style = style.get_box(); @@ -244,15 +251,22 @@ where // https://drafts.csswg.org/css2/visuren.html#dis-pos-flo if box_style.position.is_absolutely_positioned() { self.handle_absolutely_positioned_element( + node, style.clone(), inside, contents, box_slot, ) } else if box_style.float.is_floating() { - self.handle_float_element(style.clone(), inside, contents, box_slot) + self.handle_float_element(node, style.clone(), inside, contents, box_slot) } else { - self.handle_block_level_element(style.clone(), inside, contents, box_slot) + self.handle_block_level_element( + node, + style.clone(), + inside, + contents, + box_slot, + ) } }, }, @@ -365,9 +379,10 @@ where fn handle_inline_level_element( &mut self, + node: Node, style: &Arc, display_inside: DisplayInside, - contents: Contents, + contents: Contents, ) -> Arc { let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() { // We found un inline box. @@ -381,9 +396,12 @@ 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( + self.context, + node, + &style, + self, + ); let mut inline_box = self .ongoing_inline_boxes_stack @@ -395,6 +413,7 @@ where Arc::new(InlineLevelBox::Atomic( IndependentFormattingContext::construct( self.context, + node, style.clone(), display_inside, contents, @@ -408,9 +427,10 @@ where fn handle_block_level_element( &mut self, + node: Node, style: Arc, display_inside: DisplayInside, - contents: Contents, + contents: Contents, box_slot: BoxSlot<'dom>, ) { // We just found a block level element, all ongoing inline level boxes @@ -475,6 +495,7 @@ where }, }; self.block_level_boxes.push(BlockLevelJob { + node, box_slot, style, kind, @@ -483,9 +504,10 @@ where fn handle_absolutely_positioned_element( &mut self, + node: Node, style: Arc, display_inside: DisplayInside, - contents: Contents, + contents: Contents, box_slot: BoxSlot<'dom>, ) { if !self.has_ongoing_inline_formatting_context() { @@ -494,13 +516,20 @@ where display_inside, }; self.block_level_boxes.push(BlockLevelJob { + node, box_slot, style, kind, }); } else { let box_ = Arc::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox::construct(self.context, style, display_inside, contents), + AbsolutelyPositionedBox::construct( + self.context, + node, + style, + display_inside, + contents, + ), )); self.current_inline_level_boxes().push(box_.clone()); box_slot.set(LayoutBox::InlineLevel(box_)) @@ -509,9 +538,10 @@ where fn handle_float_element( &mut self, + node: Node, style: Arc, display_inside: DisplayInside, - contents: Contents, + contents: Contents, box_slot: BoxSlot<'dom>, ) { self.contains_floats = ContainsFloats::Yes; @@ -522,6 +552,7 @@ where display_inside, }; self.block_level_boxes.push(BlockLevelJob { + node, box_slot, style, kind, @@ -529,6 +560,7 @@ where } else { let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct( self.context, + node, style, display_inside, contents, @@ -567,6 +599,7 @@ where )), ); self.block_level_boxes.push(BlockLevelJob { + node: self.root, // FIXME(nox): We should be storing this somewhere. box_slot: BoxSlot::dummy(), style: anonymous_style.clone(), @@ -599,11 +632,13 @@ where context: &LayoutContext, max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>, ) -> (Arc, ContainsFloats) { + let node = self.node; let style = self.style; let (block_level_box, contains_floats) = match self.kind { BlockLevelCreator::SameFormattingContextBlock(contents) => { let (contents, contains_floats, box_content_sizes) = contents.finish( context, + node, &style, ContentSizesRequest::inline_if( max_assign_in_flow_outer_content_sizes_to.is_some() && @@ -627,6 +662,7 @@ where ); let contents = IndependentFormattingContext::construct( context, + node, style, display_inside, contents, @@ -645,7 +681,13 @@ where contents, } => { let block_level_box = Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox::construct(context, style, display_inside, contents), + AbsolutelyPositionedBox::construct( + context, + node, + style, + display_inside, + contents, + ), )); (block_level_box, ContainsFloats::No) }, @@ -654,7 +696,7 @@ where contents, } => { let block_level_box = Arc::new(BlockLevelBox::OutOfFlowFloatBox( - FloatBox::construct(context, style, display_inside, contents), + FloatBox::construct(context, node, style, display_inside, contents), )); (block_level_box, ContainsFloats::Yes) }, @@ -665,19 +707,17 @@ where } } -impl<'dom, Node> IntermediateBlockContainer -where - Node: NodeExt<'dom>, -{ - fn finish( +impl IntermediateBlockContainer { + fn finish<'dom>( self, context: &LayoutContext, + node: impl NodeExt<'dom>, style: &Arc, content_sizes: ContentSizesRequest, ) -> (BlockContainer, ContainsFloats, BoxContentSizes) { match self { IntermediateBlockContainer::Deferred(contents) => { - BlockContainer::construct(context, style, contents, content_sizes) + BlockContainer::construct(context, node, style, contents, content_sizes) }, IntermediateBlockContainer::InlineFormattingContext(ifc) => { let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context)); diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs index df9cbbaf514..7c7a2ab5a31 100644 --- a/components/layout_2020/flow/float.rs +++ b/components/layout_2020/flow/float.rs @@ -29,14 +29,16 @@ impl FloatContext { impl FloatBox { pub fn construct<'dom>( context: &LayoutContext, + node: impl NodeExt<'dom>, style: Arc, display_inside: DisplayInside, - contents: Contents>, + contents: Contents, ) -> Self { let content_sizes = ContentSizesRequest::inline_if(!style.inline_size_is_length()); Self { contents: IndependentFormattingContext::construct( context, + node, style, display_inside, contents, diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 24dea984e62..2bd72bae620 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -61,19 +61,19 @@ fn construct_for_root_element<'dom>( Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside, }; - let contents = replaced.map_or(Contents::OfElement(root_element), Contents::Replaced); + let contents = replaced.map_or(Contents::OfElement, Contents::Replaced); if box_style.position.is_absolutely_positioned() { ( ContainsFloats::No, vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox::construct(context, style, display_inside, contents), + AbsolutelyPositionedBox::construct(context, root_element, style, display_inside, contents), ))], ) } else if box_style.float.is_floating() { ( ContainsFloats::Yes, vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox( - FloatBox::construct(context, style, display_inside, contents), + FloatBox::construct(context, root_element, style, display_inside, contents), ))], ) } else { @@ -82,6 +82,7 @@ fn construct_for_root_element<'dom>( vec![Arc::new(BlockLevelBox::Independent( IndependentFormattingContext::construct( context, + root_element, style, display_inside, contents, diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index dcbbfa370a6..07598f04729 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -54,9 +54,10 @@ enum NonReplacedIFCKind<'a> { impl IndependentFormattingContext { pub fn construct<'dom>( context: &LayoutContext, + node: impl NodeExt<'dom>, style: Arc, display_inside: DisplayInside, - contents: Contents>, + contents: Contents, content_sizes: ContentSizesRequest, ) -> Self { match contents.try_into() { @@ -64,6 +65,7 @@ impl IndependentFormattingContext { DisplayInside::Flow | DisplayInside::FlowRoot => { let (bfc, content_sizes) = BlockFormattingContext::construct( context, + node, &style, non_replaced, content_sizes, diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index cfe615ae27d..ceec7cf3f54 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -60,9 +60,10 @@ pub(crate) enum AbsoluteBoxOffsets { impl AbsolutelyPositionedBox { pub fn construct<'dom>( context: &LayoutContext, + node: impl NodeExt<'dom>, style: Arc, display_inside: DisplayInside, - contents: Contents>, + contents: Contents, ) -> Self { // "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width let content_sizes = ContentSizesRequest::inline_if( @@ -76,6 +77,7 @@ impl AbsolutelyPositionedBox { Self { contents: IndependentFormattingContext::construct( context, + node, style, display_inside, contents,