layout: Implement node geometry queries against BoxTree's Fragment (#36663)

This is a followup to #36629, continuing to implement script-based
layout queries  using the `Fragment`s attached to the `BoxTree`. In this
change, geometry queris (apart from parent offset) are calculated using
`Fragment`s hanging of the `BoxTree`.

In order to make this work, all `Fragment`s for inlines split by blocks,
need to be accessible in the `BoxTree`. This required some changes to
the way that box tree items were stored in DOM `BoxSlot`s. Now every
inline level item can have more than a single `BoxTree` item. These are
carefully collected by the `InlineFormattingContextBuilder` -- currently
a bit fragile, but with more documentation.

Testing: There are tests for these changes.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Martin Robinson 2025-04-25 15:38:05 +02:00 committed by GitHub
parent cc91395397
commit b63a1818c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 197 additions and 170 deletions

View file

@ -61,7 +61,7 @@ impl InnerDOMLayoutData {
pub(super) enum LayoutBox {
DisplayContents,
BlockLevel(ArcRefCell<BlockLevelBox>),
InlineLevel(ArcRefCell<InlineItem>),
InlineLevel(Vec<ArcRefCell<InlineItem>>),
FlexLevel(ArcRefCell<FlexLevelBox>),
TableLevelBox(TableLevelBox),
TaffyItemBox(ArcRefCell<TaffyItemBox>),
@ -74,8 +74,10 @@ impl LayoutBox {
LayoutBox::BlockLevel(block_level_box) => {
block_level_box.borrow().invalidate_cached_fragment()
},
LayoutBox::InlineLevel(inline_item) => {
inline_item.borrow().invalidate_cached_fragment()
LayoutBox::InlineLevel(inline_items) => {
for inline_item in inline_items.iter() {
inline_item.borrow().invalidate_cached_fragment()
}
},
LayoutBox::FlexLevel(flex_level_box) => {
flex_level_box.borrow().invalidate_cached_fragment()
@ -91,7 +93,10 @@ impl LayoutBox {
match self {
LayoutBox::DisplayContents => vec![],
LayoutBox::BlockLevel(block_level_box) => block_level_box.borrow().fragments(),
LayoutBox::InlineLevel(inline_item) => inline_item.borrow().fragments(),
LayoutBox::InlineLevel(inline_items) => inline_items
.iter()
.flat_map(|inline_item| inline_item.borrow().fragments())
.collect(),
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(),