mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Store an OpaqueNode in boxes and fragments
This commit is contained in:
parent
47944a39fc
commit
abc2c15c28
8 changed files with 67 additions and 25 deletions
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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,8 +270,11 @@ 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,
|
||||||
|
style,
|
||||||
|
contents,
|
||||||
|
} => Fragment::Box(positioning_context.for_maybe_position_relative(
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block,
|
containing_block,
|
||||||
style,
|
style,
|
||||||
|
@ -278,14 +283,14 @@ impl BlockLevelBox {
|
||||||
layout_context,
|
layout_context,
|
||||||
positioning_context,
|
positioning_context,
|
||||||
containing_block,
|
containing_block,
|
||||||
|
*tag,
|
||||||
style,
|
style,
|
||||||
NonReplacedContents::SameFormattingContextBlock(contents),
|
NonReplacedContents::SameFormattingContextBlock(contents),
|
||||||
tree_rank,
|
tree_rank,
|
||||||
float_context,
|
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,
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue