mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Layout: Continue support incremental box tree reconstruction for flex&taffy level box (#37854)
Layout: Continue support incremental box tree reconstruction for flex&taffy level box This change reuse the flex/taffy level box from old box slot if the box slot is valid and there is no LayoutDamage to the element. Testing: This should not change observable behavior and is thus covered by existing WPT tests. Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This commit is contained in:
parent
934b3341d7
commit
068406ee6e
3 changed files with 59 additions and 32 deletions
|
@ -12,7 +12,7 @@ use style::selector_parser::PseudoElement;
|
||||||
|
|
||||||
use crate::PropagatedBoxTreeData;
|
use crate::PropagatedBoxTreeData;
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom::BoxSlot;
|
use crate::dom::{BoxSlot, LayoutBox};
|
||||||
use crate::dom_traversal::{Contents, NodeAndStyleInfo, TraversalHandler};
|
use crate::dom_traversal::{Contents, NodeAndStyleInfo, TraversalHandler};
|
||||||
use crate::flow::inline::construct::InlineFormattingContextBuilder;
|
use crate::flow::inline::construct::InlineFormattingContextBuilder;
|
||||||
use crate::flow::{BlockContainer, BlockFormattingContext};
|
use crate::flow::{BlockContainer, BlockFormattingContext};
|
||||||
|
@ -78,10 +78,9 @@ impl<'dom> ModernContainerJob<'dom> {
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(ModernItem {
|
Some(ModernItem {
|
||||||
kind: ModernItemKind::InFlow,
|
kind: ModernItemKind::InFlow(formatting_context),
|
||||||
order: 0,
|
order: 0,
|
||||||
box_slot: None,
|
box_slot: None,
|
||||||
formatting_context,
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
ModernContainerJob::ElementOrPseudoElement {
|
ModernContainerJob::ElementOrPseudoElement {
|
||||||
|
@ -91,6 +90,25 @@ impl<'dom> ModernContainerJob<'dom> {
|
||||||
box_slot,
|
box_slot,
|
||||||
} => {
|
} => {
|
||||||
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
||||||
|
let order = if is_abspos {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
info.style.clone_order()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(layout_box) = box_slot
|
||||||
|
.take_layout_box_if_undamaged(info.damage)
|
||||||
|
.and_then(|layout_box| match &layout_box {
|
||||||
|
LayoutBox::FlexLevel(_) | LayoutBox::TaffyItemBox(_) => Some(layout_box),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return Some(ModernItem {
|
||||||
|
kind: ModernItemKind::ReusedBox(layout_box),
|
||||||
|
order,
|
||||||
|
box_slot: Some(box_slot),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
||||||
// absolutes don't affect the size of ancestors so it is fine to allow descendent
|
// absolutes don't affect the size of ancestors so it is fine to allow descendent
|
||||||
|
@ -108,21 +126,16 @@ impl<'dom> ModernContainerJob<'dom> {
|
||||||
propagated_data,
|
propagated_data,
|
||||||
);
|
);
|
||||||
|
|
||||||
if is_abspos {
|
let kind = if is_abspos {
|
||||||
Some(ModernItem {
|
ModernItemKind::OutOfFlow(formatting_context)
|
||||||
kind: ModernItemKind::OutOfFlow,
|
|
||||||
order: 0,
|
|
||||||
box_slot: Some(box_slot),
|
|
||||||
formatting_context,
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
Some(ModernItem {
|
ModernItemKind::InFlow(formatting_context)
|
||||||
kind: ModernItemKind::InFlow,
|
};
|
||||||
order: info.style.clone_order(),
|
Some(ModernItem {
|
||||||
box_slot: Some(box_slot),
|
kind,
|
||||||
formatting_context,
|
order,
|
||||||
})
|
box_slot: Some(box_slot),
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,15 +159,15 @@ impl ModernContainerTextRun<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum ModernItemKind {
|
pub(crate) enum ModernItemKind {
|
||||||
InFlow,
|
InFlow(IndependentFormattingContext),
|
||||||
OutOfFlow,
|
OutOfFlow(IndependentFormattingContext),
|
||||||
|
ReusedBox(LayoutBox),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct ModernItem<'dom> {
|
pub(crate) struct ModernItem<'dom> {
|
||||||
pub kind: ModernItemKind,
|
pub kind: ModernItemKind,
|
||||||
pub order: i32,
|
pub order: i32,
|
||||||
pub box_slot: Option<BoxSlot<'dom>>,
|
pub box_slot: Option<BoxSlot<'dom>>,
|
||||||
pub formatting_context: IndependentFormattingContext,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom> TraversalHandler<'dom> for ModernContainerBuilder<'_, 'dom> {
|
impl<'dom> TraversalHandler<'dom> for ModernContainerBuilder<'_, 'dom> {
|
||||||
|
|
|
@ -113,14 +113,21 @@ impl FlexContainer {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
let box_ = match item.kind {
|
let box_ = match item.kind {
|
||||||
ModernItemKind::InFlow => ArcRefCell::new(FlexLevelBox::FlexItem(
|
ModernItemKind::InFlow(independent_formatting_context) => ArcRefCell::new(
|
||||||
FlexItemBox::new(item.formatting_context),
|
FlexLevelBox::FlexItem(FlexItemBox::new(independent_formatting_context)),
|
||||||
)),
|
),
|
||||||
ModernItemKind::OutOfFlow => {
|
ModernItemKind::OutOfFlow(independent_formatting_context) => {
|
||||||
let abs_pos_box =
|
let abs_pos_box = ArcRefCell::new(AbsolutelyPositionedBox::new(
|
||||||
ArcRefCell::new(AbsolutelyPositionedBox::new(item.formatting_context));
|
independent_formatting_context,
|
||||||
|
));
|
||||||
ArcRefCell::new(FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(abs_pos_box))
|
ArcRefCell::new(FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(abs_pos_box))
|
||||||
},
|
},
|
||||||
|
ModernItemKind::ReusedBox(layout_box) => match layout_box {
|
||||||
|
LayoutBox::FlexLevel(flex_level_box) => flex_level_box,
|
||||||
|
_ => unreachable!(
|
||||||
|
"Undamaged flex level element should be associated with flex level box"
|
||||||
|
),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(box_slot) = item.box_slot {
|
if let Some(box_slot) = item.box_slot {
|
||||||
|
|
|
@ -46,16 +46,23 @@ impl TaffyContainer {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item| {
|
.map(|item| {
|
||||||
let box_ = match item.kind {
|
let box_ = match item.kind {
|
||||||
ModernItemKind::InFlow => ArcRefCell::new(TaffyItemBox::new(
|
ModernItemKind::InFlow(independent_formatting_context) => {
|
||||||
TaffyItemBoxInner::InFlowBox(item.formatting_context),
|
ArcRefCell::new(TaffyItemBox::new(TaffyItemBoxInner::InFlowBox(
|
||||||
)),
|
independent_formatting_context,
|
||||||
ModernItemKind::OutOfFlow => {
|
)))
|
||||||
let abs_pos_box =
|
},
|
||||||
ArcRefCell::new(AbsolutelyPositionedBox::new(item.formatting_context));
|
ModernItemKind::OutOfFlow(independent_formatting_context) => {
|
||||||
|
let abs_pos_box = ArcRefCell::new(AbsolutelyPositionedBox::new(
|
||||||
|
independent_formatting_context,
|
||||||
|
));
|
||||||
ArcRefCell::new(TaffyItemBox::new(
|
ArcRefCell::new(TaffyItemBox::new(
|
||||||
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box),
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
ModernItemKind::ReusedBox(layout_box) => match layout_box {
|
||||||
|
LayoutBox::TaffyItemBox(taffy_item_box) => taffy_item_box,
|
||||||
|
_ => unreachable!("Undamaged taffy level element should be associated with taffy level box"),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(box_slot) = item.box_slot {
|
if let Some(box_slot) = item.box_slot {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue