mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
layout: Fix border widths of table wrapper with collapsed borders (#35097)
For a table wrapper in collapsed-borders mode we were just halving the border widths from the computed style. However, it needs to actually receive half of the resulting collapsed border, which can be bigger. Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
acfd2e6de4
commit
a54add0159
22 changed files with 146 additions and 165 deletions
|
@ -933,35 +933,22 @@ impl<'a> BuilderForBoxFragment<'a> {
|
||||||
bottom_border.width,
|
bottom_border.width,
|
||||||
left_border.width,
|
left_border.width,
|
||||||
);
|
);
|
||||||
|
let left_adjustment = if x == 0 {
|
||||||
let mut origin = PhysicalPoint::new(column_sum, row_sum);
|
-border_widths.left / 2
|
||||||
let mut size = PhysicalSize::new(*column_size, *row_size);
|
|
||||||
if x == 0 {
|
|
||||||
origin.x -= table_info.wrapper_border.left;
|
|
||||||
size.width += table_info.wrapper_border.left;
|
|
||||||
} else {
|
} else {
|
||||||
border_widths.left = Au::zero();
|
std::mem::take(&mut border_widths.left) / 2
|
||||||
origin.x += left_border.width / 2;
|
};
|
||||||
size.width -= left_border.width / 2;
|
let top_adjustment = if y == 0 {
|
||||||
}
|
-border_widths.top / 2
|
||||||
if y == 0 {
|
|
||||||
origin.y -= table_info.wrapper_border.top;
|
|
||||||
size.height += table_info.wrapper_border.top;
|
|
||||||
} else {
|
} else {
|
||||||
border_widths.top = Au::zero();
|
std::mem::take(&mut border_widths.top) / 2
|
||||||
origin.y += top_border.width / 2;
|
};
|
||||||
size.height -= top_border.width / 2;
|
let origin =
|
||||||
}
|
PhysicalPoint::new(column_sum + left_adjustment, row_sum + top_adjustment);
|
||||||
if x + 1 == table_info.track_sizes.x.len() {
|
let size = PhysicalSize::new(
|
||||||
size.width += table_info.wrapper_border.right;
|
*column_size - left_adjustment + border_widths.right / 2,
|
||||||
} else {
|
*row_size - top_adjustment + border_widths.bottom / 2,
|
||||||
size.width += border_widths.right / 2;
|
);
|
||||||
}
|
|
||||||
if y + 1 == table_info.track_sizes.y.len() {
|
|
||||||
size.height += table_info.wrapper_border.bottom;
|
|
||||||
} else {
|
|
||||||
size.height += border_widths.bottom / 2;
|
|
||||||
}
|
|
||||||
let border_rect = PhysicalRect::new(origin, size)
|
let border_rect = PhysicalRect::new(origin, size)
|
||||||
.translate(self.fragment.content_rect.origin.to_vector())
|
.translate(self.fragment.content_rect.origin.to_vector())
|
||||||
.translate(self.containing_block.origin.to_vector())
|
.translate(self.containing_block.origin.to_vector())
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl IndependentNonReplacedContents {
|
||||||
IndependentNonReplacedContents::Flow(fc) => fc.layout_style(base),
|
IndependentNonReplacedContents::Flow(fc) => fc.layout_style(base),
|
||||||
IndependentNonReplacedContents::Flex(fc) => fc.layout_style(),
|
IndependentNonReplacedContents::Flex(fc) => fc.layout_style(),
|
||||||
IndependentNonReplacedContents::Grid(fc) => fc.layout_style(),
|
IndependentNonReplacedContents::Grid(fc) => fc.layout_style(),
|
||||||
IndependentNonReplacedContents::Table(fc) => fc.layout_style(),
|
IndependentNonReplacedContents::Table(fc) => fc.layout_style(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use style::computed_values::border_collapse::T as BorderCollapse;
|
|
||||||
use style::computed_values::direction::T as Direction;
|
use style::computed_values::direction::T as Direction;
|
||||||
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
|
||||||
use style::computed_values::position::T as ComputedPosition;
|
use style::computed_values::position::T as ComputedPosition;
|
||||||
|
@ -33,6 +32,7 @@ use crate::geom::{
|
||||||
AuOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides, PhysicalSize,
|
AuOrAuto, LengthPercentageOrAuto, LogicalSides, LogicalVec2, PhysicalSides, PhysicalSize,
|
||||||
PhysicalVec, Size, Sizes,
|
PhysicalVec, Size, Sizes,
|
||||||
};
|
};
|
||||||
|
use crate::table::TableLayoutStyle;
|
||||||
use crate::{ContainingBlock, IndefiniteContainingBlock};
|
use crate::{ContainingBlock, IndefiniteContainingBlock};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
|
@ -805,7 +805,7 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
|
|
||||||
pub(crate) enum LayoutStyle<'a> {
|
pub(crate) enum LayoutStyle<'a> {
|
||||||
Default(&'a ComputedValues),
|
Default(&'a ComputedValues),
|
||||||
Table(&'a ComputedValues),
|
Table(TableLayoutStyle<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutStyle<'_> {
|
impl LayoutStyle<'_> {
|
||||||
|
@ -813,7 +813,7 @@ impl LayoutStyle<'_> {
|
||||||
pub(crate) fn style(&self) -> &ComputedValues {
|
pub(crate) fn style(&self) -> &ComputedValues {
|
||||||
match self {
|
match self {
|
||||||
Self::Default(style) => style,
|
Self::Default(style) => style,
|
||||||
Self::Table(style) => style,
|
Self::Table(table) => table.style(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,10 +931,7 @@ impl LayoutStyle<'_> {
|
||||||
&self,
|
&self,
|
||||||
containing_block_writing_mode: WritingMode,
|
containing_block_writing_mode: WritingMode,
|
||||||
) -> LogicalSides<LengthPercentage> {
|
) -> LogicalSides<LengthPercentage> {
|
||||||
let style = self.style();
|
if matches!(self, Self::Table(table) if table.collapses_borders()) {
|
||||||
if matches!(self, Self::Table(_)) &&
|
|
||||||
style.get_inherited_table().border_collapse == BorderCollapse::Collapse
|
|
||||||
{
|
|
||||||
// https://drafts.csswg.org/css-tables/#collapsed-style-overrides
|
// https://drafts.csswg.org/css-tables/#collapsed-style-overrides
|
||||||
// > The padding of the table-root is ignored (as if it was set to 0px).
|
// > The padding of the table-root is ignored (as if it was set to 0px).
|
||||||
return LogicalSides::zero();
|
return LogicalSides::zero();
|
||||||
|
@ -955,33 +952,24 @@ impl LayoutStyle<'_> {
|
||||||
&self,
|
&self,
|
||||||
containing_block_writing_mode: WritingMode,
|
containing_block_writing_mode: WritingMode,
|
||||||
) -> LogicalSides<Au> {
|
) -> LogicalSides<Au> {
|
||||||
let style = self.style();
|
let border_width = match self {
|
||||||
let border = style.get_border();
|
|
||||||
if matches!(self, Self::Table(_)) &&
|
|
||||||
style.get_inherited_table().border_collapse == BorderCollapse::Collapse
|
|
||||||
{
|
|
||||||
// For tables in collapsed-borders mode we halve the border widths, because
|
// For tables in collapsed-borders mode we halve the border widths, because
|
||||||
// > in this model, the width of the table includes half the table border.
|
// > in this model, the width of the table includes half the table border.
|
||||||
// https://www.w3.org/TR/CSS22/tables.html#collapsing-borders
|
// https://www.w3.org/TR/CSS22/tables.html#collapsing-borders
|
||||||
return LogicalSides::from_physical(
|
Self::Table(table) if table.collapses_borders() => table
|
||||||
&PhysicalSides::new(
|
.halved_collapsed_border_widths()
|
||||||
border.border_top_width / 2,
|
.to_physical(self.style().writing_mode),
|
||||||
border.border_right_width / 2,
|
_ => {
|
||||||
border.border_bottom_width / 2,
|
let border = self.style().get_border();
|
||||||
border.border_left_width / 2,
|
PhysicalSides::new(
|
||||||
),
|
|
||||||
containing_block_writing_mode,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
LogicalSides::from_physical(
|
|
||||||
&PhysicalSides::new(
|
|
||||||
border.border_top_width,
|
border.border_top_width,
|
||||||
border.border_right_width,
|
border.border_right_width,
|
||||||
border.border_bottom_width,
|
border.border_bottom_width,
|
||||||
border.border_left_width,
|
border.border_left_width,
|
||||||
),
|
|
||||||
containing_block_writing_mode,
|
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
LogicalSides::from_physical(&border_width, containing_block_writing_mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ use style::Zero;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
ArcRefCell, CollapsedBorder, CollapsedBorderLine, SpecificTableGridInfo, Table, TableCaption,
|
ArcRefCell, CollapsedBorder, CollapsedBorderLine, SpecificTableGridInfo, Table, TableCaption,
|
||||||
TableSlot, TableSlotCell, TableSlotCoordinates, TableTrack, TableTrackGroup,
|
TableLayoutStyle, TableSlot, TableSlotCell, TableSlotCoordinates, TableTrack, TableTrackGroup,
|
||||||
};
|
};
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
use crate::formatting_contexts::{Baselines, IndependentLayout};
|
||||||
|
@ -636,7 +636,6 @@ impl<'a> TableLayout<'a> {
|
||||||
writing_mode: WritingMode,
|
writing_mode: WritingMode,
|
||||||
) -> ContentSizes {
|
) -> ContentSizes {
|
||||||
self.compute_track_constrainedness_and_has_originating_cells(writing_mode);
|
self.compute_track_constrainedness_and_has_originating_cells(writing_mode);
|
||||||
self.compute_border_collapse(writing_mode);
|
|
||||||
self.compute_cell_measures(layout_context, writing_mode);
|
self.compute_cell_measures(layout_context, writing_mode);
|
||||||
self.compute_column_measures(writing_mode);
|
self.compute_column_measures(writing_mode);
|
||||||
|
|
||||||
|
@ -1518,7 +1517,12 @@ impl<'a> TableLayout<'a> {
|
||||||
containing_block_for_table: &ContainingBlock,
|
containing_block_for_table: &ContainingBlock,
|
||||||
) -> IndependentLayout {
|
) -> IndependentLayout {
|
||||||
let table_writing_mode = containing_block_for_children.style.writing_mode;
|
let table_writing_mode = containing_block_for_children.style.writing_mode;
|
||||||
let layout_style = self.table.layout_style();
|
self.compute_border_collapse(table_writing_mode);
|
||||||
|
let layout_style = self.table.layout_style(Some(&self));
|
||||||
|
let depends_on_block_constraints = layout_style
|
||||||
|
.content_box_sizes_and_padding_border_margin(&containing_block_for_table.into())
|
||||||
|
.depends_on_block_constraints;
|
||||||
|
|
||||||
self.pbm = layout_style
|
self.pbm = layout_style
|
||||||
.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
||||||
table_writing_mode,
|
table_writing_mode,
|
||||||
|
@ -1556,10 +1560,6 @@ impl<'a> TableLayout<'a> {
|
||||||
let offset_from_wrapper = -self.pbm.padding - self.pbm.border;
|
let offset_from_wrapper = -self.pbm.padding - self.pbm.border;
|
||||||
let mut current_block_offset = offset_from_wrapper.block_start;
|
let mut current_block_offset = offset_from_wrapper.block_start;
|
||||||
|
|
||||||
let depends_on_block_constraints = layout_style
|
|
||||||
.content_box_sizes_and_padding_border_margin(&containing_block_for_table.into())
|
|
||||||
.depends_on_block_constraints;
|
|
||||||
|
|
||||||
let mut table_layout = IndependentLayout {
|
let mut table_layout = IndependentLayout {
|
||||||
fragments: Vec::new(),
|
fragments: Vec::new(),
|
||||||
content_block_size: Zero::zero(),
|
content_block_size: Zero::zero(),
|
||||||
|
@ -1914,7 +1914,6 @@ impl<'a> TableLayout<'a> {
|
||||||
} else {
|
} else {
|
||||||
PhysicalVec::new(track_sizes.block, track_sizes.inline)
|
PhysicalVec::new(track_sizes.block, track_sizes.inline)
|
||||||
},
|
},
|
||||||
wrapper_border: self.pbm.border.to_physical(writing_mode),
|
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -2187,26 +2186,10 @@ impl<'a> TableLayout<'a> {
|
||||||
let block_start = &collapsed_borders.block[area.block_start];
|
let block_start = &collapsed_borders.block[area.block_start];
|
||||||
let block_end = &collapsed_borders.block[area.block_end];
|
let block_end = &collapsed_borders.block[area.block_end];
|
||||||
Some(LogicalSides {
|
Some(LogicalSides {
|
||||||
inline_start: if area.inline_start == 0 {
|
inline_start: inline_start.max_width / 2,
|
||||||
inline_start.max_width - self.pbm.border.inline_start
|
inline_end: inline_end.max_width / 2,
|
||||||
} else {
|
block_start: block_start.max_width / 2,
|
||||||
inline_start.max_width / 2
|
block_end: block_end.max_width / 2,
|
||||||
},
|
|
||||||
inline_end: if area.inline_end == self.table.size.width {
|
|
||||||
inline_end.max_width - self.pbm.border.inline_end
|
|
||||||
} else {
|
|
||||||
inline_end.max_width / 2
|
|
||||||
},
|
|
||||||
block_start: if area.block_start == 0 {
|
|
||||||
block_start.max_width - self.pbm.border.block_start
|
|
||||||
} else {
|
|
||||||
block_start.max_width / 2
|
|
||||||
},
|
|
||||||
block_end: if area.block_end == self.table.size.height {
|
|
||||||
block_end.max_width - self.pbm.border.block_end
|
|
||||||
} else {
|
|
||||||
block_end.max_width / 2
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2638,9 +2621,10 @@ impl ComputeInlineContentSizes for Table {
|
||||||
constraint_space: &ConstraintSpace,
|
constraint_space: &ConstraintSpace,
|
||||||
) -> InlineContentSizesResult {
|
) -> InlineContentSizesResult {
|
||||||
let writing_mode = constraint_space.writing_mode;
|
let writing_mode = constraint_space.writing_mode;
|
||||||
let layout_style = self.layout_style();
|
|
||||||
let mut layout = TableLayout::new(self);
|
let mut layout = TableLayout::new(self);
|
||||||
layout.pbm = layout_style
|
layout.compute_border_collapse(writing_mode);
|
||||||
|
layout.pbm = self
|
||||||
|
.layout_style(Some(&layout))
|
||||||
.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
|
||||||
writing_mode,
|
writing_mode,
|
||||||
Au::zero(),
|
Au::zero(),
|
||||||
|
@ -2655,6 +2639,7 @@ impl ComputeInlineContentSizes for Table {
|
||||||
// Padding and border should apply to the table grid, but they will be taken into
|
// Padding and border should apply to the table grid, but they will be taken into
|
||||||
// account when computing the inline content sizes of the table wrapper (our parent), so
|
// account when computing the inline content sizes of the table wrapper (our parent), so
|
||||||
// this code removes their contribution from the inline content size of the caption.
|
// this code removes their contribution from the inline content size of the caption.
|
||||||
|
let layout_style = self.layout_style(Some(&layout));
|
||||||
let padding = layout_style
|
let padding = layout_style
|
||||||
.padding(writing_mode)
|
.padding(writing_mode)
|
||||||
.percentages_relative_to(Au::zero());
|
.percentages_relative_to(Au::zero());
|
||||||
|
@ -2677,8 +2662,14 @@ impl ComputeInlineContentSizes for Table {
|
||||||
|
|
||||||
impl Table {
|
impl Table {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn layout_style(&self) -> LayoutStyle {
|
pub(crate) fn layout_style<'a>(
|
||||||
LayoutStyle::Table(&self.style)
|
&'a self,
|
||||||
|
layout: Option<&'a TableLayout<'a>>,
|
||||||
|
) -> LayoutStyle<'a> {
|
||||||
|
LayoutStyle::Table(TableLayoutStyle {
|
||||||
|
table: self,
|
||||||
|
layout,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2701,6 +2692,37 @@ impl TableTrackGroup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TableLayoutStyle<'_> {
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn style(&self) -> &ComputedValues {
|
||||||
|
&self.table.style
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub(crate) fn collapses_borders(&self) -> bool {
|
||||||
|
self.style().get_inherited_table().border_collapse == BorderCollapse::Collapse
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn halved_collapsed_border_widths(&self) -> LogicalSides<Au> {
|
||||||
|
debug_assert!(self.collapses_borders());
|
||||||
|
let area = LogicalSides {
|
||||||
|
inline_start: 0,
|
||||||
|
inline_end: self.table.size.width,
|
||||||
|
block_start: 0,
|
||||||
|
block_end: self.table.size.height,
|
||||||
|
};
|
||||||
|
if let Some(layout) = self.layout {
|
||||||
|
layout.get_collapsed_border_widths_for_area(area)
|
||||||
|
} else {
|
||||||
|
// TODO: this should be cached.
|
||||||
|
let mut layout = TableLayout::new(self.table);
|
||||||
|
layout.compute_border_collapse(self.style().writing_mode);
|
||||||
|
layout.get_collapsed_border_widths_for_area(area)
|
||||||
|
}
|
||||||
|
.expect("Collapsed borders should be computed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TableSlotCell {
|
impl TableSlotCell {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn layout_style(&self) -> LayoutStyle {
|
fn layout_style(&self) -> LayoutStyle {
|
||||||
|
|
|
@ -84,9 +84,10 @@ 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;
|
use crate::fragment_tree::BaseFragmentInfo;
|
||||||
use crate::geom::{PhysicalSides, 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;
|
||||||
|
use crate::table::layout::TableLayout;
|
||||||
|
|
||||||
pub type TableSize = Size2D<usize, UnknownUnit>;
|
pub type TableSize = Size2D<usize, UnknownUnit>;
|
||||||
|
|
||||||
|
@ -336,5 +337,9 @@ pub(crate) struct CollapsedBorderLine {
|
||||||
pub(crate) struct SpecificTableGridInfo {
|
pub(crate) struct SpecificTableGridInfo {
|
||||||
pub collapsed_borders: PhysicalVec<Vec<CollapsedBorderLine>>,
|
pub collapsed_borders: PhysicalVec<Vec<CollapsedBorderLine>>,
|
||||||
pub track_sizes: PhysicalVec<Vec<Au>>,
|
pub track_sizes: PhysicalVec<Vec<Au>>,
|
||||||
pub wrapper_border: PhysicalSides<Au>,
|
}
|
||||||
|
|
||||||
|
pub(crate) struct TableLayoutStyle<'a> {
|
||||||
|
table: &'a Table,
|
||||||
|
layout: Option<&'a TableLayout<'a>>,
|
||||||
}
|
}
|
||||||
|
|
2
tests/wpt/meta/MANIFEST.json
vendored
2
tests/wpt/meta/MANIFEST.json
vendored
|
@ -586076,7 +586076,7 @@
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"visibility-collapse-rowspan-004-dynamic.html": [
|
"visibility-collapse-rowspan-004-dynamic.html": [
|
||||||
"e6f65c450f7cf3da4d8f745306065278f9471036",
|
"c2f1a114fb4333aaef5459989019ee6e8c858bb5",
|
||||||
[
|
[
|
||||||
null,
|
null,
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-applies-to-007.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-color-applies-to-001.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-color-applies-to-002.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-color-applies-to-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-color-applies-to-004.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-color-applies-to-005.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-color-applies-to-007.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[collapsing-border-model-003.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[collapsing-border-model-009.xht]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[border-collapse-dynamic-section.html]
|
|
||||||
expected: FAIL
|
|
|
@ -70,105 +70,114 @@ table td {
|
||||||
tests[i][2]);
|
tests[i][2]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function width(element) {
|
||||||
|
return element.getBoundingClientRect().width;
|
||||||
|
}
|
||||||
|
function height(element) {
|
||||||
|
return element.getBoundingClientRect().height;
|
||||||
|
}
|
||||||
document.getElementById("thirdRow").style.visibility = "collapse";
|
document.getElementById("thirdRow").style.visibility = "collapse";
|
||||||
tests = [
|
tests = [
|
||||||
[
|
[
|
||||||
document.getElementById('two').offsetWidth,
|
width(document.getElementById('two')),
|
||||||
document.getElementById('one').offsetWidth,
|
width(document.getElementById('one')),
|
||||||
"spanning row visibility:collapse doesn't change table width"
|
"spanning row visibility:collapse doesn't change table width"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('firstRow').offsetHeight,
|
height(document.getElementById('firstRow')),
|
||||||
document.getElementById('firstRowRef').offsetHeight,
|
height(document.getElementById('firstRowRef')),
|
||||||
"when third row is collapsed, first row stays the same height"
|
"when third row is collapsed, first row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('secondRow').offsetHeight,
|
height(document.getElementById('secondRow')),
|
||||||
document.getElementById('secondRowRef').offsetHeight,
|
height(document.getElementById('secondRowRef')),
|
||||||
"when third row is collapsed, second row stays the same height"
|
"when third row is collapsed, second row stays the same height"
|
||||||
],
|
],
|
||||||
[ document.getElementById('thirdRow').offsetHeight,
|
[
|
||||||
|
height(document.getElementById('thirdRow')),
|
||||||
0,
|
0,
|
||||||
"third row visibility:collapse makes row height 0"
|
"third row visibility:collapse makes row height 0"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('fourthRow').offsetHeight,
|
height(document.getElementById('fourthRow')),
|
||||||
document.getElementById('fourthRowRef').offsetHeight,
|
height(document.getElementById('fourthRowRef')),
|
||||||
"when third row is collapsed, fourth row stays the same height"
|
"when third row is collapsed, fourth row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('spanningCell').offsetHeight,
|
height(document.getElementById('spanningCell')),
|
||||||
document.getElementById('firstRow').offsetHeight +
|
height(document.getElementById('firstRow')) +
|
||||||
document.getElementById('secondRow').offsetHeight +
|
height(document.getElementById('secondRow')) +
|
||||||
document.getElementById('fourthRow').offsetHeight +
|
height(document.getElementById('fourthRow')) +
|
||||||
document.getElementById('fifthRow').offsetHeight,
|
height(document.getElementById('fifthRow')),
|
||||||
"spanning cell shrinks to sum of remaining three rows' height"
|
"spanning cell shrinks to sum of remaining three rows' height"
|
||||||
]];
|
]];
|
||||||
runTests();
|
runTests();
|
||||||
document.getElementById("thirdRow").style.visibility = "visible";
|
document.getElementById("thirdRow").style.visibility = "visible";
|
||||||
tests = [
|
tests = [
|
||||||
[
|
[
|
||||||
document.getElementById('firstRow').offsetHeight,
|
height(document.getElementById('firstRow')),
|
||||||
document.getElementById('firstRowRef').offsetHeight,
|
height(document.getElementById('firstRowRef')),
|
||||||
"when third row is visible, first row stays the same height"
|
"when third row is visible, first row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('secondRow').offsetHeight,
|
height(document.getElementById('secondRow')),
|
||||||
document.getElementById('secondRowRef').offsetHeight,
|
height(document.getElementById('secondRowRef')),
|
||||||
"when third row is visible, second row stays the same height"
|
"when third row is visible, second row stays the same height"
|
||||||
],
|
],
|
||||||
[ document.getElementById('thirdRow').offsetHeight,
|
[
|
||||||
document.getElementById('secondRowRef').offsetHeight,
|
height(document.getElementById('thirdRow')),
|
||||||
|
height(document.getElementById('secondRowRef')),
|
||||||
"when third row is visible, third row stays the same height"
|
"when third row is visible, third row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('fourthRow').offsetHeight,
|
height(document.getElementById('fourthRow')),
|
||||||
document.getElementById('fourthRowRef').offsetHeight,
|
height(document.getElementById('fourthRowRef')),
|
||||||
"when third row is visible, fourth row stays the same height"
|
"when third row is visible, fourth row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('fifthRow').offsetHeight,
|
height(document.getElementById('fifthRow')),
|
||||||
document.getElementById('fifthRowRef').offsetHeight,
|
height(document.getElementById('fifthRowRef')),
|
||||||
"when third row is visible, fifth row stays the same height"
|
"when third row is visible, fifth row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('spanningCell').offsetHeight,
|
height(document.getElementById('spanningCell')),
|
||||||
document.getElementById('spanningCellRef').offsetHeight,
|
height(document.getElementById('spanningCellRef')),
|
||||||
"when third row is visible, spanning cell stays the same height"
|
"when third row is visible, spanning cell stays the same height"
|
||||||
]];
|
]];
|
||||||
runTests();
|
runTests();
|
||||||
document.getElementById("thirdRow").style.visibility = "collapse";
|
document.getElementById("thirdRow").style.visibility = "collapse";
|
||||||
tests = [
|
tests = [
|
||||||
[
|
[
|
||||||
document.getElementById('two').offsetWidth,
|
width(document.getElementById('two')),
|
||||||
document.getElementById('one').offsetWidth,
|
width(document.getElementById('one')),
|
||||||
"(2nd collapse) spanning row visibility:collapse doesn't change table width"
|
"(2nd collapse) spanning row visibility:collapse doesn't change table width"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('firstRow').offsetHeight,
|
height(document.getElementById('firstRow')),
|
||||||
document.getElementById('firstRowRef').offsetHeight,
|
height(document.getElementById('firstRowRef')),
|
||||||
"when third row is collapsed again, first row stays the same height"
|
"when third row is collapsed again, first row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('secondRow').offsetHeight,
|
height(document.getElementById('secondRow')),
|
||||||
document.getElementById('secondRowRef').offsetHeight,
|
height(document.getElementById('secondRowRef')),
|
||||||
"when third row is collapsed again, second row stays the same height"
|
"when third row is collapsed again, second row stays the same height"
|
||||||
],
|
],
|
||||||
[ document.getElementById('thirdRow').offsetHeight,
|
[
|
||||||
|
height(document.getElementById('thirdRow')),
|
||||||
0,
|
0,
|
||||||
"(2nd collapse) third row visibility:collapse makes row height 0"
|
"(2nd collapse) third row visibility:collapse makes row height 0"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('fourthRow').offsetHeight,
|
height(document.getElementById('fourthRow')),
|
||||||
document.getElementById('fourthRowRef').offsetHeight,
|
height(document.getElementById('fourthRowRef')),
|
||||||
"when third row is collapsed again, fourth row stays the same height"
|
"when third row is collapsed again, fourth row stays the same height"
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
document.getElementById('spanningCell').offsetHeight,
|
height(document.getElementById('spanningCell')),
|
||||||
document.getElementById('firstRow').offsetHeight +
|
height(document.getElementById('firstRow')) +
|
||||||
document.getElementById('secondRow').offsetHeight +
|
height(document.getElementById('secondRow')) +
|
||||||
document.getElementById('fourthRow').offsetHeight +
|
height(document.getElementById('fourthRow')) +
|
||||||
document.getElementById('fifthRow').offsetHeight,
|
height(document.getElementById('fifthRow')),
|
||||||
"(2nd collapse) spanning cell shrinks to sum of remaining three rows' height"
|
"(2nd collapse) spanning cell shrinks to sum of remaining three rows' height"
|
||||||
]];
|
]];
|
||||||
runTests();
|
runTests();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue