Store an OpaqueNode in boxes and fragments

This commit is contained in:
Anthony Ramine 2019-12-13 01:46:46 +01:00
parent 47944a39fc
commit abc2c15c28
8 changed files with 67 additions and 25 deletions

View file

@ -51,7 +51,7 @@ pub(super) trait TraversalHandler<'dom, Node>
where where
Node: 'dom, Node: 'dom,
{ {
fn handle_text(&mut self, text: String, parent_style: &ServoArc<ComputedValues>); fn handle_text(&mut self, node: Node, text: String, parent_style: &ServoArc<ComputedValues>);
/// Or pseudo-element /// Or pseudo-element
fn handle_element( fn handle_element(
@ -76,7 +76,7 @@ fn traverse_children_of<'dom, Node>(
let mut next = parent_element.first_child(); let mut next = parent_element.first_child();
while let Some(child) = next { while let Some(child) = next {
if let Some(contents) = child.as_text() { 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() { } else if child.is_element() {
traverse_element(child, context, handler); traverse_element(child, context, handler);
} }
@ -157,7 +157,9 @@ fn traverse_pseudo_element_contents<'dom, Node>(
let mut anonymous_style = None; let mut anonymous_style = None;
for item in items { for item in items {
match item { 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) => { PseudoElementContentItem::Replaced(contents) => {
let item_style = anonymous_style.get_or_insert_with(|| { let item_style = anonymous_style.get_or_insert_with(|| {
context context

View file

@ -273,7 +273,7 @@ where
} }
} }
fn handle_text(&mut self, input: String, parent_style: &Arc<ComputedValues>) { fn handle_text(&mut self, node: Node, input: String, parent_style: &Arc<ComputedValues>) {
let (leading_whitespace, mut input) = self.handle_leading_whitespace(&input); let (leading_whitespace, mut input) = self.handle_leading_whitespace(&input);
if leading_whitespace || !input.is_empty() { if leading_whitespace || !input.is_empty() {
// This text node should be pushed either to the next ongoing // This text node should be pushed either to the next ongoing
@ -330,6 +330,7 @@ where
if let Some(text) = new_text_run_contents { if let Some(text) = new_text_run_contents {
let parent_style = parent_style.clone(); let parent_style = parent_style.clone();
inlines.push(Arc::new(InlineLevelBox::TextRun(TextRun { inlines.push(Arc::new(InlineLevelBox::TextRun(TextRun {
tag: node.as_opaque(),
parent_style, parent_style,
text, text,
}))) })))
@ -389,6 +390,7 @@ where
// Whatever happened before, all we need to do before recurring // Whatever happened before, all we need to do before recurring
// is to remember this ongoing inline level box. // is to remember this ongoing inline level box.
self.ongoing_inline_boxes_stack.push(InlineBox { self.ongoing_inline_boxes_stack.push(InlineBox {
tag: node.as_opaque(),
style: style.clone(), style: style.clone(),
first_fragment: true, first_fragment: true,
last_fragment: false, last_fragment: false,
@ -444,6 +446,7 @@ where
.rev() .rev()
.map(|ongoing| { .map(|ongoing| {
let fragmented = InlineBox { let fragmented = InlineBox {
tag: ongoing.tag,
style: ongoing.style.clone(), style: ongoing.style.clone(),
first_fragment: ongoing.first_fragment, first_fragment: ongoing.first_fragment,
// The fragmented boxes before the block level element // 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 { 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(&style))
} }
let block_level_box = let block_level_box = Arc::new(BlockLevelBox::SameFormattingContextBlock {
Arc::new(BlockLevelBox::SameFormattingContextBlock { contents, style }); tag: node.as_opaque(),
contents,
style,
});
(block_level_box, contains_floats) (block_level_box, contains_floats)
}, },
BlockLevelCreator::Independent { BlockLevelCreator::Independent {

View file

@ -16,6 +16,7 @@ use crate::ContainingBlock;
use app_units::Au; use app_units::Au;
use gfx::text::text_run::GlyphRun; use gfx::text::text_run::GlyphRun;
use servo_arc::Arc; use servo_arc::Arc;
use style::dom::OpaqueNode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage}; use style::values::computed::{Length, LengthPercentage, Percentage};
use style::values::specified::text::TextAlignKeyword; use style::values::specified::text::TextAlignKeyword;
@ -38,6 +39,7 @@ pub(crate) enum InlineLevelBox {
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct InlineBox { pub(crate) struct InlineBox {
pub tag: OpaqueNode,
pub style: Arc<ComputedValues>, pub style: Arc<ComputedValues>,
pub first_fragment: bool, pub first_fragment: bool,
pub last_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 /// https://www.w3.org/TR/css-display-3/#css-text-run
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct TextRun { pub(crate) struct TextRun {
pub tag: OpaqueNode,
pub parent_style: Arc<ComputedValues>, pub parent_style: Arc<ComputedValues>,
pub text: String, pub text: String,
} }
@ -59,6 +62,7 @@ struct InlineNestingLevelState<'box_tree> {
} }
struct PartialInlineBoxFragment<'box_tree> { struct PartialInlineBoxFragment<'box_tree> {
tag: OpaqueNode,
style: Arc<ComputedValues>, style: Arc<ComputedValues>,
start_corner: Vec2<Length>, start_corner: Vec2<Length>,
padding: Sides<Length>, padding: Sides<Length>,
@ -371,6 +375,7 @@ impl InlineBox {
start_corner += &relative_adjustement(&style, ifc.containing_block) start_corner += &relative_adjustement(&style, ifc.containing_block)
} }
PartialInlineBoxFragment { PartialInlineBoxFragment {
tag: self.tag,
style, style,
start_corner, start_corner,
padding, padding,
@ -398,6 +403,7 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> {
at_line_break: bool, at_line_break: bool,
) { ) {
let mut fragment = BoxFragment { let mut fragment = BoxFragment {
tag: self.tag,
style: self.style.clone(), style: self.style.clone(),
children: std::mem::take(&mut nesting_level.fragments_so_far), children: std::mem::take(&mut nesting_level.fragments_so_far),
content_rect: Rect { content_rect: Rect {
@ -465,6 +471,7 @@ fn layout_atomic<'box_tree>(
let fragments = replaced.make_fragments(&atomic.style, size.clone()); let fragments = replaced.make_fragments(&atomic.style, size.clone());
let content_rect = Rect { start_corner, size }; let content_rect = Rect { start_corner, size };
BoxFragment { BoxFragment {
tag: atomic.tag,
style: atomic.style.clone(), style: atomic.style.clone(),
children: fragments, children: fragments,
content_rect, content_rect,
@ -539,6 +546,7 @@ fn layout_atomic<'box_tree>(
}, },
}; };
BoxFragment { BoxFragment {
tag: atomic.tag,
style: atomic.style.clone(), style: atomic.style.clone(),
children: independent_layout.fragments, children: independent_layout.fragments,
content_rect, content_rect,
@ -685,6 +693,7 @@ impl TextRun {
ifc.current_nesting_level ifc.current_nesting_level
.fragments_so_far .fragments_so_far
.push(Fragment::Text(TextFragment { .push(Fragment::Text(TextFragment {
tag: self.tag,
parent_style: self.parent_style.clone(), parent_style: self.parent_style.clone(),
rect, rect,
ascent: font_ascent.into(), ascent: font_ascent.into(),

View file

@ -18,6 +18,7 @@ use crate::ContainingBlock;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt; use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc; use servo_arc::Arc;
use style::dom::OpaqueNode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto}; use style::values::computed::{Length, LengthOrAuto};
use style::Zero; use style::Zero;
@ -44,6 +45,7 @@ pub(crate) enum BlockContainer {
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum BlockLevelBox { pub(crate) enum BlockLevelBox {
SameFormattingContextBlock { SameFormattingContextBlock {
tag: OpaqueNode,
style: Arc<ComputedValues>, style: Arc<ComputedValues>,
contents: BlockContainer, contents: BlockContainer,
}, },
@ -268,24 +270,27 @@ impl BlockLevelBox {
float_context: Option<&mut FloatContext>, float_context: Option<&mut FloatContext>,
) -> Fragment { ) -> Fragment {
match self { match self {
BlockLevelBox::SameFormattingContextBlock { style, contents } => { BlockLevelBox::SameFormattingContextBlock {
Fragment::Box(positioning_context.for_maybe_position_relative( tag,
layout_context, style,
containing_block, contents,
style, } => Fragment::Box(positioning_context.for_maybe_position_relative(
|positioning_context| { layout_context,
layout_in_flow_non_replaced_block_level( containing_block,
layout_context, style,
positioning_context, |positioning_context| {
containing_block, layout_in_flow_non_replaced_block_level(
style, layout_context,
NonReplacedContents::SameFormattingContextBlock(contents), positioning_context,
tree_rank, containing_block,
float_context, *tag,
) style,
}, NonReplacedContents::SameFormattingContextBlock(contents),
)) tree_rank,
}, float_context,
)
},
)),
BlockLevelBox::Independent(contents) => { BlockLevelBox::Independent(contents) => {
Fragment::Box(positioning_context.for_maybe_position_relative( Fragment::Box(positioning_context.for_maybe_position_relative(
layout_context, layout_context,
@ -294,6 +299,7 @@ impl BlockLevelBox {
|positioning_context| match contents.as_replaced() { |positioning_context| match contents.as_replaced() {
Ok(replaced) => layout_in_flow_replaced_block_level( Ok(replaced) => layout_in_flow_replaced_block_level(
containing_block, containing_block,
contents.tag,
&contents.style, &contents.style,
replaced, replaced,
), ),
@ -301,6 +307,7 @@ impl BlockLevelBox {
layout_context, layout_context,
positioning_context, positioning_context,
containing_block, containing_block,
contents.tag,
&contents.style, &contents.style,
NonReplacedContents::EstablishesAnIndependentFormattingContext( NonReplacedContents::EstablishesAnIndependentFormattingContext(
non_replaced, non_replaced,
@ -339,6 +346,7 @@ fn layout_in_flow_non_replaced_block_level<'a>(
layout_context: &LayoutContext, layout_context: &LayoutContext,
positioning_context: &mut PositioningContext<'a>, positioning_context: &mut PositioningContext<'a>,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tag: OpaqueNode,
style: &Arc<ComputedValues>, style: &Arc<ComputedValues>,
block_level_kind: NonReplacedContents<'a>, block_level_kind: NonReplacedContents<'a>,
tree_rank: usize, tree_rank: usize,
@ -488,6 +496,7 @@ fn layout_in_flow_non_replaced_block_level<'a>(
}, },
}; };
BoxFragment { BoxFragment {
tag,
style: style.clone(), style: style.clone(),
children: fragments, children: fragments,
content_rect, 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 /// https://drafts.csswg.org/css2/visudet.html#inline-replaced-height
fn layout_in_flow_replaced_block_level<'a>( fn layout_in_flow_replaced_block_level<'a>(
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tag: OpaqueNode,
style: &Arc<ComputedValues>, style: &Arc<ComputedValues>,
replaced: &ReplacedContent, replaced: &ReplacedContent,
) -> BoxFragment { ) -> BoxFragment {
@ -536,6 +546,7 @@ fn layout_in_flow_replaced_block_level<'a>(
size, size,
}; };
BoxFragment { BoxFragment {
tag,
style: style.clone(), style: style.clone(),
children: fragments, children: fragments,
content_rect, content_rect,

View file

@ -66,7 +66,13 @@ fn construct_for_root_element<'dom>(
( (
ContainsFloats::No, ContainsFloats::No,
vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox( 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() { } else if box_style.float.is_floating() {

View file

@ -13,12 +13,14 @@ use crate::style_ext::DisplayInside;
use crate::ContainingBlock; use crate::ContainingBlock;
use servo_arc::Arc; use servo_arc::Arc;
use std::convert::TryInto; use std::convert::TryInto;
use style::dom::OpaqueNode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::Length; use style::values::computed::Length;
/// https://drafts.csswg.org/css-display/#independent-formatting-context /// https://drafts.csswg.org/css-display/#independent-formatting-context
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct IndependentFormattingContext { pub(crate) struct IndependentFormattingContext {
pub tag: OpaqueNode,
pub style: Arc<ComputedValues>, pub style: Arc<ComputedValues>,
/// If it was requested during construction /// If it was requested during construction
@ -71,6 +73,7 @@ impl IndependentFormattingContext {
content_sizes, content_sizes,
); );
Self { Self {
tag: node.as_opaque(),
style, style,
content_sizes, content_sizes,
contents: IndependentFormattingContextContents::Flow(bfc), contents: IndependentFormattingContextContents::Flow(bfc),
@ -80,6 +83,7 @@ impl IndependentFormattingContext {
Err(replaced) => { Err(replaced) => {
let content_sizes = content_sizes.compute(|| replaced.inline_content_sizes(&style)); let content_sizes = content_sizes.compute(|| replaced.inline_content_sizes(&style));
Self { Self {
tag: node.as_opaque(),
style, style,
content_sizes, content_sizes,
contents: IndependentFormattingContextContents::Replaced(replaced), contents: IndependentFormattingContextContents::Replaced(replaced),

View file

@ -6,6 +6,7 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2};
use gfx::text::glyph::GlyphStore; use gfx::text::glyph::GlyphStore;
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use std::sync::Arc; use std::sync::Arc;
use style::dom::OpaqueNode;
use style::logical_geometry::WritingMode; use style::logical_geometry::WritingMode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::Length; use style::values::computed::Length;
@ -20,6 +21,7 @@ pub(crate) enum Fragment {
} }
pub(crate) struct BoxFragment { pub(crate) struct BoxFragment {
pub tag: OpaqueNode,
pub style: ServoArc<ComputedValues>, pub style: ServoArc<ComputedValues>,
pub children: Vec<Fragment>, pub children: Vec<Fragment>,
@ -55,6 +57,7 @@ pub(crate) struct AnonymousFragment {
} }
pub(crate) struct TextFragment { pub(crate) struct TextFragment {
pub tag: OpaqueNode,
pub parent_style: ServoArc<ComputedValues>, pub parent_style: ServoArc<ComputedValues>,
pub rect: Rect<Length>, pub rect: Rect<Length>,
pub ascent: Length, pub ascent: Length,

View file

@ -471,6 +471,7 @@ impl<'box_tree> HoistedAbsolutelyPositionedBox<'box_tree> {
}; };
BoxFragment { BoxFragment {
tag: self.absolutely_positioned_box.contents.tag,
style: style.clone(), style: style.clone(),
children: fragments, children: fragments,
content_rect, content_rect,