mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Hide collapsed borders crossed by spanning cells (#35129)
For example, a cell with `rowspan="2"` can cross a collapsed border that was set on the rows. Now the slice of this row border that is crossed by the cell will be hidden. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
aa54a0b1a6
commit
5e5379d3bf
7 changed files with 290 additions and 21 deletions
|
@ -240,6 +240,10 @@ impl BorderStyleColor {
|
|||
Self::new(border.border_left_style, border.border_left_color.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn hidden() -> Self {
|
||||
Self::new(BorderStyle::Hidden, Color::TRANSPARENT_BLACK)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BorderStyleColor {
|
||||
|
|
|
@ -149,6 +149,11 @@ impl CollapsedBorder {
|
|||
collapsed_border.max_assign(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn hide(&mut self) {
|
||||
self.style_color = BorderStyleColor::hidden();
|
||||
self.width = Au::zero();
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/css-tables/#border-specificity>
|
||||
|
@ -185,6 +190,8 @@ impl PartialOrd for CollapsedBorder {
|
|||
|
||||
impl Eq for CollapsedBorder {}
|
||||
|
||||
type CollapsedBorders = LogicalVec2<Vec<CollapsedBorderLine>>;
|
||||
|
||||
/// A helper struct that performs the layout of the box tree version
|
||||
/// of a table into the fragment tree version. This implements
|
||||
/// <https://drafts.csswg.org/css-tables/#table-layout-algorithm>
|
||||
|
@ -208,7 +215,7 @@ pub(crate) struct TableLayout<'a> {
|
|||
cells_laid_out: Vec<Vec<Option<CellLayout>>>,
|
||||
basis_for_cell_padding_percentage: Au,
|
||||
/// Information about collapsed borders.
|
||||
collapsed_borders: Option<LogicalVec2<Vec<CollapsedBorderLine>>>,
|
||||
collapsed_borders: Option<CollapsedBorders>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -2110,22 +2117,38 @@ impl<'a> TableLayout<'a> {
|
|||
],
|
||||
};
|
||||
|
||||
let mut apply_border =
|
||||
|layout_style: &LayoutStyle, block: &Range<usize>, inline: &Range<usize>| {
|
||||
let border = CollapsedBorder::from_layout_style(layout_style, writing_mode);
|
||||
border
|
||||
.block_start
|
||||
.max_assign_to_slice(&mut collapsed_borders.block[block.start][inline.clone()]);
|
||||
border
|
||||
.block_end
|
||||
.max_assign_to_slice(&mut collapsed_borders.block[block.end][inline.clone()]);
|
||||
border.inline_start.max_assign_to_slice(
|
||||
&mut collapsed_borders.inline[inline.start][block.clone()],
|
||||
);
|
||||
border
|
||||
.inline_end
|
||||
.max_assign_to_slice(&mut collapsed_borders.inline[inline.end][block.clone()]);
|
||||
};
|
||||
let apply_border = |collapsed_borders: &mut CollapsedBorders,
|
||||
layout_style: &LayoutStyle,
|
||||
block: &Range<usize>,
|
||||
inline: &Range<usize>| {
|
||||
let border = CollapsedBorder::from_layout_style(layout_style, writing_mode);
|
||||
border
|
||||
.block_start
|
||||
.max_assign_to_slice(&mut collapsed_borders.block[block.start][inline.clone()]);
|
||||
border
|
||||
.block_end
|
||||
.max_assign_to_slice(&mut collapsed_borders.block[block.end][inline.clone()]);
|
||||
border
|
||||
.inline_start
|
||||
.max_assign_to_slice(&mut collapsed_borders.inline[inline.start][block.clone()]);
|
||||
border
|
||||
.inline_end
|
||||
.max_assign_to_slice(&mut collapsed_borders.inline[inline.end][block.clone()]);
|
||||
};
|
||||
let hide_inner_borders = |collapsed_borders: &mut CollapsedBorders,
|
||||
block: &Range<usize>,
|
||||
inline: &Range<usize>| {
|
||||
for x in inline.clone() {
|
||||
for y in block.clone() {
|
||||
if x != inline.start {
|
||||
collapsed_borders.inline[x][y].hide();
|
||||
}
|
||||
if y != block.start {
|
||||
collapsed_borders.block[y][x].hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let all_rows = 0..self.table.size.height;
|
||||
let all_columns = 0..self.table.size.width;
|
||||
for row_index in all_rows.clone() {
|
||||
|
@ -2134,16 +2157,20 @@ impl<'a> TableLayout<'a> {
|
|||
TableSlot::Cell(ref cell) => cell,
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let block_range = row_index..row_index + cell.rowspan;
|
||||
let inline_range = column_index..column_index + cell.colspan;
|
||||
hide_inner_borders(&mut collapsed_borders, &block_range, &inline_range);
|
||||
apply_border(
|
||||
&mut collapsed_borders,
|
||||
&cell.layout_style(),
|
||||
&(row_index..row_index + cell.rowspan),
|
||||
&(column_index..column_index + cell.colspan),
|
||||
&block_range,
|
||||
&inline_range,
|
||||
);
|
||||
}
|
||||
}
|
||||
for (row_index, row) in self.table.rows.iter().enumerate() {
|
||||
apply_border(
|
||||
&mut collapsed_borders,
|
||||
&row.layout_style(),
|
||||
&(row_index..row_index + 1),
|
||||
&all_columns,
|
||||
|
@ -2151,6 +2178,7 @@ impl<'a> TableLayout<'a> {
|
|||
}
|
||||
for row_group in &self.table.row_groups {
|
||||
apply_border(
|
||||
&mut collapsed_borders,
|
||||
&row_group.layout_style(),
|
||||
&row_group.track_range,
|
||||
&all_columns,
|
||||
|
@ -2158,6 +2186,7 @@ impl<'a> TableLayout<'a> {
|
|||
}
|
||||
for (column_index, column) in self.table.columns.iter().enumerate() {
|
||||
apply_border(
|
||||
&mut collapsed_borders,
|
||||
&column.layout_style(),
|
||||
&all_rows,
|
||||
&(column_index..column_index + 1),
|
||||
|
@ -2165,12 +2194,18 @@ impl<'a> TableLayout<'a> {
|
|||
}
|
||||
for column_group in &self.table.column_groups {
|
||||
apply_border(
|
||||
&mut collapsed_borders,
|
||||
&column_group.layout_style(),
|
||||
&all_rows,
|
||||
&column_group.track_range,
|
||||
);
|
||||
}
|
||||
apply_border(&self.table.layout_style_for_grid(), &all_rows, &all_columns);
|
||||
apply_border(
|
||||
&mut collapsed_borders,
|
||||
&self.table.layout_style_for_grid(),
|
||||
&all_rows,
|
||||
&all_columns,
|
||||
);
|
||||
|
||||
self.collapsed_borders = Some(collapsed_borders);
|
||||
}
|
||||
|
|
52
tests/wpt/meta/MANIFEST.json
vendored
52
tests/wpt/meta/MANIFEST.json
vendored
|
@ -247576,6 +247576,58 @@
|
|||
]
|
||||
],
|
||||
"tentative": {
|
||||
"border-collapse-spanning-cells-001.html": [
|
||||
"47d5c634f8396d674f56a1bd046462201d5ac48a",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/reference/ref-filled-green-200px-square.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"border-collapse-spanning-cells-002.html": [
|
||||
"83543b0708bfbcae732d7883bd28f46fe856fa7b",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/reference/ref-filled-green-200px-square.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"border-collapse-spanning-cells-003.html": [
|
||||
"9d28d4c730e79e6e858137483eb25d4d4bcde880",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/reference/ref-filled-green-200px-square.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"border-collapse-spanning-cells-004.html": [
|
||||
"1eb77891053aba7ce65afd3f4965a3ab1d7d45e3",
|
||||
[
|
||||
null,
|
||||
[
|
||||
[
|
||||
"/css/reference/ref-filled-green-200px-square.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"padding-percentage.html": [
|
||||
"67f8009de365a32275232b5c5b008072a0c8fc17",
|
||||
[
|
||||
|
|
44
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-001.html
vendored
Normal file
44
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-001.html
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test (Tables): spanning cells crossing collapsed track borders</title>
|
||||
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-tables/#border-collapsing">
|
||||
<link rel="help" href="https://github.com/servo/servo/issues/35123">
|
||||
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||
<meta name="assert" content="
|
||||
The cells with colspan cross columns with red borders.
|
||||
These red borders shouldn't be visible.
|
||||
">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
|
||||
|
||||
<style>
|
||||
table { border-collapse: collapse; font: 20px/1 Ahem; color: transparent; background: green; }
|
||||
table { border: 30px solid green; }
|
||||
tr, col { border: 20px solid red }
|
||||
td { padding: 0; border: 20px solid green; }
|
||||
td[rowspan], td[colspan] { border: none }
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<table>
|
||||
<col></col> <col></col> <col></col> <col></col>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">X X X X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">X X X X</td>
|
||||
</tr>
|
||||
</table>
|
44
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-002.html
vendored
Normal file
44
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-002.html
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test (Tables): spanning cells crossing collapsed track borders</title>
|
||||
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-tables/#border-collapsing">
|
||||
<link rel="help" href="https://github.com/servo/servo/issues/35123">
|
||||
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||
<meta name="assert" content="
|
||||
The cells with rowspan cross rows with red borders.
|
||||
These red borders shouldn't be visible.
|
||||
">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
|
||||
|
||||
<style>
|
||||
table { border-collapse: collapse; font: 20px/1 Ahem; color: transparent; background: green; }
|
||||
table { border: 30px solid green; }
|
||||
tr, col { border: 20px solid red }
|
||||
td { padding: 0; border: 20px solid green; }
|
||||
td[rowspan], td[colspan] { border: none }
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<table>
|
||||
<col></col> <col></col> <col></col> <col></col>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td rowspan="4">X<br><br>X<br><br>X<br><br>X</td>
|
||||
<td>X</td>
|
||||
<td rowspan="4">X<br><br>X<br><br>X<br><br>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
</table>
|
47
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-003.html
vendored
Normal file
47
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-003.html
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test (Tables): spanning cells crossing collapsed track borders</title>
|
||||
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-tables/#border-collapsing">
|
||||
<link rel="help" href="https://github.com/servo/servo/issues/35123">
|
||||
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||
<meta name="assert" content="
|
||||
The cell with colspan and rowspan crosses columns and rows with red borders.
|
||||
These red borders shouldn't be visible.
|
||||
">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
|
||||
|
||||
<style>
|
||||
table { border-collapse: collapse; font: 20px/1 Ahem; color: transparent; background: green; }
|
||||
table { border: 30px solid green; }
|
||||
tr, col { border: 20px solid red }
|
||||
td { padding: 0; border: 20px solid green; }
|
||||
td[rowspan], td[colspan] { border: none }
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<table>
|
||||
<col></col> <col></col> <col></col> <col></col>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td colspan="2" rowspan="2">X X<br><br>X X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
</table>
|
43
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-004.html
vendored
Normal file
43
tests/wpt/tests/css/css-tables/tentative/border-collapse-spanning-cells-004.html
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test (Tables): spanning cells crossing collapsed track borders</title>
|
||||
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-tables/#border-collapsing">
|
||||
<link rel="help" href="https://github.com/servo/servo/issues/35123">
|
||||
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||
<meta name="assert" content="
|
||||
The cells with colspan cross columns with red borders.
|
||||
The cells with rowspan cross rows with red borders.
|
||||
These red borders shouldn't be visible.
|
||||
">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
|
||||
|
||||
<style>
|
||||
table { border-collapse: collapse; font: 20px/1 Ahem; color: transparent; background: green; }
|
||||
table { border: 30px solid green; }
|
||||
tr, col { border: 20px solid red }
|
||||
td { padding: 0; border: 20px solid green; }
|
||||
td[rowspan], td[colspan] { border: none }
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
|
||||
<table>
|
||||
<col></col> <col></col> <col></col> <col></col>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td rowspan="4">X<br><br>X<br><br>X<br><br>X</td>
|
||||
<td>X</td>
|
||||
<td rowspan="4">X<br><br>X<br><br>X<br><br>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">X X X X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>X</td>
|
||||
<td>X</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">X X X X</td>
|
||||
</tr>
|
||||
</table>
|
Loading…
Add table
Add a link
Reference in a new issue