diff options
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/display_list/mod.rs | 9 | ||||
-rw-r--r-- | components/layout/display_list/stacking_context.rs | 2 | ||||
-rw-r--r-- | components/layout/flexbox/layout.rs | 9 | ||||
-rw-r--r-- | components/layout/flow/float.rs | 3 | ||||
-rw-r--r-- | components/layout/flow/inline/line.rs | 3 | ||||
-rw-r--r-- | components/layout/flow/inline/mod.rs | 3 | ||||
-rw-r--r-- | components/layout/flow/mod.rs | 4 | ||||
-rw-r--r-- | components/layout/flow/root.rs | 2 | ||||
-rw-r--r-- | components/layout/fragment_tree/box_fragment.rs | 106 | ||||
-rw-r--r-- | components/layout/fragment_tree/fragment.rs | 17 | ||||
-rw-r--r-- | components/layout/fragment_tree/fragment_tree.rs | 21 | ||||
-rw-r--r-- | components/layout/fragment_tree/positioning_fragment.rs | 2 | ||||
-rw-r--r-- | components/layout/positioned.rs | 36 | ||||
-rw-r--r-- | components/layout/style_ext.rs | 36 | ||||
-rw-r--r-- | components/layout/table/layout.rs | 6 | ||||
-rw-r--r-- | components/layout/taffy/layout.rs | 5 |
16 files changed, 202 insertions, 62 deletions
diff --git a/components/layout/display_list/mod.rs b/components/layout/display_list/mod.rs index 912c69366bd..3908da69ce1 100644 --- a/components/layout/display_list/mod.rs +++ b/components/layout/display_list/mod.rs @@ -39,7 +39,7 @@ use webrender_api::{ use wr::units::LayoutVector2D; use crate::context::{LayoutContext, ResolvedImage}; -use crate::display_list::conversions::ToWebRender; +pub use crate::display_list::conversions::ToWebRender; use crate::display_list::stacking_context::StackingContextSection; use crate::fragment_tree::{ BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag, @@ -711,7 +711,12 @@ impl<'a> BuilderForBoxFragment<'a> { fn build(&mut self, builder: &mut DisplayListBuilder, section: StackingContextSection) { if self.is_hit_test_for_scrollable_overflow { - self.build_hit_test(builder, self.fragment.scrollable_overflow().to_webrender()); + self.build_hit_test( + builder, + self.fragment + .reachable_scrollable_overflow_region() + .to_webrender(), + ); return; } diff --git a/components/layout/display_list/stacking_context.rs b/components/layout/display_list/stacking_context.rs index 9809e428d6e..b044b713260 100644 --- a/components/layout/display_list/stacking_context.rs +++ b/components/layout/display_list/stacking_context.rs @@ -1477,7 +1477,7 @@ impl BoxFragment { y: overflow.y.into(), }; - let content_rect = self.scrollable_overflow().to_webrender(); + let content_rect = self.reachable_scrollable_overflow_region().to_webrender(); let scroll_tree_node_id = display_list.define_scroll_frame( parent_scroll_node_id, diff --git a/components/layout/flexbox/layout.rs b/components/layout/flexbox/layout.rs index 77069236787..a5540123681 100644 --- a/components/layout/flexbox/layout.rs +++ b/components/layout/flexbox/layout.rs @@ -1774,7 +1774,9 @@ impl FlexItem<'_> { non_stretch_layout_result: Option<&mut FlexItemLayoutResult>, ) -> Option<FlexItemLayoutResult> { let containing_block = flex_context.containing_block; - let mut positioning_context = PositioningContext::new_for_style(self.box_.style()) + let independent_formatting_context = &self.box_.independent_formatting_context; + let mut positioning_context = independent_formatting_context + .new_positioning_context() .unwrap_or_else(|| { PositioningContext::new_for_subtree( flex_context @@ -1783,7 +1785,6 @@ impl FlexItem<'_> { ) }); - let independent_formatting_context = &self.box_.independent_formatting_context; let item_writing_mode = independent_formatting_context.style().writing_mode; let item_is_horizontal = item_writing_mode.is_horizontal(); let flex_axis = flex_context.config.flex_axis; @@ -2616,7 +2617,9 @@ impl FlexItemBox { cross_size_stretches_to_container_size: bool, intrinsic_sizing_mode: IntrinsicSizingMode, ) -> Au { - let mut positioning_context = PositioningContext::new_for_style(self.style()) + let mut positioning_context = self + .independent_formatting_context + .new_positioning_context() .unwrap_or_else(|| { PositioningContext::new_for_subtree( flex_context diff --git a/components/layout/flow/float.rs b/components/layout/flow/float.rs index 0570ce0d0f4..dbc50c07603 100644 --- a/components/layout/flow/float.rs +++ b/components/layout/flow/float.rs @@ -913,11 +913,10 @@ impl FloatBox { positioning_context: &mut PositioningContext, containing_block: &ContainingBlock, ) -> BoxFragment { - let style = self.contents.style().clone(); positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, - &style, + &self.contents.base, |positioning_context| { self.contents .layout_float_or_atomic_inline( diff --git a/components/layout/flow/inline/line.rs b/components/layout/flow/inline/line.rs index c42f32c9242..e65eaed2367 100644 --- a/components/layout/flow/inline/line.rs +++ b/components/layout/flow/inline/line.rs @@ -326,13 +326,12 @@ impl LineItemLayout<'_, '_> { let inline_box = self.layout.ifc.inline_boxes.get(identifier); let inline_box = &*(inline_box.borrow()); - let style = &inline_box.base.style; let space_above_baseline = inline_box_state.calculate_space_above_baseline(); let block_start_offset = self.calculate_inline_box_block_start(inline_box_state, space_above_baseline); let positioning_context_or_start_offset_in_parent = - match PositioningContext::new_for_style(style) { + match inline_box.base.new_positioning_context() { Some(positioning_context) => Either::Left(positioning_context), None => Either::Right(self.current_positioning_context_mut().len()), }; diff --git a/components/layout/flow/inline/mod.rs b/components/layout/flow/inline/mod.rs index dabb9773410..25fbaa324b1 100644 --- a/components/layout/flow/inline/mod.rs +++ b/components/layout/flow/inline/mod.rs @@ -2004,7 +2004,8 @@ impl IndependentFormattingContext { bidi_level: Level, ) { // We need to know the inline size of the atomic before deciding whether to do the line break. - let mut child_positioning_context = PositioningContext::new_for_style(self.style()) + let mut child_positioning_context = self + .new_positioning_context() .unwrap_or_else(|| PositioningContext::new_for_subtree(true)); let IndependentFloatOrAtomicLayoutResult { mut fragment, diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs index d983e8592c4..983282dc389 100644 --- a/components/layout/flow/mod.rs +++ b/components/layout/flow/mod.rs @@ -779,7 +779,7 @@ impl BlockLevelBox { ArcRefCell::new(positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, - &base.style, + base, |positioning_context| { layout_in_flow_non_replaced_block_level_same_formatting_context( layout_context, @@ -798,7 +798,7 @@ impl BlockLevelBox { positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, - independent.style(), + &independent.base, |positioning_context| { independent.layout_in_flow_block_level( layout_context, diff --git a/components/layout/flow/root.rs b/components/layout/flow/root.rs index 187726595f8..c6498eeed63 100644 --- a/components/layout/flow/root.rs +++ b/components/layout/flow/root.rs @@ -411,7 +411,7 @@ impl BoxTree { let scrollable_overflow = root_fragments .iter() .fold(PhysicalRect::zero(), |acc, child| { - let child_overflow = child.scrollable_overflow(); + let child_overflow = child.scrollable_overflow_for_parent(); // https://drafts.csswg.org/css-overflow/#scrolling-direction // We want to clip scrollable overflow on box-start and inline-start diff --git a/components/layout/fragment_tree/box_fragment.rs b/components/layout/fragment_tree/box_fragment.rs index e87826ec3ca..65ad1c4aa93 100644 --- a/components/layout/fragment_tree/box_fragment.rs +++ b/components/layout/fragment_tree/box_fragment.rs @@ -2,11 +2,12 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use app_units::Au; +use app_units::{Au, MAX_AU, MIN_AU}; use atomic_refcell::AtomicRefCell; use base::print_tree::PrintTree; use malloc_size_of_derive::MallocSizeOf; use servo_arc::Arc as ServoArc; +use servo_geometry::f32_rect_to_au_rect; use style::Zero; use style::computed_values::border_collapse::T as BorderCollapse; use style::computed_values::overflow_x::T as ComputedOverflow; @@ -16,6 +17,7 @@ use style::properties::ComputedValues; use style::values::specified::box_::DisplayOutside; use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment}; +use crate::display_list::ToWebRender; use crate::formatting_contexts::Baselines; use crate::geom::{ AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical, @@ -116,7 +118,7 @@ impl BoxFragment { ) -> BoxFragment { let scrollable_overflow_from_children = children.iter().fold(PhysicalRect::zero(), |acc, child| { - acc.union(&child.scrollable_overflow()) + acc.union(&child.scrollable_overflow_for_parent()) }); BoxFragment { @@ -267,30 +269,96 @@ impl BoxFragment { pub fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { let mut overflow = self.border_rect(); - if self.style.establishes_scroll_container(self.base.flags) { - return overflow; + if !self.style.establishes_scroll_container(self.base.flags) { + // https://www.w3.org/TR/css-overflow-3/#scrollable + // Only include the scrollable overflow of a child box if it has overflow: visible. + let scrollable_overflow = self.scrollable_overflow(); + let bottom_right = PhysicalPoint::new( + overflow.max_x().max(scrollable_overflow.max_x()), + overflow.max_y().max(scrollable_overflow.max_y()), + ); + + let overflow_style = self.style.effective_overflow(self.base.flags); + if overflow_style.y == ComputedOverflow::Visible { + overflow.origin.y = overflow.origin.y.min(scrollable_overflow.origin.y); + overflow.size.height = bottom_right.y - overflow.origin.y; + } + + if overflow_style.x == ComputedOverflow::Visible { + overflow.origin.x = overflow.origin.x.min(scrollable_overflow.origin.x); + overflow.size.width = bottom_right.x - overflow.origin.x; + } } - // https://www.w3.org/TR/css-overflow-3/#scrollable - // Only include the scrollable overflow of a child box if it has overflow: visible. - let scrollable_overflow = self.scrollable_overflow(); - let bottom_right = PhysicalPoint::new( - overflow.max_x().max(scrollable_overflow.max_x()), - overflow.max_y().max(scrollable_overflow.max_y()), - ); + // <https://drafts.csswg.org/css-overflow-3/#scrollable-overflow-region> + // > ...accounting for transforms by projecting each box onto the plane of + // > the element that establishes its 3D rendering context. [CSS3-TRANSFORMS] + // Both boxes and its scrollable overflow (if it is included) should be transformed accordingly. + // + // TODO(stevennovaryo): We are supposed to handle perspective transform and 3d context, but it is yet to happen. + if self + .style + .has_effective_transform_or_perspective(self.base.flags) + { + if let Some(transform) = + self.calculate_transform_matrix(&self.border_rect().to_untyped()) + { + if let Some(transformed_overflow_box) = + transform.outer_transformed_rect(&overflow.to_webrender().to_rect()) + { + overflow = + f32_rect_to_au_rect(transformed_overflow_box.to_untyped()).cast_unit(); + } + } + } + + overflow + } - let overflow_style = self.style.effective_overflow(self.base.flags); - if overflow_style.y == ComputedOverflow::Visible { - overflow.origin.y = overflow.origin.y.min(scrollable_overflow.origin.y); - overflow.size.height = bottom_right.y - overflow.origin.y; + /// <https://drafts.csswg.org/css-overflow/#unreachable-scrollable-overflow-region> + /// > area beyond the scroll origin in either axis is considered the unreachable scrollable overflow region + /// + /// Return the clipped the scrollable overflow based on its scroll origin, determined by overflow direction. + /// For an element, the clip rect is the padding rect and for viewport, it is the initial containing block. + pub fn clip_unreachable_scrollable_overflow_region( + &self, + scrollable_overflow: PhysicalRect<Au>, + clipping_rect: PhysicalRect<Au>, + ) -> PhysicalRect<Au> { + let scrolling_direction = self.style.overflow_direction(); + let mut scrollable_overflow_box = scrollable_overflow.to_box2d(); + let mut clipping_box = clipping_rect.to_box2d(); + + if scrolling_direction.rightward { + clipping_box.max.x = MAX_AU; + } else { + clipping_box.min.x = MIN_AU; } - if overflow_style.x == ComputedOverflow::Visible { - overflow.origin.x = overflow.origin.x.min(scrollable_overflow.origin.x); - overflow.size.width = bottom_right.x - overflow.origin.x; + if scrolling_direction.downward { + clipping_box.max.y = MAX_AU; + } else { + clipping_box.min.y = MIN_AU; } - overflow + scrollable_overflow_box = scrollable_overflow_box.intersection_unchecked(&clipping_box); + + match scrollable_overflow_box.is_negative() { + true => PhysicalRect::zero(), + false => scrollable_overflow_box.to_rect(), + } + } + + /// <https://drafts.csswg.org/css-overflow/#unreachable-scrollable-overflow-region> + /// > area beyond the scroll origin in either axis is considered the unreachable scrollable overflow region + /// + /// Return the clipped the scrollable overflow based on its scroll origin, determined by overflow direction. + /// This will coincides with the scrollport if the fragment is a scroll container. + pub fn reachable_scrollable_overflow_region(&self) -> PhysicalRect<Au> { + self.clip_unreachable_scrollable_overflow_region( + self.scrollable_overflow(), + self.padding_rect(), + ) } pub(crate) fn calculate_resolved_insets_if_positioned(&self) -> PhysicalSides<AuOrAuto> { diff --git a/components/layout/fragment_tree/fragment.rs b/components/layout/fragment_tree/fragment.rs index 7708b0893ee..1c5324fa1c4 100644 --- a/components/layout/fragment_tree/fragment.rs +++ b/components/layout/fragment_tree/fragment.rs @@ -170,17 +170,28 @@ impl Fragment { } } - pub fn scrolling_area(&self) -> PhysicalRect<Au> { + pub fn unclipped_scrolling_area(&self) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { let fragment = fragment.borrow(); fragment.offset_by_containing_block(&fragment.scrollable_overflow()) }, - _ => self.scrollable_overflow(), + _ => self.scrollable_overflow_for_parent(), + } + } + + pub fn scrolling_area(&self) -> PhysicalRect<Au> { + match self { + Fragment::Box(fragment) | Fragment::Float(fragment) => { + let fragment = fragment.borrow(); + fragment + .offset_by_containing_block(&fragment.reachable_scrollable_overflow_region()) + }, + _ => self.scrollable_overflow_for_parent(), } } - pub fn scrollable_overflow(&self) -> PhysicalRect<Au> { + pub fn scrollable_overflow_for_parent(&self) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { fragment.borrow().scrollable_overflow_for_parent() diff --git a/components/layout/fragment_tree/fragment_tree.rs b/components/layout/fragment_tree/fragment_tree.rs index 3a082c99389..1499a50dacf 100644 --- a/components/layout/fragment_tree/fragment_tree.rs +++ b/components/layout/fragment_tree/fragment_tree.rs @@ -138,11 +138,26 @@ impl FragmentTree { .find_map(|child| child.find(&info, 0, &mut process_func)) } + /// <https://drafts.csswg.org/cssom-view/#scrolling-area> + /// + /// Scrolling area for a viewport that is clipped according to overflow direction of root element. pub fn get_scrolling_area_for_viewport(&self) -> PhysicalRect<Au> { let mut scroll_area = self.initial_containing_block; - for fragment in self.root_fragments.iter() { - scroll_area = fragment.scrolling_area().union(&scroll_area); + if let Some(root_fragment) = self.root_fragments.first() { + for fragment in self.root_fragments.iter() { + scroll_area = fragment.unclipped_scrolling_area().union(&scroll_area); + } + match root_fragment { + Fragment::Box(fragment) | Fragment::Float(fragment) => fragment + .borrow() + .clip_unreachable_scrollable_overflow_region( + scroll_area, + self.initial_containing_block, + ), + _ => scroll_area, + } + } else { + scroll_area } - scroll_area } } diff --git a/components/layout/fragment_tree/positioning_fragment.rs b/components/layout/fragment_tree/positioning_fragment.rs index 1fe968eb484..0cf525a3479 100644 --- a/components/layout/fragment_tree/positioning_fragment.rs +++ b/components/layout/fragment_tree/positioning_fragment.rs @@ -56,7 +56,7 @@ impl PositioningFragment { let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| { acc.union( &child - .scrollable_overflow() + .scrollable_overflow_for_parent() .translate(content_origin.to_vector()), ) }); diff --git a/components/layout/positioned.rs b/components/layout/positioned.rs index 5f08e4e86c5..6bfe2af87ef 100644 --- a/components/layout/positioned.rs +++ b/components/layout/positioned.rs @@ -29,6 +29,7 @@ use crate::geom::{ PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, PhysicalVec, Size, Sizes, ToLogical, ToLogicalWithContainingBlock, }; +use crate::layout_box_base::LayoutBoxBase; use crate::sizing::ContentSizes; use crate::style_ext::{Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, DisplayInside}; use crate::{ @@ -103,6 +104,20 @@ impl AbsolutelyPositionedBox { } } +impl IndependentFormattingContext { + #[inline] + pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> { + self.base.new_positioning_context() + } +} + +impl LayoutBoxBase { + #[inline] + pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> { + PositioningContext::new_for_style(&self.style, &self.base_fragment_info.flags) + } +} + impl PositioningContext { pub(crate) fn new_for_containing_block_for_all_descendants() -> Self { Self { @@ -130,14 +145,10 @@ impl PositioningContext { self.for_nearest_positioned_ancestor.is_some() } - pub(crate) fn new_for_style(style: &ComputedValues) -> Option<Self> { - // NB: We never make PositioningContexts for replaced elements, which is why we always - // pass false here. - if style.establishes_containing_block_for_all_descendants(FragmentFlags::empty()) { + fn new_for_style(style: &ComputedValues, flags: &FragmentFlags) -> Option<Self> { + if style.establishes_containing_block_for_all_descendants(*flags) { Some(Self::new_for_containing_block_for_all_descendants()) - } else if style - .establishes_containing_block_for_absolute_descendants(FragmentFlags::empty()) - { + } else if style.establishes_containing_block_for_absolute_descendants(*flags) { Some(Self { for_nearest_positioned_ancestor: Some(Vec::new()), for_nearest_containing_block_for_all_descendants: Vec::new(), @@ -213,12 +224,12 @@ impl PositioningContext { &mut self, layout_context: &LayoutContext, containing_block: &ContainingBlock, - style: &ComputedValues, + base: &LayoutBoxBase, fragment_layout_fn: impl FnOnce(&mut Self) -> BoxFragment, ) -> BoxFragment { // Try to create a context, but if one isn't necessary, simply create the fragment // using the given closure and the current `PositioningContext`. - let mut new_context = match Self::new_for_style(style) { + let mut new_context = match base.new_positioning_context() { Some(new_context) => new_context, None => return fragment_layout_fn(self), }; @@ -229,9 +240,8 @@ impl PositioningContext { // If the new context has any hoisted boxes for the nearest containing block for // pass them up the tree. self.append(new_context); - - if style.clone_position() == Position::Relative { - new_fragment.content_rect.origin += relative_adjustement(style, containing_block) + if base.style.clone_position() == Position::Relative { + new_fragment.content_rect.origin += relative_adjustement(&base.style, containing_block) .to_physical_vector(containing_block.style.writing_mode) } @@ -586,7 +596,7 @@ impl HoistedAbsolutelyPositionedBox { .sizes })); - let mut positioning_context = PositioningContext::new_for_style(&style).unwrap(); + let mut positioning_context = context.new_positioning_context().unwrap(); let mut new_fragment = { let content_size: LogicalVec2<Au>; let fragments; diff --git a/components/layout/style_ext.rs b/components/layout/style_ext.rs index b157be914e0..023db6b07f1 100644 --- a/components/layout/style_ext.rs +++ b/components/layout/style_ext.rs @@ -12,7 +12,7 @@ use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode; use style::computed_values::position::T as ComputedPosition; use style::computed_values::transform_style::T as ComputedTransformStyle; use style::computed_values::unicode_bidi::T as UnicodeBidi; -use style::logical_geometry::{Direction as AxisDirection, WritingMode}; +use style::logical_geometry::{Direction as AxisDirection, PhysicalSide, WritingMode}; use style::properties::ComputedValues; use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; @@ -280,6 +280,16 @@ impl Default for BorderStyleColor { } } +/// <https://drafts.csswg.org/cssom-view/#overflow-directions> +/// > A scrolling box of a viewport or element has two overflow directions, +/// > which are the block-end and inline-end directions for that viewport or element. +pub(crate) struct OverflowDirection { + /// Whether block-end or inline-end direction is [PhysicalSide::Right]. + pub rightward: bool, + /// Whether block-end or inline-end direction is [PhysicalSide::Bottom]. + pub downward: bool, +} + pub(crate) trait ComputedValuesExt { fn physical_box_offsets(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>; fn box_offsets(&self, writing_mode: WritingMode) -> LogicalSides<LengthPercentageOrAuto<'_>>; @@ -354,6 +364,7 @@ pub(crate) trait ComputedValuesExt { writing_mode: WritingMode, ) -> bool; fn is_inline_box(&self, fragment_flags: FragmentFlags) -> bool; + fn overflow_direction(&self) -> OverflowDirection; } impl ComputedValuesExt for ComputedValues { @@ -834,9 +845,9 @@ impl ComputedValuesExt for ComputedValues { // > A value other than none for the filter property results in the creation of a containing // > block for absolute and fixed positioned descendants unless the element it applies to is // > a document root element in the current browsing context. - // FIXME(#35391): Need to check if this is the root element. - if !self.get_effects().filter.0.is_empty() || - will_change_bits.intersects(WillChangeBits::FIXPOS_CB_NON_SVG) + if !fragment_flags.contains(FragmentFlags::IS_ROOT_ELEMENT) && + (!self.get_effects().filter.0.is_empty() || + will_change_bits.intersects(WillChangeBits::FIXPOS_CB_NON_SVG)) { return true; } @@ -980,6 +991,23 @@ impl ComputedValuesExt for ComputedValues { }; has_percentage(box_offsets.block_start) || has_percentage(box_offsets.block_end) } + + // <https://drafts.csswg.org/cssom-view/#overflow-directions> + fn overflow_direction(&self) -> OverflowDirection { + let inline_end_direction = self.writing_mode.inline_end_physical_side(); + let block_end_direction = self.writing_mode.block_end_physical_side(); + + let rightward = inline_end_direction == PhysicalSide::Right || + block_end_direction == PhysicalSide::Right; + let downward = inline_end_direction == PhysicalSide::Bottom || + block_end_direction == PhysicalSide::Bottom; + + // TODO(stevennovaryo): We should consider the flex-container's CSS (e.g. flow-direction: column-reverse). + OverflowDirection { + rightward, + downward, + } + } } pub(crate) enum LayoutStyle<'a> { diff --git a/components/layout/table/layout.rs b/components/layout/table/layout.rs index 2261f7d165c..0cbe3e9ca76 100644 --- a/components/layout/table/layout.rs +++ b/components/layout/table/layout.rs @@ -1503,7 +1503,7 @@ impl<'a> TableLayout<'a> { layout_context: &LayoutContext, parent_positioning_context: &mut PositioningContext, ) -> BoxFragment { - let mut positioning_context = PositioningContext::new_for_style(caption.context.style()); + let mut positioning_context = caption.context.new_positioning_context(); let containing_block = &ContainingBlock { size: ContainingBlockSize { inline: self.table_width + self.pbm.padding_border_sums.inline, @@ -2325,7 +2325,7 @@ impl<'a> RowFragmentLayout<'a> { Self { row: table_row, rect, - positioning_context: PositioningContext::new_for_style(&table_row.base.style), + positioning_context: table_row.base.new_positioning_context(), containing_block, fragments: Vec::new(), } @@ -2410,7 +2410,7 @@ impl RowGroupFragmentLayout { let row_group = row_group.borrow(); ( dimensions.get_row_group_rect(&row_group), - PositioningContext::new_for_style(&row_group.base.style), + row_group.base.new_positioning_context(), ) }; Self { diff --git a/components/layout/taffy/layout.rs b/components/layout/taffy/layout.rs index a7581136bf2..3777c902053 100644 --- a/components/layout/taffy/layout.rs +++ b/components/layout/taffy/layout.rs @@ -251,8 +251,9 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> { style, }; let layout = { - let mut child_positioning_context = - PositioningContext::new_for_style(style).unwrap_or_else(|| { + let mut child_positioning_context = independent_context + .new_positioning_context() + .unwrap_or_else(|| { PositioningContext::new_for_subtree( self.positioning_context .collects_for_nearest_positioned_ancestor(), |