diff options
Diffstat (limited to 'components/layout_2020/flow')
-rw-r--r-- | components/layout_2020/flow/construct.rs | 169 | ||||
-rw-r--r-- | components/layout_2020/flow/float.rs | 12 | ||||
-rw-r--r-- | components/layout_2020/flow/inline.rs | 9 | ||||
-rw-r--r-- | components/layout_2020/flow/mod.rs | 13 | ||||
-rw-r--r-- | components/layout_2020/flow/root.rs | 43 |
5 files changed, 101 insertions, 145 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, diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs index 4a647f23071..da70838499f 100644 --- a/components/layout_2020/flow/float.rs +++ b/components/layout_2020/flow/float.rs @@ -3,12 +3,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::context::LayoutContext; -use crate::dom_traversal::{Contents, NodeExt}; +use crate::dom_traversal::{Contents, NodeAndStyleInfo, NodeExt}; use crate::formatting_contexts::IndependentFormattingContext; use crate::sizing::ContentSizesRequest; use crate::style_ext::{ComputedValuesExt, DisplayInside}; -use servo_arc::Arc; -use style::properties::ComputedValues; use style::values::specified::text::TextDecorationLine; #[derive(Debug, Serialize)] @@ -30,17 +28,15 @@ impl FloatContext { impl FloatBox { pub fn construct<'dom>( context: &LayoutContext, - node: impl NodeExt<'dom>, - style: Arc<ComputedValues>, + info: &NodeAndStyleInfo<impl NodeExt<'dom>>, display_inside: DisplayInside, contents: Contents, ) -> Self { - let content_sizes = ContentSizesRequest::inline_if(!style.inline_size_is_length()); + let content_sizes = ContentSizesRequest::inline_if(!info.style.inline_size_is_length()); Self { contents: IndependentFormattingContext::construct( context, - node, - style, + info, display_inside, contents, content_sizes, diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index c129582a358..6676cb39f1e 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -9,7 +9,7 @@ use crate::flow::FlowLayout; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragments::{ AbsoluteOrFixedPositionedFragment, AnonymousFragment, BoxFragment, CollapsedBlockMargins, - DebugId, FontMetrics, Fragment, TextFragment, + DebugId, FontMetrics, Fragment, Tag, TextFragment, }; use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::positioned::{ @@ -22,7 +22,6 @@ 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; @@ -47,7 +46,7 @@ pub(crate) enum InlineLevelBox { #[derive(Debug, Serialize)] pub(crate) struct InlineBox { - pub tag: OpaqueNode, + pub tag: Tag, #[serde(skip_serializing)] pub style: Arc<ComputedValues>, pub first_fragment: bool, @@ -58,7 +57,7 @@ pub(crate) struct InlineBox { /// https://www.w3.org/TR/css-display-3/#css-text-run #[derive(Debug, Serialize)] pub(crate) struct TextRun { - pub tag: OpaqueNode, + pub tag: Tag, #[serde(skip_serializing)] pub parent_style: Arc<ComputedValues>, pub text: String, @@ -78,7 +77,7 @@ struct InlineNestingLevelState<'box_tree> { } struct PartialInlineBoxFragment<'box_tree> { - tag: OpaqueNode, + tag: Tag, style: Arc<ComputedValues>, start_corner: Vec2<Length>, padding: Sides<Length>, diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index b7b04cbe3a6..2443e91a0c8 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -9,8 +9,10 @@ use crate::context::LayoutContext; use crate::flow::float::{FloatBox, FloatContext}; use crate::flow::inline::InlineFormattingContext; use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout, NonReplacedIFC}; -use crate::fragments::{AbsoluteOrFixedPositionedFragment, AnonymousFragment, BoxFragment}; -use crate::fragments::{CollapsedBlockMargins, CollapsedMargin, Fragment}; +use crate::fragments::{ + AbsoluteOrFixedPositionedFragment, AnonymousFragment, BoxFragment, CollapsedBlockMargins, + CollapsedMargin, Fragment, Tag, +}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::replaced::ReplacedContent; @@ -19,7 +21,6 @@ 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; @@ -46,7 +47,7 @@ pub(crate) enum BlockContainer { #[derive(Debug, Serialize)] pub(crate) enum BlockLevelBox { SameFormattingContextBlock { - tag: OpaqueNode, + tag: Tag, #[serde(skip_serializing)] style: Arc<ComputedValues>, contents: BlockContainer, @@ -345,7 +346,7 @@ fn layout_in_flow_non_replaced_block_level( layout_context: &LayoutContext, positioning_context: &mut PositioningContext, containing_block: &ContainingBlock, - tag: OpaqueNode, + tag: Tag, style: &Arc<ComputedValues>, block_level_kind: NonReplacedContents, tree_rank: usize, @@ -500,7 +501,7 @@ fn layout_in_flow_non_replaced_block_level( /// https://drafts.csswg.org/css2/visudet.html#inline-replaced-height fn layout_in_flow_replaced_block_level<'a>( containing_block: &ContainingBlock, - tag: OpaqueNode, + tag: Tag, style: &Arc<ComputedValues>, replaced: &ReplacedContent, ) -> BoxFragment { diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 4c86b477d14..7de94e95ff8 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -8,7 +8,7 @@ use crate::display_list::stacking_context::{ ContainingBlock, ContainingBlockInfo, StackingContext, StackingContextBuildMode, StackingContextBuilder, }; -use crate::dom_traversal::{iter_child_nodes, Contents, NodeExt}; +use crate::dom_traversal::{iter_child_nodes, Contents, NodeAndStyleInfo, NodeExt}; use crate::element_data::LayoutBox; use crate::flexbox::FlexLevelBox; use crate::flow::construct::ContainsFloats; @@ -16,7 +16,7 @@ use crate::flow::float::FloatBox; use crate::flow::inline::InlineLevelBox; use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox}; use crate::formatting_contexts::IndependentFormattingContext; -use crate::fragments::Fragment; +use crate::fragments::{Fragment, Tag}; use crate::geom::flow_relative::Vec2; use crate::geom::{PhysicalPoint, PhysicalRect, PhysicalSize}; use crate::positioned::AbsolutelyPositionedBox; @@ -206,14 +206,10 @@ impl BoxTree { if let Some((primary_style, display_inside, update_point)) = update_point(dirty_node) { let contents = ReplacedContent::for_element(dirty_node) .map_or(Contents::OfElement, Contents::Replaced); - let out_of_flow_absolutely_positioned_box = - Arc::new(AbsolutelyPositionedBox::construct( - context, - dirty_node, - primary_style, - display_inside, - contents, - )); + let info = NodeAndStyleInfo::new(dirty_node, Arc::clone(&primary_style)); + let out_of_flow_absolutely_positioned_box = Arc::new( + AbsolutelyPositionedBox::construct(context, &info, display_inside, contents), + ); match update_point { UpdatePoint::AbsolutelyPositionedBlockLevelBox(block_level_box) => { *block_level_box.borrow_mut() = @@ -248,8 +244,8 @@ fn construct_for_root_element<'dom>( context: &LayoutContext, root_element: impl NodeExt<'dom>, ) -> (ContainsFloats, Vec<ArcRefCell<BlockLevelBox>>) { - let style = root_element.style(context); - let box_style = style.get_box(); + let info = NodeAndStyleInfo::new(root_element, root_element.style(context)); + let box_style = info.style.get_box(); let display_inside = match Display::from(box_style.display) { Display::None => { @@ -272,13 +268,7 @@ fn construct_for_root_element<'dom>( ( ContainsFloats::No, BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(Arc::new( - AbsolutelyPositionedBox::construct( - context, - root_element, - style, - display_inside, - contents, - ), + AbsolutelyPositionedBox::construct(context, &info, display_inside, contents), )), ) } else if box_style.float.is_floating() { @@ -286,20 +276,18 @@ fn construct_for_root_element<'dom>( ContainsFloats::Yes, BlockLevelBox::OutOfFlowFloatBox(FloatBox::construct( context, - root_element, - style, + &info, display_inside, contents, )), ) } else { - let propagated_text_decoration_line = style.clone_text_decoration_line(); + let propagated_text_decoration_line = info.style.clone_text_decoration_line(); ( ContainsFloats::No, BlockLevelBox::Independent(IndependentFormattingContext::construct( context, - root_element, - style, + &info, display_inside, contents, ContentSizesRequest::None, @@ -461,7 +449,7 @@ impl FragmentTree { pub fn remove_nodes_in_fragment_tree_from_set(&self, set: &mut FxHashSet<OpaqueNode>) { self.find(|fragment, _| { if let Some(tag) = fragment.tag().as_ref() { - set.remove(tag); + set.remove(&tag.node()); } None::<()> }); @@ -469,8 +457,9 @@ impl FragmentTree { pub fn get_content_box_for_node(&self, requested_node: OpaqueNode) -> Rect<Au> { let mut bounding_box = PhysicalRect::zero(); + let tag_to_find = Tag::Node(requested_node); self.find(|fragment, containing_block| { - if fragment.tag() != Some(requested_node) { + if fragment.tag() != Some(tag_to_find) { return None::<()>; } @@ -507,7 +496,7 @@ impl FragmentTree { pub fn get_border_dimensions_for_node(&self, requested_node: OpaqueNode) -> Rect<i32> { self.find(|fragment, containing_block| { let (style, padding_rect) = match fragment { - Fragment::Box(fragment) if fragment.tag == requested_node => { + Fragment::Box(fragment) if fragment.tag.node() == requested_node => { (&fragment.style, fragment.padding_rect()) }, Fragment::AbsoluteOrFixedPositioned(_) | |