mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
layout: Store Fragment
results in LayoutBoxBase
and start using them for queries (#36583)
Start storing a link to laid-out `Fragment`s in `LayoutBoxBase`, so that these are accessible for queries and eventually for incremental layout. Some box tree data structures lacked a `LayoutBoxBase`, such as table tracks and table track groups[^1]. In addition, start using these `Fragment`s for queries instead of walking the entire `Fragment` tree. Currently, this isn't possible for most queries as `Fragment`s do not cache their absolute offsets (which are often necessary). This change uses the new box tree `Fragment`s for most resolved style queries. [^1]: Note that only rows and row groups store `Fragment`s as columsn and colgroups do not produce any. Testing: This is covered by existing tests. Fixes: This is part of #36525. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
fc201927ae
commit
2ee8427665
15 changed files with 387 additions and 222 deletions
|
@ -24,6 +24,7 @@ use crate::context::LayoutContext;
|
||||||
use crate::flexbox::FlexLevelBox;
|
use crate::flexbox::FlexLevelBox;
|
||||||
use crate::flow::BlockLevelBox;
|
use crate::flow::BlockLevelBox;
|
||||||
use crate::flow::inline::InlineItem;
|
use crate::flow::inline::InlineItem;
|
||||||
|
use crate::fragment_tree::Fragment;
|
||||||
use crate::geom::PhysicalSize;
|
use crate::geom::PhysicalSize;
|
||||||
use crate::replaced::{CanvasInfo, CanvasSource};
|
use crate::replaced::{CanvasInfo, CanvasSource};
|
||||||
use crate::table::TableLevelBox;
|
use crate::table::TableLevelBox;
|
||||||
|
@ -38,6 +39,20 @@ pub struct InnerDOMLayoutData {
|
||||||
pub(super) pseudo_marker_box: ArcRefCell<Option<LayoutBox>>,
|
pub(super) pseudo_marker_box: ArcRefCell<Option<LayoutBox>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl InnerDOMLayoutData {
|
||||||
|
pub(crate) fn for_pseudo(
|
||||||
|
&self,
|
||||||
|
pseudo_element: Option<PseudoElement>,
|
||||||
|
) -> AtomicRef<Option<LayoutBox>> {
|
||||||
|
match pseudo_element {
|
||||||
|
Some(PseudoElement::Before) => self.pseudo_before_box.borrow(),
|
||||||
|
Some(PseudoElement::After) => self.pseudo_after_box.borrow(),
|
||||||
|
Some(PseudoElement::Marker) => self.pseudo_marker_box.borrow(),
|
||||||
|
_ => self.self_box.borrow(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A box that is stored in one of the `DOMLayoutData` slots.
|
/// A box that is stored in one of the `DOMLayoutData` slots.
|
||||||
pub(super) enum LayoutBox {
|
pub(super) enum LayoutBox {
|
||||||
DisplayContents,
|
DisplayContents,
|
||||||
|
@ -67,6 +82,17 @@ impl LayoutBox {
|
||||||
LayoutBox::TableLevelBox(table_box) => table_box.invalidate_cached_fragment(),
|
LayoutBox::TableLevelBox(table_box) => table_box.invalidate_cached_fragment(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
match self {
|
||||||
|
LayoutBox::DisplayContents => vec![],
|
||||||
|
LayoutBox::BlockLevel(block_level_box) => block_level_box.borrow().fragments(),
|
||||||
|
LayoutBox::InlineLevel(inline_item) => inline_item.borrow().fragments(),
|
||||||
|
LayoutBox::FlexLevel(flex_level_box) => flex_level_box.borrow().fragments(),
|
||||||
|
LayoutBox::TaffyItemBox(taffy_item_box) => taffy_item_box.borrow().fragments(),
|
||||||
|
LayoutBox::TableLevelBox(table_box) => table_box.fragments(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for [`InnerDOMLayoutData`]. This is necessary to give the entire data
|
/// A wrapper for [`InnerDOMLayoutData`]. This is necessary to give the entire data
|
||||||
|
@ -138,6 +164,7 @@ pub(crate) trait NodeExt<'dom>: 'dom + LayoutNode<'dom> {
|
||||||
/// Remove boxes for the element itself, and its `:before` and `:after` if any.
|
/// Remove boxes for the element itself, and its `:before` and `:after` if any.
|
||||||
fn unset_all_boxes(self);
|
fn unset_all_boxes(self);
|
||||||
|
|
||||||
|
fn fragments_for_pseudo(&self, pseudo_element: Option<PseudoElement>) -> Vec<Fragment>;
|
||||||
fn invalidate_cached_fragment(self);
|
fn invalidate_cached_fragment(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,4 +314,15 @@ where
|
||||||
data.invalidate_cached_fragment();
|
data.invalidate_cached_fragment();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fragments_for_pseudo(&self, pseudo_element: Option<PseudoElement>) -> Vec<Fragment> {
|
||||||
|
NodeExt::layout_data(*self)
|
||||||
|
.and_then(|layout_data| {
|
||||||
|
layout_data
|
||||||
|
.for_pseudo(pseudo_element)
|
||||||
|
.as_ref()
|
||||||
|
.map(LayoutBox::fragments)
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ impl FlexLineItem<'_> {
|
||||||
flex_context: &mut FlexContext,
|
flex_context: &mut FlexContext,
|
||||||
all_baselines: &mut Baselines,
|
all_baselines: &mut Baselines,
|
||||||
main_position_cursor: &mut Au,
|
main_position_cursor: &mut Au,
|
||||||
) -> (BoxFragment, PositioningContext) {
|
) -> (ArcRefCell<BoxFragment>, PositioningContext) {
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-main-align
|
// https://drafts.csswg.org/css-flexbox/#algo-main-align
|
||||||
// “Align the items along the main-axis”
|
// “Align the items along the main-axis”
|
||||||
*main_position_cursor +=
|
*main_position_cursor +=
|
||||||
|
@ -312,6 +312,12 @@ impl FlexLineItem<'_> {
|
||||||
.to_physical_size(containing_block.style.writing_mode)
|
.to_physical_size(containing_block.style.writing_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fragment = ArcRefCell::new(fragment);
|
||||||
|
self.item
|
||||||
|
.box_
|
||||||
|
.independent_formatting_context
|
||||||
|
.base
|
||||||
|
.set_fragment(Fragment::Box(fragment.clone()));
|
||||||
(fragment, self.layout_result.positioning_context)
|
(fragment, self.layout_result.positioning_context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +329,7 @@ struct FinalFlexLineLayout {
|
||||||
cross_size: Au,
|
cross_size: Au,
|
||||||
/// The [`BoxFragment`]s and [`PositioningContext`]s of all flex items,
|
/// The [`BoxFragment`]s and [`PositioningContext`]s of all flex items,
|
||||||
/// one per flex item in "order-modified document order."
|
/// one per flex item in "order-modified document order."
|
||||||
item_fragments: Vec<(BoxFragment, PositioningContext)>,
|
item_fragments: Vec<(ArcRefCell<BoxFragment>, PositioningContext)>,
|
||||||
/// The 'shared alignment baseline' of this flex line. This is the baseline used for
|
/// The 'shared alignment baseline' of this flex line. This is the baseline used for
|
||||||
/// baseline-aligned items if there are any, otherwise `None`.
|
/// baseline-aligned items if there are any, otherwise `None`.
|
||||||
shared_alignment_baseline: Option<Au>,
|
shared_alignment_baseline: Option<Au>,
|
||||||
|
@ -935,7 +941,7 @@ impl FlexContainer {
|
||||||
let physical_line_position =
|
let physical_line_position =
|
||||||
flow_relative_line_position.to_physical_size(self.style.writing_mode);
|
flow_relative_line_position.to_physical_size(self.style.writing_mode);
|
||||||
for (fragment, _) in &mut final_line_layout.item_fragments {
|
for (fragment, _) in &mut final_line_layout.item_fragments {
|
||||||
fragment.content_rect.origin += physical_line_position;
|
fragment.borrow_mut().content_rect.origin += physical_line_position;
|
||||||
}
|
}
|
||||||
final_line_layout.item_fragments
|
final_line_layout.item_fragments
|
||||||
})
|
})
|
||||||
|
@ -957,7 +963,7 @@ impl FlexContainer {
|
||||||
// per flex item, in the original order.
|
// per flex item, in the original order.
|
||||||
let (fragment, mut child_positioning_context) =
|
let (fragment, mut child_positioning_context) =
|
||||||
flex_item_fragments.next().unwrap();
|
flex_item_fragments.next().unwrap();
|
||||||
let fragment = Fragment::Box(ArcRefCell::new(fragment));
|
let fragment = Fragment::Box(fragment);
|
||||||
child_positioning_context.adjust_static_position_of_hoisted_fragments(
|
child_positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||||
&fragment,
|
&fragment,
|
||||||
PositioningContextLength::zero(),
|
PositioningContextLength::zero(),
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::context::LayoutContext;
|
||||||
use crate::dom::{LayoutBox, NodeExt};
|
use crate::dom::{LayoutBox, NodeExt};
|
||||||
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::{BaseFragmentInfo, Fragment};
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
|
|
||||||
mod geom;
|
mod geom;
|
||||||
|
@ -157,6 +157,18 @@ impl FlexLevelBox {
|
||||||
.invalidate_cached_fragment(),
|
.invalidate_cached_fragment(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
match self {
|
||||||
|
FlexLevelBox::FlexItem(flex_item_box) => flex_item_box
|
||||||
|
.independent_formatting_context
|
||||||
|
.base
|
||||||
|
.fragments(),
|
||||||
|
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
||||||
|
positioned_box.borrow().context.base.fragments()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct FlexItemBox {
|
pub(crate) struct FlexItemBox {
|
||||||
|
|
|
@ -73,6 +73,10 @@ impl InlineBoxes {
|
||||||
self.inline_boxes.len()
|
self.inline_boxes.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn iter(&self) -> impl Iterator<Item = &ArcRefCell<InlineBox>> {
|
||||||
|
self.inline_boxes.iter()
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn get(&self, identifier: &InlineBoxIdentifier) -> ArcRefCell<InlineBox> {
|
pub(super) fn get(&self, identifier: &InlineBoxIdentifier) -> ArcRefCell<InlineBox> {
|
||||||
self.inline_boxes[identifier.index_in_inline_boxes as usize].clone()
|
self.inline_boxes[identifier.index_in_inline_boxes as usize].clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,9 +492,11 @@ impl LineItemLayout<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.inline_advance += inner_state.inline_advance + pbm_sums.inline_sum();
|
self.current_state.inline_advance += inner_state.inline_advance + pbm_sums.inline_sum();
|
||||||
self.current_state
|
|
||||||
.fragments
|
let fragment = Fragment::Box(ArcRefCell::new(fragment));
|
||||||
.push((Fragment::Box(ArcRefCell::new(fragment)), content_rect));
|
inline_box.base.add_fragment(fragment.clone());
|
||||||
|
|
||||||
|
self.current_state.fragments.push((fragment, content_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_inline_box_block_start(
|
fn calculate_inline_box_block_start(
|
||||||
|
@ -587,32 +589,34 @@ impl LineItemLayout<'_, '_> {
|
||||||
// This needs to be added to the calculated block and inline positions.
|
// This needs to be added to the calculated block and inline positions.
|
||||||
// Make the final result relative to the parent box.
|
// Make the final result relative to the parent box.
|
||||||
let ifc_writing_mode = self.layout.containing_block.style.writing_mode;
|
let ifc_writing_mode = self.layout.containing_block.style.writing_mode;
|
||||||
let padding_border_margin_sides = atomic
|
let content_rect = {
|
||||||
.fragment
|
let block_start = atomic.calculate_block_start(&self.line_metrics);
|
||||||
.padding_border_margin()
|
let atomic_fragment = atomic.fragment.borrow_mut();
|
||||||
.to_logical(ifc_writing_mode);
|
let padding_border_margin_sides = atomic_fragment
|
||||||
|
.padding_border_margin()
|
||||||
|
.to_logical(ifc_writing_mode);
|
||||||
|
|
||||||
let mut atomic_offset = LogicalVec2 {
|
let mut atomic_offset = LogicalVec2 {
|
||||||
inline: self.current_state.inline_advance + padding_border_margin_sides.inline_start,
|
inline: self.current_state.inline_advance +
|
||||||
block: atomic.calculate_block_start(&self.line_metrics) -
|
padding_border_margin_sides.inline_start,
|
||||||
self.current_state.parent_offset.block +
|
block: block_start - self.current_state.parent_offset.block +
|
||||||
padding_border_margin_sides.block_start,
|
padding_border_margin_sides.block_start,
|
||||||
};
|
};
|
||||||
|
|
||||||
if atomic.fragment.style.get_box().position == Position::Relative {
|
if atomic_fragment.style.get_box().position == Position::Relative {
|
||||||
atomic_offset +=
|
atomic_offset +=
|
||||||
relative_adjustement(&atomic.fragment.style, self.layout.containing_block);
|
relative_adjustement(&atomic_fragment.style, self.layout.containing_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconstruct a logical rectangle relative to the inline box container that will be used
|
// Reconstruct a logical rectangle relative to the inline box container that will be used
|
||||||
// after the inline box is procesed to find a final physical rectangle.
|
// after the inline box is procesed to find a final physical rectangle.
|
||||||
let content_rect = LogicalRect {
|
LogicalRect {
|
||||||
start_corner: atomic_offset,
|
start_corner: atomic_offset,
|
||||||
size: atomic
|
size: atomic_fragment
|
||||||
.fragment
|
.content_rect
|
||||||
.content_rect
|
.size
|
||||||
.size
|
.to_logical(ifc_writing_mode),
|
||||||
.to_logical(ifc_writing_mode),
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(mut positioning_context) = atomic.positioning_context {
|
if let Some(mut positioning_context) = atomic.positioning_context {
|
||||||
|
@ -628,10 +632,10 @@ impl LineItemLayout<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.inline_advance += atomic.size.inline;
|
self.current_state.inline_advance += atomic.size.inline;
|
||||||
self.current_state.fragments.push((
|
|
||||||
Fragment::Box(ArcRefCell::new(atomic.fragment)),
|
self.current_state
|
||||||
content_rect,
|
.fragments
|
||||||
));
|
.push((Fragment::Box(atomic.fragment), content_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) {
|
fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) {
|
||||||
|
@ -691,7 +695,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_float(&mut self, mut float: FloatLineItem) {
|
fn layout_float(&mut self, float: FloatLineItem) {
|
||||||
self.current_state
|
self.current_state
|
||||||
.flags
|
.flags
|
||||||
.insert(LineLayoutInlineContainerFlags::HAD_ANY_FLOATS);
|
.insert(LineLayoutInlineContainerFlags::HAD_ANY_FLOATS);
|
||||||
|
@ -705,13 +709,12 @@ impl LineItemLayout<'_, '_> {
|
||||||
inline: self.current_state.parent_offset.inline,
|
inline: self.current_state.parent_offset.inline,
|
||||||
block: self.line_metrics.block_offset + self.current_state.parent_offset.block,
|
block: self.line_metrics.block_offset + self.current_state.parent_offset.block,
|
||||||
};
|
};
|
||||||
float.fragment.content_rect.origin -= distance_from_parent_to_ifc
|
float.fragment.borrow_mut().content_rect.origin -= distance_from_parent_to_ifc
|
||||||
.to_physical_size(self.layout.containing_block.style.writing_mode);
|
.to_physical_size(self.layout.containing_block.style.writing_mode);
|
||||||
|
|
||||||
self.current_state.fragments.push((
|
self.current_state
|
||||||
Fragment::Float(ArcRefCell::new(float.fragment)),
|
.fragments
|
||||||
LogicalRect::zero(),
|
.push((Fragment::Float(float.fragment), LogicalRect::zero()));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,7 +832,7 @@ impl TextRunLineItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct AtomicLineItem {
|
pub(super) struct AtomicLineItem {
|
||||||
pub fragment: BoxFragment,
|
pub fragment: ArcRefCell<BoxFragment>,
|
||||||
pub size: LogicalVec2<Au>,
|
pub size: LogicalVec2<Au>,
|
||||||
pub positioning_context: Option<PositioningContext>,
|
pub positioning_context: Option<PositioningContext>,
|
||||||
|
|
||||||
|
@ -849,7 +852,7 @@ impl AtomicLineItem {
|
||||||
/// Given the metrics for a line, our vertical alignment, and our block size, find a block start
|
/// Given the metrics for a line, our vertical alignment, and our block size, find a block start
|
||||||
/// position relative to the top of the line.
|
/// position relative to the top of the line.
|
||||||
fn calculate_block_start(&self, line_metrics: &LineMetrics) -> Au {
|
fn calculate_block_start(&self, line_metrics: &LineMetrics) -> Au {
|
||||||
match self.fragment.style.clone_vertical_align() {
|
match self.fragment.borrow().style.clone_vertical_align() {
|
||||||
GenericVerticalAlign::Keyword(VerticalAlignKeyword::Top) => Au::zero(),
|
GenericVerticalAlign::Keyword(VerticalAlignKeyword::Top) => Au::zero(),
|
||||||
GenericVerticalAlign::Keyword(VerticalAlignKeyword::Bottom) => {
|
GenericVerticalAlign::Keyword(VerticalAlignKeyword::Bottom) => {
|
||||||
line_metrics.block_size - self.size.block
|
line_metrics.block_size - self.size.block
|
||||||
|
@ -869,7 +872,7 @@ pub(super) struct AbsolutelyPositionedLineItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct FloatLineItem {
|
pub(super) struct FloatLineItem {
|
||||||
pub fragment: BoxFragment,
|
pub fragment: ArcRefCell<BoxFragment>,
|
||||||
/// Whether or not this float Fragment has been placed yet. Fragments that
|
/// Whether or not this float Fragment has been placed yet. Fragments that
|
||||||
/// do not fit on a line need to be placed after the hypothetical block start
|
/// do not fit on a line need to be placed after the hypothetical block start
|
||||||
/// of the next line.
|
/// of the next line.
|
||||||
|
|
|
@ -221,6 +221,22 @@ impl InlineItem {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
match self {
|
||||||
|
InlineItem::StartInlineBox(inline_box) => inline_box.borrow().base.fragments(),
|
||||||
|
InlineItem::EndInlineBox | InlineItem::TextRun(..) => {
|
||||||
|
unreachable!("Should never have these kind of fragments attached to a DOM node")
|
||||||
|
},
|
||||||
|
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
|
||||||
|
positioned_box.borrow().context.base.fragments()
|
||||||
|
},
|
||||||
|
InlineItem::OutOfFlowFloatBox(float_box) => float_box.contents.base.fragments(),
|
||||||
|
InlineItem::Atomic(independent_formatting_context, ..) => {
|
||||||
|
independent_formatting_context.base.fragments()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about the current line under construction for a particular
|
/// Information about the current line under construction for a particular
|
||||||
|
@ -1081,8 +1097,8 @@ impl InlineFormattingContextLayout<'_> {
|
||||||
float_item: &mut FloatLineItem,
|
float_item: &mut FloatLineItem,
|
||||||
line_inline_size_without_trailing_whitespace: Au,
|
line_inline_size_without_trailing_whitespace: Au,
|
||||||
) {
|
) {
|
||||||
let logical_margin_rect_size = float_item
|
let mut float_fragment = float_item.fragment.borrow_mut();
|
||||||
.fragment
|
let logical_margin_rect_size = float_fragment
|
||||||
.margin_rect()
|
.margin_rect()
|
||||||
.size
|
.size
|
||||||
.to_logical(self.containing_block.style.writing_mode);
|
.to_logical(self.containing_block.style.writing_mode);
|
||||||
|
@ -1106,7 +1122,7 @@ impl InlineFormattingContextLayout<'_> {
|
||||||
if needs_placement_later {
|
if needs_placement_later {
|
||||||
self.current_line.has_floats_waiting_to_be_placed = true;
|
self.current_line.has_floats_waiting_to_be_placed = true;
|
||||||
} else {
|
} else {
|
||||||
self.place_float_fragment(&mut float_item.fragment);
|
self.place_float_fragment(&mut float_fragment);
|
||||||
float_item.needs_placement = false;
|
float_item.needs_placement = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1657,6 +1673,11 @@ impl InlineFormattingContext {
|
||||||
Au::zero()
|
Au::zero()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clear any cached inline fragments from previous layouts.
|
||||||
|
for inline_box in self.inline_boxes.iter() {
|
||||||
|
inline_box.borrow().base.clear_fragments();
|
||||||
|
}
|
||||||
|
|
||||||
let style = containing_block.style;
|
let style = containing_block.style;
|
||||||
|
|
||||||
// It's unfortunate that it isn't possible to get this during IFC text processing, but in
|
// It's unfortunate that it isn't possible to get this during IFC text processing, but in
|
||||||
|
@ -2055,6 +2076,10 @@ impl IndependentFormattingContext {
|
||||||
size.inline,
|
size.inline,
|
||||||
SegmentContentFlags::empty(),
|
SegmentContentFlags::empty(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let fragment = ArcRefCell::new(fragment);
|
||||||
|
self.base.set_fragment(Fragment::Box(fragment.clone()));
|
||||||
|
|
||||||
layout.push_line_item_to_unbreakable_segment(LineItem::Atomic(
|
layout.push_line_item_to_unbreakable_segment(LineItem::Atomic(
|
||||||
layout.current_inline_box_identifier(),
|
layout.current_inline_box_identifier(),
|
||||||
AtomicLineItem {
|
AtomicLineItem {
|
||||||
|
@ -2131,11 +2156,15 @@ impl IndependentFormattingContext {
|
||||||
|
|
||||||
impl FloatBox {
|
impl FloatBox {
|
||||||
fn layout_into_line_items(&self, layout: &mut InlineFormattingContextLayout) {
|
fn layout_into_line_items(&self, layout: &mut InlineFormattingContextLayout) {
|
||||||
let fragment = self.layout(
|
let fragment = ArcRefCell::new(self.layout(
|
||||||
layout.layout_context,
|
layout.layout_context,
|
||||||
layout.positioning_context,
|
layout.positioning_context,
|
||||||
layout.containing_block,
|
layout.containing_block,
|
||||||
);
|
));
|
||||||
|
|
||||||
|
self.contents
|
||||||
|
.base
|
||||||
|
.set_fragment(Fragment::Box(fragment.clone()));
|
||||||
layout.push_line_item_to_unbreakable_segment(LineItem::Float(
|
layout.push_line_item_to_unbreakable_segment(LineItem::Float(
|
||||||
layout.current_inline_box_identifier(),
|
layout.current_inline_box_identifier(),
|
||||||
FloatLineItem {
|
FloatLineItem {
|
||||||
|
@ -2150,7 +2179,7 @@ fn place_pending_floats(ifc: &mut InlineFormattingContextLayout, line_items: &mu
|
||||||
for item in line_items.iter_mut() {
|
for item in line_items.iter_mut() {
|
||||||
if let LineItem::Float(_, float_line_item) = item {
|
if let LineItem::Float(_, float_line_item) = item {
|
||||||
if float_line_item.needs_placement {
|
if float_line_item.needs_placement {
|
||||||
ifc.place_float_fragment(&mut float_line_item.fragment);
|
ifc.place_float_fragment(&mut float_line_item.fragment.borrow_mut());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,23 +91,25 @@ pub(crate) enum BlockLevelBox {
|
||||||
|
|
||||||
impl BlockLevelBox {
|
impl BlockLevelBox {
|
||||||
pub(crate) fn invalidate_cached_fragment(&self) {
|
pub(crate) fn invalidate_cached_fragment(&self) {
|
||||||
|
self.with_base(LayoutBoxBase::invalidate_cached_fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
self.with_base(LayoutBoxBase::fragments)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
||||||
match self {
|
match self {
|
||||||
BlockLevelBox::Independent(independent_formatting_context) => {
|
BlockLevelBox::Independent(independent_formatting_context) => {
|
||||||
&independent_formatting_context.base
|
callback(&independent_formatting_context.base)
|
||||||
},
|
},
|
||||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
||||||
positioned_box
|
callback(&positioned_box.borrow().context.base)
|
||||||
.borrow()
|
|
||||||
.context
|
|
||||||
.base
|
|
||||||
.invalidate_cached_fragment();
|
|
||||||
return;
|
|
||||||
},
|
},
|
||||||
BlockLevelBox::OutOfFlowFloatBox(float_box) => &float_box.contents.base,
|
BlockLevelBox::OutOfFlowFloatBox(float_box) => callback(&float_box.contents.base),
|
||||||
BlockLevelBox::OutsideMarker(outside_marker) => &outside_marker.base,
|
BlockLevelBox::OutsideMarker(outside_marker) => callback(&outside_marker.base),
|
||||||
BlockLevelBox::SameFormattingContextBlock { base, .. } => base,
|
BlockLevelBox::SameFormattingContextBlock { base, .. } => callback(base),
|
||||||
}
|
}
|
||||||
.invalidate_cached_fragment();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_floats(&self) -> bool {
|
fn contains_floats(&self) -> bool {
|
||||||
|
@ -770,7 +772,7 @@ impl BlockLevelBox {
|
||||||
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
|
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
|
||||||
ignore_block_margins_for_stretch: LogicalSides1D<bool>,
|
ignore_block_margins_for_stretch: LogicalSides1D<bool>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
match self {
|
let fragment = match self {
|
||||||
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => Fragment::Box(
|
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => Fragment::Box(
|
||||||
ArcRefCell::new(positioning_context.layout_maybe_position_relative_fragment(
|
ArcRefCell::new(positioning_context.layout_maybe_position_relative_fragment(
|
||||||
layout_context,
|
layout_context,
|
||||||
|
@ -836,7 +838,11 @@ impl BlockLevelBox {
|
||||||
sequential_layout_state,
|
sequential_layout_state,
|
||||||
collapsible_with_parent_start_margin,
|
collapsible_with_parent_start_margin,
|
||||||
),
|
),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
self.with_base(|base| base.set_fragment(fragment.clone()));
|
||||||
|
|
||||||
|
fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inline_content_sizes(
|
fn inline_content_sizes(
|
||||||
|
|
|
@ -29,6 +29,7 @@ pub(crate) struct LayoutBoxBase {
|
||||||
pub cached_inline_content_size:
|
pub cached_inline_content_size:
|
||||||
AtomicRefCell<Option<Box<(SizeConstraint, InlineContentSizesResult)>>>,
|
AtomicRefCell<Option<Box<(SizeConstraint, InlineContentSizesResult)>>>,
|
||||||
pub cached_layout_result: AtomicRefCell<Option<Box<CacheableLayoutResultAndInputs>>>,
|
pub cached_layout_result: AtomicRefCell<Option<Box<CacheableLayoutResultAndInputs>>>,
|
||||||
|
pub fragments: AtomicRefCell<Vec<Fragment>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutBoxBase {
|
impl LayoutBoxBase {
|
||||||
|
@ -38,6 +39,7 @@ impl LayoutBoxBase {
|
||||||
style,
|
style,
|
||||||
cached_inline_content_size: AtomicRefCell::default(),
|
cached_inline_content_size: AtomicRefCell::default(),
|
||||||
cached_layout_result: AtomicRefCell::default(),
|
cached_layout_result: AtomicRefCell::default(),
|
||||||
|
fragments: AtomicRefCell::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +71,22 @@ impl LayoutBoxBase {
|
||||||
pub(crate) fn invalidate_cached_fragment(&self) {
|
pub(crate) fn invalidate_cached_fragment(&self) {
|
||||||
let _ = self.cached_layout_result.borrow_mut().take();
|
let _ = self.cached_layout_result.borrow_mut().take();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
self.fragments.borrow().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn add_fragment(&self, fragment: Fragment) {
|
||||||
|
self.fragments.borrow_mut().push(fragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_fragment(&self, fragment: Fragment) {
|
||||||
|
*self.fragments.borrow_mut() = vec![fragment];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn clear_fragments(&self) {
|
||||||
|
self.fragments.borrow_mut().clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for LayoutBoxBase {
|
impl Debug for LayoutBoxBase {
|
||||||
|
|
|
@ -436,9 +436,8 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
containing_block_padding,
|
containing_block_padding,
|
||||||
);
|
);
|
||||||
|
|
||||||
hoisted_box.fragment.borrow_mut().fragment =
|
hoisted_box.fragment.borrow_mut().fragment = Some(new_fragment.clone());
|
||||||
Some(Fragment::Box(new_fragment.clone()));
|
(new_fragment, new_hoisted_boxes)
|
||||||
(Fragment::Box(new_fragment), new_hoisted_boxes)
|
|
||||||
})
|
})
|
||||||
.unzip_into_vecs(&mut new_fragments, &mut new_hoisted_boxes);
|
.unzip_into_vecs(&mut new_fragments, &mut new_hoisted_boxes);
|
||||||
|
|
||||||
|
@ -454,8 +453,8 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
containing_block_padding,
|
containing_block_padding,
|
||||||
);
|
);
|
||||||
|
|
||||||
box_.fragment.borrow_mut().fragment = Some(Fragment::Box(new_fragment.clone()));
|
box_.fragment.borrow_mut().fragment = Some(new_fragment.clone());
|
||||||
Fragment::Box(new_fragment)
|
new_fragment
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,7 +465,7 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>,
|
for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>,
|
||||||
containing_block: &DefiniteContainingBlock,
|
containing_block: &DefiniteContainingBlock,
|
||||||
containing_block_padding: PhysicalSides<Au>,
|
containing_block_padding: PhysicalSides<Au>,
|
||||||
) -> ArcRefCell<BoxFragment> {
|
) -> Fragment {
|
||||||
let cbis = containing_block.size.inline;
|
let cbis = containing_block.size.inline;
|
||||||
let cbbs = containing_block.size.block;
|
let cbbs = containing_block.size.block;
|
||||||
let containing_block_writing_mode = containing_block.style.writing_mode;
|
let containing_block_writing_mode = containing_block.style.writing_mode;
|
||||||
|
@ -714,7 +713,9 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
for_nearest_containing_block_for_all_descendants
|
for_nearest_containing_block_for_all_descendants
|
||||||
.extend(positioning_context.for_nearest_containing_block_for_all_descendants);
|
.extend(positioning_context.for_nearest_containing_block_for_all_descendants);
|
||||||
|
|
||||||
ArcRefCell::new(new_fragment)
|
let fragment = Fragment::Box(ArcRefCell::new(new_fragment));
|
||||||
|
context.base.set_fragment(fragment.clone());
|
||||||
|
fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ use style::values::specified::GenericGridTemplateComponent;
|
||||||
use style::values::specified::box_::DisplayInside;
|
use style::values::specified::box_::DisplayInside;
|
||||||
use style_traits::{ParsingMode, ToCss};
|
use style_traits::{ParsingMode, ToCss};
|
||||||
|
|
||||||
|
use crate::dom::NodeExt;
|
||||||
use crate::flow::inline::construct::{TextTransformation, WhitespaceCollapse};
|
use crate::flow::inline::construct::{TextTransformation, WhitespaceCollapse};
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag,
|
BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag,
|
||||||
|
@ -105,7 +106,7 @@ pub fn process_node_scroll_area_request(
|
||||||
/// <https://drafts.csswg.org/cssom/#resolved-value>
|
/// <https://drafts.csswg.org/cssom/#resolved-value>
|
||||||
pub fn process_resolved_style_request<'dom>(
|
pub fn process_resolved_style_request<'dom>(
|
||||||
context: &SharedStyleContext,
|
context: &SharedStyleContext,
|
||||||
node: impl LayoutNode<'dom>,
|
node: impl LayoutNode<'dom> + 'dom,
|
||||||
pseudo: &Option<PseudoElement>,
|
pseudo: &Option<PseudoElement>,
|
||||||
property: &PropertyId,
|
property: &PropertyId,
|
||||||
fragment_tree: Option<Arc<FragmentTree>>,
|
fragment_tree: Option<Arc<FragmentTree>>,
|
||||||
|
@ -190,90 +191,102 @@ pub fn process_resolved_style_request<'dom>(
|
||||||
return computed_style(None);
|
return computed_style(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolve_for_fragment = |fragment: &Fragment, containing_block: &PhysicalRect<Au>| {
|
let resolve_for_fragment =
|
||||||
let (content_rect, margins, padding, specific_layout_info) = match fragment {
|
|fragment: &Fragment, containing_block: Option<&PhysicalRect<Au>>| {
|
||||||
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
|
let (content_rect, margins, padding, specific_layout_info) = match fragment {
|
||||||
let box_fragment = box_fragment.borrow();
|
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
|
||||||
if style.get_box().position != Position::Static {
|
let box_fragment = box_fragment.borrow();
|
||||||
let resolved_insets =
|
if style.get_box().position != Position::Static {
|
||||||
|| box_fragment.calculate_resolved_insets_if_positioned(containing_block);
|
let resolved_insets = || {
|
||||||
match longhand_id {
|
box_fragment
|
||||||
LonghandId::Top => return resolved_insets().top.to_css_string(),
|
.calculate_resolved_insets_if_positioned(containing_block.unwrap())
|
||||||
LonghandId::Right => {
|
};
|
||||||
return resolved_insets().right.to_css_string();
|
match longhand_id {
|
||||||
},
|
LonghandId::Top => return resolved_insets().top.to_css_string(),
|
||||||
LonghandId::Bottom => {
|
LonghandId::Right => {
|
||||||
return resolved_insets().bottom.to_css_string();
|
return resolved_insets().right.to_css_string();
|
||||||
},
|
},
|
||||||
LonghandId::Left => {
|
LonghandId::Bottom => {
|
||||||
return resolved_insets().left.to_css_string();
|
return resolved_insets().bottom.to_css_string();
|
||||||
},
|
},
|
||||||
_ => {},
|
LonghandId::Left => {
|
||||||
|
return resolved_insets().left.to_css_string();
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let content_rect = box_fragment.content_rect;
|
||||||
|
let margins = box_fragment.margin;
|
||||||
|
let padding = box_fragment.padding;
|
||||||
|
let specific_layout_info = box_fragment.specific_layout_info.clone();
|
||||||
|
(content_rect, margins, padding, specific_layout_info)
|
||||||
|
},
|
||||||
|
Fragment::Positioning(positioning_fragment) => {
|
||||||
|
let content_rect = positioning_fragment.borrow().rect;
|
||||||
|
(
|
||||||
|
content_rect,
|
||||||
|
SideOffsets2D::zero(),
|
||||||
|
SideOffsets2D::zero(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_ => return computed_style(Some(fragment)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-grid/#resolved-track-list
|
||||||
|
// > The grid-template-rows and grid-template-columns properties are
|
||||||
|
// > resolved value special case properties.
|
||||||
|
//
|
||||||
|
// > When an element generates a grid container box...
|
||||||
|
if display.inside() == DisplayInside::Grid {
|
||||||
|
if let Some(SpecificLayoutInfo::Grid(info)) = specific_layout_info {
|
||||||
|
if let Some(value) = resolve_grid_template(&info, style, longhand_id) {
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let content_rect = box_fragment.content_rect;
|
}
|
||||||
let margins = box_fragment.margin;
|
|
||||||
let padding = box_fragment.padding;
|
// https://drafts.csswg.org/cssom/#resolved-value-special-case-property-like-height
|
||||||
let specific_layout_info = box_fragment.specific_layout_info.clone();
|
// > If the property applies to the element or pseudo-element and the resolved value of the
|
||||||
(content_rect, margins, padding, specific_layout_info)
|
// > display property is not none or contents, then the resolved value is the used value.
|
||||||
},
|
// > Otherwise the resolved value is the computed value.
|
||||||
Fragment::Positioning(positioning_fragment) => {
|
//
|
||||||
let content_rect = positioning_fragment.borrow().rect;
|
// However, all browsers ignore that for margin and padding properties, and resolve to a length
|
||||||
(
|
// even if the property doesn't apply: https://github.com/w3c/csswg-drafts/issues/10391
|
||||||
content_rect,
|
match longhand_id {
|
||||||
SideOffsets2D::zero(),
|
LonghandId::Width if resolved_size_should_be_used_value(fragment) => {
|
||||||
SideOffsets2D::zero(),
|
content_rect.size.width
|
||||||
None,
|
},
|
||||||
)
|
LonghandId::Height if resolved_size_should_be_used_value(fragment) => {
|
||||||
},
|
content_rect.size.height
|
||||||
_ => return computed_style(Some(fragment)),
|
},
|
||||||
|
LonghandId::MarginBottom => margins.bottom,
|
||||||
|
LonghandId::MarginTop => margins.top,
|
||||||
|
LonghandId::MarginLeft => margins.left,
|
||||||
|
LonghandId::MarginRight => margins.right,
|
||||||
|
LonghandId::PaddingBottom => padding.bottom,
|
||||||
|
LonghandId::PaddingTop => padding.top,
|
||||||
|
LonghandId::PaddingLeft => padding.left,
|
||||||
|
LonghandId::PaddingRight => padding.right,
|
||||||
|
_ => return computed_style(Some(fragment)),
|
||||||
|
}
|
||||||
|
.to_css_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-grid/#resolved-track-list
|
if !matches!(
|
||||||
// > The grid-template-rows and grid-template-columns properties are
|
longhand_id,
|
||||||
// > resolved value special case properties.
|
LonghandId::Top | LonghandId::Bottom | LonghandId::Left | LonghandId::Right
|
||||||
//
|
) {
|
||||||
// > When an element generates a grid container box...
|
if let Some(fragment) = node.fragments_for_pseudo(*pseudo).first() {
|
||||||
if display.inside() == DisplayInside::Grid {
|
return resolve_for_fragment(fragment, None);
|
||||||
if let Some(SpecificLayoutInfo::Grid(info)) = specific_layout_info {
|
|
||||||
if let Some(value) = resolve_grid_template(&info, style, longhand_id) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// https://drafts.csswg.org/cssom/#resolved-value-special-case-property-like-height
|
|
||||||
// > If the property applies to the element or pseudo-element and the resolved value of the
|
|
||||||
// > display property is not none or contents, then the resolved value is the used value.
|
|
||||||
// > Otherwise the resolved value is the computed value.
|
|
||||||
//
|
|
||||||
// However, all browsers ignore that for margin and padding properties, and resolve to a length
|
|
||||||
// even if the property doesn't apply: https://github.com/w3c/csswg-drafts/issues/10391
|
|
||||||
match longhand_id {
|
|
||||||
LonghandId::Width if resolved_size_should_be_used_value(fragment) => {
|
|
||||||
content_rect.size.width
|
|
||||||
},
|
|
||||||
LonghandId::Height if resolved_size_should_be_used_value(fragment) => {
|
|
||||||
content_rect.size.height
|
|
||||||
},
|
|
||||||
LonghandId::MarginBottom => margins.bottom,
|
|
||||||
LonghandId::MarginTop => margins.top,
|
|
||||||
LonghandId::MarginLeft => margins.left,
|
|
||||||
LonghandId::MarginRight => margins.right,
|
|
||||||
LonghandId::PaddingBottom => padding.bottom,
|
|
||||||
LonghandId::PaddingTop => padding.top,
|
|
||||||
LonghandId::PaddingLeft => padding.left,
|
|
||||||
LonghandId::PaddingRight => padding.right,
|
|
||||||
_ => return computed_style(Some(fragment)),
|
|
||||||
}
|
|
||||||
.to_css_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
fragment_tree
|
fragment_tree
|
||||||
.and_then(|fragment_tree| {
|
.and_then(|fragment_tree| {
|
||||||
fragment_tree.find(|fragment, _, containing_block| {
|
fragment_tree.find(|fragment, _, containing_block| {
|
||||||
if Some(tag_to_find) == fragment.tag() {
|
if Some(tag_to_find) == fragment.tag() {
|
||||||
Some(resolve_for_fragment(fragment, containing_block))
|
Some(resolve_for_fragment(fragment, Some(containing_block)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -728,8 +728,7 @@ where
|
||||||
|
|
||||||
let style = anonymous_info.style.clone();
|
let style = anonymous_info.style.clone();
|
||||||
self.push_table_row(ArcRefCell::new(TableTrack {
|
self.push_table_row(ArcRefCell::new(TableTrack {
|
||||||
base_fragment_info: (&anonymous_info).into(),
|
base: LayoutBoxBase::new((&anonymous_info).into(), style),
|
||||||
style,
|
|
||||||
group_index: self.current_row_group_index,
|
group_index: self.current_row_group_index,
|
||||||
is_anonymous: true,
|
is_anonymous: true,
|
||||||
}));
|
}));
|
||||||
|
@ -773,8 +772,7 @@ where
|
||||||
|
|
||||||
let next_row_index = self.builder.table.rows.len();
|
let next_row_index = self.builder.table.rows.len();
|
||||||
let row_group = ArcRefCell::new(TableTrackGroup {
|
let row_group = ArcRefCell::new(TableTrackGroup {
|
||||||
base_fragment_info: info.into(),
|
base: LayoutBoxBase::new(info.into(), info.style.clone()),
|
||||||
style: info.style.clone(),
|
|
||||||
group_type: internal.into(),
|
group_type: internal.into(),
|
||||||
track_range: next_row_index..next_row_index,
|
track_range: next_row_index..next_row_index,
|
||||||
});
|
});
|
||||||
|
@ -816,8 +814,7 @@ where
|
||||||
row_builder.finish();
|
row_builder.finish();
|
||||||
|
|
||||||
let row = ArcRefCell::new(TableTrack {
|
let row = ArcRefCell::new(TableTrack {
|
||||||
base_fragment_info: info.into(),
|
base: LayoutBoxBase::new(info.into(), info.style.clone()),
|
||||||
style: info.style.clone(),
|
|
||||||
group_index: self.current_row_group_index,
|
group_index: self.current_row_group_index,
|
||||||
is_anonymous: false,
|
is_anonymous: false,
|
||||||
});
|
});
|
||||||
|
@ -862,8 +859,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let column_group = ArcRefCell::new(TableTrackGroup {
|
let column_group = ArcRefCell::new(TableTrackGroup {
|
||||||
base_fragment_info: info.into(),
|
base: LayoutBoxBase::new(info.into(), info.style.clone()),
|
||||||
style: info.style.clone(),
|
|
||||||
group_type: internal.into(),
|
group_type: internal.into(),
|
||||||
track_range: first_column..self.builder.table.columns.len(),
|
track_range: first_column..self.builder.table.columns.len(),
|
||||||
});
|
});
|
||||||
|
@ -1155,8 +1151,7 @@ fn add_column<'dom, Node: NodeExt<'dom>>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let column = ArcRefCell::new(TableTrack {
|
let column = ArcRefCell::new(TableTrack {
|
||||||
base_fragment_info: column_info.into(),
|
base: LayoutBoxBase::new(column_info.into(), column_info.style.clone()),
|
||||||
style: column_info.style.clone(),
|
|
||||||
group_index,
|
group_index,
|
||||||
is_anonymous,
|
is_anonymous,
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ use super::{
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::formatting_contexts::Baselines;
|
use crate::formatting_contexts::Baselines;
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
|
BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
|
||||||
PositioningFragment, SpecificLayoutInfo,
|
PositioningFragment, SpecificLayoutInfo,
|
||||||
};
|
};
|
||||||
use crate::geom::{
|
use crate::geom::{
|
||||||
|
@ -396,13 +396,13 @@ impl<'a> TableLayout<'a> {
|
||||||
for column_index in 0..self.table.size.width {
|
for column_index in 0..self.table.size.width {
|
||||||
if let Some(column) = self.table.columns.get(column_index) {
|
if let Some(column) = self.table.columns.get(column_index) {
|
||||||
let column = column.borrow();
|
let column = column.borrow();
|
||||||
if is_length(&column.style.box_size(writing_mode).inline) {
|
if is_length(&column.base.style.box_size(writing_mode).inline) {
|
||||||
self.columns[column_index].constrained = true;
|
self.columns[column_index].constrained = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(column_group_index) = column.group_index {
|
if let Some(column_group_index) = column.group_index {
|
||||||
let column_group = self.table.column_groups[column_group_index].borrow();
|
let column_group = self.table.column_groups[column_group_index].borrow();
|
||||||
if is_length(&column_group.style.box_size(writing_mode).inline) {
|
if is_length(&column_group.base.style.box_size(writing_mode).inline) {
|
||||||
self.columns[column_index].constrained = true;
|
self.columns[column_index].constrained = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -413,13 +413,13 @@ impl<'a> TableLayout<'a> {
|
||||||
for row_index in 0..self.table.size.height {
|
for row_index in 0..self.table.size.height {
|
||||||
if let Some(row) = self.table.rows.get(row_index) {
|
if let Some(row) = self.table.rows.get(row_index) {
|
||||||
let row = row.borrow();
|
let row = row.borrow();
|
||||||
if is_length(&row.style.box_size(writing_mode).block) {
|
if is_length(&row.base.style.box_size(writing_mode).block) {
|
||||||
self.rows[row_index].constrained = true;
|
self.rows[row_index].constrained = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(row_group_index) = row.group_index {
|
if let Some(row_group_index) = row.group_index {
|
||||||
let row_group = self.table.row_groups[row_group_index].borrow();
|
let row_group = self.table.row_groups[row_group_index].borrow();
|
||||||
if is_length(&row_group.style.box_size(writing_mode).block) {
|
if is_length(&row_group.base.style.box_size(writing_mode).block) {
|
||||||
self.rows[row_index].constrained = true;
|
self.rows[row_index].constrained = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1086,13 +1086,15 @@ impl<'a> TableLayout<'a> {
|
||||||
row.group_index.is_some_and(|group_index| {
|
row.group_index.is_some_and(|group_index| {
|
||||||
self.table.row_groups[group_index]
|
self.table.row_groups[group_index]
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.base
|
||||||
.style
|
.style
|
||||||
.establishes_containing_block_for_absolute_descendants(
|
.establishes_containing_block_for_absolute_descendants(
|
||||||
FragmentFlags::empty(),
|
FragmentFlags::empty(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
row_group_collects_for_nearest_positioned_ancestor ||
|
row_group_collects_for_nearest_positioned_ancestor ||
|
||||||
row.style
|
row.base
|
||||||
|
.style
|
||||||
.establishes_containing_block_for_absolute_descendants(
|
.establishes_containing_block_for_absolute_descendants(
|
||||||
FragmentFlags::empty(),
|
FragmentFlags::empty(),
|
||||||
)
|
)
|
||||||
|
@ -1650,6 +1652,8 @@ impl<'a> TableLayout<'a> {
|
||||||
&caption_fragment,
|
&caption_fragment,
|
||||||
original_positioning_context_length,
|
original_positioning_context_length,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
caption.context.base.set_fragment(caption_fragment.clone());
|
||||||
Some(caption_fragment)
|
Some(caption_fragment)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1745,6 +1749,8 @@ impl<'a> TableLayout<'a> {
|
||||||
&caption_fragment,
|
&caption_fragment,
|
||||||
original_positioning_context_length,
|
original_positioning_context_length,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
caption.context.base.set_fragment(caption_fragment.clone());
|
||||||
Some(caption_fragment)
|
Some(caption_fragment)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1845,18 +1851,18 @@ impl<'a> TableLayout<'a> {
|
||||||
if table_row.group_index != old_row_group_index {
|
if table_row.group_index != old_row_group_index {
|
||||||
// First create the Fragment for any existing RowGroupFragmentLayout.
|
// First create the Fragment for any existing RowGroupFragmentLayout.
|
||||||
if let Some(old_row_group_layout) = row_group_fragment_layout.take() {
|
if let Some(old_row_group_layout) = row_group_fragment_layout.take() {
|
||||||
table_fragments.push(Fragment::Box(old_row_group_layout.finish(
|
table_fragments.push(old_row_group_layout.finish(
|
||||||
layout_context,
|
layout_context,
|
||||||
positioning_context,
|
positioning_context,
|
||||||
containing_block_for_logical_conversion,
|
containing_block_for_logical_conversion,
|
||||||
containing_block_for_children,
|
containing_block_for_children,
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then, create a new RowGroupFragmentLayout for the current and potentially subsequent rows.
|
// Then, create a new RowGroupFragmentLayout for the current and potentially subsequent rows.
|
||||||
if let Some(new_group_index) = table_row.group_index {
|
if let Some(new_group_index) = table_row.group_index {
|
||||||
row_group_fragment_layout = Some(RowGroupFragmentLayout::new(
|
row_group_fragment_layout = Some(RowGroupFragmentLayout::new(
|
||||||
&self.table.row_groups[new_group_index].borrow(),
|
self.table.row_groups[new_group_index].clone(),
|
||||||
new_group_index,
|
new_group_index,
|
||||||
&table_and_track_dimensions,
|
&table_and_track_dimensions,
|
||||||
));
|
));
|
||||||
|
@ -1881,13 +1887,13 @@ impl<'a> TableLayout<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let row_fragment = Fragment::Box(row_fragment_layout.finish(
|
let row_fragment = row_fragment_layout.finish(
|
||||||
layout_context,
|
layout_context,
|
||||||
positioning_context,
|
positioning_context,
|
||||||
containing_block_for_logical_conversion,
|
containing_block_for_logical_conversion,
|
||||||
containing_block_for_children,
|
containing_block_for_children,
|
||||||
&mut row_group_fragment_layout,
|
&mut row_group_fragment_layout,
|
||||||
));
|
);
|
||||||
|
|
||||||
match row_group_fragment_layout.as_mut() {
|
match row_group_fragment_layout.as_mut() {
|
||||||
Some(layout) => layout.fragments.push(row_fragment),
|
Some(layout) => layout.fragments.push(row_fragment),
|
||||||
|
@ -1896,12 +1902,12 @@ impl<'a> TableLayout<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(row_group_layout) = row_group_fragment_layout.take() {
|
if let Some(row_group_layout) = row_group_fragment_layout.take() {
|
||||||
table_fragments.push(Fragment::Box(row_group_layout.finish(
|
table_fragments.push(row_group_layout.finish(
|
||||||
layout_context,
|
layout_context,
|
||||||
positioning_context,
|
positioning_context,
|
||||||
containing_block_for_logical_conversion,
|
containing_block_for_logical_conversion,
|
||||||
containing_block_for_children,
|
containing_block_for_children,
|
||||||
)));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let content_rect = LogicalRect {
|
let content_rect = LogicalRect {
|
||||||
|
@ -1973,14 +1979,14 @@ impl<'a> TableLayout<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let row = row.borrow();
|
let row = row.borrow();
|
||||||
if row.style.get_inherited_box().visibility == Visibility::Collapse {
|
if row.base.style.get_inherited_box().visibility == Visibility::Collapse {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let row_group = match row.group_index {
|
let row_group = match row.group_index {
|
||||||
Some(group_index) => self.table.row_groups[group_index].borrow(),
|
Some(group_index) => self.table.row_groups[group_index].borrow(),
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
row_group.style.get_inherited_box().visibility == Visibility::Collapse
|
row_group.base.style.get_inherited_box().visibility == Visibility::Collapse
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_column_collapsed(&self, column_index: usize) -> bool {
|
fn is_column_collapsed(&self, column_index: usize) -> bool {
|
||||||
|
@ -1988,14 +1994,14 @@ impl<'a> TableLayout<'a> {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let column = column.borrow();
|
let column = column.borrow();
|
||||||
if column.style.get_inherited_box().visibility == Visibility::Collapse {
|
if column.base.style.get_inherited_box().visibility == Visibility::Collapse {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let col_group = match column.group_index {
|
let col_group = match column.group_index {
|
||||||
Some(group_index) => self.table.column_groups[group_index].borrow(),
|
Some(group_index) => self.table.column_groups[group_index].borrow(),
|
||||||
None => return false,
|
None => return false,
|
||||||
};
|
};
|
||||||
col_group.style.get_inherited_box().visibility == Visibility::Collapse
|
col_group.base.style.get_inherited_box().visibility == Visibility::Collapse
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -2088,7 +2094,7 @@ impl<'a> TableLayout<'a> {
|
||||||
let column_group = column_group.borrow();
|
let column_group = column_group.borrow();
|
||||||
let rect = make_relative_to_row_start(dimensions.get_column_group_rect(&column_group));
|
let rect = make_relative_to_row_start(dimensions.get_column_group_rect(&column_group));
|
||||||
fragment.add_extra_background(ExtraBackground {
|
fragment.add_extra_background(ExtraBackground {
|
||||||
style: column_group.style.clone(),
|
style: column_group.base.style.clone(),
|
||||||
rect,
|
rect,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2097,7 +2103,7 @@ impl<'a> TableLayout<'a> {
|
||||||
if !column.is_anonymous {
|
if !column.is_anonymous {
|
||||||
let rect = make_relative_to_row_start(dimensions.get_column_rect(column_index));
|
let rect = make_relative_to_row_start(dimensions.get_column_rect(column_index));
|
||||||
fragment.add_extra_background(ExtraBackground {
|
fragment.add_extra_background(ExtraBackground {
|
||||||
style: column.style.clone(),
|
style: column.base.style.clone(),
|
||||||
rect,
|
rect,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2110,7 +2116,7 @@ impl<'a> TableLayout<'a> {
|
||||||
let rect =
|
let rect =
|
||||||
make_relative_to_row_start(dimensions.get_row_group_rect(&row_group.borrow()));
|
make_relative_to_row_start(dimensions.get_row_group_rect(&row_group.borrow()));
|
||||||
fragment.add_extra_background(ExtraBackground {
|
fragment.add_extra_background(ExtraBackground {
|
||||||
style: row_group.borrow().style.clone(),
|
style: row_group.borrow().base.style.clone(),
|
||||||
rect,
|
rect,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2118,13 +2124,14 @@ impl<'a> TableLayout<'a> {
|
||||||
let row = row.borrow();
|
let row = row.borrow();
|
||||||
let rect = make_relative_to_row_start(row_fragment_layout.rect);
|
let rect = make_relative_to_row_start(row_fragment_layout.rect);
|
||||||
fragment.add_extra_background(ExtraBackground {
|
fragment.add_extra_background(ExtraBackground {
|
||||||
style: row.style.clone(),
|
style: row.base.style.clone(),
|
||||||
rect,
|
rect,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
row_fragment_layout
|
|
||||||
.fragments
|
let fragment = Fragment::Box(ArcRefCell::new(fragment));
|
||||||
.push(Fragment::Box(ArcRefCell::new(fragment)));
|
cell.base.set_fragment(fragment.clone());
|
||||||
|
row_fragment_layout.fragments.push(fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_fragments_for_columns_and_column_groups(
|
fn make_fragments_for_columns_and_column_groups(
|
||||||
|
@ -2136,11 +2143,11 @@ impl<'a> TableLayout<'a> {
|
||||||
let column_group = column_group.borrow();
|
let column_group = column_group.borrow();
|
||||||
if !column_group.is_empty() {
|
if !column_group.is_empty() {
|
||||||
fragments.push(Fragment::Positioning(PositioningFragment::new_empty(
|
fragments.push(Fragment::Positioning(PositioningFragment::new_empty(
|
||||||
column_group.base_fragment_info,
|
column_group.base.base_fragment_info,
|
||||||
dimensions
|
dimensions
|
||||||
.get_column_group_rect(&column_group)
|
.get_column_group_rect(&column_group)
|
||||||
.as_physical(None),
|
.as_physical(None),
|
||||||
column_group.style.clone(),
|
column_group.base.style.clone(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2148,9 +2155,9 @@ impl<'a> TableLayout<'a> {
|
||||||
for (column_index, column) in self.table.columns.iter().enumerate() {
|
for (column_index, column) in self.table.columns.iter().enumerate() {
|
||||||
let column = column.borrow();
|
let column = column.borrow();
|
||||||
fragments.push(Fragment::Positioning(PositioningFragment::new_empty(
|
fragments.push(Fragment::Positioning(PositioningFragment::new_empty(
|
||||||
column.base_fragment_info,
|
column.base.base_fragment_info,
|
||||||
dimensions.get_column_rect(column_index).as_physical(None),
|
dimensions.get_column_rect(column_index).as_physical(None),
|
||||||
column.style.clone(),
|
column.base.style.clone(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2314,7 +2321,7 @@ impl<'a> RowFragmentLayout<'a> {
|
||||||
Self {
|
Self {
|
||||||
row: table_row,
|
row: table_row,
|
||||||
rect,
|
rect,
|
||||||
positioning_context: PositioningContext::new_for_style(&table_row.style),
|
positioning_context: PositioningContext::new_for_style(&table_row.base.style),
|
||||||
containing_block,
|
containing_block,
|
||||||
fragments: Vec::new(),
|
fragments: Vec::new(),
|
||||||
}
|
}
|
||||||
|
@ -2326,10 +2333,10 @@ impl<'a> RowFragmentLayout<'a> {
|
||||||
containing_block_for_logical_conversion: &ContainingBlock,
|
containing_block_for_logical_conversion: &ContainingBlock,
|
||||||
containing_block_for_children: &ContainingBlock,
|
containing_block_for_children: &ContainingBlock,
|
||||||
row_group_fragment_layout: &mut Option<RowGroupFragmentLayout>,
|
row_group_fragment_layout: &mut Option<RowGroupFragmentLayout>,
|
||||||
) -> ArcRefCell<BoxFragment> {
|
) -> Fragment {
|
||||||
if self.positioning_context.is_some() {
|
if self.positioning_context.is_some() {
|
||||||
self.rect.start_corner +=
|
self.rect.start_corner +=
|
||||||
relative_adjustement(&self.row.style, containing_block_for_children);
|
relative_adjustement(&self.row.base.style, containing_block_for_children);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (inline_size, block_size) = if let Some(row_group_layout) = row_group_fragment_layout {
|
let (inline_size, block_size) = if let Some(row_group_layout) = row_group_fragment_layout {
|
||||||
|
@ -2354,8 +2361,8 @@ impl<'a> RowFragmentLayout<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut row_fragment = BoxFragment::new(
|
let mut row_fragment = BoxFragment::new(
|
||||||
self.row.base_fragment_info,
|
self.row.base.base_fragment_info,
|
||||||
self.row.style.clone(),
|
self.row.base.style.clone(),
|
||||||
self.fragments,
|
self.fragments,
|
||||||
self.rect.as_physical(Some(&row_group_containing_block)),
|
self.rect.as_physical(Some(&row_group_containing_block)),
|
||||||
PhysicalSides::zero(), /* padding */
|
PhysicalSides::zero(), /* padding */
|
||||||
|
@ -2375,13 +2382,14 @@ impl<'a> RowFragmentLayout<'a> {
|
||||||
positioning_context.append(row_positioning_context);
|
positioning_context.append(row_positioning_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArcRefCell::new(row_fragment)
|
let fragment = Fragment::Box(ArcRefCell::new(row_fragment));
|
||||||
|
self.row.base.set_fragment(fragment.clone());
|
||||||
|
fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RowGroupFragmentLayout {
|
struct RowGroupFragmentLayout {
|
||||||
base_fragment_info: BaseFragmentInfo,
|
row_group: ArcRefCell<TableTrackGroup>,
|
||||||
style: Arc<ComputedValues>,
|
|
||||||
rect: LogicalRect<Au>,
|
rect: LogicalRect<Au>,
|
||||||
positioning_context: Option<PositioningContext>,
|
positioning_context: Option<PositioningContext>,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -2390,16 +2398,21 @@ struct RowGroupFragmentLayout {
|
||||||
|
|
||||||
impl RowGroupFragmentLayout {
|
impl RowGroupFragmentLayout {
|
||||||
fn new(
|
fn new(
|
||||||
row_group: &TableTrackGroup,
|
row_group: ArcRefCell<TableTrackGroup>,
|
||||||
index: usize,
|
index: usize,
|
||||||
dimensions: &TableAndTrackDimensions,
|
dimensions: &TableAndTrackDimensions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let rect = dimensions.get_row_group_rect(row_group);
|
let (rect, positioning_context) = {
|
||||||
|
let row_group = row_group.borrow();
|
||||||
|
(
|
||||||
|
dimensions.get_row_group_rect(&row_group),
|
||||||
|
PositioningContext::new_for_style(&row_group.base.style),
|
||||||
|
)
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
base_fragment_info: row_group.base_fragment_info,
|
row_group,
|
||||||
style: row_group.style.clone(),
|
|
||||||
rect,
|
rect,
|
||||||
positioning_context: PositioningContext::new_for_style(&row_group.style),
|
positioning_context,
|
||||||
index,
|
index,
|
||||||
fragments: Vec::new(),
|
fragments: Vec::new(),
|
||||||
}
|
}
|
||||||
|
@ -2411,15 +2424,16 @@ impl RowGroupFragmentLayout {
|
||||||
table_positioning_context: &mut PositioningContext,
|
table_positioning_context: &mut PositioningContext,
|
||||||
containing_block_for_logical_conversion: &ContainingBlock,
|
containing_block_for_logical_conversion: &ContainingBlock,
|
||||||
containing_block_for_children: &ContainingBlock,
|
containing_block_for_children: &ContainingBlock,
|
||||||
) -> ArcRefCell<BoxFragment> {
|
) -> Fragment {
|
||||||
|
let row_group = self.row_group.borrow();
|
||||||
if self.positioning_context.is_some() {
|
if self.positioning_context.is_some() {
|
||||||
self.rect.start_corner +=
|
self.rect.start_corner +=
|
||||||
relative_adjustement(&self.style, containing_block_for_children);
|
relative_adjustement(&row_group.base.style, containing_block_for_children);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut row_group_fragment = BoxFragment::new(
|
let mut row_group_fragment = BoxFragment::new(
|
||||||
self.base_fragment_info,
|
row_group.base.base_fragment_info,
|
||||||
self.style,
|
row_group.base.style.clone(),
|
||||||
self.fragments,
|
self.fragments,
|
||||||
self.rect
|
self.rect
|
||||||
.as_physical(Some(containing_block_for_logical_conversion)),
|
.as_physical(Some(containing_block_for_logical_conversion)),
|
||||||
|
@ -2436,7 +2450,9 @@ impl RowGroupFragmentLayout {
|
||||||
table_positioning_context.append(row_positioning_context);
|
table_positioning_context.append(row_positioning_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArcRefCell::new(row_group_fragment)
|
let fragment = Fragment::Box(ArcRefCell::new(row_group_fragment));
|
||||||
|
row_group.base.set_fragment(fragment.clone());
|
||||||
|
fragment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2634,7 +2650,7 @@ impl Table {
|
||||||
max: max_size,
|
max: max_size,
|
||||||
percentage: percentage_size,
|
percentage: percentage_size,
|
||||||
} = CellOrColumnOuterSizes::new(
|
} = CellOrColumnOuterSizes::new(
|
||||||
&column.style,
|
&column.base.style,
|
||||||
writing_mode,
|
writing_mode,
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
is_in_fixed_mode,
|
is_in_fixed_mode,
|
||||||
|
@ -2672,8 +2688,8 @@ impl Table {
|
||||||
// (except for new layout boxes like grid and flex containers). Note that
|
// (except for new layout boxes like grid and flex containers). Note that
|
||||||
// other browsers don't seem to use the min and max sizing properties here.
|
// other browsers don't seem to use the min and max sizing properties here.
|
||||||
let row = row.borrow();
|
let row = row.borrow();
|
||||||
let size = row.style.box_size(writing_mode);
|
let size = row.base.style.box_size(writing_mode);
|
||||||
let max_size = row.style.max_box_size(writing_mode);
|
let max_size = row.base.style.max_box_size(writing_mode);
|
||||||
let percentage_contribution = get_size_percentage_contribution(&size, &max_size);
|
let percentage_contribution = get_size_percentage_contribution(&size, &max_size);
|
||||||
|
|
||||||
CellOrTrackMeasure {
|
CellOrTrackMeasure {
|
||||||
|
@ -2769,14 +2785,14 @@ impl Table {
|
||||||
impl TableTrack {
|
impl TableTrack {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
||||||
LayoutStyle::Default(&self.style)
|
LayoutStyle::Default(&self.base.style)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableTrackGroup {
|
impl TableTrackGroup {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
||||||
LayoutStyle::Default(&self.style)
|
LayoutStyle::Default(&self.base.style)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ use super::flow::BlockFormattingContext;
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
use crate::flow::BlockContainer;
|
use crate::flow::BlockContainer;
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::BaseFragmentInfo;
|
use crate::fragment_tree::{BaseFragmentInfo, Fragment};
|
||||||
use crate::geom::PhysicalVec;
|
use crate::geom::PhysicalVec;
|
||||||
use crate::layout_box_base::LayoutBoxBase;
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::style_ext::BorderStyleColor;
|
use crate::style_ext::BorderStyleColor;
|
||||||
|
@ -272,13 +272,10 @@ impl TableSlot {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A row or column of a table.
|
/// A row or column of a table.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TableTrack {
|
pub struct TableTrack {
|
||||||
/// The [`BaseFragmentInfo`] of this cell.
|
/// The [`LayoutBoxBase`] of this [`TableTrack`].
|
||||||
base_fragment_info: BaseFragmentInfo,
|
base: LayoutBoxBase,
|
||||||
|
|
||||||
/// The style of this table column.
|
|
||||||
style: Arc<ComputedValues>,
|
|
||||||
|
|
||||||
/// The index of the table row or column group parent in the table's list of row or column
|
/// The index of the table row or column group parent in the table's list of row or column
|
||||||
/// groups.
|
/// groups.
|
||||||
|
@ -299,11 +296,8 @@ pub enum TableTrackGroupType {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TableTrackGroup {
|
pub struct TableTrackGroup {
|
||||||
/// The [`BaseFragmentInfo`] of this [`TableTrackGroup`].
|
/// The [`LayoutBoxBase`] of this [`TableTrackGroup`].
|
||||||
base_fragment_info: BaseFragmentInfo,
|
base: LayoutBoxBase,
|
||||||
|
|
||||||
/// The style of this [`TableTrackGroup`].
|
|
||||||
style: Arc<ComputedValues>,
|
|
||||||
|
|
||||||
/// The type of this [`TableTrackGroup`].
|
/// The type of this [`TableTrackGroup`].
|
||||||
group_type: TableTrackGroupType,
|
group_type: TableTrackGroupType,
|
||||||
|
@ -366,8 +360,19 @@ impl TableLevelBox {
|
||||||
TableLevelBox::Cell(cell) => {
|
TableLevelBox::Cell(cell) => {
|
||||||
cell.borrow().base.invalidate_cached_fragment();
|
cell.borrow().base.invalidate_cached_fragment();
|
||||||
},
|
},
|
||||||
TableLevelBox::TrackGroup(..) => {},
|
TableLevelBox::TrackGroup(track_group) => {
|
||||||
TableLevelBox::Track(..) => {},
|
track_group.borrow().base.invalidate_cached_fragment()
|
||||||
|
},
|
||||||
|
TableLevelBox::Track(track) => track.borrow().base.invalidate_cached_fragment(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
match self {
|
||||||
|
TableLevelBox::Caption(caption) => caption.borrow().context.base.fragments(),
|
||||||
|
TableLevelBox::Cell(cell) => cell.borrow().base.fragments(),
|
||||||
|
TableLevelBox::TrackGroup(track_group) => track_group.borrow().base.fragments(),
|
||||||
|
TableLevelBox::Track(track) => track.borrow().base.fragments(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,7 +550,7 @@ impl TaffyContainer {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
match &mut child.taffy_level_box {
|
let fragment = match &mut child.taffy_level_box {
|
||||||
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
||||||
let mut fragment_info = independent_box.base_fragment_info();
|
let mut fragment_info = independent_box.base_fragment_info();
|
||||||
fragment_info
|
fragment_info
|
||||||
|
@ -594,7 +594,6 @@ impl TaffyContainer {
|
||||||
container_ctx
|
container_ctx
|
||||||
.positioning_context
|
.positioning_context
|
||||||
.append(child_positioning_context);
|
.append(child_positioning_context);
|
||||||
|
|
||||||
fragment
|
fragment
|
||||||
},
|
},
|
||||||
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box) => {
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box) => {
|
||||||
|
@ -628,7 +627,16 @@ impl TaffyContainer {
|
||||||
container_ctx.positioning_context.push(hoisted_box);
|
container_ctx.positioning_context.push(hoisted_box);
|
||||||
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if let TaffyItemBoxInner::InFlowBox(independent_formatting_context) =
|
||||||
|
&child.taffy_level_box
|
||||||
|
{
|
||||||
|
independent_formatting_context
|
||||||
|
.base
|
||||||
|
.set_fragment(fragment.clone());
|
||||||
}
|
}
|
||||||
|
fragment
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,17 @@ impl TaffyItemBox {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
||||||
|
match self.taffy_level_box {
|
||||||
|
TaffyItemBoxInner::InFlowBox(ref independent_formatting_context) => {
|
||||||
|
independent_formatting_context.base.fragments()
|
||||||
|
},
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(ref positioned_box) => {
|
||||||
|
positioned_box.borrow().context.base.fragments()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Details from Taffy grid layout that will be stored
|
/// Details from Taffy grid layout that will be stored
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue