mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
layout: Make Fragment
hold ArcRefCell
inside (#34923)
Push the interior mutability into enum variants of `Fragment`, so that they can be cloned. This saves memory in the `Fragment` tree as the `Fragment` enum is now a relatively wee 16 bytes and the interior parts can be a variety of sizes. Before, every `Fragment` was the size of the biggest kind (`BoxFragment` - 248 bytes). This a step on the way toward incremental layout. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
c936dd6c4e
commit
de780dcde4
18 changed files with 257 additions and 233 deletions
|
@ -246,6 +246,7 @@ impl Fragment {
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
|
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
|
||||||
|
let box_fragment = &*box_fragment.borrow();
|
||||||
match box_fragment.style.get_inherited_box().visibility {
|
match box_fragment.style.get_inherited_box().visibility {
|
||||||
Visibility::Visible => BuilderForBoxFragment::new(
|
Visibility::Visible => BuilderForBoxFragment::new(
|
||||||
box_fragment,
|
box_fragment,
|
||||||
|
@ -259,6 +260,7 @@ impl Fragment {
|
||||||
},
|
},
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) => {},
|
Fragment::AbsoluteOrFixedPositioned(_) => {},
|
||||||
Fragment::Positioning(positioning_fragment) => {
|
Fragment::Positioning(positioning_fragment) => {
|
||||||
|
let positioning_fragment = positioning_fragment.borrow();
|
||||||
if let Some(style) = positioning_fragment.style.as_ref() {
|
if let Some(style) = positioning_fragment.style.as_ref() {
|
||||||
let rect = positioning_fragment
|
let rect = positioning_fragment
|
||||||
.rect
|
.rect
|
||||||
|
@ -272,65 +274,74 @@ impl Fragment {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Fragment::Image(image) => match image.style.get_inherited_box().visibility {
|
Fragment::Image(image) => {
|
||||||
Visibility::Visible => {
|
let image = image.borrow();
|
||||||
builder.is_contentful = true;
|
match image.style.get_inherited_box().visibility {
|
||||||
|
Visibility::Visible => {
|
||||||
|
builder.is_contentful = true;
|
||||||
|
|
||||||
let image_rendering = image
|
let image_rendering = image
|
||||||
.style
|
.style
|
||||||
.get_inherited_box()
|
.get_inherited_box()
|
||||||
.image_rendering
|
.image_rendering
|
||||||
.to_webrender();
|
.to_webrender();
|
||||||
let rect = image
|
let rect = image
|
||||||
.rect
|
.rect
|
||||||
.translate(containing_block.origin.to_vector())
|
.translate(containing_block.origin.to_vector())
|
||||||
.to_webrender();
|
.to_webrender();
|
||||||
let clip = image
|
let clip = image
|
||||||
.clip
|
.clip
|
||||||
.translate(containing_block.origin.to_vector())
|
.translate(containing_block.origin.to_vector())
|
||||||
.to_webrender();
|
.to_webrender();
|
||||||
let common = builder.common_properties(clip, &image.style);
|
let common = builder.common_properties(clip, &image.style);
|
||||||
|
|
||||||
if let Some(image_key) = image.image_key {
|
if let Some(image_key) = image.image_key {
|
||||||
builder.wr().push_image(
|
builder.wr().push_image(
|
||||||
&common,
|
&common,
|
||||||
rect,
|
rect,
|
||||||
image_rendering,
|
image_rendering,
|
||||||
wr::AlphaType::PremultipliedAlpha,
|
wr::AlphaType::PremultipliedAlpha,
|
||||||
image_key,
|
image_key,
|
||||||
wr::ColorF::WHITE,
|
wr::ColorF::WHITE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Visibility::Hidden => (),
|
||||||
|
Visibility::Collapse => (),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Fragment::IFrame(iframe) => {
|
||||||
|
let iframe = iframe.borrow();
|
||||||
|
match iframe.style.get_inherited_box().visibility {
|
||||||
|
Visibility::Visible => {
|
||||||
|
builder.is_contentful = true;
|
||||||
|
let rect = iframe.rect.translate(containing_block.origin.to_vector());
|
||||||
|
|
||||||
|
let common = builder.common_properties(rect.to_webrender(), &iframe.style);
|
||||||
|
builder.wr().push_iframe(
|
||||||
|
rect.to_webrender(),
|
||||||
|
common.clip_rect,
|
||||||
|
&wr::SpaceAndClipInfo {
|
||||||
|
spatial_id: common.spatial_id,
|
||||||
|
clip_chain_id: common.clip_chain_id,
|
||||||
|
},
|
||||||
|
iframe.pipeline_id.into(),
|
||||||
|
true,
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
},
|
Visibility::Hidden => (),
|
||||||
Visibility::Hidden => (),
|
Visibility::Collapse => (),
|
||||||
Visibility::Collapse => (),
|
}
|
||||||
},
|
},
|
||||||
Fragment::IFrame(iframe) => match iframe.style.get_inherited_box().visibility {
|
Fragment::Text(text) => {
|
||||||
Visibility::Visible => {
|
let text = &*text.borrow();
|
||||||
builder.is_contentful = true;
|
match text.parent_style.get_inherited_box().visibility {
|
||||||
let rect = iframe.rect.translate(containing_block.origin.to_vector());
|
Visibility::Visible => {
|
||||||
|
self.build_display_list_for_text_fragment(text, builder, containing_block)
|
||||||
let common = builder.common_properties(rect.to_webrender(), &iframe.style);
|
},
|
||||||
builder.wr().push_iframe(
|
Visibility::Hidden => (),
|
||||||
rect.to_webrender(),
|
Visibility::Collapse => (),
|
||||||
common.clip_rect,
|
}
|
||||||
&wr::SpaceAndClipInfo {
|
|
||||||
spatial_id: common.spatial_id,
|
|
||||||
clip_chain_id: common.clip_chain_id,
|
|
||||||
},
|
|
||||||
iframe.pipeline_id.into(),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
Visibility::Hidden => (),
|
|
||||||
Visibility::Collapse => (),
|
|
||||||
},
|
|
||||||
Fragment::Text(t) => match t.parent_style.get_inherited_box().visibility {
|
|
||||||
Visibility::Visible => {
|
|
||||||
self.build_display_list_for_text_fragment(t, builder, containing_block)
|
|
||||||
},
|
|
||||||
Visibility::Hidden => (),
|
|
||||||
Visibility::Collapse => (),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ use wr::{ClipChainId, SpatialTreeItemKey, StickyOffsetBounds};
|
||||||
|
|
||||||
use super::clip_path::build_clip_path_clip_chain_if_necessary;
|
use super::clip_path::build_clip_path_clip_chain_if_necessary;
|
||||||
use super::DisplayList;
|
use super::DisplayList;
|
||||||
use crate::cell::ArcRefCell;
|
|
||||||
use crate::display_list::conversions::{FilterToWebRender, ToWebRender};
|
use crate::display_list::conversions::{FilterToWebRender, ToWebRender};
|
||||||
use crate::display_list::{BuilderForBoxFragment, DisplayListBuilder};
|
use crate::display_list::{BuilderForBoxFragment, DisplayListBuilder};
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
|
@ -142,8 +141,7 @@ impl DisplayList {
|
||||||
|
|
||||||
let mut root_stacking_context = StackingContext::create_root(&self.wr, debug);
|
let mut root_stacking_context = StackingContext::create_root(&self.wr, debug);
|
||||||
for fragment in &fragment_tree.root_fragments {
|
for fragment in &fragment_tree.root_fragments {
|
||||||
fragment.borrow_mut().build_stacking_context_tree(
|
fragment.build_stacking_context_tree(
|
||||||
fragment,
|
|
||||||
self,
|
self,
|
||||||
&containing_block_info,
|
&containing_block_info,
|
||||||
&mut root_stacking_context,
|
&mut root_stacking_context,
|
||||||
|
@ -260,7 +258,7 @@ pub(crate) enum StackingContextContent {
|
||||||
clip_chain_id: wr::ClipChainId,
|
clip_chain_id: wr::ClipChainId,
|
||||||
section: StackingContextSection,
|
section: StackingContextSection,
|
||||||
containing_block: PhysicalRect<Au>,
|
containing_block: PhysicalRect<Au>,
|
||||||
fragment: ArcRefCell<Fragment>,
|
fragment: Fragment,
|
||||||
is_hit_test_for_scrollable_overflow: bool,
|
is_hit_test_for_scrollable_overflow: bool,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -296,7 +294,7 @@ impl StackingContextContent {
|
||||||
builder.current_scroll_node_id = *scroll_node_id;
|
builder.current_scroll_node_id = *scroll_node_id;
|
||||||
builder.current_reference_frame_scroll_node_id = *reference_frame_scroll_node_id;
|
builder.current_reference_frame_scroll_node_id = *reference_frame_scroll_node_id;
|
||||||
builder.current_clip_chain_id = *clip_chain_id;
|
builder.current_clip_chain_id = *clip_chain_id;
|
||||||
fragment.borrow().build_display_list(
|
fragment.build_display_list(
|
||||||
builder,
|
builder,
|
||||||
containing_block,
|
containing_block,
|
||||||
*section,
|
*section,
|
||||||
|
@ -632,13 +630,11 @@ impl StackingContext {
|
||||||
else {
|
else {
|
||||||
debug_panic!("Expected a fragment, not a stacking container");
|
debug_panic!("Expected a fragment, not a stacking container");
|
||||||
};
|
};
|
||||||
let fragment = fragment.borrow();
|
let box_fragment = match fragment {
|
||||||
let box_fragment = match &*fragment {
|
|
||||||
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => box_fragment,
|
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => box_fragment,
|
||||||
_ => {
|
_ => debug_panic!("Expected a box-generated fragment"),
|
||||||
debug_panic!("Expected a box-generated fragment");
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
let box_fragment = &*box_fragment.borrow();
|
||||||
|
|
||||||
// The `StackingContextFragment` we found is for the root DOM element:
|
// The `StackingContextFragment` we found is for the root DOM element:
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
@ -849,16 +845,17 @@ pub(crate) enum StackingContextBuildMode {
|
||||||
|
|
||||||
impl Fragment {
|
impl Fragment {
|
||||||
pub(crate) fn build_stacking_context_tree(
|
pub(crate) fn build_stacking_context_tree(
|
||||||
&mut self,
|
&self,
|
||||||
fragment_ref: &ArcRefCell<Fragment>,
|
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
containing_block_info: &ContainingBlockInfo,
|
containing_block_info: &ContainingBlockInfo,
|
||||||
stacking_context: &mut StackingContext,
|
stacking_context: &mut StackingContext,
|
||||||
mode: StackingContextBuildMode,
|
mode: StackingContextBuildMode,
|
||||||
) {
|
) {
|
||||||
let containing_block = containing_block_info.get_containing_block_for_fragment(self);
|
let containing_block = containing_block_info.get_containing_block_for_fragment(self);
|
||||||
|
let fragment_clone = self.clone();
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
|
let fragment = fragment.borrow();
|
||||||
if mode == StackingContextBuildMode::SkipHoisted &&
|
if mode == StackingContextBuildMode::SkipHoisted &&
|
||||||
fragment.style.clone_position().is_absolutely_positioned()
|
fragment.style.clone_position().is_absolutely_positioned()
|
||||||
{
|
{
|
||||||
|
@ -876,7 +873,7 @@ impl Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment.build_stacking_context_tree(
|
fragment.build_stacking_context_tree(
|
||||||
fragment_ref,
|
fragment_clone,
|
||||||
display_list,
|
display_list,
|
||||||
containing_block,
|
containing_block,
|
||||||
containing_block_info,
|
containing_block_info,
|
||||||
|
@ -890,8 +887,7 @@ impl Fragment {
|
||||||
None => unreachable!("Found hoisted box with missing fragment."),
|
None => unreachable!("Found hoisted box with missing fragment."),
|
||||||
};
|
};
|
||||||
|
|
||||||
fragment_ref.borrow_mut().build_stacking_context_tree(
|
fragment_ref.build_stacking_context_tree(
|
||||||
fragment_ref,
|
|
||||||
display_list,
|
display_list,
|
||||||
containing_block_info,
|
containing_block_info,
|
||||||
stacking_context,
|
stacking_context,
|
||||||
|
@ -899,6 +895,7 @@ impl Fragment {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Fragment::Positioning(fragment) => {
|
Fragment::Positioning(fragment) => {
|
||||||
|
let fragment = fragment.borrow();
|
||||||
fragment.build_stacking_context_tree(
|
fragment.build_stacking_context_tree(
|
||||||
display_list,
|
display_list,
|
||||||
containing_block,
|
containing_block,
|
||||||
|
@ -917,7 +914,7 @@ impl Fragment {
|
||||||
.scroll_node_id,
|
.scroll_node_id,
|
||||||
clip_chain_id: containing_block.clip_chain_id,
|
clip_chain_id: containing_block.clip_chain_id,
|
||||||
containing_block: containing_block.rect,
|
containing_block: containing_block.rect,
|
||||||
fragment: fragment_ref.clone(),
|
fragment: fragment_clone,
|
||||||
is_hit_test_for_scrollable_overflow: false,
|
is_hit_test_for_scrollable_overflow: false,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -971,8 +968,8 @@ impl BoxFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_stacking_context_tree(
|
fn build_stacking_context_tree(
|
||||||
&mut self,
|
&self,
|
||||||
fragment: &ArcRefCell<Fragment>,
|
fragment: Fragment,
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
containing_block_info: &ContainingBlockInfo,
|
containing_block_info: &ContainingBlockInfo,
|
||||||
|
@ -988,8 +985,8 @@ impl BoxFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_stacking_context_tree_maybe_creating_reference_frame(
|
fn build_stacking_context_tree_maybe_creating_reference_frame(
|
||||||
&mut self,
|
&self,
|
||||||
fragment: &ArcRefCell<Fragment>,
|
fragment: Fragment,
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
containing_block_info: &ContainingBlockInfo,
|
containing_block_info: &ContainingBlockInfo,
|
||||||
|
@ -1052,8 +1049,8 @@ impl BoxFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_stacking_context_tree_maybe_creating_stacking_context(
|
fn build_stacking_context_tree_maybe_creating_stacking_context(
|
||||||
&mut self,
|
&self,
|
||||||
fragment: &ArcRefCell<Fragment>,
|
fragment: Fragment,
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
containing_block_info: &ContainingBlockInfo,
|
containing_block_info: &ContainingBlockInfo,
|
||||||
|
@ -1128,8 +1125,8 @@ impl BoxFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_stacking_context_tree_for_children(
|
fn build_stacking_context_tree_for_children(
|
||||||
&mut self,
|
&self,
|
||||||
fragment: &ArcRefCell<Fragment>,
|
fragment: Fragment,
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
containing_block: &ContainingBlock,
|
containing_block: &ContainingBlock,
|
||||||
containing_block_info: &ContainingBlockInfo,
|
containing_block_info: &ContainingBlockInfo,
|
||||||
|
@ -1273,8 +1270,7 @@ impl BoxFragment {
|
||||||
};
|
};
|
||||||
|
|
||||||
for child in &self.children {
|
for child in &self.children {
|
||||||
child.borrow_mut().build_stacking_context_tree(
|
child.build_stacking_context_tree(
|
||||||
child,
|
|
||||||
display_list,
|
display_list,
|
||||||
&new_containing_block_info,
|
&new_containing_block_info,
|
||||||
stacking_context,
|
stacking_context,
|
||||||
|
@ -1381,7 +1377,7 @@ impl BoxFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_sticky_frame_if_necessary(
|
fn build_sticky_frame_if_necessary(
|
||||||
&mut self,
|
&self,
|
||||||
display_list: &mut DisplayList,
|
display_list: &mut DisplayList,
|
||||||
parent_scroll_node_id: &ScrollTreeNodeId,
|
parent_scroll_node_id: &ScrollTreeNodeId,
|
||||||
containing_block_rect: &PhysicalRect<Au>,
|
containing_block_rect: &PhysicalRect<Au>,
|
||||||
|
@ -1411,7 +1407,7 @@ impl BoxFragment {
|
||||||
offsets.bottom.map(|v| v.to_used_value(scroll_frame_height)),
|
offsets.bottom.map(|v| v.to_used_value(scroll_frame_height)),
|
||||||
offsets.left.map(|v| v.to_used_value(scroll_frame_width)),
|
offsets.left.map(|v| v.to_used_value(scroll_frame_width)),
|
||||||
);
|
);
|
||||||
self.resolved_sticky_insets = Some(offsets);
|
*self.resolved_sticky_insets.borrow_mut() = Some(offsets);
|
||||||
|
|
||||||
if scroll_frame_size.is_none() {
|
if scroll_frame_size.is_none() {
|
||||||
return None;
|
return None;
|
||||||
|
@ -1610,8 +1606,7 @@ impl PositioningFragment {
|
||||||
containing_block_info.new_for_non_absolute_descendants(&new_containing_block);
|
containing_block_info.new_for_non_absolute_descendants(&new_containing_block);
|
||||||
|
|
||||||
for child in &self.children {
|
for child in &self.children {
|
||||||
child.borrow_mut().build_stacking_context_tree(
|
child.build_stacking_context_tree(
|
||||||
child,
|
|
||||||
display_list,
|
display_list,
|
||||||
&new_containing_block_info,
|
&new_containing_block_info,
|
||||||
stacking_context,
|
stacking_context,
|
||||||
|
|
|
@ -947,7 +947,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(fragment);
|
let fragment = Fragment::Box(ArcRefCell::new(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(),
|
||||||
|
|
|
@ -292,9 +292,9 @@ impl LineItemLayout<'_, '_> {
|
||||||
// We do not know the actual physical position of a logically laid out inline element, until
|
// We do not know the actual physical position of a logically laid out inline element, until
|
||||||
// we know the width of the containing inline block. This step converts the logical rectangle
|
// we know the width of the containing inline block. This step converts the logical rectangle
|
||||||
// into a physical one based on the inline formatting context width.
|
// into a physical one based on the inline formatting context width.
|
||||||
if let Some(content_rect) = fragment.content_rect_mut() {
|
fragment.mutate_content_rect(|content_rect| {
|
||||||
*content_rect = logical_rect.as_physical(Some(self.layout.containing_block))
|
*content_rect = logical_rect.as_physical(Some(self.layout.containing_block))
|
||||||
}
|
});
|
||||||
|
|
||||||
fragment
|
fragment
|
||||||
})
|
})
|
||||||
|
@ -436,7 +436,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(mut fragment, logical_rect)| {
|
.map(|(mut fragment, logical_rect)| {
|
||||||
let is_float = matches!(fragment, Fragment::Float(_));
|
let is_float = matches!(fragment, Fragment::Float(_));
|
||||||
if let Some(content_rect) = fragment.content_rect_mut() {
|
fragment.mutate_content_rect(|content_rect| {
|
||||||
if is_float {
|
if is_float {
|
||||||
content_rect.origin -=
|
content_rect.origin -=
|
||||||
pbm_sums.start_offset().to_physical_size(ifc_writing_mode);
|
pbm_sums.start_offset().to_physical_size(ifc_writing_mode);
|
||||||
|
@ -446,7 +446,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
// into a physical one now that we've computed inline size of the containing inline block above.
|
// into a physical one now that we've computed inline size of the containing inline block above.
|
||||||
*content_rect = logical_rect.as_physical(Some(&inline_box_containing_block))
|
*content_rect = logical_rect.as_physical(Some(&inline_box_containing_block))
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
fragment
|
fragment
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -495,7 +495,7 @@ 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
|
self.current_state
|
||||||
.fragments
|
.fragments
|
||||||
.push((Fragment::Box(fragment), content_rect));
|
.push((Fragment::Box(ArcRefCell::new(fragment)), content_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_inline_box_block_start(
|
fn calculate_inline_box_block_start(
|
||||||
|
@ -566,7 +566,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
|
|
||||||
self.current_state.inline_advance += inline_advance;
|
self.current_state.inline_advance += inline_advance;
|
||||||
self.current_state.fragments.push((
|
self.current_state.fragments.push((
|
||||||
Fragment::Text(TextFragment {
|
Fragment::Text(ArcRefCell::new(TextFragment {
|
||||||
base: text_item.base_fragment_info.into(),
|
base: text_item.base_fragment_info.into(),
|
||||||
parent_style: text_item.parent_style,
|
parent_style: text_item.parent_style,
|
||||||
rect: PhysicalRect::zero(),
|
rect: PhysicalRect::zero(),
|
||||||
|
@ -575,7 +575,7 @@ impl LineItemLayout<'_, '_> {
|
||||||
glyphs: text_item.text,
|
glyphs: text_item.text,
|
||||||
text_decoration_line: text_item.text_decoration_line,
|
text_decoration_line: text_item.text_decoration_line,
|
||||||
justification_adjustment: self.justification_adjustment,
|
justification_adjustment: self.justification_adjustment,
|
||||||
}),
|
})),
|
||||||
content_rect,
|
content_rect,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -627,9 +627,10 @@ impl LineItemLayout<'_, '_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.inline_advance += atomic.size.inline;
|
self.current_state.inline_advance += atomic.size.inline;
|
||||||
self.current_state
|
self.current_state.fragments.push((
|
||||||
.fragments
|
Fragment::Box(ArcRefCell::new(atomic.fragment)),
|
||||||
.push((Fragment::Box(atomic.fragment), content_rect));
|
content_rect,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) {
|
fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) {
|
||||||
|
@ -706,9 +707,10 @@ impl LineItemLayout<'_, '_> {
|
||||||
float.fragment.content_rect.origin -= distance_from_parent_to_ifc
|
float.fragment.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
|
self.current_state.fragments.push((
|
||||||
.fragments
|
Fragment::Float(ArcRefCell::new(float.fragment)),
|
||||||
.push((Fragment::Float(float.fragment), LogicalRect::zero()));
|
LogicalRect::zero(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,9 +289,9 @@ impl OutsideMarker {
|
||||||
.fold(Au::zero(), |current_max, fragment| {
|
.fold(Au::zero(), |current_max, fragment| {
|
||||||
current_max.max(
|
current_max.max(
|
||||||
match fragment {
|
match fragment {
|
||||||
Fragment::Text(text) => text.rect,
|
Fragment::Text(text) => text.borrow().rect,
|
||||||
Fragment::Image(image) => image.rect,
|
Fragment::Image(image) => image.borrow().rect,
|
||||||
Fragment::Positioning(positioning) => positioning.rect,
|
Fragment::Positioning(positioning) => positioning.borrow().rect,
|
||||||
Fragment::Box(_) |
|
Fragment::Box(_) |
|
||||||
Fragment::Float(_) |
|
Fragment::Float(_) |
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) |
|
Fragment::AbsoluteOrFixedPositioned(_) |
|
||||||
|
@ -331,7 +331,7 @@ impl OutsideMarker {
|
||||||
let mut base_fragment_info = BaseFragmentInfo::anonymous();
|
let mut base_fragment_info = BaseFragmentInfo::anonymous();
|
||||||
base_fragment_info.flags |= FragmentFlags::IS_OUTSIDE_LIST_ITEM_MARKER;
|
base_fragment_info.flags |= FragmentFlags::IS_OUTSIDE_LIST_ITEM_MARKER;
|
||||||
|
|
||||||
Fragment::Box(BoxFragment::new(
|
Fragment::Box(ArcRefCell::new(BoxFragment::new(
|
||||||
base_fragment_info,
|
base_fragment_info,
|
||||||
self.marker_style.clone(),
|
self.marker_style.clone(),
|
||||||
flow_layout.fragments,
|
flow_layout.fragments,
|
||||||
|
@ -341,7 +341,7 @@ impl OutsideMarker {
|
||||||
PhysicalSides::zero(),
|
PhysicalSides::zero(),
|
||||||
None,
|
None,
|
||||||
CollapsedBlockMargins::zero(),
|
CollapsedBlockMargins::zero(),
|
||||||
))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,8 +724,8 @@ impl BlockLevelBox {
|
||||||
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
|
collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
match self {
|
match self {
|
||||||
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => {
|
BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => Fragment::Box(
|
||||||
Fragment::Box(positioning_context.layout_maybe_position_relative_fragment(
|
ArcRefCell::new(positioning_context.layout_maybe_position_relative_fragment(
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block,
|
containing_block,
|
||||||
&base.style,
|
&base.style,
|
||||||
|
@ -740,10 +740,10 @@ impl BlockLevelBox {
|
||||||
collapsible_with_parent_start_margin,
|
collapsible_with_parent_start_margin,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
))
|
)),
|
||||||
},
|
),
|
||||||
BlockLevelBox::Independent(independent) => {
|
BlockLevelBox::Independent(independent) => Fragment::Box(ArcRefCell::new(
|
||||||
Fragment::Box(positioning_context.layout_maybe_position_relative_fragment(
|
positioning_context.layout_maybe_position_relative_fragment(
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block,
|
containing_block,
|
||||||
independent.style(),
|
independent.style(),
|
||||||
|
@ -755,8 +755,8 @@ impl BlockLevelBox {
|
||||||
sequential_layout_state,
|
sequential_layout_state,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
))
|
),
|
||||||
},
|
)),
|
||||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
|
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
|
||||||
// The static position of zero here is incorrect, however we do not know
|
// The static position of zero here is incorrect, however we do not know
|
||||||
// the correct positioning until later, in place_block_level_fragment, and
|
// the correct positioning until later, in place_block_level_fragment, and
|
||||||
|
@ -777,10 +777,8 @@ impl BlockLevelBox {
|
||||||
positioning_context.push(hoisted_box);
|
positioning_context.push(hoisted_box);
|
||||||
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)
|
||||||
},
|
},
|
||||||
BlockLevelBox::OutOfFlowFloatBox(float_box) => Fragment::Float(float_box.layout(
|
BlockLevelBox::OutOfFlowFloatBox(float_box) => Fragment::Float(ArcRefCell::new(
|
||||||
layout_context,
|
float_box.layout(layout_context, positioning_context, containing_block),
|
||||||
positioning_context,
|
|
||||||
containing_block,
|
|
||||||
)),
|
)),
|
||||||
BlockLevelBox::OutsideMarker(outside_marker) => outside_marker.layout(
|
BlockLevelBox::OutsideMarker(outside_marker) => outside_marker.layout(
|
||||||
layout_context,
|
layout_context,
|
||||||
|
@ -1912,6 +1910,7 @@ impl<'container> PlacementState<'container> {
|
||||||
Fragment::Box(box_fragment) => box_fragment,
|
Fragment::Box(box_fragment) => box_fragment,
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
let box_fragment = box_fragment.borrow();
|
||||||
|
|
||||||
// From <https://drafts.csswg.org/css-align-3/#baseline-export>:
|
// From <https://drafts.csswg.org/css-align-3/#baseline-export>:
|
||||||
// > When finding the first/last baseline set of an inline-block, any baselines
|
// > When finding the first/last baseline set of an inline-block, any baselines
|
||||||
|
@ -1955,6 +1954,7 @@ impl<'container> PlacementState<'container> {
|
||||||
// between the marker and the item. For instance the marker should be positioned at
|
// between the marker and the item. For instance the marker should be positioned at
|
||||||
// the baseline of list item content and the first line of the item content should
|
// the baseline of list item content and the first line of the item content should
|
||||||
// be at least as tall as the marker -- not the entire list item itself.
|
// be at least as tall as the marker -- not the entire list item itself.
|
||||||
|
let fragment = &mut *fragment.borrow_mut();
|
||||||
let is_outside_marker = fragment
|
let is_outside_marker = fragment
|
||||||
.base
|
.base
|
||||||
.flags
|
.flags
|
||||||
|
@ -2049,6 +2049,7 @@ impl<'container> PlacementState<'container> {
|
||||||
.expect("Found float fragment without SequentialLayoutState");
|
.expect("Found float fragment without SequentialLayoutState");
|
||||||
let block_offset_from_containing_block_top =
|
let block_offset_from_containing_block_top =
|
||||||
self.current_block_direction_position + self.current_margin.solve();
|
self.current_block_direction_position + self.current_margin.solve();
|
||||||
|
let box_fragment = &mut *box_fragment.borrow_mut();
|
||||||
sequential_layout_state.place_float_fragment(
|
sequential_layout_state.place_float_fragment(
|
||||||
box_fragment,
|
box_fragment,
|
||||||
self.containing_block,
|
self.containing_block,
|
||||||
|
|
|
@ -357,11 +357,7 @@ impl BoxTree {
|
||||||
&(&initial_containing_block).into(),
|
&(&initial_containing_block).into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut root_fragments = independent_layout
|
let mut root_fragments = independent_layout.fragments.into_iter().collect::<Vec<_>>();
|
||||||
.fragments
|
|
||||||
.into_iter()
|
|
||||||
.map(ArcRefCell::new)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Zero box for `:root { display: none }`, one for the root element otherwise.
|
// Zero box for `:root { display: none }`, one for the root element otherwise.
|
||||||
assert!(root_fragments.len() <= 1);
|
assert!(root_fragments.len() <= 1);
|
||||||
|
@ -378,7 +374,7 @@ impl BoxTree {
|
||||||
let scrollable_overflow = root_fragments
|
let scrollable_overflow = root_fragments
|
||||||
.iter()
|
.iter()
|
||||||
.fold(PhysicalRect::zero(), |acc, child| {
|
.fold(PhysicalRect::zero(), |acc, child| {
|
||||||
let child_overflow = child.borrow().scrollable_overflow();
|
let child_overflow = child.scrollable_overflow();
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-overflow/#scrolling-direction
|
// https://drafts.csswg.org/css-overflow/#scrolling-direction
|
||||||
// We want to clip scrollable overflow on box-start and inline-start
|
// We want to clip scrollable overflow on box-start and inline-start
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::layout_debug::DebugId;
|
||||||
/// This data structure stores fields that are common to all non-base
|
/// This data structure stores fields that are common to all non-base
|
||||||
/// Fragment types and should generally be the first member of all
|
/// Fragment types and should generally be the first member of all
|
||||||
/// concrete fragments.
|
/// concrete fragments.
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
pub(crate) struct BaseFragment {
|
pub(crate) struct BaseFragment {
|
||||||
/// A tag which identifies the DOM node and pseudo element of this
|
/// A tag which identifies the DOM node and pseudo element of this
|
||||||
/// Fragment's content. If this fragment isn't related to any DOM
|
/// Fragment's content. If this fragment isn't related to any DOM
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
|
use atomic_refcell::AtomicRefCell;
|
||||||
use base::print_tree::PrintTree;
|
use base::print_tree::PrintTree;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use servo_arc::Arc as ServoArc;
|
use servo_arc::Arc as ServoArc;
|
||||||
|
@ -13,7 +14,6 @@ use style::properties::ComputedValues;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
|
|
||||||
use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment};
|
use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment};
|
||||||
use crate::cell::ArcRefCell;
|
|
||||||
use crate::formatting_contexts::Baselines;
|
use crate::formatting_contexts::Baselines;
|
||||||
use crate::fragment_tree::FragmentFlags;
|
use crate::fragment_tree::FragmentFlags;
|
||||||
use crate::geom::{
|
use crate::geom::{
|
||||||
|
@ -53,7 +53,7 @@ pub(crate) struct BoxFragment {
|
||||||
|
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub style: ServoArc<ComputedValues>,
|
pub style: ServoArc<ComputedValues>,
|
||||||
pub children: Vec<ArcRefCell<Fragment>>,
|
pub children: Vec<Fragment>,
|
||||||
|
|
||||||
/// The content rect of this fragment in the parent fragment's content rectangle. This
|
/// The content rect of this fragment in the parent fragment's content rectangle. This
|
||||||
/// does not include padding, border, or margin -- it only includes content.
|
/// does not include padding, border, or margin -- it only includes content.
|
||||||
|
@ -84,7 +84,8 @@ pub(crate) struct BoxFragment {
|
||||||
/// The resolved box insets if this box is `position: sticky`. These are calculated
|
/// The resolved box insets if this box is `position: sticky`. These are calculated
|
||||||
/// during stacking context tree construction because they rely on the size of the
|
/// during stacking context tree construction because they rely on the size of the
|
||||||
/// scroll container.
|
/// scroll container.
|
||||||
pub(crate) resolved_sticky_insets: Option<PhysicalSides<AuOrAuto>>,
|
#[serde(skip_serializing)]
|
||||||
|
pub(crate) resolved_sticky_insets: AtomicRefCell<Option<PhysicalSides<AuOrAuto>>>,
|
||||||
|
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub background_mode: BackgroundMode,
|
pub background_mode: BackgroundMode,
|
||||||
|
@ -115,7 +116,7 @@ impl BoxFragment {
|
||||||
BoxFragment {
|
BoxFragment {
|
||||||
base: base_fragment_info.into(),
|
base: base_fragment_info.into(),
|
||||||
style,
|
style,
|
||||||
children: children.into_iter().map(ArcRefCell::new).collect(),
|
children,
|
||||||
content_rect,
|
content_rect,
|
||||||
padding,
|
padding,
|
||||||
border,
|
border,
|
||||||
|
@ -124,7 +125,7 @@ impl BoxFragment {
|
||||||
baselines: Baselines::default(),
|
baselines: Baselines::default(),
|
||||||
block_margins_collapsed_with_children,
|
block_margins_collapsed_with_children,
|
||||||
scrollable_overflow_from_children,
|
scrollable_overflow_from_children,
|
||||||
resolved_sticky_insets: None,
|
resolved_sticky_insets: AtomicRefCell::default(),
|
||||||
background_mode: BackgroundMode::Normal,
|
background_mode: BackgroundMode::Normal,
|
||||||
detailed_layout_info: None,
|
detailed_layout_info: None,
|
||||||
}
|
}
|
||||||
|
@ -234,7 +235,7 @@ impl BoxFragment {
|
||||||
));
|
));
|
||||||
|
|
||||||
for child in &self.children {
|
for child in &self.children {
|
||||||
child.borrow().print(tree);
|
child.print(tree);
|
||||||
}
|
}
|
||||||
tree.end_level();
|
tree.end_level();
|
||||||
}
|
}
|
||||||
|
@ -278,7 +279,7 @@ impl BoxFragment {
|
||||||
"Should not call this method on statically positioned box."
|
"Should not call this method on statically positioned box."
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(resolved_sticky_insets) = self.resolved_sticky_insets {
|
if let Some(resolved_sticky_insets) = *self.resolved_sticky_insets.borrow() {
|
||||||
return resolved_sticky_insets;
|
return resolved_sticky_insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub(crate) struct ContainingBlockManager<'a, T> {
|
||||||
impl<'a, T> ContainingBlockManager<'a, T> {
|
impl<'a, T> ContainingBlockManager<'a, T> {
|
||||||
pub(crate) fn get_containing_block_for_fragment(&self, fragment: &Fragment) -> &T {
|
pub(crate) fn get_containing_block_for_fragment(&self, fragment: &Fragment) -> &T {
|
||||||
if let Fragment::Box(box_fragment) = fragment {
|
if let Fragment::Box(box_fragment) = fragment {
|
||||||
match box_fragment.style.clone_position() {
|
match box_fragment.borrow().style.clone_position() {
|
||||||
ComputedPosition::Fixed => self.for_absolute_and_fixed_descendants,
|
ComputedPosition::Fixed => self.for_absolute_and_fixed_descendants,
|
||||||
ComputedPosition::Absolute => self
|
ComputedPosition::Absolute => self
|
||||||
.for_absolute_descendants
|
.for_absolute_descendants
|
||||||
|
|
|
@ -23,16 +23,16 @@ use crate::cell::ArcRefCell;
|
||||||
use crate::geom::{LogicalSides, PhysicalRect};
|
use crate::geom::{LogicalSides, PhysicalRect};
|
||||||
use crate::style_ext::ComputedValuesExt;
|
use crate::style_ext::ComputedValuesExt;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Clone, Serialize)]
|
||||||
pub(crate) enum Fragment {
|
pub(crate) enum Fragment {
|
||||||
Box(BoxFragment),
|
Box(ArcRefCell<BoxFragment>),
|
||||||
/// Floating content. A floated fragment is very similar to a normal
|
/// Floating content. A floated fragment is very similar to a normal
|
||||||
/// [BoxFragment] but it isn't positioned using normal in block flow
|
/// [BoxFragment] but it isn't positioned using normal in block flow
|
||||||
/// positioning rules (margin collapse, etc). Instead, they are laid
|
/// positioning rules (margin collapse, etc). Instead, they are laid
|
||||||
/// out by the [crate::flow::float::SequentialLayoutState] of their
|
/// out by the [crate::flow::float::SequentialLayoutState] of their
|
||||||
/// float containing block formatting context.
|
/// float containing block formatting context.
|
||||||
Float(BoxFragment),
|
Float(ArcRefCell<BoxFragment>),
|
||||||
Positioning(PositioningFragment),
|
Positioning(ArcRefCell<PositioningFragment>),
|
||||||
/// Absolute and fixed position fragments are hoisted up so that they
|
/// Absolute and fixed position fragments are hoisted up so that they
|
||||||
/// are children of the BoxFragment that establishes their containing
|
/// are children of the BoxFragment that establishes their containing
|
||||||
/// blocks, so that they can be laid out properly. When this happens
|
/// blocks, so that they can be laid out properly. When this happens
|
||||||
|
@ -41,9 +41,9 @@ pub(crate) enum Fragment {
|
||||||
/// regard to their original tree order during stacking context tree /
|
/// regard to their original tree order during stacking context tree /
|
||||||
/// display list construction.
|
/// display list construction.
|
||||||
AbsoluteOrFixedPositioned(ArcRefCell<HoistedSharedFragment>),
|
AbsoluteOrFixedPositioned(ArcRefCell<HoistedSharedFragment>),
|
||||||
Text(TextFragment),
|
Text(ArcRefCell<TextFragment>),
|
||||||
Image(ImageFragment),
|
Image(ArcRefCell<ImageFragment>),
|
||||||
IFrame(IFrameFragment),
|
IFrame(ArcRefCell<IFrameFragment>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -99,26 +99,26 @@ pub(crate) struct IFrameFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fragment {
|
impl Fragment {
|
||||||
pub fn base(&self) -> Option<&BaseFragment> {
|
pub fn base(&self) -> Option<BaseFragment> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
Fragment::Box(fragment) => &fragment.base,
|
Fragment::Box(fragment) => fragment.borrow().base.clone(),
|
||||||
Fragment::Text(fragment) => &fragment.base,
|
Fragment::Text(fragment) => fragment.borrow().base.clone(),
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) => return None,
|
Fragment::AbsoluteOrFixedPositioned(_) => return None,
|
||||||
Fragment::Positioning(fragment) => &fragment.base,
|
Fragment::Positioning(fragment) => fragment.borrow().base.clone(),
|
||||||
Fragment::Image(fragment) => &fragment.base,
|
Fragment::Image(fragment) => fragment.borrow().base.clone(),
|
||||||
Fragment::IFrame(fragment) => &fragment.base,
|
Fragment::IFrame(fragment) => fragment.borrow().base.clone(),
|
||||||
Fragment::Float(fragment) => &fragment.base,
|
Fragment::Float(fragment) => fragment.borrow().base.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub(crate) fn content_rect_mut(&mut self) -> Option<&mut PhysicalRect<Au>> {
|
pub(crate) fn mutate_content_rect(&mut self, callback: impl FnOnce(&mut PhysicalRect<Au>)) {
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
|
Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => {
|
||||||
Some(&mut box_fragment.content_rect)
|
callback(&mut box_fragment.borrow_mut().content_rect)
|
||||||
},
|
},
|
||||||
Fragment::Positioning(_) | Fragment::AbsoluteOrFixedPositioned(_) => None,
|
Fragment::Positioning(_) | Fragment::AbsoluteOrFixedPositioned(_) => {},
|
||||||
Fragment::Text(text_fragment) => Some(&mut text_fragment.rect),
|
Fragment::Text(text_fragment) => callback(&mut text_fragment.borrow_mut().rect),
|
||||||
Fragment::Image(image_fragment) => Some(&mut image_fragment.rect),
|
Fragment::Image(image_fragment) => callback(&mut image_fragment.borrow_mut().rect),
|
||||||
Fragment::IFrame(iframe_fragment) => Some(&mut iframe_fragment.rect),
|
Fragment::IFrame(iframe_fragment) => callback(&mut iframe_fragment.borrow_mut().rect),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,25 +128,26 @@ impl Fragment {
|
||||||
|
|
||||||
pub fn print(&self, tree: &mut PrintTree) {
|
pub fn print(&self, tree: &mut PrintTree) {
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(fragment) => fragment.print(tree),
|
Fragment::Box(fragment) => fragment.borrow().print(tree),
|
||||||
Fragment::Float(fragment) => {
|
Fragment::Float(fragment) => {
|
||||||
tree.new_level("Float".to_string());
|
tree.new_level("Float".to_string());
|
||||||
fragment.print(tree);
|
fragment.borrow().print(tree);
|
||||||
tree.end_level();
|
tree.end_level();
|
||||||
},
|
},
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) => {
|
Fragment::AbsoluteOrFixedPositioned(_) => {
|
||||||
tree.add_item("AbsoluteOrFixedPositioned".to_string());
|
tree.add_item("AbsoluteOrFixedPositioned".to_string());
|
||||||
},
|
},
|
||||||
Fragment::Positioning(fragment) => fragment.print(tree),
|
Fragment::Positioning(fragment) => fragment.borrow().print(tree),
|
||||||
Fragment::Text(fragment) => fragment.print(tree),
|
Fragment::Text(fragment) => fragment.borrow().print(tree),
|
||||||
Fragment::Image(fragment) => fragment.print(tree),
|
Fragment::Image(fragment) => fragment.borrow().print(tree),
|
||||||
Fragment::IFrame(fragment) => fragment.print(tree),
|
Fragment::IFrame(fragment) => fragment.borrow().print(tree),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scrolling_area(&self, containing_block: &PhysicalRect<Au>) -> PhysicalRect<Au> {
|
pub fn scrolling_area(&self, containing_block: &PhysicalRect<Au>) -> PhysicalRect<Au> {
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment
|
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment
|
||||||
|
.borrow()
|
||||||
.scrollable_overflow()
|
.scrollable_overflow()
|
||||||
.translate(containing_block.origin.to_vector()),
|
.translate(containing_block.origin.to_vector()),
|
||||||
_ => self.scrollable_overflow(),
|
_ => self.scrollable_overflow(),
|
||||||
|
@ -156,13 +157,13 @@ impl Fragment {
|
||||||
pub fn scrollable_overflow(&self) -> PhysicalRect<Au> {
|
pub fn scrollable_overflow(&self) -> PhysicalRect<Au> {
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
fragment.scrollable_overflow_for_parent()
|
fragment.borrow().scrollable_overflow_for_parent()
|
||||||
},
|
},
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) => PhysicalRect::zero(),
|
Fragment::AbsoluteOrFixedPositioned(_) => PhysicalRect::zero(),
|
||||||
Fragment::Positioning(fragment) => fragment.scrollable_overflow,
|
Fragment::Positioning(fragment) => fragment.borrow().scrollable_overflow,
|
||||||
Fragment::Text(fragment) => fragment.rect,
|
Fragment::Text(fragment) => fragment.borrow().rect,
|
||||||
Fragment::Image(fragment) => fragment.rect,
|
Fragment::Image(fragment) => fragment.borrow().rect,
|
||||||
Fragment::IFrame(fragment) => fragment.rect,
|
Fragment::IFrame(fragment) => fragment.borrow().rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +180,7 @@ impl Fragment {
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
|
let fragment = fragment.borrow();
|
||||||
let content_rect = fragment
|
let content_rect = fragment
|
||||||
.content_rect
|
.content_rect
|
||||||
.translate(containing_block.origin.to_vector());
|
.translate(containing_block.origin.to_vector());
|
||||||
|
@ -202,15 +204,16 @@ impl Fragment {
|
||||||
fragment
|
fragment
|
||||||
.children
|
.children
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|child| child.borrow().find(&new_manager, level + 1, process_func))
|
.find_map(|child| child.find(&new_manager, level + 1, process_func))
|
||||||
},
|
},
|
||||||
Fragment::Positioning(fragment) => {
|
Fragment::Positioning(fragment) => {
|
||||||
|
let fragment = fragment.borrow();
|
||||||
let content_rect = fragment.rect.translate(containing_block.origin.to_vector());
|
let content_rect = fragment.rect.translate(containing_block.origin.to_vector());
|
||||||
let new_manager = manager.new_for_non_absolute_descendants(&content_rect);
|
let new_manager = manager.new_for_non_absolute_descendants(&content_rect);
|
||||||
fragment
|
fragment
|
||||||
.children
|
.children
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|child| child.borrow().find(&new_manager, level + 1, process_func))
|
.find_map(|child| child.find(&new_manager, level + 1, process_func))
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use webrender_api::units;
|
||||||
use webrender_traits::display_list::ScrollSensitivity;
|
use webrender_traits::display_list::ScrollSensitivity;
|
||||||
|
|
||||||
use super::{ContainingBlockManager, Fragment, Tag};
|
use super::{ContainingBlockManager, Fragment, Tag};
|
||||||
use crate::cell::ArcRefCell;
|
|
||||||
use crate::display_list::StackingContext;
|
use crate::display_list::StackingContext;
|
||||||
use crate::flow::CanvasBackground;
|
use crate::flow::CanvasBackground;
|
||||||
use crate::geom::PhysicalRect;
|
use crate::geom::PhysicalRect;
|
||||||
|
@ -28,7 +27,7 @@ pub struct FragmentTree {
|
||||||
/// * The first fragment is generated by the root element.
|
/// * The first fragment is generated by the root element.
|
||||||
/// * There may be additional fragments generated by positioned boxes
|
/// * There may be additional fragments generated by positioned boxes
|
||||||
/// that have the initial containing block.
|
/// that have the initial containing block.
|
||||||
pub(crate) root_fragments: Vec<ArcRefCell<Fragment>>,
|
pub(crate) root_fragments: Vec<Fragment>,
|
||||||
|
|
||||||
/// The scrollable overflow rectangle for the entire tree
|
/// The scrollable overflow rectangle for the entire tree
|
||||||
/// <https://drafts.csswg.org/css-overflow/#scrollable>
|
/// <https://drafts.csswg.org/css-overflow/#scrollable>
|
||||||
|
@ -63,7 +62,7 @@ impl FragmentTree {
|
||||||
pub fn print(&self) {
|
pub fn print(&self) {
|
||||||
let mut print_tree = PrintTree::new("Fragment Tree".to_string());
|
let mut print_tree = PrintTree::new("Fragment Tree".to_string());
|
||||||
for fragment in &self.root_fragments {
|
for fragment in &self.root_fragments {
|
||||||
fragment.borrow().print(&mut print_tree);
|
fragment.print(&mut print_tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ impl FragmentTree {
|
||||||
};
|
};
|
||||||
self.root_fragments
|
self.root_fragments
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|child| child.borrow().find(&info, 0, &mut process_func))
|
.find_map(|child| child.find(&info, 0, &mut process_func))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_nodes_in_fragment_tree_from_set(&self, set: &mut FxHashSet<AnimationSetKey>) {
|
pub fn remove_nodes_in_fragment_tree_from_set(&self, set: &mut FxHashSet<AnimationSetKey>) {
|
||||||
|
@ -110,9 +109,11 @@ impl FragmentTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
let fragment_relative_rect = match fragment {
|
let fragment_relative_rect = match fragment {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment.border_rect(),
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
Fragment::Positioning(fragment) => fragment.rect,
|
fragment.borrow().border_rect()
|
||||||
Fragment::Text(fragment) => fragment.rect,
|
},
|
||||||
|
Fragment::Positioning(fragment) => fragment.borrow().rect,
|
||||||
|
Fragment::Text(fragment) => fragment.borrow().rect,
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) |
|
Fragment::AbsoluteOrFixedPositioned(_) |
|
||||||
Fragment::Image(_) |
|
Fragment::Image(_) |
|
||||||
Fragment::IFrame(_) => return None,
|
Fragment::IFrame(_) => return None,
|
||||||
|
@ -140,6 +141,7 @@ impl FragmentTree {
|
||||||
// CSS layout box is inline, return zero." For this check we
|
// CSS layout box is inline, return zero." For this check we
|
||||||
// also explicitly ignore the list item portion of the display
|
// also explicitly ignore the list item portion of the display
|
||||||
// style.
|
// style.
|
||||||
|
let fragment = fragment.borrow();
|
||||||
if fragment.is_inline_box() {
|
if fragment.is_inline_box() {
|
||||||
return Some(Rect::zero());
|
return Some(Rect::zero());
|
||||||
}
|
}
|
||||||
|
@ -151,7 +153,7 @@ impl FragmentTree {
|
||||||
Size2D::new(padding_rect.size.width, padding_rect.size.height),
|
Size2D::new(padding_rect.size.width, padding_rect.size.height),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Fragment::Positioning(fragment) => fragment.rect.cast_unit(),
|
Fragment::Positioning(fragment) => fragment.borrow().rect.cast_unit(),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -168,7 +170,6 @@ impl FragmentTree {
|
||||||
let mut scroll_area = self.initial_containing_block;
|
let mut scroll_area = self.initial_containing_block;
|
||||||
for fragment in self.root_fragments.iter() {
|
for fragment in self.root_fragments.iter() {
|
||||||
scroll_area = fragment
|
scroll_area = fragment
|
||||||
.borrow()
|
|
||||||
.scrolling_area(&self.initial_containing_block)
|
.scrolling_area(&self.initial_containing_block)
|
||||||
.union(&scroll_area);
|
.union(&scroll_area);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ use style::logical_geometry::WritingMode;
|
||||||
use style::values::specified::align::AlignFlags;
|
use style::values::specified::align::AlignFlags;
|
||||||
|
|
||||||
use super::Fragment;
|
use super::Fragment;
|
||||||
use crate::cell::ArcRefCell;
|
|
||||||
use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec};
|
use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec};
|
||||||
|
|
||||||
/// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox`
|
/// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox`
|
||||||
|
@ -16,7 +15,7 @@ use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec};
|
||||||
/// This will be used later in order to paint this hoisted box in tree order.
|
/// This will be used later in order to paint this hoisted box in tree order.
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub(crate) struct HoistedSharedFragment {
|
pub(crate) struct HoistedSharedFragment {
|
||||||
pub fragment: Option<ArcRefCell<Fragment>>,
|
pub fragment: Option<Fragment>,
|
||||||
/// The "static-position rect" of this absolutely positioned box. This is defined by the
|
/// The "static-position rect" of this absolutely positioned box. This is defined by the
|
||||||
/// layout mode from which the box originates.
|
/// layout mode from which the box originates.
|
||||||
///
|
///
|
||||||
|
|
|
@ -19,7 +19,7 @@ use crate::geom::PhysicalRect;
|
||||||
pub(crate) struct PositioningFragment {
|
pub(crate) struct PositioningFragment {
|
||||||
pub base: BaseFragment,
|
pub base: BaseFragment,
|
||||||
pub rect: PhysicalRect<Au>,
|
pub rect: PhysicalRect<Au>,
|
||||||
pub children: Vec<ArcRefCell<Fragment>>,
|
pub children: Vec<Fragment>,
|
||||||
/// The scrollable overflow of this anonymous fragment's children.
|
/// The scrollable overflow of this anonymous fragment's children.
|
||||||
pub scrollable_overflow: PhysicalRect<Au>,
|
pub scrollable_overflow: PhysicalRect<Au>,
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ pub(crate) struct PositioningFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PositioningFragment {
|
impl PositioningFragment {
|
||||||
pub fn new_anonymous(rect: PhysicalRect<Au>, children: Vec<Fragment>) -> Self {
|
pub fn new_anonymous(rect: PhysicalRect<Au>, children: Vec<Fragment>) -> ArcRefCell<Self> {
|
||||||
Self::new_with_base_fragment(BaseFragment::anonymous(), None, rect, children)
|
Self::new_with_base_fragment(BaseFragment::anonymous(), None, rect, children)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ impl PositioningFragment {
|
||||||
base_fragment_info: BaseFragmentInfo,
|
base_fragment_info: BaseFragmentInfo,
|
||||||
rect: PhysicalRect<Au>,
|
rect: PhysicalRect<Au>,
|
||||||
style: ServoArc<ComputedValues>,
|
style: ServoArc<ComputedValues>,
|
||||||
) -> Self {
|
) -> ArcRefCell<Self> {
|
||||||
Self::new_with_base_fragment(base_fragment_info.into(), Some(style), rect, Vec::new())
|
Self::new_with_base_fragment(base_fragment_info.into(), Some(style), rect, Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ impl PositioningFragment {
|
||||||
style: Option<ServoArc<ComputedValues>>,
|
style: Option<ServoArc<ComputedValues>>,
|
||||||
rect: PhysicalRect<Au>,
|
rect: PhysicalRect<Au>,
|
||||||
children: Vec<Fragment>,
|
children: Vec<Fragment>,
|
||||||
) -> Self {
|
) -> ArcRefCell<Self> {
|
||||||
let content_origin = rect.origin;
|
let content_origin = rect.origin;
|
||||||
let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| {
|
let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| {
|
||||||
acc.union(
|
acc.union(
|
||||||
|
@ -55,13 +55,13 @@ impl PositioningFragment {
|
||||||
.translate(content_origin.to_vector()),
|
.translate(content_origin.to_vector()),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
PositioningFragment {
|
ArcRefCell::new(PositioningFragment {
|
||||||
base,
|
base,
|
||||||
style,
|
style,
|
||||||
rect,
|
rect,
|
||||||
children: children.into_iter().map(ArcRefCell::new).collect(),
|
children,
|
||||||
scrollable_overflow,
|
scrollable_overflow,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print(&self, tree: &mut PrintTree) {
|
pub fn print(&self, tree: &mut PrintTree) {
|
||||||
|
@ -74,7 +74,7 @@ impl PositioningFragment {
|
||||||
));
|
));
|
||||||
|
|
||||||
for child in &self.children {
|
for child in &self.children {
|
||||||
child.borrow().print(tree);
|
child.print(tree);
|
||||||
}
|
}
|
||||||
tree.end_level();
|
tree.end_level();
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,9 +161,11 @@ impl PositioningContext {
|
||||||
index: PositioningContextLength,
|
index: PositioningContextLength,
|
||||||
) {
|
) {
|
||||||
let start_offset = match &parent_fragment {
|
let start_offset = match &parent_fragment {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => &fragment.content_rect.origin,
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
|
fragment.borrow().content_rect.origin
|
||||||
|
},
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) => return,
|
Fragment::AbsoluteOrFixedPositioned(_) => return,
|
||||||
Fragment::Positioning(fragment) => &fragment.rect.origin,
|
Fragment::Positioning(fragment) => fragment.borrow().rect.origin,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
self.adjust_static_position_of_hoisted_fragments_with_offset(
|
self.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||||
|
@ -335,7 +337,7 @@ impl PositioningContext {
|
||||||
&mut self,
|
&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
initial_containing_block: &DefiniteContainingBlock,
|
initial_containing_block: &DefiniteContainingBlock,
|
||||||
fragments: &mut Vec<ArcRefCell<Fragment>>,
|
fragments: &mut Vec<Fragment>,
|
||||||
) {
|
) {
|
||||||
debug_assert!(self.for_nearest_positioned_ancestor.is_none());
|
debug_assert!(self.for_nearest_positioned_ancestor.is_none());
|
||||||
|
|
||||||
|
@ -409,7 +411,7 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
pub(crate) fn layout_many(
|
pub(crate) fn layout_many(
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
boxes: &mut [Self],
|
boxes: &mut [Self],
|
||||||
fragments: &mut Vec<ArcRefCell<Fragment>>,
|
fragments: &mut Vec<Fragment>,
|
||||||
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,
|
||||||
) {
|
) {
|
||||||
|
@ -421,14 +423,15 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
.par_iter_mut()
|
.par_iter_mut()
|
||||||
.map(|hoisted_box| {
|
.map(|hoisted_box| {
|
||||||
let mut new_hoisted_boxes: Vec<HoistedAbsolutelyPositionedBox> = Vec::new();
|
let mut new_hoisted_boxes: Vec<HoistedAbsolutelyPositionedBox> = Vec::new();
|
||||||
let new_fragment = ArcRefCell::new(Fragment::Box(hoisted_box.layout(
|
let new_fragment = hoisted_box.layout(
|
||||||
layout_context,
|
layout_context,
|
||||||
&mut new_hoisted_boxes,
|
&mut new_hoisted_boxes,
|
||||||
containing_block,
|
containing_block,
|
||||||
)));
|
);
|
||||||
|
|
||||||
hoisted_box.fragment.borrow_mut().fragment = Some(new_fragment.clone());
|
hoisted_box.fragment.borrow_mut().fragment =
|
||||||
(new_fragment, new_hoisted_boxes)
|
Some(Fragment::Box(new_fragment.clone()));
|
||||||
|
(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);
|
||||||
|
|
||||||
|
@ -437,13 +440,14 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
.extend(new_hoisted_boxes.into_iter().flatten());
|
.extend(new_hoisted_boxes.into_iter().flatten());
|
||||||
} else {
|
} else {
|
||||||
fragments.extend(boxes.iter_mut().map(|box_| {
|
fragments.extend(boxes.iter_mut().map(|box_| {
|
||||||
let new_fragment = ArcRefCell::new(Fragment::Box(box_.layout(
|
let new_fragment = box_.layout(
|
||||||
layout_context,
|
layout_context,
|
||||||
for_nearest_containing_block_for_all_descendants,
|
for_nearest_containing_block_for_all_descendants,
|
||||||
containing_block,
|
containing_block,
|
||||||
)));
|
);
|
||||||
box_.fragment.borrow_mut().fragment = Some(new_fragment.clone());
|
|
||||||
new_fragment
|
box_.fragment.borrow_mut().fragment = Some(Fragment::Box(new_fragment.clone()));
|
||||||
|
Fragment::Box(new_fragment)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,7 +457,7 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
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,
|
||||||
) -> BoxFragment {
|
) -> ArcRefCell<BoxFragment> {
|
||||||
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;
|
||||||
|
@ -696,7 +700,7 @@ 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);
|
||||||
|
|
||||||
new_fragment
|
ArcRefCell::new(new_fragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,7 @@ pub fn process_resolved_style_request<'dom>(
|
||||||
|
|
||||||
let (content_rect, margins, padding, detailed_layout_info) = match fragment {
|
let (content_rect, margins, padding, detailed_layout_info) = match fragment {
|
||||||
Fragment::Box(ref box_fragment) | Fragment::Float(ref box_fragment) => {
|
Fragment::Box(ref box_fragment) | Fragment::Float(ref box_fragment) => {
|
||||||
|
let box_fragment = box_fragment.borrow();
|
||||||
if style.get_box().position != Position::Static {
|
if style.get_box().position != Position::Static {
|
||||||
let resolved_insets = || {
|
let resolved_insets = || {
|
||||||
box_fragment.calculate_resolved_insets_if_positioned(containing_block)
|
box_fragment.calculate_resolved_insets_if_positioned(containing_block)
|
||||||
|
@ -213,16 +214,16 @@ pub fn process_resolved_style_request<'dom>(
|
||||||
let content_rect = box_fragment.content_rect;
|
let content_rect = box_fragment.content_rect;
|
||||||
let margins = box_fragment.margin;
|
let margins = box_fragment.margin;
|
||||||
let padding = box_fragment.padding;
|
let padding = box_fragment.padding;
|
||||||
let detailed_layout_info = &box_fragment.detailed_layout_info;
|
let detailed_layout_info = box_fragment.detailed_layout_info.clone();
|
||||||
(content_rect, margins, padding, detailed_layout_info)
|
(content_rect, margins, padding, detailed_layout_info)
|
||||||
},
|
},
|
||||||
Fragment::Positioning(positioning_fragment) => {
|
Fragment::Positioning(positioning_fragment) => {
|
||||||
let content_rect = positioning_fragment.rect;
|
let content_rect = positioning_fragment.borrow().rect;
|
||||||
(
|
(
|
||||||
content_rect,
|
content_rect,
|
||||||
SideOffsets2D::zero(),
|
SideOffsets2D::zero(),
|
||||||
SideOffsets2D::zero(),
|
SideOffsets2D::zero(),
|
||||||
&None,
|
None,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -235,7 +236,7 @@ pub fn process_resolved_style_request<'dom>(
|
||||||
// > When an element generates a grid container box...
|
// > When an element generates a grid container box...
|
||||||
if display.inside() == DisplayInside::Grid {
|
if display.inside() == DisplayInside::Grid {
|
||||||
if let Some(SpecificLayoutInfo::Grid(info)) = detailed_layout_info {
|
if let Some(SpecificLayoutInfo::Grid(info)) = detailed_layout_info {
|
||||||
if let Some(value) = resolve_grid_template(info, style, longhand_id) {
|
if let Some(value) = resolve_grid_template(&info, style, longhand_id) {
|
||||||
return Some(value);
|
return Some(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -274,7 +275,7 @@ fn resolved_size_should_be_used_value(fragment: &Fragment) -> bool {
|
||||||
// https://drafts.csswg.org/css-sizing-3/#preferred-size-properties
|
// https://drafts.csswg.org/css-sizing-3/#preferred-size-properties
|
||||||
// > Applies to: all elements except non-replaced inlines
|
// > Applies to: all elements except non-replaced inlines
|
||||||
match fragment {
|
match fragment {
|
||||||
Fragment::Box(box_fragment) => !box_fragment.is_inline_box(),
|
Fragment::Box(box_fragment) => !box_fragment.borrow().is_inline_box(),
|
||||||
Fragment::Float(_) |
|
Fragment::Float(_) |
|
||||||
Fragment::Positioning(_) |
|
Fragment::Positioning(_) |
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) |
|
Fragment::AbsoluteOrFixedPositioned(_) |
|
||||||
|
@ -446,9 +447,9 @@ fn process_offset_parent_query_inner(
|
||||||
//
|
//
|
||||||
// [1]: https://github.com/w3c/csswg-drafts/issues/4541
|
// [1]: https://github.com/w3c/csswg-drafts/issues/4541
|
||||||
let fragment_relative_rect = match fragment {
|
let fragment_relative_rect = match fragment {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment.border_rect(),
|
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment.borrow().border_rect(),
|
||||||
Fragment::Text(fragment) => fragment.rect,
|
Fragment::Text(fragment) => fragment.borrow().rect,
|
||||||
Fragment::Positioning(fragment) => fragment.rect,
|
Fragment::Positioning(fragment) => fragment.borrow().rect,
|
||||||
Fragment::AbsoluteOrFixedPositioned(_) |
|
Fragment::AbsoluteOrFixedPositioned(_) |
|
||||||
Fragment::Image(_) |
|
Fragment::Image(_) |
|
||||||
Fragment::IFrame(_) => unreachable!(),
|
Fragment::IFrame(_) => unreachable!(),
|
||||||
|
@ -460,7 +461,7 @@ fn process_offset_parent_query_inner(
|
||||||
// this algorithm: [...] The element’s computed value of the
|
// this algorithm: [...] The element’s computed value of the
|
||||||
// `position` property is `fixed`."
|
// `position` property is `fixed`."
|
||||||
let is_fixed = matches!(
|
let is_fixed = matches!(
|
||||||
fragment, Fragment::Box(fragment) if fragment.style.get_box().position == Position::Fixed
|
fragment, Fragment::Box(fragment) if fragment.borrow().style.get_box().position == Position::Fixed
|
||||||
);
|
);
|
||||||
|
|
||||||
if is_body_element {
|
if is_body_element {
|
||||||
|
@ -489,6 +490,7 @@ fn process_offset_parent_query_inner(
|
||||||
// Record the paths of the nodes being traversed.
|
// Record the paths of the nodes being traversed.
|
||||||
let parent_node_address = match fragment {
|
let parent_node_address = match fragment {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
|
let fragment = &*fragment.borrow();
|
||||||
let is_eligible_parent = is_eligible_parent(fragment);
|
let is_eligible_parent = is_eligible_parent(fragment);
|
||||||
let is_static_body_element = is_body_element &&
|
let is_static_body_element = is_body_element &&
|
||||||
fragment.style.get_box().position == Position::Static;
|
fragment.style.get_box().position == Position::Static;
|
||||||
|
@ -538,14 +540,15 @@ fn process_offset_parent_query_inner(
|
||||||
unreachable!();
|
unreachable!();
|
||||||
};
|
};
|
||||||
// Again, take the *first* associated CSS layout box.
|
// Again, take the *first* associated CSS layout box.
|
||||||
fragment.border_rect().origin.to_vector() + containing_block.origin.to_vector()
|
fragment.borrow().border_rect().origin.to_vector() +
|
||||||
|
containing_block.origin.to_vector()
|
||||||
}
|
}
|
||||||
|
|
||||||
let containing_block = &fragment_tree.initial_containing_block;
|
let containing_block = &fragment_tree.initial_containing_block;
|
||||||
let fragment = &(*fragment_tree.root_fragments[0].borrow());
|
let fragment = &fragment_tree.root_fragments[0];
|
||||||
if let Fragment::AbsoluteOrFixedPositioned(shared_fragment) = fragment {
|
if let Fragment::AbsoluteOrFixedPositioned(shared_fragment) = fragment {
|
||||||
let shared_fragment = &*shared_fragment.borrow();
|
let shared_fragment = &*shared_fragment.borrow();
|
||||||
let fragment = &*shared_fragment.fragment.as_ref().unwrap().borrow();
|
let fragment = shared_fragment.fragment.as_ref().unwrap();
|
||||||
extract_box_fragment(fragment, containing_block)
|
extract_box_fragment(fragment, containing_block)
|
||||||
} else {
|
} else {
|
||||||
extract_box_fragment(fragment, containing_block)
|
extract_box_fragment(fragment, containing_block)
|
||||||
|
@ -561,6 +564,7 @@ fn process_offset_parent_query_inner(
|
||||||
.find(|fragment, _, containing_block| {
|
.find(|fragment, _, containing_block| {
|
||||||
match fragment {
|
match fragment {
|
||||||
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
Fragment::Box(fragment) | Fragment::Float(fragment) => {
|
||||||
|
let fragment = fragment.borrow();
|
||||||
if fragment.base.tag == Some(offset_parent_node_tag) {
|
if fragment.base.tag == Some(offset_parent_node_tag) {
|
||||||
// Again, take the *first* associated CSS layout box.
|
// Again, take the *first* associated CSS layout box.
|
||||||
let padding_box_corner = fragment.padding_rect().origin.to_vector()
|
let padding_box_corner = fragment.padding_rect().origin.to_vector()
|
||||||
|
|
|
@ -27,6 +27,7 @@ use style::Zero;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webrender_api::ImageKey;
|
use webrender_api::ImageKey;
|
||||||
|
|
||||||
|
use crate::cell::ArcRefCell;
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::dom::NodeExt;
|
use crate::dom::NodeExt;
|
||||||
use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment};
|
use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment};
|
||||||
|
@ -334,23 +335,25 @@ impl ReplacedContents {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|image| image.id)
|
.and_then(|image| image.id)
|
||||||
.map(|image_key| {
|
.map(|image_key| {
|
||||||
Fragment::Image(ImageFragment {
|
Fragment::Image(ArcRefCell::new(ImageFragment {
|
||||||
base: self.base_fragment_info.into(),
|
base: self.base_fragment_info.into(),
|
||||||
style: style.clone(),
|
style: style.clone(),
|
||||||
rect,
|
rect,
|
||||||
clip,
|
clip,
|
||||||
image_key: Some(image_key),
|
image_key: Some(image_key),
|
||||||
})
|
}))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect(),
|
.collect(),
|
||||||
ReplacedContentKind::Video(video) => vec![Fragment::Image(ImageFragment {
|
ReplacedContentKind::Video(video) => {
|
||||||
base: self.base_fragment_info.into(),
|
vec![Fragment::Image(ArcRefCell::new(ImageFragment {
|
||||||
style: style.clone(),
|
base: self.base_fragment_info.into(),
|
||||||
rect,
|
style: style.clone(),
|
||||||
clip,
|
rect,
|
||||||
image_key: video.as_ref().map(|video| video.image_key),
|
clip,
|
||||||
})],
|
image_key: video.as_ref().map(|video| video.image_key),
|
||||||
|
}))]
|
||||||
|
},
|
||||||
ReplacedContentKind::IFrame(iframe) => {
|
ReplacedContentKind::IFrame(iframe) => {
|
||||||
let size = Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px());
|
let size = Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px());
|
||||||
layout_context.iframe_sizes.lock().insert(
|
layout_context.iframe_sizes.lock().insert(
|
||||||
|
@ -361,13 +364,13 @@ impl ReplacedContents {
|
||||||
size,
|
size,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
vec![Fragment::IFrame(IFrameFragment {
|
vec![Fragment::IFrame(ArcRefCell::new(IFrameFragment {
|
||||||
base: self.base_fragment_info.into(),
|
base: self.base_fragment_info.into(),
|
||||||
style: style.clone(),
|
style: style.clone(),
|
||||||
pipeline_id: iframe.pipeline_id,
|
pipeline_id: iframe.pipeline_id,
|
||||||
browsing_context_id: iframe.browsing_context_id,
|
browsing_context_id: iframe.browsing_context_id,
|
||||||
rect,
|
rect,
|
||||||
})]
|
}))]
|
||||||
},
|
},
|
||||||
ReplacedContentKind::Canvas(canvas_info) => {
|
ReplacedContentKind::Canvas(canvas_info) => {
|
||||||
if self.natural_size.width == Some(Au::zero()) ||
|
if self.natural_size.width == Some(Au::zero()) ||
|
||||||
|
@ -392,13 +395,13 @@ impl ReplacedContents {
|
||||||
},
|
},
|
||||||
CanvasSource::Empty => return vec![],
|
CanvasSource::Empty => return vec![],
|
||||||
};
|
};
|
||||||
vec![Fragment::Image(ImageFragment {
|
vec![Fragment::Image(ArcRefCell::new(ImageFragment {
|
||||||
base: self.base_fragment_info.into(),
|
base: self.base_fragment_info.into(),
|
||||||
style: style.clone(),
|
style: style.clone(),
|
||||||
rect,
|
rect,
|
||||||
clip,
|
clip,
|
||||||
image_key: Some(image_key),
|
image_key: Some(image_key),
|
||||||
})]
|
}))]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,9 @@ use style::values::generics::box_::{GenericVerticalAlign as VerticalAlign, Verti
|
||||||
use style::values::generics::length::GenericLengthPercentageOrAuto::{Auto, LengthPercentage};
|
use style::values::generics::length::GenericLengthPercentageOrAuto::{Auto, LengthPercentage};
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
|
|
||||||
use super::{Table, TableCaption, TableSlot, TableSlotCell, TableTrack, TableTrackGroup};
|
use super::{
|
||||||
|
ArcRefCell, Table, TableCaption, TableSlot, TableSlotCell, TableTrack, TableTrackGroup,
|
||||||
|
};
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
|
@ -1740,7 +1742,7 @@ impl<'a> TableLayout<'a> {
|
||||||
.to_logical(table_writing_mode)
|
.to_logical(table_writing_mode)
|
||||||
.block;
|
.block;
|
||||||
|
|
||||||
let caption_fragment = Fragment::Box(caption_fragment);
|
let caption_fragment = Fragment::Box(ArcRefCell::new(caption_fragment));
|
||||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||||
&caption_fragment,
|
&caption_fragment,
|
||||||
original_positioning_context_length,
|
original_positioning_context_length,
|
||||||
|
@ -1790,7 +1792,7 @@ impl<'a> TableLayout<'a> {
|
||||||
.block;
|
.block;
|
||||||
table_layout.content_inline_size_for_table = Some(logical_grid_content_rect.size.inline);
|
table_layout.content_inline_size_for_table = Some(logical_grid_content_rect.size.inline);
|
||||||
|
|
||||||
let grid_fragment = Fragment::Box(grid_fragment);
|
let grid_fragment = Fragment::Box(ArcRefCell::new(grid_fragment));
|
||||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||||
&grid_fragment,
|
&grid_fragment,
|
||||||
original_positioning_context_length,
|
original_positioning_context_length,
|
||||||
|
@ -1831,7 +1833,7 @@ impl<'a> TableLayout<'a> {
|
||||||
.to_logical(table_writing_mode)
|
.to_logical(table_writing_mode)
|
||||||
.block;
|
.block;
|
||||||
|
|
||||||
let caption_fragment = Fragment::Box(caption_fragment);
|
let caption_fragment = Fragment::Box(ArcRefCell::new(caption_fragment));
|
||||||
positioning_context.adjust_static_position_of_hoisted_fragments(
|
positioning_context.adjust_static_position_of_hoisted_fragments(
|
||||||
&caption_fragment,
|
&caption_fragment,
|
||||||
original_positioning_context_length,
|
original_positioning_context_length,
|
||||||
|
@ -2182,7 +2184,9 @@ impl<'a> TableLayout<'a> {
|
||||||
rect,
|
rect,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
row_fragment_layout.fragments.push(Fragment::Box(fragment));
|
row_fragment_layout
|
||||||
|
.fragments
|
||||||
|
.push(Fragment::Box(ArcRefCell::new(fragment)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_fragments_for_columns_and_column_groups(
|
fn make_fragments_for_columns_and_column_groups(
|
||||||
|
@ -2345,7 +2349,7 @@ 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>,
|
||||||
) -> BoxFragment {
|
) -> ArcRefCell<BoxFragment> {
|
||||||
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.style, containing_block_for_children);
|
||||||
|
@ -2396,7 +2400,7 @@ impl<'a> RowFragmentLayout<'a> {
|
||||||
positioning_context.append(row_positioning_context);
|
positioning_context.append(row_positioning_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
row_fragment
|
ArcRefCell::new(row_fragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2432,7 +2436,7 @@ 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,
|
||||||
) -> BoxFragment {
|
) -> ArcRefCell<BoxFragment> {
|
||||||
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(&self.style, containing_block_for_children);
|
||||||
|
@ -2458,7 +2462,7 @@ impl RowGroupFragmentLayout {
|
||||||
table_positioning_context.append(row_positioning_context);
|
table_positioning_context.append(row_positioning_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
row_group_fragment
|
ArcRefCell::new(row_group_fragment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -551,7 +551,7 @@ impl TaffyContainer {
|
||||||
|
|
||||||
match &mut child.taffy_level_box {
|
match &mut child.taffy_level_box {
|
||||||
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
||||||
let fragment = Fragment::Box(
|
let fragment = Fragment::Box(ArcRefCell::new(
|
||||||
BoxFragment::new(
|
BoxFragment::new(
|
||||||
independent_box.base_fragment_info(),
|
independent_box.base_fragment_info(),
|
||||||
independent_box.style().clone(),
|
independent_box.style().clone(),
|
||||||
|
@ -568,7 +568,7 @@ impl TaffyContainer {
|
||||||
last: None,
|
last: None,
|
||||||
})
|
})
|
||||||
.with_detailed_layout_info(child_detailed_layout_info),
|
.with_detailed_layout_info(child_detailed_layout_info),
|
||||||
);
|
));
|
||||||
|
|
||||||
child
|
child
|
||||||
.positioning_context
|
.positioning_context
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue