aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOriol Brufau <obrufau@igalia.com>2025-01-20 09:18:20 -0800
committerGitHub <noreply@github.com>2025-01-20 17:18:20 +0000
commit9b388da9cb9f6a898050464360ae4c8ce90f6693 (patch)
tree00023a4b0142f3f6ee97480a3c6b7b6c6476401c
parentb5d1d0369859504963d6f1ad90a25672dcc09400 (diff)
downloadservo-9b388da9cb9f6a898050464360ae4c8ce90f6693.tar.gz
servo-9b388da9cb9f6a898050464360ae4c8ce90f6693.zip
layout: Fix clientWidth & friends for tables (#35096)
`clientWidth` shouldn't include the borders of a box. The problem was that we pretend that table wrapper boxes have the border specified on the table element, even though this border actually applies to the table grid box instead of the table wrapper box. Therefore, `clientWidth` was wrong when it subtracted the borders. This patch fixes it. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
-rw-r--r--components/layout_2020/display_list/mod.rs2
-rw-r--r--components/layout_2020/fragment_tree/box_fragment.rs14
-rw-r--r--components/layout_2020/fragment_tree/fragment_tree.rs20
-rw-r--r--components/layout_2020/table/layout.rs8
-rw-r--r--components/layout_2020/table/mod.rs2
-rw-r--r--tests/wpt/meta/css/cssom-view/table-client-props.html.ini6
-rw-r--r--tests/wpt/meta/css/cssom-view/table-with-border-client-width-height.html.ini4
7 files changed, 30 insertions, 26 deletions
diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs
index aa6e22602f8..e54b46b4b55 100644
--- a/components/layout_2020/display_list/mod.rs
+++ b/components/layout_2020/display_list/mod.rs
@@ -908,7 +908,7 @@ impl<'a> BuilderForBoxFragment<'a> {
}
let style_color = match &self.fragment.detailed_layout_info {
- Some(SpecificLayoutInfo::TableOrTableCell(table_info)) => {
+ Some(SpecificLayoutInfo::TableGridOrTableCell(table_info)) => {
table_info.border_style_color.clone()
},
_ => BorderStyleColor::from_border(border),
diff --git a/components/layout_2020/fragment_tree/box_fragment.rs b/components/layout_2020/fragment_tree/box_fragment.rs
index a0d86f290ee..b3d921ee065 100644
--- a/components/layout_2020/fragment_tree/box_fragment.rs
+++ b/components/layout_2020/fragment_tree/box_fragment.rs
@@ -19,7 +19,7 @@ use crate::geom::{
AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical,
};
use crate::style_ext::ComputedValuesExt;
-use crate::table::SpecificTableOrTableCellInfo;
+use crate::table::SpecificTableGridOrTableCellInfo;
use crate::taffy::SpecificTaffyGridInfo;
/// Describes how a [`BoxFragment`] paints its background.
@@ -43,7 +43,8 @@ pub(crate) struct ExtraBackground {
#[derive(Clone, Debug)]
pub(crate) enum SpecificLayoutInfo {
Grid(Box<SpecificTaffyGridInfo>),
- TableOrTableCell(Box<SpecificTableOrTableCellInfo>),
+ TableGridOrTableCell(Box<SpecificTableGridOrTableCellInfo>),
+ TableWrapper,
}
pub(crate) struct BoxFragment {
@@ -346,4 +347,13 @@ impl BoxFragment {
self.style.get_box().display.is_inline_flow() &&
!self.base.flags.contains(FragmentFlags::IS_REPLACED)
}
+
+ /// Whether this is a table wrapper box.
+ /// <https://www.w3.org/TR/css-tables-3/#table-wrapper-box>
+ pub(crate) fn is_table_wrapper(&self) -> bool {
+ matches!(
+ self.detailed_layout_info,
+ Some(SpecificLayoutInfo::TableWrapper)
+ )
+ }
}
diff --git a/components/layout_2020/fragment_tree/fragment_tree.rs b/components/layout_2020/fragment_tree/fragment_tree.rs
index 545eef2df0f..7bc01f994f0 100644
--- a/components/layout_2020/fragment_tree/fragment_tree.rs
+++ b/components/layout_2020/fragment_tree/fragment_tree.rs
@@ -14,7 +14,7 @@ use webrender_traits::display_list::ScrollSensitivity;
use super::{ContainingBlockManager, Fragment, Tag};
use crate::display_list::StackingContext;
use crate::flow::CanvasBackground;
-use crate::geom::PhysicalRect;
+use crate::geom::{PhysicalPoint, PhysicalRect};
pub struct FragmentTree {
/// Fragments at the top-level of the tree.
@@ -142,13 +142,17 @@ impl FragmentTree {
if fragment.is_inline_box() {
return Some(Rect::zero());
}
-
- let border = fragment.style.get_border();
- let padding_rect = fragment.padding_rect();
- Rect::new(
- Point2D::new(border.border_left_width, border.border_top_width),
- Size2D::new(padding_rect.size.width, padding_rect.size.height),
- )
+ if fragment.is_table_wrapper() {
+ // For tables the border actually belongs to the table grid box,
+ // so we need to include it in the dimension of the table wrapper box.
+ let mut rect = fragment.border_rect();
+ rect.origin = PhysicalPoint::zero();
+ rect
+ } else {
+ let mut rect = fragment.padding_rect();
+ rect.origin = PhysicalPoint::new(fragment.border.left, fragment.border.top);
+ rect
+ }
},
Fragment::Positioning(fragment) => fragment.borrow().rect.cast_unit(),
_ => return None,
diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs
index 50a05e0b3dd..5d6c27d1796 100644
--- a/components/layout_2020/table/layout.rs
+++ b/components/layout_2020/table/layout.rs
@@ -41,7 +41,7 @@ use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesR
use crate::style_ext::{
BorderStyleColor, Clamp, ComputedValuesExt, LayoutStyle, PaddingBorderMargin,
};
-use crate::table::{SpecificTableOrTableCellInfo, TableSlotCoordinates};
+use crate::table::{SpecificTableGridOrTableCellInfo, TableSlotCoordinates};
use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode,
};
@@ -50,8 +50,8 @@ fn detailed_layout_info(
border_style_color: Option<LogicalSides<BorderStyleColor>>,
writing_mode: WritingMode,
) -> Option<SpecificLayoutInfo> {
- Some(SpecificLayoutInfo::TableOrTableCell(Box::new(
- SpecificTableOrTableCellInfo {
+ Some(SpecificLayoutInfo::TableGridOrTableCell(Box::new(
+ SpecificTableGridOrTableCellInfo {
border_style_color: border_style_color?.to_physical(writing_mode),
},
)))
@@ -1697,7 +1697,7 @@ impl<'a> TableLayout<'a> {
content_inline_size_for_table: None,
baselines: Baselines::default(),
depends_on_block_constraints,
- detailed_layout_info: None,
+ detailed_layout_info: Some(SpecificLayoutInfo::TableWrapper),
};
table_layout
diff --git a/components/layout_2020/table/mod.rs b/components/layout_2020/table/mod.rs
index 147c5285fc1..193c93547c9 100644
--- a/components/layout_2020/table/mod.rs
+++ b/components/layout_2020/table/mod.rs
@@ -318,7 +318,7 @@ pub struct TableCaption {
}
#[derive(Clone, Debug)]
-pub(crate) struct SpecificTableOrTableCellInfo {
+pub(crate) struct SpecificTableGridOrTableCellInfo {
/// For tables is in collapsed-borders mode, this is used as an override for the
/// style and color of the border of the table and table cells.
pub border_style_color: PhysicalSides<BorderStyleColor>,
diff --git a/tests/wpt/meta/css/cssom-view/table-client-props.html.ini b/tests/wpt/meta/css/cssom-view/table-client-props.html.ini
deleted file mode 100644
index e321c3dfe9e..00000000000
--- a/tests/wpt/meta/css/cssom-view/table-client-props.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[table-client-props.html]
- [Table with separated border]
- expected: FAIL
-
- [Table with collapsed border]
- expected: FAIL
diff --git a/tests/wpt/meta/css/cssom-view/table-with-border-client-width-height.html.ini b/tests/wpt/meta/css/cssom-view/table-with-border-client-width-height.html.ini
deleted file mode 100644
index 3127bb7a068..00000000000
--- a/tests/wpt/meta/css/cssom-view/table-with-border-client-width-height.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[table-with-border-client-width-height.html]
- [Table's clientWidth/Height and OffsetWidth/Height should be the same]
- expected: FAIL
-