aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/display_list/mod.rs9
-rw-r--r--components/layout/display_list/stacking_context.rs2
-rw-r--r--components/layout/flexbox/layout.rs9
-rw-r--r--components/layout/flow/float.rs3
-rw-r--r--components/layout/flow/inline/line.rs3
-rw-r--r--components/layout/flow/inline/mod.rs3
-rw-r--r--components/layout/flow/mod.rs4
-rw-r--r--components/layout/flow/root.rs2
-rw-r--r--components/layout/fragment_tree/box_fragment.rs106
-rw-r--r--components/layout/fragment_tree/fragment.rs17
-rw-r--r--components/layout/fragment_tree/fragment_tree.rs21
-rw-r--r--components/layout/fragment_tree/positioning_fragment.rs2
-rw-r--r--components/layout/positioned.rs36
-rw-r--r--components/layout/style_ext.rs36
-rw-r--r--components/layout/table/layout.rs6
-rw-r--r--components/layout/taffy/layout.rs5
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(),