mirror of
https://github.com/servo/servo.git
synced 2025-08-26 23:58:20 +01:00
layout: Use overflow: visible
if overflow
was propagated to viewport (#38598)
The `overflow-*` values of either the root element or the `<body>` get propagated to the viewport. However, we were missing this part: > The element from which the value is propagated must then have a used `overflow` value of `visible`. See https://drafts.csswg.org/css-overflow/#overflow-propagation Testing: - `css/cssom-view/scrolling-quirks-vs-nonquirks.html` - `css/css-overflow/overflow-body-propagation-007.html` - `css/css-overflow/overflow-body-propagation-008.html` - `css/css-overflow/overflow-body-propagation-009.html` - `css/css-overflow/scrollable-overflow-with-nested-elements-001.html` - `css/css-overflow/scrollable-overflow-with-nested-elements-002.html` - `css/css-overflow/scrollable-overflow-with-nested-elements-003.html` - `css/css-overflow/scrollable-overflow-with-nested-elements-004.html` - `css/css-overflow/scrollbar-gutter-scroll-into-view.html` Failures: - `css/css-overflow/overflow-body-propagation-010.html` Failing because of missing support for `contain: paint`. - `css/css-overflow/scrollable-overflow-with-nested-elements-005.html` Failing because of wrong `data-expected-height`, but correct `data-expected-scroll-height` which is core of this PR. `data-expected-height` can be dealt separately. Fixes: #38248 --------- Signed-off-by: Shubham Gupta <shubham13297@gmail.com> Signed-off-by: Oriol Brufau <obrufau@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
37088aa4c3
commit
d8ff9c7a08
22 changed files with 373 additions and 72 deletions
|
@ -27,6 +27,7 @@ use crate::flow::BlockLevelBox;
|
||||||
use crate::flow::inline::{InlineItem, SharedInlineStyles};
|
use crate::flow::inline::{InlineItem, SharedInlineStyles};
|
||||||
use crate::fragment_tree::Fragment;
|
use crate::fragment_tree::Fragment;
|
||||||
use crate::geom::PhysicalSize;
|
use crate::geom::PhysicalSize;
|
||||||
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::replaced::CanvasInfo;
|
use crate::replaced::CanvasInfo;
|
||||||
use crate::table::TableLevelBox;
|
use crate::table::TableLevelBox;
|
||||||
use crate::taffy::TaffyItemBox;
|
use crate::taffy::TaffyItemBox;
|
||||||
|
@ -73,7 +74,7 @@ impl InnerDOMLayoutData {
|
||||||
self.self_box
|
self.self_box
|
||||||
.borrow()
|
.borrow()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(LayoutBox::fragments)
|
.map(|layout_box| layout_box.with_base_flat(LayoutBoxBase::fragments))
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,17 +140,38 @@ impl LayoutBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
pub(crate) fn with_base_flat<T>(&self, callback: impl Fn(&LayoutBoxBase) -> Vec<T>) -> Vec<T> {
|
||||||
match self {
|
match self {
|
||||||
LayoutBox::DisplayContents(..) => vec![],
|
LayoutBox::DisplayContents(..) => vec![],
|
||||||
LayoutBox::BlockLevel(block_level_box) => block_level_box.borrow().fragments(),
|
LayoutBox::BlockLevel(block_level_box) => block_level_box.borrow().with_base(callback),
|
||||||
LayoutBox::InlineLevel(inline_items) => inline_items
|
LayoutBox::InlineLevel(inline_items) => inline_items
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|inline_item| inline_item.borrow().fragments())
|
.flat_map(|inline_item| inline_item.borrow().with_base(&callback))
|
||||||
.collect(),
|
.collect(),
|
||||||
LayoutBox::FlexLevel(flex_level_box) => flex_level_box.borrow().fragments(),
|
LayoutBox::FlexLevel(flex_level_box) => flex_level_box.borrow().with_base(callback),
|
||||||
LayoutBox::TaffyItemBox(taffy_item_box) => taffy_item_box.borrow().fragments(),
|
LayoutBox::TaffyItemBox(taffy_item_box) => taffy_item_box.borrow().with_base(callback),
|
||||||
LayoutBox::TableLevelBox(table_box) => table_box.fragments(),
|
LayoutBox::TableLevelBox(table_box) => table_box.with_base(callback),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_base_mut(&mut self, callback: impl Fn(&mut LayoutBoxBase)) {
|
||||||
|
match self {
|
||||||
|
LayoutBox::DisplayContents(..) => {},
|
||||||
|
LayoutBox::BlockLevel(block_level_box) => {
|
||||||
|
block_level_box.borrow_mut().with_base_mut(callback);
|
||||||
|
},
|
||||||
|
LayoutBox::InlineLevel(inline_items) => {
|
||||||
|
for inline_item in inline_items {
|
||||||
|
inline_item.borrow_mut().with_base_mut(&callback);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
LayoutBox::FlexLevel(flex_level_box) => {
|
||||||
|
flex_level_box.borrow_mut().with_base_mut(callback)
|
||||||
|
},
|
||||||
|
LayoutBox::TableLevelBox(table_level_box) => table_level_box.with_base_mut(callback),
|
||||||
|
LayoutBox::TaffyItemBox(taffy_item_box) => {
|
||||||
|
taffy_item_box.borrow_mut().with_base_mut(callback)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@ use crate::context::LayoutContext;
|
||||||
use crate::dom::LayoutBox;
|
use crate::dom::LayoutBox;
|
||||||
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::{BaseFragmentInfo, Fragment};
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
|
|
||||||
mod geom;
|
mod geom;
|
||||||
|
@ -190,14 +191,24 @@ impl FlexLevelBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
||||||
match self {
|
match self {
|
||||||
FlexLevelBox::FlexItem(flex_item_box) => flex_item_box
|
FlexLevelBox::FlexItem(flex_item_box) => {
|
||||||
.independent_formatting_context
|
callback(&flex_item_box.independent_formatting_context.base)
|
||||||
.base
|
},
|
||||||
.fragments(),
|
|
||||||
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
||||||
positioned_box.borrow().context.base.fragments()
|
callback(&positioned_box.borrow().context.base)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_base_mut<T>(&mut self, callback: impl Fn(&mut LayoutBoxBase) -> T) -> T {
|
||||||
|
match self {
|
||||||
|
FlexLevelBox::FlexItem(flex_item_box) => {
|
||||||
|
callback(&mut flex_item_box.independent_formatting_context.base)
|
||||||
|
},
|
||||||
|
FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
||||||
|
callback(&mut positioned_box.borrow_mut().context.base)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,7 @@ use crate::fragment_tree::{
|
||||||
PositioningFragment,
|
PositioningFragment,
|
||||||
};
|
};
|
||||||
use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
|
||||||
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||||
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
|
||||||
|
@ -273,20 +274,38 @@ impl InlineItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
||||||
match self {
|
match self {
|
||||||
InlineItem::StartInlineBox(inline_box) => inline_box.borrow().base.fragments(),
|
InlineItem::StartInlineBox(inline_box) => callback(&inline_box.borrow().base),
|
||||||
InlineItem::EndInlineBox | InlineItem::TextRun(..) => {
|
InlineItem::EndInlineBox | InlineItem::TextRun(..) => {
|
||||||
unreachable!("Should never have these kind of fragments attached to a DOM node")
|
unreachable!("Should never have these kind of fragments attached to a DOM node")
|
||||||
},
|
},
|
||||||
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
|
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
|
||||||
positioned_box.borrow().context.base.fragments()
|
callback(&positioned_box.borrow().context.base)
|
||||||
|
},
|
||||||
|
InlineItem::OutOfFlowFloatBox(float_box) => callback(&float_box.borrow().contents.base),
|
||||||
|
InlineItem::Atomic(independent_formatting_context, ..) => {
|
||||||
|
callback(&independent_formatting_context.borrow().base)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_base_mut(&mut self, callback: impl Fn(&mut LayoutBoxBase)) {
|
||||||
|
match self {
|
||||||
|
InlineItem::StartInlineBox(inline_box) => {
|
||||||
|
callback(&mut inline_box.borrow_mut().base);
|
||||||
|
},
|
||||||
|
InlineItem::EndInlineBox | InlineItem::TextRun(..) => {
|
||||||
|
unreachable!("Should never have these kind of fragments attached to a DOM node")
|
||||||
|
},
|
||||||
|
InlineItem::OutOfFlowAbsolutelyPositionedBox(positioned_box, ..) => {
|
||||||
|
callback(&mut positioned_box.borrow_mut().context.base)
|
||||||
},
|
},
|
||||||
InlineItem::OutOfFlowFloatBox(float_box) => {
|
InlineItem::OutOfFlowFloatBox(float_box) => {
|
||||||
float_box.borrow().contents.base.fragments()
|
callback(&mut float_box.borrow_mut().contents.base)
|
||||||
},
|
},
|
||||||
InlineItem::Atomic(independent_formatting_context, ..) => {
|
InlineItem::Atomic(independent_formatting_context, ..) => {
|
||||||
independent_formatting_context.borrow().base.fragments()
|
callback(&mut independent_formatting_context.borrow_mut().base)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,10 +139,6 @@ impl BlockLevelBox {
|
||||||
self.with_base(|base| base.clear_fragment_layout_cache());
|
self.with_base(|base| base.clear_fragment_layout_cache());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
|
||||||
self.with_base(LayoutBoxBase::fragments)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
||||||
match self {
|
match self {
|
||||||
BlockLevelBox::Independent(independent_formatting_context) => {
|
BlockLevelBox::Independent(independent_formatting_context) => {
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::flow::float::FloatBox;
|
||||||
use crate::flow::inline::InlineItem;
|
use crate::flow::inline::InlineItem;
|
||||||
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::FragmentTree;
|
use crate::fragment_tree::{FragmentFlags, FragmentTree};
|
||||||
use crate::geom::{LogicalVec2, PhysicalSize};
|
use crate::geom::{LogicalVec2, PhysicalSize};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::replaced::ReplacedContents;
|
use crate::replaced::ReplacedContents;
|
||||||
|
@ -48,10 +48,6 @@ impl BoxTree {
|
||||||
#[servo_tracing::instrument(name = "Box Tree Construction", skip_all)]
|
#[servo_tracing::instrument(name = "Box Tree Construction", skip_all)]
|
||||||
pub(crate) fn construct(context: &LayoutContext, root_element: ServoLayoutNode<'_>) -> Self {
|
pub(crate) fn construct(context: &LayoutContext, root_element: ServoLayoutNode<'_>) -> Self {
|
||||||
let root_element = root_element.to_threadsafe();
|
let root_element = root_element.to_threadsafe();
|
||||||
let boxes = construct_for_root_element(context, root_element);
|
|
||||||
|
|
||||||
// Zero box for `:root { display: none }`, one for the root element otherwise.
|
|
||||||
assert!(boxes.len() <= 1);
|
|
||||||
|
|
||||||
// From https://www.w3.org/TR/css-overflow-3/#overflow-propagation:
|
// From https://www.w3.org/TR/css-overflow-3/#overflow-propagation:
|
||||||
// > UAs must apply the overflow-* values set on the root element to the viewport when the
|
// > UAs must apply the overflow-* values set on the root element to the viewport when the
|
||||||
|
@ -65,6 +61,7 @@ impl BoxTree {
|
||||||
|
|
||||||
let mut viewport_overflow_x = root_style.clone_overflow_x();
|
let mut viewport_overflow_x = root_style.clone_overflow_x();
|
||||||
let mut viewport_overflow_y = root_style.clone_overflow_y();
|
let mut viewport_overflow_y = root_style.clone_overflow_y();
|
||||||
|
let mut element_propagating_overflow = root_element;
|
||||||
if viewport_overflow_x == Overflow::Visible &&
|
if viewport_overflow_x == Overflow::Visible &&
|
||||||
viewport_overflow_y == Overflow::Visible &&
|
viewport_overflow_y == Overflow::Visible &&
|
||||||
!root_style.get_box().display.is_none()
|
!root_style.get_box().display.is_none()
|
||||||
|
@ -81,12 +78,28 @@ impl BoxTree {
|
||||||
if !style.get_box().display.is_none() {
|
if !style.get_box().display.is_none() {
|
||||||
viewport_overflow_x = style.clone_overflow_x();
|
viewport_overflow_x = style.clone_overflow_x();
|
||||||
viewport_overflow_y = style.clone_overflow_y();
|
viewport_overflow_y = style.clone_overflow_y();
|
||||||
|
element_propagating_overflow = child;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let boxes = construct_for_root_element(context, root_element);
|
||||||
|
|
||||||
|
// Zero box for `:root { display: none }`, one for the root element otherwise.
|
||||||
|
assert!(boxes.len() <= 1);
|
||||||
|
|
||||||
|
if let Some(layout_data) = element_propagating_overflow.inner_layout_data() {
|
||||||
|
if let Some(ref mut layout_box) = *layout_data.self_box.borrow_mut() {
|
||||||
|
layout_box.with_base_mut(|base| {
|
||||||
|
base.base_fragment_info
|
||||||
|
.flags
|
||||||
|
.insert(FragmentFlags::PROPAGATED_OVERFLOW_TO_VIEWPORT)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let contents = BlockContainer::BlockLevelBoxes(boxes);
|
let contents = BlockContainer::BlockLevelBoxes(boxes);
|
||||||
let contains_floats = contents.contains_floats();
|
let contains_floats = contents.contains_floats();
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -176,6 +176,9 @@ bitflags! {
|
||||||
const SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM = 1 << 8;
|
const SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM = 1 << 8;
|
||||||
/// Whether or not the node that created this fragment is the root element.
|
/// Whether or not the node that created this fragment is the root element.
|
||||||
const IS_ROOT_ELEMENT = 1 << 9;
|
const IS_ROOT_ELEMENT = 1 << 9;
|
||||||
|
/// If element has propagated the overflow value to viewport.
|
||||||
|
const PROPAGATED_OVERFLOW_TO_VIEWPORT = 1 << 10;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -598,6 +598,15 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
let mut overflow_x = style_box.overflow_x;
|
let mut overflow_x = style_box.overflow_x;
|
||||||
let mut overflow_y = style_box.overflow_y;
|
let mut overflow_y = style_box.overflow_y;
|
||||||
|
|
||||||
|
// https://www.w3.org/TR/css-overflow-3/#overflow-propagation
|
||||||
|
// The element from which the value is propagated must then have a used overflow value of visible.
|
||||||
|
if fragment_flags.contains(FragmentFlags::PROPAGATED_OVERFLOW_TO_VIEWPORT) {
|
||||||
|
return AxesOverflow {
|
||||||
|
x: Overflow::Visible,
|
||||||
|
y: Overflow::Visible,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// From <https://www.w3.org/TR/css-overflow-4/#overflow-control>:
|
// From <https://www.w3.org/TR/css-overflow-4/#overflow-control>:
|
||||||
// "On replaced elements, the used values of all computed values other than visible is clip."
|
// "On replaced elements, the used values of all computed values other than visible is clip."
|
||||||
if fragment_flags.contains(FragmentFlags::IS_REPLACED) {
|
if fragment_flags.contains(FragmentFlags::IS_REPLACED) {
|
||||||
|
|
|
@ -88,7 +88,7 @@ use crate::SharedStyle;
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
use crate::flow::BlockContainer;
|
use crate::flow::BlockContainer;
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::{BaseFragmentInfo, Fragment};
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
use crate::geom::PhysicalVec;
|
use crate::geom::PhysicalVec;
|
||||||
use crate::layout_box_base::LayoutBoxBase;
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::style_ext::BorderStyleColor;
|
use crate::style_ext::BorderStyleColor;
|
||||||
|
@ -412,12 +412,21 @@ impl TableLevelBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
||||||
match self {
|
match self {
|
||||||
TableLevelBox::Caption(caption) => caption.borrow().context.base.fragments(),
|
TableLevelBox::Caption(caption) => callback(&caption.borrow().context.base),
|
||||||
TableLevelBox::Cell(cell) => cell.borrow().base.fragments(),
|
TableLevelBox::Cell(cell) => callback(&cell.borrow().base),
|
||||||
TableLevelBox::TrackGroup(track_group) => track_group.borrow().base.fragments(),
|
TableLevelBox::TrackGroup(track_group) => callback(&track_group.borrow().base),
|
||||||
TableLevelBox::Track(track) => track.borrow().base.fragments(),
|
TableLevelBox::Track(track) => callback(&track.borrow().base),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_base_mut<T>(&mut self, callback: impl Fn(&mut LayoutBoxBase) -> T) -> T {
|
||||||
|
match self {
|
||||||
|
TableLevelBox::Caption(caption) => callback(&mut caption.borrow_mut().context.base),
|
||||||
|
TableLevelBox::Cell(cell) => callback(&mut cell.borrow_mut().base),
|
||||||
|
TableLevelBox::TrackGroup(track_group) => callback(&mut track_group.borrow_mut().base),
|
||||||
|
TableLevelBox::Track(track) => callback(&mut track.borrow_mut().base),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ use crate::dom::LayoutBox;
|
||||||
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
|
||||||
use crate::formatting_contexts::IndependentFormattingContext;
|
use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::fragment_tree::Fragment;
|
use crate::fragment_tree::Fragment;
|
||||||
|
use crate::layout_box_base::LayoutBoxBase;
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
|
|
||||||
#[derive(Debug, MallocSizeOf)]
|
#[derive(Debug, MallocSizeOf)]
|
||||||
|
@ -146,13 +147,24 @@ impl TaffyItemBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn fragments(&self) -> Vec<Fragment> {
|
pub(crate) fn with_base<T>(&self, callback: impl Fn(&LayoutBoxBase) -> T) -> T {
|
||||||
match self.taffy_level_box {
|
match self.taffy_level_box {
|
||||||
TaffyItemBoxInner::InFlowBox(ref independent_formatting_context) => {
|
TaffyItemBoxInner::InFlowBox(ref independent_formatting_context) => {
|
||||||
independent_formatting_context.base.fragments()
|
callback(&independent_formatting_context.base)
|
||||||
},
|
},
|
||||||
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(ref positioned_box) => {
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(ref positioned_box) => {
|
||||||
positioned_box.borrow().context.base.fragments()
|
callback(&positioned_box.borrow().context.base)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_base_mut<T>(&mut self, callback: impl Fn(&mut LayoutBoxBase) -> T) -> T {
|
||||||
|
match &mut self.taffy_level_box {
|
||||||
|
TaffyItemBoxInner::InFlowBox(independent_formatting_context) => {
|
||||||
|
callback(&mut independent_formatting_context.base)
|
||||||
|
},
|
||||||
|
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(positioned_box) => {
|
||||||
|
callback(&mut positioned_box.borrow_mut().context.base)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
tests/wpt/meta/MANIFEST.json
vendored
35
tests/wpt/meta/MANIFEST.json
vendored
|
@ -607767,6 +607767,41 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"scrollable-overflow-with-nested-elements-001.html": [
|
||||||
|
"9bf0d16841996fbe9643b44868bc81ca190fe30b",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"scrollable-overflow-with-nested-elements-002.html": [
|
||||||
|
"10ec866995ebf5cb55425599dbd11083a29f543f",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"scrollable-overflow-with-nested-elements-003.html": [
|
||||||
|
"563cadb7faeb66ff0eb8611e61c3681fd576e9b6",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"scrollable-overflow-with-nested-elements-004.html": [
|
||||||
|
"07866f341b9b2ae74e3566b8883adc735cefe702",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"scrollable-overflow-with-nested-elements-005.html": [
|
||||||
|
"95e3e53e09fa9aaf8b54435dcb3b9a8236031e0d",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"scrollable-overflow-zero-one-axis.html": [
|
"scrollable-overflow-zero-one-axis.html": [
|
||||||
"1986a8d48b98fde17fda826c5bbf9d75d870f45e",
|
"1986a8d48b98fde17fda826c5bbf9d75d870f45e",
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-body-propagation-007.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-body-propagation-008.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[overflow-body-propagation-009.html]
|
|
||||||
expected: FAIL
|
|
2
tests/wpt/meta/css/css-overflow/overflow-body-propagation-010.html.ini
vendored
Normal file
2
tests/wpt/meta/css/css-overflow/overflow-body-propagation-010.html.ini
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[overflow-body-propagation-010.html]
|
||||||
|
expected: FAIL
|
3
tests/wpt/meta/css/css-overflow/scrollable-overflow-with-nested-elements-005.html.ini
vendored
Normal file
3
tests/wpt/meta/css/css-overflow/scrollable-overflow-with-nested-elements-005.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[scrollable-overflow-with-nested-elements-005.html]
|
||||||
|
[html 1]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[scrollbar-gutter-scroll-into-view.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,27 +0,0 @@
|
||||||
[scrolling-quirks-vs-nonquirks.html]
|
|
||||||
[scrollWidth/scrollHeight on the root element in non-quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scrollWidth/scrollHeight on the root element in quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scrollWidth/scrollHeight on the HTML body element in quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scroll() on the root element in non-quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scrollBy() on the root element in non-quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scrollLeft/scrollTop on the root element in non-quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scroll() on the HTML body element in quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scrollBy() on the HTML body element in quirks mode]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[scrollLeft/scrollTop on the HTML body element in quirks mode]
|
|
||||||
expected: FAIL
|
|
37
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-001.html
vendored
Normal file
37
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-001.html
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Overflow: Scrollable Overflow Transform Rotate Nested Element</title>
|
||||||
|
<link rel="author" title="Shubham Gupta" href="mailto:shubham13297@gmail.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
|
||||||
|
<meta name="assert" content="Checks the scrollable overflow with overflow property and some nested element">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
<style>
|
||||||
|
.container-2 {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
overflow: auto;
|
||||||
|
background: silver;
|
||||||
|
border: solid thick;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.element {
|
||||||
|
width: 1000px;
|
||||||
|
height: 5000px;
|
||||||
|
background: lime;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.container')">
|
||||||
|
<div class="container" data-expected-scroll-height="110" data-expected-height="110"
|
||||||
|
data-expected-client-height="110">
|
||||||
|
<div class="container-2" data-expected-scroll-height="5000" data-expected-scroll-width="1000"
|
||||||
|
data-expected-client-width="100" data-expected-client-height="100"
|
||||||
|
data-expected-bounding-client-rect-width="110" data-expected-bounding-client-rect-height="110"
|
||||||
|
data-expected-height="110" data-expected-width="110">
|
||||||
|
<div class="element">hello</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
50
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-002.html
vendored
Normal file
50
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-002.html
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Overflow: Scrollable Overflow Transform Rotate Nested Element</title>
|
||||||
|
<link rel="author" title="Shubham Gupta" href="mailto:shubham13297@gmail.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
|
||||||
|
<meta name="assert" content="Checks the scrollable overflow of parent with overflow auto and some nested element">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: silver;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list .item {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: lime;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
position: relative;
|
||||||
|
background: grey;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body onload="checkLayout('.container')">
|
||||||
|
<div class="container" style="overflow-x: hidden;" data-expected-scroll-height="1010" data-expected-height="100" data-expected-width="100">
|
||||||
|
<div class="list" data-expected-scroll-height="1010"
|
||||||
|
data-expected-bounding-client-rect-height="0" data-expected-bounding-client-rect-width="100"
|
||||||
|
data-expected-height="0" data-expected-width="100">
|
||||||
|
<p class="item" style="top:0px;"></p>
|
||||||
|
<p class="item" style="top:1000px;"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container" data-expected-scroll-height="1010" data-expected-height="100" data-expected-width="100">
|
||||||
|
<div class="list" data-expected-scroll-height="1010"
|
||||||
|
data-expected-bounding-client-rect-height="0" data-expected-bounding-client-rect-width="100"
|
||||||
|
data-expected-height="0" data-expected-width="100">
|
||||||
|
<p class="item" style="top:0px;"></p>
|
||||||
|
<p class="item" style="top:1000px;"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
34
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-003.html
vendored
Normal file
34
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-003.html
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Overflow: Scrollable Overflow Transform Rotate Nested Element</title>
|
||||||
|
<link rel="author" title="Shubham Gupta" href="mailto:shubham13297@gmail.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
|
||||||
|
<meta name="assert" content="Checks the scrollable overflow with overflow property and some nested element">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list .item {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: lime;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
position: relative;
|
||||||
|
background: grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body onload="checkLayout('body')" data-expected-scroll-height="1010" data-expected-height="0" data-expected-client-height="0">
|
||||||
|
<div class="list" data-expected-scroll-height="1010" data-expected-height="0">
|
||||||
|
<p class="item" style="top:0px;"></p>
|
||||||
|
<p class="item" style="top:1000px;"></p>
|
||||||
|
</div>
|
||||||
|
</body>
|
42
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-004.html
vendored
Normal file
42
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-004.html
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Overflow: Scrollable Overflow Transform Rotate Nested Element</title>
|
||||||
|
<link rel="author" title="Shubham Gupta" href="mailto:shubham13297@gmail.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
|
||||||
|
<meta name="assert" content="Checks the scrollable overflow with overflow property and some nested element">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background: silver;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list .item {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: lime;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
position: relative;
|
||||||
|
background: grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<body onload="checkLayout('body')" data-expected-scroll-height="100" data-expected-height="100">
|
||||||
|
<div class="container" data-expected-scroll-height="1010"
|
||||||
|
data-expected-height="100" data-expected-width="100"
|
||||||
|
data-expected-client-height="100" data-expected-client-width="100">
|
||||||
|
<div class="list" data-expected-scroll-height="1010" data-expected-height="0">
|
||||||
|
<p class="item" style="top:0px;"></p>
|
||||||
|
<p class="item" style="top:1000px;"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
39
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-005.html
vendored
Normal file
39
tests/wpt/tests/css/css-overflow/scrollable-overflow-with-nested-elements-005.html
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html data-expected-scroll-height="1018" data-expected-height="8">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Overflow: Scrollable Overflow Transform Rotate Nested Element</title>
|
||||||
|
<link rel="author" title="Shubham Gupta" href="mailto:shubham13297@gmail.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#scrollable" />
|
||||||
|
<meta name="assert" content="Checks the scrollable overflow with overflow property and some nested element">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/check-layout-th.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list .item {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: lime;
|
||||||
|
position: absolute;
|
||||||
|
margin: 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
position: relative;
|
||||||
|
background: grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="checkLayout('html')" data-expected-scroll-height="1010" data-expected-height="0" data-expected-client-height="0">
|
||||||
|
<div class="list" data-expected-scroll-height="1010" data-expected-height="0" data-expected-client-height="0">
|
||||||
|
<p class="item" style="top:0px;"></p>
|
||||||
|
<p class="item" style="top:1000px;"></p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue