From abc2c15c284d1a2e758ca630d8dcdd13b01ceabf Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Fri, 13 Dec 2019 01:46:46 +0100 Subject: [PATCH] Store an OpaqueNode in boxes and fragments --- components/layout_2020/dom_traversal.rs | 8 ++-- components/layout_2020/flow/construct.rs | 12 +++-- components/layout_2020/flow/inline.rs | 9 ++++ components/layout_2020/flow/mod.rs | 47 ++++++++++++------- components/layout_2020/flow/root.rs | 8 +++- components/layout_2020/formatting_contexts.rs | 4 ++ components/layout_2020/fragments.rs | 3 ++ components/layout_2020/positioned.rs | 1 + 8 files changed, 67 insertions(+), 25 deletions(-) diff --git a/components/layout_2020/dom_traversal.rs b/components/layout_2020/dom_traversal.rs index 947cf3aa5ec..5ccf8310d53 100644 --- a/components/layout_2020/dom_traversal.rs +++ b/components/layout_2020/dom_traversal.rs @@ -51,7 +51,7 @@ pub(super) trait TraversalHandler<'dom, Node> where Node: 'dom, { - fn handle_text(&mut self, text: String, parent_style: &ServoArc); + fn handle_text(&mut self, node: Node, text: String, parent_style: &ServoArc); /// Or pseudo-element fn handle_element( @@ -76,7 +76,7 @@ fn traverse_children_of<'dom, Node>( let mut next = parent_element.first_child(); while let Some(child) = next { if let Some(contents) = child.as_text() { - handler.handle_text(contents, &child.style(context)); + handler.handle_text(child, contents, &child.style(context)); } else if child.is_element() { traverse_element(child, context, handler); } @@ -157,7 +157,9 @@ fn traverse_pseudo_element_contents<'dom, Node>( let mut anonymous_style = None; for item in items { match item { - PseudoElementContentItem::Text(text) => handler.handle_text(text, pseudo_element_style), + PseudoElementContentItem::Text(text) => { + handler.handle_text(node, text, pseudo_element_style) + }, PseudoElementContentItem::Replaced(contents) => { let item_style = anonymous_style.get_or_insert_with(|| { context diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 80de8c0135d..cff3fa281a6 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -273,7 +273,7 @@ where } } - fn handle_text(&mut self, input: String, parent_style: &Arc) { + fn handle_text(&mut self, node: Node, input: String, parent_style: &Arc) { 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 @@ -330,6 +330,7 @@ where if let Some(text) = new_text_run_contents { let parent_style = parent_style.clone(); inlines.push(Arc::new(InlineLevelBox::TextRun(TextRun { + tag: node.as_opaque(), parent_style, text, }))) @@ -389,6 +390,7 @@ where // 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(), first_fragment: true, last_fragment: false, @@ -444,6 +446,7 @@ where .rev() .map(|ongoing| { let fragmented = InlineBox { + tag: ongoing.tag, style: ongoing.style.clone(), first_fragment: ongoing.first_fragment, // The fragmented boxes before the block level element @@ -648,8 +651,11 @@ where if let Some(to) = max_assign_in_flow_outer_content_sizes_to { to.max_assign(&box_content_sizes.outer_inline(&style)) } - let block_level_box = - Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style }); + let block_level_box = Arc::new(BlockLevelBox::SameFormattingContextBlock { + tag: node.as_opaque(), + contents, + style, + }); (block_level_box, contains_floats) }, BlockLevelCreator::Independent { diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 93d7d6f8bdc..7c3fd9a29e3 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -16,6 +16,7 @@ use crate::ContainingBlock; use app_units::Au; use gfx::text::text_run::GlyphRun; use servo_arc::Arc; +use style::dom::OpaqueNode; use style::properties::ComputedValues; use style::values::computed::{Length, LengthPercentage, Percentage}; use style::values::specified::text::TextAlignKeyword; @@ -38,6 +39,7 @@ pub(crate) enum InlineLevelBox { #[derive(Debug)] pub(crate) struct InlineBox { + pub tag: OpaqueNode, pub style: Arc, pub first_fragment: bool, pub last_fragment: bool, @@ -47,6 +49,7 @@ pub(crate) struct InlineBox { /// https://www.w3.org/TR/css-display-3/#css-text-run #[derive(Debug)] pub(crate) struct TextRun { + pub tag: OpaqueNode, pub parent_style: Arc, pub text: String, } @@ -59,6 +62,7 @@ struct InlineNestingLevelState<'box_tree> { } struct PartialInlineBoxFragment<'box_tree> { + tag: OpaqueNode, style: Arc, start_corner: Vec2, padding: Sides, @@ -371,6 +375,7 @@ impl InlineBox { start_corner += &relative_adjustement(&style, ifc.containing_block) } PartialInlineBoxFragment { + tag: self.tag, style, start_corner, padding, @@ -398,6 +403,7 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> { at_line_break: bool, ) { let mut fragment = BoxFragment { + tag: self.tag, style: self.style.clone(), children: std::mem::take(&mut nesting_level.fragments_so_far), content_rect: Rect { @@ -465,6 +471,7 @@ fn layout_atomic<'box_tree>( let fragments = replaced.make_fragments(&atomic.style, size.clone()); let content_rect = Rect { start_corner, size }; BoxFragment { + tag: atomic.tag, style: atomic.style.clone(), children: fragments, content_rect, @@ -539,6 +546,7 @@ fn layout_atomic<'box_tree>( }, }; BoxFragment { + tag: atomic.tag, style: atomic.style.clone(), children: independent_layout.fragments, content_rect, @@ -685,6 +693,7 @@ impl TextRun { ifc.current_nesting_level .fragments_so_far .push(Fragment::Text(TextFragment { + tag: self.tag, parent_style: self.parent_style.clone(), rect, ascent: font_ascent.into(), diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 64f87ea09d0..b7373baf55a 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -18,6 +18,7 @@ use crate::ContainingBlock; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon_croissant::ParallelIteratorExt; use servo_arc::Arc; +use style::dom::OpaqueNode; use style::properties::ComputedValues; use style::values::computed::{Length, LengthOrAuto}; use style::Zero; @@ -44,6 +45,7 @@ pub(crate) enum BlockContainer { #[derive(Debug)] pub(crate) enum BlockLevelBox { SameFormattingContextBlock { + tag: OpaqueNode, style: Arc, contents: BlockContainer, }, @@ -268,24 +270,27 @@ impl BlockLevelBox { float_context: Option<&mut FloatContext>, ) -> Fragment { match self { - BlockLevelBox::SameFormattingContextBlock { style, contents } => { - Fragment::Box(positioning_context.for_maybe_position_relative( - layout_context, - containing_block, - style, - |positioning_context| { - layout_in_flow_non_replaced_block_level( - layout_context, - positioning_context, - containing_block, - style, - NonReplacedContents::SameFormattingContextBlock(contents), - tree_rank, - float_context, - ) - }, - )) - }, + BlockLevelBox::SameFormattingContextBlock { + tag, + style, + contents, + } => Fragment::Box(positioning_context.for_maybe_position_relative( + layout_context, + containing_block, + style, + |positioning_context| { + layout_in_flow_non_replaced_block_level( + layout_context, + positioning_context, + containing_block, + *tag, + style, + NonReplacedContents::SameFormattingContextBlock(contents), + tree_rank, + float_context, + ) + }, + )), BlockLevelBox::Independent(contents) => { Fragment::Box(positioning_context.for_maybe_position_relative( layout_context, @@ -294,6 +299,7 @@ impl BlockLevelBox { |positioning_context| match contents.as_replaced() { Ok(replaced) => layout_in_flow_replaced_block_level( containing_block, + contents.tag, &contents.style, replaced, ), @@ -301,6 +307,7 @@ impl BlockLevelBox { layout_context, positioning_context, containing_block, + contents.tag, &contents.style, NonReplacedContents::EstablishesAnIndependentFormattingContext( non_replaced, @@ -339,6 +346,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( layout_context: &LayoutContext, positioning_context: &mut PositioningContext<'a>, containing_block: &ContainingBlock, + tag: OpaqueNode, style: &Arc, block_level_kind: NonReplacedContents<'a>, tree_rank: usize, @@ -488,6 +496,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( }, }; BoxFragment { + tag, style: style.clone(), children: fragments, content_rect, @@ -503,6 +512,7 @@ fn layout_in_flow_non_replaced_block_level<'a>( /// https://drafts.csswg.org/css2/visudet.html#inline-replaced-height fn layout_in_flow_replaced_block_level<'a>( containing_block: &ContainingBlock, + tag: OpaqueNode, style: &Arc, replaced: &ReplacedContent, ) -> BoxFragment { @@ -536,6 +546,7 @@ fn layout_in_flow_replaced_block_level<'a>( size, }; BoxFragment { + tag, style: style.clone(), children: fragments, content_rect, diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 2bd72bae620..fda5eff5116 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -66,7 +66,13 @@ fn construct_for_root_element<'dom>( ( ContainsFloats::No, vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox( - AbsolutelyPositionedBox::construct(context, root_element, style, display_inside, contents), + AbsolutelyPositionedBox::construct( + context, + root_element, + style, + display_inside, + contents, + ), ))], ) } else if box_style.float.is_floating() { diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs index 07598f04729..b8fc029c887 100644 --- a/components/layout_2020/formatting_contexts.rs +++ b/components/layout_2020/formatting_contexts.rs @@ -13,12 +13,14 @@ use crate::style_ext::DisplayInside; use crate::ContainingBlock; use servo_arc::Arc; use std::convert::TryInto; +use style::dom::OpaqueNode; use style::properties::ComputedValues; use style::values::computed::Length; /// https://drafts.csswg.org/css-display/#independent-formatting-context #[derive(Debug)] pub(crate) struct IndependentFormattingContext { + pub tag: OpaqueNode, pub style: Arc, /// If it was requested during construction @@ -71,6 +73,7 @@ impl IndependentFormattingContext { content_sizes, ); Self { + tag: node.as_opaque(), style, content_sizes, contents: IndependentFormattingContextContents::Flow(bfc), @@ -80,6 +83,7 @@ impl IndependentFormattingContext { Err(replaced) => { let content_sizes = content_sizes.compute(|| replaced.inline_content_sizes(&style)); Self { + tag: node.as_opaque(), style, content_sizes, contents: IndependentFormattingContextContents::Replaced(replaced), diff --git a/components/layout_2020/fragments.rs b/components/layout_2020/fragments.rs index 29f9db8e0b3..730037a984b 100644 --- a/components/layout_2020/fragments.rs +++ b/components/layout_2020/fragments.rs @@ -6,6 +6,7 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2}; use gfx::text::glyph::GlyphStore; use servo_arc::Arc as ServoArc; use std::sync::Arc; +use style::dom::OpaqueNode; use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::computed::Length; @@ -20,6 +21,7 @@ pub(crate) enum Fragment { } pub(crate) struct BoxFragment { + pub tag: OpaqueNode, pub style: ServoArc, pub children: Vec, @@ -55,6 +57,7 @@ pub(crate) struct AnonymousFragment { } pub(crate) struct TextFragment { + pub tag: OpaqueNode, pub parent_style: ServoArc, pub rect: Rect, pub ascent: Length, diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index ceec7cf3f54..c9ad2dd97c4 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -471,6 +471,7 @@ impl<'box_tree> HoistedAbsolutelyPositionedBox<'box_tree> { }; BoxFragment { + tag: self.absolutely_positioned_box.contents.tag, style: style.clone(), children: fragments, content_rect,