mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Implement 'visibility: collapse' on table parts (#32333)
https://drafts.csswg.org/css2/#dynamic-effects Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
add18db67e
commit
5d5ac4ec64
23 changed files with 64 additions and 100 deletions
|
@ -8,9 +8,10 @@ use app_units::{Au, MAX_AU};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use style::computed_values::border_collapse::T as BorderCollapse;
|
use style::computed_values::border_collapse::T as BorderCollapse;
|
||||||
|
use style::computed_values::box_sizing::T as BoxSizing;
|
||||||
|
use style::computed_values::empty_cells::T as EmptyCells;
|
||||||
|
use style::computed_values::visibility::T as Visibility;
|
||||||
use style::logical_geometry::WritingMode;
|
use style::logical_geometry::WritingMode;
|
||||||
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
|
||||||
use style::properties::longhands::empty_cells::computed_value::T as EmptyCells;
|
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{
|
use style::values::computed::{
|
||||||
CSSPixelLength, Length, LengthPercentage as ComputedLengthPercentage, Percentage,
|
CSSPixelLength, Length, LengthPercentage as ComputedLengthPercentage, Percentage,
|
||||||
|
@ -1480,6 +1481,27 @@ impl<'a> TableLayout<'a> {
|
||||||
|
|
||||||
let mut row_group_fragment_layout = None;
|
let mut row_group_fragment_layout = None;
|
||||||
for row_index in 0..self.table.size.height {
|
for row_index in 0..self.table.size.height {
|
||||||
|
// From <https://drafts.csswg.org/css-align-3/#baseline-export>
|
||||||
|
// > If any cells in the row participate in first baseline/last baseline alignment along
|
||||||
|
// > the inline axis, the first/last baseline set of the row is generated from their
|
||||||
|
// > shared alignment baseline and the row’s first available font, after alignment has
|
||||||
|
// > been performed. Otherwise, the first/last baseline set of the row is synthesized from
|
||||||
|
// > the lowest and highest content edges of the cells in the row. [CSS2]
|
||||||
|
//
|
||||||
|
// If any cell below has baseline alignment, these values will be overwritten,
|
||||||
|
// but they are initialized to the content edge of the first row.
|
||||||
|
if row_index == 0 {
|
||||||
|
let row_end = table_and_track_dimensions
|
||||||
|
.get_row_rect(0)
|
||||||
|
.max_block_position();
|
||||||
|
baselines.first = Some(row_end);
|
||||||
|
baselines.last = Some(row_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.is_row_collapsed(row_index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let table_row = &self.table.rows[row_index];
|
let table_row = &self.table.rows[row_index];
|
||||||
let mut row_fragment_layout =
|
let mut row_fragment_layout =
|
||||||
RowFragmentLayout::new(table_row, row_index, &table_and_track_dimensions);
|
RowFragmentLayout::new(table_row, row_index, &table_and_track_dimensions);
|
||||||
|
@ -1507,26 +1529,13 @@ impl<'a> TableLayout<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// From <https://drafts.csswg.org/css-align-3/#baseline-export>
|
|
||||||
// > If any cells in the row participate in first baseline/last baseline alignment along
|
|
||||||
// > the inline axis, the first/last baseline set of the row is generated from their
|
|
||||||
// > shared alignment baseline and the row’s first available font, after alignment has
|
|
||||||
// > been performed. Otherwise, the first/last baseline set of the row is synthesized from
|
|
||||||
// > the lowest and highest content edges of the cells in the row. [CSS2]
|
|
||||||
//
|
|
||||||
// If any cell below has baseline alignment, these values will be overwritten,
|
|
||||||
// but they are initialized to the content edge of the first row.
|
|
||||||
if row_index == 0 {
|
|
||||||
let row_end = table_and_track_dimensions
|
|
||||||
.get_row_rect(0)
|
|
||||||
.max_block_position();
|
|
||||||
baselines.first = Some(row_end);
|
|
||||||
baselines.last = Some(row_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
let column_indices = 0..self.table.size.width;
|
let column_indices = 0..self.table.size.width;
|
||||||
row_fragment_layout.fragments.reserve(self.table.size.width);
|
row_fragment_layout.fragments.reserve(self.table.size.width);
|
||||||
for column_index in column_indices {
|
for column_index in column_indices {
|
||||||
|
if self.is_column_collapsed(column_index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// The PositioningContext for cells is, in order or preference, the PositioningContext of the row,
|
// The PositioningContext for cells is, in order or preference, the PositioningContext of the row,
|
||||||
// the PositioningContext of the row group, or the PositioningContext of the table.
|
// the PositioningContext of the row group, or the PositioningContext of the table.
|
||||||
let row_group_positioning_context = row_group_fragment_layout
|
let row_group_positioning_context = row_group_fragment_layout
|
||||||
|
@ -1580,6 +1589,34 @@ impl<'a> TableLayout<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_row_collapsed(&self, row_index: usize) -> bool {
|
||||||
|
let Some(row) = &self.table.rows.get(row_index) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if row.style.get_inherited_box().visibility == Visibility::Collapse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let row_group = match row.group_index {
|
||||||
|
Some(group_index) => &self.table.row_groups[group_index],
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
row_group.style.get_inherited_box().visibility == Visibility::Collapse
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_column_collapsed(&self, column_index: usize) -> bool {
|
||||||
|
let Some(col) = &self.table.columns.get(column_index) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if col.style.get_inherited_box().visibility == Visibility::Collapse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let col_group = match col.group_index {
|
||||||
|
Some(group_index) => &self.table.column_groups[group_index],
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
col_group.style.get_inherited_box().visibility == Visibility::Collapse
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn do_final_cell_layout(
|
fn do_final_cell_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1913,6 +1950,10 @@ impl TableAndTrackDimensions {
|
||||||
border_spacing.inline
|
border_spacing.inline
|
||||||
};
|
};
|
||||||
for column_index in 0..table_layout.table.size.width {
|
for column_index in 0..table_layout.table.size.width {
|
||||||
|
if table_layout.is_column_collapsed(column_index) {
|
||||||
|
column_dimensions.push((column_offset, column_offset));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let column_size = table_layout.distributed_column_widths[column_index];
|
let column_size = table_layout.distributed_column_widths[column_index];
|
||||||
column_dimensions.push((column_offset, column_offset + column_size));
|
column_dimensions.push((column_offset, column_offset + column_size));
|
||||||
column_offset += column_size + border_spacing.inline;
|
column_offset += column_size + border_spacing.inline;
|
||||||
|
@ -1925,6 +1966,10 @@ impl TableAndTrackDimensions {
|
||||||
border_spacing.block
|
border_spacing.block
|
||||||
};
|
};
|
||||||
for row_index in 0..table_layout.table.size.height {
|
for row_index in 0..table_layout.table.size.height {
|
||||||
|
if table_layout.is_row_collapsed(row_index) {
|
||||||
|
row_dimensions.push((row_offset, row_offset));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let row_size = table_layout.row_sizes[row_index];
|
let row_size = table_layout.row_sizes[row_index];
|
||||||
row_dimensions.push((row_offset, row_offset + row_size));
|
row_dimensions.push((row_offset, row_offset + row_size));
|
||||||
row_offset += row_size + border_spacing.block;
|
row_offset += row_size + border_spacing.block;
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[row-visibility-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[row-visibility-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[visibility-collapse-border-spacing.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-col-001.html]
|
|
||||||
[col visibility:collapse changes table width]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-col-002.html]
|
|
||||||
[col visibility:collapse changes table width]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-col-003.html]
|
|
||||||
[col visibility:collapse changes table width]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-col-004-dynamic.html]
|
|
||||||
[col visibility:collapse changes table width]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-colspan-001.html]
|
|
||||||
[col visibility:collapse changes table width]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-colspan-002.html]
|
|
||||||
[col visibility:collapse changes table width]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-row-001.html]
|
|
||||||
[row visibility:collapse changes table height, unlike visibility:hidden]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-row-002-dynamic.html]
|
|
||||||
[row visibility:collapse changes table height, unlike visibility:hidden]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-row-003-dynamic.html]
|
|
||||||
[row visibility:collapse changes table height, unlike visibility:hidden]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +0,0 @@
|
||||||
[visibility-collapse-row-005.html]
|
|
||||||
[collapsed row should not contribute to overflow]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[collapsed section should not contribute to overflow]
|
|
||||||
expected: FAIL
|
|
|
@ -1,9 +0,0 @@
|
||||||
[visibility-collapse-row-group-001.html]
|
|
||||||
[row group visibility:collapse changes table height]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[the first row should be collapsed]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[the second row should be collapsed]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-row-group-002.html]
|
|
||||||
[row group visibility:collapse changes table height]
|
|
||||||
expected: FAIL
|
|
|
@ -1,6 +1,3 @@
|
||||||
[visibility-collapse-rowcol-001.html]
|
[visibility-collapse-rowcol-001.html]
|
||||||
[spanning col visibility:collapse changes table width]
|
[spanning col visibility:collapse changes table width]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[spanning row visibility:collapse changes height]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
[visibility-collapse-rowcol-002.html]
|
[visibility-collapse-rowcol-002.html]
|
||||||
[spanning row visibility:collapse doesn't change table width]
|
[spanning row visibility:collapse doesn't change table width]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[spanning row visibility:collapse doesn't change height in this case]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
[visibility-collapse-rowspan-002-border-separate.html]
|
[visibility-collapse-rowspan-002-border-separate.html]
|
||||||
[spanning cell shrinks to sum of remaining three rows' height]
|
[spanning cell shrinks to sum of remaining three rows' height]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[spanning row visibility:collapse makes row height 0]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
[visibility-collapse-rowspan-002.html]
|
[visibility-collapse-rowspan-002.html]
|
||||||
[spanning cell shrinks to sum of remaining three rows' height]
|
[spanning cell shrinks to sum of remaining three rows' height]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[spanning row visibility:collapse makes row height 0]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-rowspan-003-border-separate.html]
|
|
||||||
[collapsed row has zero height]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[visibility-collapse-rowspan-003.html]
|
|
||||||
[collapsed row has zero height]
|
|
||||||
expected: FAIL
|
|
|
@ -1,12 +0,0 @@
|
||||||
[visibility-collapse-rowspan-004-dynamic.html]
|
|
||||||
[spanning cell shrinks to sum of remaining three rows' height]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[(2nd collapse) spanning cell shrinks to sum of remaining three rows' height]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[third row visibility:collapse makes row height 0]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[(2nd collapse) third row visibility:collapse makes row height 0]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue