layout: Improve painting of collapsed borders in table layout (#34933)

This is still not the right approach, because we are not painting
collapsed borders as a single thing. Instead, we are splitting them
into two halves and paint each half on a different cell. This only
looks good for solid borders.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-01-10 16:38:31 -08:00 committed by GitHub
parent 25a94efcdf
commit e2be55b873
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
88 changed files with 181 additions and 256 deletions

View file

@ -22,7 +22,7 @@ use style::properties::style_structs::Border;
use style::properties::ComputedValues;
use style::values::computed::image::Image;
use style::values::computed::{
BorderImageSideWidth, BorderImageWidth, BorderStyle, Color, LengthPercentage,
BorderImageSideWidth, BorderImageWidth, BorderStyle, LengthPercentage,
NonNegativeLengthOrNumber, NumberOrPercentage, OutlineStyle,
};
use style::values::generics::rect::Rect;
@ -44,11 +44,12 @@ use crate::context::LayoutContext;
use crate::display_list::conversions::ToWebRender;
use crate::display_list::stacking_context::StackingContextSection;
use crate::fragment_tree::{
BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, Tag, TextFragment,
BackgroundMode, BoxFragment, Fragment, FragmentFlags, FragmentTree, SpecificLayoutInfo, Tag,
TextFragment,
};
use crate::geom::{LengthPercentageOrAuto, PhysicalPoint, PhysicalRect};
use crate::replaced::NaturalSizes;
use crate::style_ext::ComputedValuesExt;
use crate::style_ext::{BorderStyleColor, ComputedValuesExt};
mod background;
mod clip_path;
@ -863,10 +864,10 @@ impl<'a> BuilderForBoxFragment<'a> {
}
}
fn build_border_side(&mut self, style: BorderStyle, color: Color) -> wr::BorderSide {
fn build_border_side(&mut self, style_color: BorderStyleColor) -> wr::BorderSide {
wr::BorderSide {
color: rgba(self.fragment.style.resolve_color(color)),
style: match style {
color: rgba(self.fragment.style.resolve_color(style_color.color)),
style: match style_color.style {
BorderStyle::None => wr::BorderStyle::None,
BorderStyle::Solid => wr::BorderStyle::Solid,
BorderStyle::Double => wr::BorderStyle::Double,
@ -895,16 +896,17 @@ impl<'a> BuilderForBoxFragment<'a> {
return;
}
let style_color = match &self.fragment.detailed_layout_info {
Some(SpecificLayoutInfo::TableOrTableCell(table_info)) => {
table_info.border_style_color.clone()
},
_ => BorderStyleColor::from_border(border),
};
let details = wr::BorderDetails::Normal(wr::NormalBorder {
top: self.build_border_side(border.border_top_style, border.border_top_color.clone()),
right: self
.build_border_side(border.border_right_style, border.border_right_color.clone()),
bottom: self.build_border_side(
border.border_bottom_style,
border.border_bottom_color.clone(),
),
left: self
.build_border_side(border.border_left_style, border.border_left_color.clone()),
top: self.build_border_side(style_color.top),
right: self.build_border_side(style_color.right),
bottom: self.build_border_side(style_color.bottom),
left: self.build_border_side(style_color.left),
radius: self.border_radius,
do_aa: true,
});
@ -1028,7 +1030,10 @@ impl<'a> BuilderForBoxFragment<'a> {
OutlineStyle::Auto => BorderStyle::Solid,
OutlineStyle::BorderStyle(s) => s,
};
let side = self.build_border_side(style, outline.outline_color.clone());
let side = self.build_border_side(BorderStyleColor {
style,
color: outline.outline_color.clone(),
});
let details = wr::BorderDetails::Normal(wr::NormalBorder {
top: side,
right: side,

View file

@ -20,6 +20,7 @@ use crate::geom::{
AuOrAuto, LengthPercentageOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, ToLogical,
};
use crate::style_ext::ComputedValuesExt;
use crate::table::SpecificTableOrTableCellInfo;
use crate::taffy::SpecificTaffyGridInfo;
/// Describes how a [`BoxFragment`] paints its background.
@ -43,6 +44,7 @@ pub(crate) struct ExtraBackground {
#[derive(Clone, Debug)]
pub(crate) enum SpecificLayoutInfo {
Grid(Box<SpecificTaffyGridInfo>),
TableOrTableCell(Box<SpecificTableOrTableCellInfo>),
}
#[derive(Serialize)]

View file

@ -13,11 +13,12 @@ use style::logical_geometry::{Direction as AxisDirection, WritingMode};
use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::longhands::column_span::computed_value::T as ColumnSpan;
use style::properties::style_structs::Border;
use style::properties::ComputedValues;
use style::servo::selector_parser::PseudoElement;
use style::values::computed::basic_shape::ClipPath;
use style::values::computed::image::Image as ComputedImageLayer;
use style::values::computed::{AlignItems, BorderStyle, Inset, LengthPercentage, Margin};
use style::values::computed::{AlignItems, BorderStyle, Color, Inset, LengthPercentage, Margin};
use style::values::generics::box_::Perspective;
use style::values::generics::position::{GenericAspectRatio, PreferredRatio};
use style::values::specified::align::AlignFlags;
@ -217,6 +218,36 @@ pub(crate) struct ContentBoxSizesAndPBMDeprecated {
pub depends_on_block_constraints: bool,
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct BorderStyleColor {
pub style: BorderStyle,
pub color: Color,
}
impl BorderStyleColor {
pub(crate) fn new(style: BorderStyle, color: Color) -> Self {
Self { style, color }
}
pub(crate) fn from_border(border: &Border) -> PhysicalSides<Self> {
PhysicalSides::<Self>::new(
Self::new(border.border_top_style, border.border_top_color.clone()),
Self::new(border.border_right_style, border.border_right_color.clone()),
Self::new(
border.border_bottom_style,
border.border_bottom_color.clone(),
),
Self::new(border.border_left_style, border.border_left_color.clone()),
)
}
}
impl Default for BorderStyleColor {
fn default() -> Self {
Self::new(BorderStyle::None, Color::TRANSPARENT_BLACK)
}
}
pub(crate) trait ComputedValuesExt {
fn physical_box_offsets(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
fn box_offsets(&self, writing_mode: WritingMode) -> LogicalSides<LengthPercentageOrAuto<'_>>;
@ -279,8 +310,10 @@ pub(crate) trait ComputedValuesExt {
) -> PaddingBorderMargin;
fn padding(&self, containing_block_writing_mode: WritingMode)
-> LogicalSides<LengthPercentage>;
fn border_style(&self, containing_block_writing_mode: WritingMode)
-> LogicalSides<BorderStyle>;
fn border_style_color(
&self,
containing_block_writing_mode: WritingMode,
) -> LogicalSides<BorderStyleColor>;
fn border_width(&self, containing_block_writing_mode: WritingMode) -> LogicalSides<Au>;
fn physical_margin(&self) -> PhysicalSides<LengthPercentageOrAuto<'_>>;
fn margin(
@ -598,18 +631,12 @@ impl ComputedValuesExt for ComputedValues {
)
}
fn border_style(
fn border_style_color(
&self,
containing_block_writing_mode: WritingMode,
) -> LogicalSides<BorderStyle> {
let border = self.get_border();
) -> LogicalSides<BorderStyleColor> {
LogicalSides::from_physical(
&PhysicalSides::new(
border.border_top_style,
border.border_right_style,
border.border_bottom_style,
border.border_left_style,
),
&BorderStyleColor::from_border(self.get_border()),
containing_block_writing_mode,
)
}

View file

@ -29,7 +29,7 @@ use crate::context::LayoutContext;
use crate::formatting_contexts::{Baselines, IndependentLayout};
use crate::fragment_tree::{
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
PositioningFragment,
PositioningFragment, SpecificLayoutInfo,
};
use crate::geom::{
AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides,
@ -37,12 +37,22 @@ use crate::geom::{
};
use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin};
use crate::table::TableSlotCoordinates;
use crate::style_ext::{BorderStyleColor, Clamp, ComputedValuesExt, PaddingBorderMargin};
use crate::table::{SpecificTableOrTableCellInfo, TableSlotCoordinates};
use crate::{
ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, WritingMode,
};
fn detailed_layout_info(
border_style_color: Option<PhysicalSides<BorderStyleColor>>,
) -> Option<SpecificLayoutInfo> {
Some(SpecificLayoutInfo::TableOrTableCell(Box::new(
SpecificTableOrTableCellInfo {
border_style_color: border_style_color?,
},
)))
}
/// A result of a final or speculative layout of a single cell in
/// the table. Note that this is only done for slots that are not
/// covered by spans or empty.
@ -50,6 +60,7 @@ struct CellLayout {
layout: IndependentLayout,
padding: LogicalSides<Au>,
border: LogicalSides<Au>,
detailed_layout_info: Option<SpecificLayoutInfo>,
positioning_context: PositioningContext,
}
@ -97,31 +108,25 @@ struct ColumnLayout {
}
/// A calculated collapsed border.
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Default, PartialEq)]
struct CollapsedBorder {
style: BorderStyle,
style_color: BorderStyleColor,
width: Au,
}
impl Default for CollapsedBorder {
fn default() -> Self {
Self::new(BorderStyle::None, Au::zero())
}
}
impl CollapsedBorder {
fn new(style: BorderStyle, width: Au) -> Self {
Self { style, width }
fn new(style_color: BorderStyleColor, width: Au) -> Self {
Self { style_color, width }
}
fn from_style(style: &ComputedValues, writing_mode: WritingMode) -> LogicalSides<Self> {
let border_style = style.border_style(writing_mode);
let border_style_color = style.border_style_color(writing_mode);
let border_width = style.border_width(writing_mode);
LogicalSides {
inline_start: Self::new(border_style.inline_start, border_width.inline_start),
inline_end: Self::new(border_style.inline_end, border_width.inline_end),
block_start: Self::new(border_style.block_start, border_width.block_start),
block_end: Self::new(border_style.block_end, border_width.block_end),
inline_start: Self::new(border_style_color.inline_start, border_width.inline_start),
inline_end: Self::new(border_style_color.inline_end, border_width.inline_end),
block_start: Self::new(border_style_color.block_start, border_width.block_start),
block_end: Self::new(border_style_color.block_end, border_width.block_end),
}
}
@ -138,9 +143,10 @@ impl CollapsedBorder {
/// > 2. … has the biggest border-width, once converted into css pixels
/// > 3. … has the border-style which comes first in the following list:
/// > double, solid, dashed, dotted, ridge, outset, groove, inset, none
impl Ord for CollapsedBorder {
fn cmp(&self, other: &Self) -> Ordering {
let style_specificity = |border: &Self| match border.style {
impl PartialOrd for CollapsedBorder {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let is_hidden = |border: &Self| border.style_color.style == BorderStyle::Hidden;
let style_specificity = |border: &Self| match border.style_color.style {
BorderStyle::None => 0,
BorderStyle::Inset => 1,
BorderStyle::Groove => 2,
@ -152,17 +158,18 @@ impl Ord for CollapsedBorder {
BorderStyle::Double => 8,
BorderStyle::Hidden => 9,
};
((self.style == BorderStyle::Hidden).cmp(&(other.style == BorderStyle::Hidden)))
let candidate = (is_hidden(self).cmp(&is_hidden(other)))
.then_with(|| self.width.cmp(&other.width))
.then_with(|| style_specificity(self).cmp(&style_specificity(other)))
.then_with(|| style_specificity(self).cmp(&style_specificity(other)));
if !candidate.is_eq() || self.style_color.color == other.style_color.color {
Some(candidate)
} else {
None
}
}
}
impl PartialOrd for CollapsedBorder {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for CollapsedBorder {}
/// The calculated collapsed borders.
#[derive(Clone, Debug, Default)]
@ -275,7 +282,10 @@ impl<'a> TableLayout<'a> {
cell,
TableSlotCoordinates::new(column_index, row_index),
)
.unwrap_or_else(|| cell.base.style.border_width(writing_mode));
.map_or_else(
|| cell.base.style.border_width(writing_mode),
|(border, _)| border,
);
let padding_border_sums = LogicalVec2 {
inline: padding.inline_sum() + border.inline_sum(),
@ -1185,13 +1195,20 @@ impl<'a> TableLayout<'a> {
};
let coordinates = TableSlotCoordinates::new(column_index, row_index);
let border: LogicalSides<Au> = self
.get_collapsed_borders_for_cell(cell, coordinates)
.unwrap_or_else(|| {
cell.base
.style
.border_width(containing_block_for_table.style.writing_mode)
});
let (border, detailed_layout_info) =
match self.get_collapsed_borders_for_cell(cell, coordinates) {
Some((border_width, border_style_color)) => {
let border_style_color = border_style_color
.to_physical(self.table.style.writing_mode);
(border_width, detailed_layout_info(Some(border_style_color)))
},
None => (
cell.base.style.border_width(
containing_block_for_table.style.writing_mode,
),
None,
),
};
let padding: LogicalSides<Au> = cell
.base
@ -1228,6 +1245,7 @@ impl<'a> TableLayout<'a> {
layout,
padding,
border,
detailed_layout_info,
positioning_context,
})
})
@ -1852,6 +1870,21 @@ impl<'a> TableLayout<'a> {
assert_eq!(self.table.size.height, self.row_sizes.len());
assert_eq!(self.table.size.width, self.distributed_column_widths.len());
let border_style_color = self.collapsed_borders.as_ref().map(|collapsed_borders| {
LogicalSides {
inline_start: collapsed_borders.inline[0].style_color.clone(),
inline_end: collapsed_borders.inline[self.table.size.width]
.style_color
.clone(),
block_start: collapsed_borders.block[0].style_color.clone(),
block_end: collapsed_borders.block[self.table.size.height]
.style_color
.clone(),
}
.to_physical(table_writing_mode)
});
let detailed_layout_info = detailed_layout_info(border_style_color);
if self.table.size.width == 0 && self.table.size.height == 0 {
let content_rect = LogicalRect {
start_corner: LogicalVec2::zero(),
@ -1871,7 +1904,8 @@ impl<'a> TableLayout<'a> {
PhysicalSides::zero(),
None, /* clearance */
CollapsedBlockMargins::zero(),
);
)
.with_detailed_layout_info(detailed_layout_info);
}
let mut table_fragments = Vec::new();
@ -1998,6 +2032,7 @@ impl<'a> TableLayout<'a> {
CollapsedBlockMargins::zero(),
)
.with_baselines(baselines)
.with_detailed_layout_info(detailed_layout_info)
}
fn is_row_collapsed(&self, row_index: usize) -> bool {
@ -2232,39 +2267,43 @@ impl<'a> TableLayout<'a> {
&self,
cell: &TableSlotCell,
coordinates: TableSlotCoordinates,
) -> Option<LogicalSides<Au>> {
) -> Option<(LogicalSides<Au>, LogicalSides<BorderStyleColor>)> {
let collapsed_borders = self.collapsed_borders.as_ref()?;
let end_x = coordinates.x + cell.colspan;
let end_y = coordinates.y + cell.rowspan;
let mut result = LogicalSides {
inline_start: collapsed_borders.inline[coordinates.x].width,
inline_end: collapsed_borders.inline[end_x].width,
block_start: collapsed_borders.block[coordinates.y].width,
block_end: collapsed_borders.block[end_y].width,
let inline_start = &collapsed_borders.inline[coordinates.x];
let inline_end = &collapsed_borders.inline[end_x];
let block_start = &collapsed_borders.block[coordinates.y];
let block_end = &collapsed_borders.block[end_y];
let border_width = LogicalSides {
inline_start: if coordinates.x == 0 {
inline_start.width - self.pbm.border.inline_start
} else {
inline_start.width / 2
},
inline_end: if end_x == self.table.size.width {
inline_end.width - self.pbm.border.inline_end
} else {
inline_end.width / 2
},
block_start: if coordinates.y == 0 {
block_start.width - self.pbm.border.block_start
} else {
block_start.width / 2
},
block_end: if end_y == self.table.size.height {
block_end.width - self.pbm.border.block_end
} else {
block_end.width / 2
},
};
if coordinates.x == 0 {
result.inline_start -= self.pbm.border.inline_start;
} else {
result.inline_start /= 2;
}
if coordinates.y == 0 {
result.block_start -= self.pbm.border.block_start;
} else {
result.block_start /= 2;
}
if end_x == self.table.size.width {
result.inline_end -= self.pbm.border.inline_end;
} else {
result.inline_end /= 2;
}
if end_y == self.table.size.height {
result.block_end -= self.pbm.border.block_end;
} else {
result.block_end /= 2;
}
Some(result)
let border_style_color = LogicalSides {
inline_start: inline_start.style_color.clone(),
inline_end: inline_end.style_color.clone(),
block_start: block_start.style_color.clone(),
block_end: block_end.style_color.clone(),
};
Some((border_width, border_style_color))
}
}
@ -2828,6 +2867,7 @@ impl TableSlotCell {
CollapsedBlockMargins::zero(),
)
.with_baselines(layout.layout.baselines)
.with_detailed_layout_info(layout.detailed_layout_info)
}
}

View file

@ -84,7 +84,9 @@ use crate::cell::ArcRefCell;
use crate::flow::BlockContainer;
use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragment_tree::BaseFragmentInfo;
use crate::geom::PhysicalSides;
use crate::layout_box_base::LayoutBoxBase;
use crate::style_ext::BorderStyleColor;
pub type TableSize = Size2D<usize, UnknownUnit>;
@ -320,3 +322,10 @@ pub struct TableCaption {
/// The contents of this cell, with its own layout.
context: ArcRefCell<IndependentFormattingContext>,
}
#[derive(Clone, Debug)]
pub(crate) struct SpecificTableOrTableCellInfo {
/// 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>,
}

View file

@ -1,2 +0,0 @@
[border-bottom-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-color-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-color-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-color-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-color-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-color-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-width-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-width-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-width-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-width-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-bottom-width-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-applies-to-006.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-color-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-color-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-color-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-color-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-color-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-color-applies-to-006.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-width-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-width-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-width-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-width-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-width-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-left-width-applies-to-006.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-applies-to-006.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-color-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-color-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-color-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-color-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-color-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-color-applies-to-006.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-width-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-width-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-width-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-width-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-width-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-right-width-applies-to-006.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-color-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-color-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-color-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-color-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-color-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-width-applies-to-001.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-width-applies-to-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-width-applies-to-003.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-width-applies-to-004.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-top-width-applies-to-005.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[blocks-025.xht]
expected: FAIL

View file

@ -0,0 +1,2 @@
[border-collapse-dynamic-cell-002.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-conflict-element-001a.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-conflict-element-001b.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-conflict-element-001c.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003e01.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003e02.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003e03.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003e04.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003e05.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003e06.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003f01.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[fixed-table-layout-003f02.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-collapse-dynamic-oof.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border-conflict-resolution.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[collapsed-border-remove-cell.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[border_collapse_row_a.html]
expected: FAIL