aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2024-07-03 20:24:19 +0200
committerGitHub <noreply@github.com>2024-07-03 18:24:19 +0000
commit959ffad99a57f5f8f0554fed0983317577ae8290 (patch)
treeb39a61902cdb8d2bf648b27469ea69dbdcb5aed4
parentf8e4ae60401358ac6adaa480e63c587f9f8293a2 (diff)
downloadservo-959ffad99a57f5f8f0554fed0983317577ae8290.tar.gz
servo-959ffad99a57f5f8f0554fed0983317577ae8290.zip
layout: Add support for table captions (#32657)
This adds initial support for table captions. To do this, the idea of the table wrapper becomes a bit more concrete. Even so, the wrapper is still reponsible for allocating space for the grid's border and padding, as those properties are specified on the wrapper and not grid in CSS. In order to account for this weirdness of HTML/CSS captions and grid are now laid out and placed with a negative offset in the table wrapper content rect. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
-rw-r--r--Cargo.lock26
-rw-r--r--components/layout_2020/flow/mod.rs8
-rw-r--r--components/layout_2020/formatting_contexts.rs29
-rw-r--r--components/layout_2020/fragment_tree/base_fragment.rs17
-rw-r--r--components/layout_2020/fragment_tree/box_fragment.rs8
-rw-r--r--components/layout_2020/geom.rs21
-rw-r--r--components/layout_2020/style_ext.rs7
-rw-r--r--components/layout_2020/table/construct.rs62
-rw-r--r--components/layout_2020/table/layout.rs354
-rw-r--r--components/layout_2020/table/mod.rs38
-rw-r--r--resources/servo.css35
-rw-r--r--resources/user-agent.css5
-rw-r--r--tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/borders/border-top-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/box-display/display-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/colors/color-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/fonts/font-variant-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/fonts/font-weight-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/generated-content/after-content-display-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/generated-content/before-content-display-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/linebox/line-height-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/linebox/vertical-align-baseline-009.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/lists/list-style-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/margin-padding-clear/margin-top-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/margin-padding-clear/padding-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/margin-padding-clear/padding-bottom-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/margin-padding-clear/padding-left-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/margin-padding-clear/padding-top-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-001.html.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-002.html.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-position-001.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-006.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-007.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-008.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-009.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-010.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-011.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-012.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-013.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-014.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/text/letter-spacing-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/text/text-decoration-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/text/text-indent-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/text/text-transform-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/CSS2/text/word-spacing-applies-to-015.xht.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/ortho-table-item-001.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-as-item-auto-min-width.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-as-item-fixed-min-width.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-as-item-inflexible-in-row-1.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-as-item-narrow-content.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-as-item-specified-width-vertical.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-as-item-wide-content.html.ini2
-rw-r--r--tests/wpt/meta/css/css-flexbox/table-item-flex-percentage-min-width.html.ini2
-rw-r--r--tests/wpt/meta/css/css-logical/animations/caption-side-no-interpolation.html.ini87
-rw-r--r--tests/wpt/meta/css/css-tables/caption-side-1.html.ini6
-rw-r--r--tests/wpt/meta/css/css-tables/inheritance.html.ini6
-rw-r--r--tests/wpt/meta/css/css-tables/parsing/caption-side-computed.html.ini6
-rw-r--r--tests/wpt/meta/css/css-tables/parsing/caption-side-valid.html.ini6
-rw-r--r--tests/wpt/meta/css/css-tables/table-model-fixup-2.html.ini9
-rw-r--r--tests/wpt/meta/css/css-tables/table-model-fixup.html.ini3
-rw-r--r--tests/wpt/meta/css/css-tables/tentative/caption.html.ini18
-rw-r--r--tests/wpt/meta/css/css-tables/tentative/table-minmax.html.ini3
-rw-r--r--tests/wpt/meta/css/css-text/white-space/ws-break-spaces-applies-to-015.html.ini2
-rw-r--r--tests/wpt/meta/css/css-transforms/transform-transformed-caption-contains-fixed-position.html.ini2
-rw-r--r--tests/wpt/meta/css/cssom-view/offsetTopLeft-table-caption.html.ini3
-rw-r--r--tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini3
-rw-r--r--tests/wpt/meta/css/cssom/serialize-values.html.ini9
-rw-r--r--tests/wpt/mozilla/meta/css/table_caption_bottom_a.html.ini2
-rw-r--r--tests/wpt/mozilla/meta/css/table_caption_top_a.html.ini2
76 files changed, 551 insertions, 322 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e0cf0870777..434deb75bbf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1288,7 +1288,7 @@ dependencies = [
[[package]]
name = "derive_common"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"darling",
"proc-macro2",
@@ -3751,7 +3751,7 @@ dependencies = [
[[package]]
name = "malloc_size_of"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"accountable-refcell",
"app_units",
@@ -5400,7 +5400,7 @@ dependencies = [
[[package]]
name = "selectors"
version = "0.24.0"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"bitflags 2.6.0",
"cssparser",
@@ -5688,7 +5688,7 @@ dependencies = [
[[package]]
name = "servo_arc"
version = "0.2.0"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"nodrop",
"serde",
@@ -5698,7 +5698,7 @@ dependencies = [
[[package]]
name = "servo_atoms"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"string_cache",
"string_cache_codegen",
@@ -5885,7 +5885,7 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "size_of_test"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"static_assertions",
]
@@ -6026,7 +6026,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "static_prefs"
version = "0.1.0"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
[[package]]
name = "strict-num"
@@ -6063,7 +6063,7 @@ dependencies = [
[[package]]
name = "style"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"app_units",
"arrayvec",
@@ -6121,7 +6121,7 @@ dependencies = [
[[package]]
name = "style_config"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"lazy_static",
]
@@ -6129,7 +6129,7 @@ dependencies = [
[[package]]
name = "style_derive"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"darling",
"derive_common",
@@ -6160,7 +6160,7 @@ dependencies = [
[[package]]
name = "style_traits"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"app_units",
"bitflags 2.6.0",
@@ -6510,7 +6510,7 @@ dependencies = [
[[package]]
name = "to_shmem"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"cssparser",
"servo_arc",
@@ -6523,7 +6523,7 @@ dependencies = [
[[package]]
name = "to_shmem_derive"
version = "0.0.1"
-source = "git+https://github.com/servo/stylo?branch=2024-05-31#e8a14bce9453ad5939eb0c34de150ad2f10d1bc2"
+source = "git+https://github.com/servo/stylo?branch=2024-05-31#141446aeea5a0741927c3c83de54a9512e12f4ab"
dependencies = [
"darling",
"derive_common",
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs
index f47136eba24..49d1e09974f 100644
--- a/components/layout_2020/flow/mod.rs
+++ b/components/layout_2020/flow/mod.rs
@@ -1367,9 +1367,9 @@ struct ContainingBlockPaddingAndBorder<'a> {
max_box_size: LogicalVec2<Option<Length>>,
}
-struct ResolvedMargins {
+pub(crate) struct ResolvedMargins {
/// Used value for the margin properties, as exposed in getComputedStyle().
- margin: LogicalSides<Au>,
+ pub margin: LogicalSides<Au>,
/// Distance between the border box and the containing block on the inline-start side.
/// This is typically the same as the inline-start margin, but can be greater when
@@ -1377,7 +1377,7 @@ struct ResolvedMargins {
/// The reason we aren't just adjusting the used margin-inline-start is that
/// this shouldn't be observable via getComputedStyle().
/// <https://drafts.csswg.org/css-align/#justify-self-property>
- effective_margin_inline_start: Au,
+ pub effective_margin_inline_start: Au,
}
/// Given the style for an in-flow box and its containing block, determine the containing
@@ -1440,7 +1440,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>(
/// Note that in the presence of floats, this shouldn't be used for a block-level box
/// that establishes an independent formatting context (or is replaced), since the
/// margins could then be incorrect.
-fn solve_margins(
+pub(crate) fn solve_margins(
containing_block: &ContainingBlock<'_>,
pbm: &PaddingBorderMargin,
inline_size: Au,
diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs
index f3c51e9579b..371201e09eb 100644
--- a/components/layout_2020/formatting_contexts.rs
+++ b/components/layout_2020/formatting_contexts.rs
@@ -7,6 +7,7 @@ use serde::Serialize;
use servo_arc::Arc;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
+use style::selector_parser::PseudoElement;
use style::values::specified::text::TextDecorationLine;
use crate::context::LayoutContext;
@@ -59,12 +60,21 @@ pub(crate) enum NonReplacedFormattingContextContents {
/// The baselines of a layout or a [`crate::fragment_tree::BoxFragment`]. Some layout
/// uses the first and some layout uses the last.
-#[derive(Debug, Default, Serialize)]
+#[derive(Clone, Copy, Debug, Default, Serialize)]
pub(crate) struct Baselines {
pub first: Option<Au>,
pub last: Option<Au>,
}
+impl Baselines {
+ pub(crate) fn offset(&self, block_offset: Au) -> Baselines {
+ Self {
+ first: self.first.map(|first| first + block_offset),
+ last: self.last.map(|last| last + block_offset),
+ }
+ }
+}
+
pub(crate) struct IndependentLayout {
pub fragments: Vec<Fragment>,
@@ -83,15 +93,16 @@ pub(crate) struct IndependentLayout {
}
impl IndependentFormattingContext {
- pub fn construct<'dom>(
+ pub fn construct<'dom, Node: NodeExt<'dom>>(
context: &LayoutContext,
- node_and_style_info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
+ node_and_style_info: &NodeAndStyleInfo<Node>,
display_inside: DisplayInside,
contents: Contents,
propagated_text_decoration_line: TextDecorationLine,
) -> Self {
match contents {
Contents::NonReplaced(non_replaced_contents) => {
+ let mut base_fragment_info: BaseFragmentInfo = node_and_style_info.into();
let contents = match display_inside {
DisplayInside::Flow { is_list_item } |
DisplayInside::FlowRoot { is_list_item } => {
@@ -114,17 +125,27 @@ impl IndependentFormattingContext {
))
},
DisplayInside::Table => {
+ let table_grid_style = context
+ .shared_context()
+ .stylist
+ .style_for_anonymous::<Node::ConcreteElement>(
+ &context.shared_context().guards,
+ &PseudoElement::ServoTableGrid,
+ &node_and_style_info.style,
+ );
+ base_fragment_info.flags.insert(FragmentFlags::DO_NOT_PAINT);
NonReplacedFormattingContextContents::Table(Table::construct(
context,
node_and_style_info,
+ table_grid_style,
non_replaced_contents,
propagated_text_decoration_line,
))
},
};
Self::NonReplaced(NonReplacedFormattingContext {
- base_fragment_info: node_and_style_info.into(),
style: Arc::clone(&node_and_style_info.style),
+ base_fragment_info,
content_sizes: None,
contents,
})
diff --git a/components/layout_2020/fragment_tree/base_fragment.rs b/components/layout_2020/fragment_tree/base_fragment.rs
index dacc082581d..a40174cf05e 100644
--- a/components/layout_2020/fragment_tree/base_fragment.rs
+++ b/components/layout_2020/fragment_tree/base_fragment.rs
@@ -85,22 +85,23 @@ bitflags! {
#[derive(Clone, Copy, Debug, Serialize)]
pub(crate) struct FragmentFlags: u8 {
/// Whether or not the node that created this fragment is a `<body>` element on an HTML document.
- const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 0b00000001;
+ const IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT = 1 << 0;
/// Whether or not the node that created this Fragment is a `<br>` element.
- const IS_BR_ELEMENT = 0b00000010;
+ const IS_BR_ELEMENT = 1 << 1;
/// Whether or not the node that created was a `<table>`, `<th>` or
/// `<td>` element. Note that this does *not* include elements with
/// `display: table` or `display: table-cell`.
- const IS_TABLE_TH_OR_TD_ELEMENT = 0b00000100;
+ const IS_TABLE_TH_OR_TD_ELEMENT = 1 << 2;
/// Whether or not this Fragment was created to contain a replaced element or is
/// a replaced element.
- const IS_REPLACED = 0b00001000;
+ const IS_REPLACED = 1 << 3;
/// Whether or not this Fragment was created to contain a list item marker
/// with a used value of `list-style-position: outside`.
- const IS_OUTSIDE_LIST_ITEM_MARKER = 0b00010000;
- /// Avoid painting the fragment, this is used for empty table cells when 'empty-cells' is 'hide'.
- /// This flag doesn't avoid hit-testing.
- const DO_NOT_PAINT = 0b00100000;
+ const IS_OUTSIDE_LIST_ITEM_MARKER = 1 << 4;
+ /// Avoid painting the borders, backgrounds, and drop shadow for this fragment, this is used
+ /// for empty table cells when 'empty-cells' is 'hide' and also table wrappers. This flag
+ /// doesn't avoid hit-testing nor does it prevent the painting outlines.
+ const DO_NOT_PAINT = 1 << 5;
}
}
diff --git a/components/layout_2020/fragment_tree/box_fragment.rs b/components/layout_2020/fragment_tree/box_fragment.rs
index a37cdbfb693..3c6d737c4d8 100644
--- a/components/layout_2020/fragment_tree/box_fragment.rs
+++ b/components/layout_2020/fragment_tree/box_fragment.rs
@@ -215,14 +215,18 @@ impl BoxFragment {
)
}
- pub fn padding_rect(&self) -> LogicalRect<Au> {
+ pub(crate) fn padding_rect(&self) -> LogicalRect<Au> {
self.content_rect.inflate(&self.padding)
}
- pub fn border_rect(&self) -> LogicalRect<Au> {
+ pub(crate) fn border_rect(&self) -> LogicalRect<Au> {
self.padding_rect().inflate(&self.border)
}
+ pub(crate) fn margin_rect(&self) -> LogicalRect<Au> {
+ self.border_rect().inflate(&self.margin)
+ }
+
pub fn print(&self, tree: &mut PrintTree) {
tree.new_level(format!(
"Box\
diff --git a/components/layout_2020/geom.rs b/components/layout_2020/geom.rs
index bb7b26f7661..41931e89617 100644
--- a/components/layout_2020/geom.rs
+++ b/components/layout_2020/geom.rs
@@ -370,6 +370,19 @@ impl<T: Add<Output = T> + Copy> Add<LogicalSides<T>> for LogicalSides<T> {
}
}
+impl<T: Sub<Output = T> + Copy> Sub<LogicalSides<T>> for LogicalSides<T> {
+ type Output = LogicalSides<T>;
+
+ fn sub(self, other: Self) -> Self::Output {
+ LogicalSides {
+ inline_start: self.inline_start - other.inline_start,
+ inline_end: self.inline_end - other.inline_end,
+ block_start: self.block_start - other.block_start,
+ block_end: self.block_end - other.block_end,
+ }
+ }
+}
+
impl<T: Neg<Output = T> + Copy> Neg for LogicalSides<T> {
type Output = LogicalSides<T>;
fn neg(self) -> Self::Output {
@@ -384,7 +397,7 @@ impl<T: Neg<Output = T> + Copy> Neg for LogicalSides<T> {
impl<T: Zero> LogicalSides<T> {
pub(crate) fn zero() -> LogicalSides<T> {
- LogicalSides {
+ Self {
inline_start: T::zero(),
inline_end: T::zero(),
block_start: T::zero(),
@@ -395,7 +408,7 @@ impl<T: Zero> LogicalSides<T> {
impl From<LogicalSides<CSSPixelLength>> for LogicalSides<Au> {
fn from(value: LogicalSides<CSSPixelLength>) -> Self {
- LogicalSides {
+ Self {
inline_start: value.inline_start.into(),
inline_end: value.inline_end.into(),
block_start: value.block_start.into(),
@@ -406,7 +419,7 @@ impl From<LogicalSides<CSSPixelLength>> for LogicalSides<Au> {
impl From<LogicalSides<Au>> for LogicalSides<CSSPixelLength> {
fn from(value: LogicalSides<Au>) -> Self {
- LogicalSides {
+ Self {
inline_start: value.inline_start.into(),
inline_end: value.inline_end.into(),
block_start: value.block_start.into(),
@@ -435,7 +448,7 @@ impl<T> LogicalRect<T> {
T: Add<Output = T> + Copy,
T: Sub<Output = T> + Copy,
{
- LogicalRect {
+ Self {
start_corner: LogicalVec2 {
inline: self.start_corner.inline - sides.inline_start,
block: self.start_corner.block - sides.block_start,
diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs
index 060bed97dc3..da3f94f88c1 100644
--- a/components/layout_2020/style_ext.rs
+++ b/components/layout_2020/style_ext.rs
@@ -134,6 +134,13 @@ impl PaddingBorderMargin {
padding_border_sums: LogicalVec2::zero(),
}
}
+
+ pub(crate) fn border_padding_start(&self) -> LogicalVec2<Au> {
+ LogicalVec2 {
+ inline: self.border.inline_start + self.padding.inline_start,
+ block: self.border.block_start + self.padding.block_start,
+ }
+ }
}
pub(crate) trait ComputedValuesExt {
diff --git a/components/layout_2020/table/construct.rs b/components/layout_2020/table/construct.rs
index fd2441daf18..9be0331aba1 100644
--- a/components/layout_2020/table/construct.rs
+++ b/components/layout_2020/table/construct.rs
@@ -15,8 +15,8 @@ use style::str::char_is_whitespace;
use style::values::specified::TextDecorationLine;
use super::{
- Table, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset, TableTrack,
- TableTrackGroup, TableTrackGroupType,
+ Table, TableCaption, TableSlot, TableSlotCell, TableSlotCoordinates, TableSlotOffset,
+ TableTrack, TableTrackGroup, TableTrackGroupType,
};
use crate::context::LayoutContext;
use crate::dom::{BoxSlot, NodeExt};
@@ -73,12 +73,14 @@ impl Table {
pub(crate) fn construct<'dom>(
context: &LayoutContext,
info: &NodeAndStyleInfo<impl NodeExt<'dom>>,
+ grid_style: Arc<ComputedValues>,
contents: NonReplacedContents,
propagated_text_decoration_line: TextDecorationLine,
) -> Self {
let text_decoration_line =
propagated_text_decoration_line | info.style.clone_text_decoration_line();
- let mut traversal = TableBuilderTraversal::new(context, info, text_decoration_line);
+ let mut traversal =
+ TableBuilderTraversal::new(context, info, grid_style, text_decoration_line);
contents.traverse(context, info, &mut traversal);
traversal.finish()
}
@@ -92,7 +94,7 @@ impl Table {
where
Node: crate::dom::NodeExt<'dom>,
{
- let anonymous_style = context
+ let grid_and_wrapper_style = context
.shared_context()
.stylist
.style_for_anonymous::<Node::ConcreteElement>(
@@ -100,10 +102,14 @@ impl Table {
&PseudoElement::ServoAnonymousTable,
&parent_info.style,
);
- let anonymous_info = parent_info.new_anonymous(anonymous_style.clone());
+ let anonymous_info = parent_info.new_anonymous(grid_and_wrapper_style.clone());
- let mut table_builder =
- TableBuilderTraversal::new(context, &anonymous_info, propagated_text_decoration_line);
+ let mut table_builder = TableBuilderTraversal::new(
+ context,
+ &anonymous_info,
+ grid_and_wrapper_style.clone(),
+ propagated_text_decoration_line,
+ );
for content in contents {
match content {
@@ -128,7 +134,7 @@ impl Table {
IndependentFormattingContext::NonReplaced(NonReplacedFormattingContext {
base_fragment_info: (&anonymous_info).into(),
- style: anonymous_style,
+ style: grid_and_wrapper_style,
content_sizes: None,
contents: NonReplacedFormattingContextContents::Table(table),
})
@@ -229,15 +235,23 @@ pub struct TableBuilder {
}
impl TableBuilder {
- pub(super) fn new(style: Arc<ComputedValues>) -> Self {
+ pub(super) fn new(
+ style: Arc<ComputedValues>,
+ grid_style: Arc<ComputedValues>,
+ base_fragment_info: BaseFragmentInfo,
+ ) -> Self {
Self {
- table: Table::new(style),
+ table: Table::new(style, grid_style, base_fragment_info),
incoming_rowspans: Vec::new(),
}
}
pub fn new_for_tests() -> Self {
- Self::new(ComputedValues::initial_values().to_arc())
+ Self::new(
+ ComputedValues::initial_values().to_arc(),
+ ComputedValues::initial_values().to_arc(),
+ BaseFragmentInfo::anonymous(),
+ )
}
pub fn last_row_index_in_row_group_at_row_n(&self, n: usize) -> usize {
@@ -622,13 +636,14 @@ where
pub(crate) fn new(
context: &'style LayoutContext<'style>,
info: &'style NodeAndStyleInfo<Node>,
+ grid_style: Arc<ComputedValues>,
text_decoration_line: TextDecorationLine,
) -> Self {
TableBuilderTraversal {
context,
info,
current_text_decoration_line: text_decoration_line,
- builder: TableBuilder::new(info.style.clone()),
+ builder: TableBuilder::new(info.style.clone(), grid_style, info.into()),
current_anonymous_row_content: Vec::new(),
current_row_group_index: None,
}
@@ -825,9 +840,28 @@ where
::std::mem::forget(box_slot);
},
DisplayLayoutInternal::TableCaption => {
- // TODO: Handle table captions.
+ let contents = match contents.try_into() {
+ Ok(non_replaced_contents) => {
+ BlockFormattingContext::construct(
+ self.context,
+ info,
+ non_replaced_contents,
+ self.current_text_decoration_line,
+ false, /* is_list_item */
+ )
+ },
+ Err(_replaced) => {
+ unreachable!("Replaced should not have a LayoutInternal display type.");
+ },
+ };
+ self.builder.table.captions.push(TableCaption {
+ contents,
+ style: info.style.clone(),
+ base_fragment_info: info.into(),
+ });
+
// We are doing this until we have actually set a Box for this `BoxSlot`.
- ::std::mem::forget(box_slot);
+ ::std::mem::forget(box_slot)
},
DisplayLayoutInternal::TableCell => {
self.current_anonymous_row_content
diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs
index 83a9839d4e7..1f4b5b511e5 100644
--- a/components/layout_2020/table/layout.rs
+++ b/components/layout_2020/table/layout.rs
@@ -10,6 +10,7 @@ use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIter
use servo_arc::Arc;
use style::computed_values::border_collapse::T as BorderCollapse;
use style::computed_values::box_sizing::T as BoxSizing;
+use style::computed_values::caption_side::T as CaptionSide;
use style::computed_values::empty_cells::T as EmptyCells;
use style::computed_values::visibility::T as Visibility;
use style::logical_geometry::WritingMode;
@@ -19,8 +20,9 @@ use style::values::generics::box_::{GenericVerticalAlign as VerticalAlign, Verti
use style::values::generics::length::GenericLengthPercentageOrAuto::{Auto, LengthPercentage};
use style::Zero;
-use super::{Table, TableSlot, TableSlotCell, TableTrack, TableTrackGroup};
+use super::{Table, TableCaption, TableSlot, TableSlotCell, TableTrack, TableTrackGroup};
use crate::context::LayoutContext;
+use crate::flow::{solve_margins, ResolvedMargins};
use crate::formatting_contexts::{Baselines, IndependentLayout};
use crate::fragment_tree::{
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
@@ -103,6 +105,7 @@ pub(crate) struct TableLayout<'a> {
rows: Vec<RowLayout>,
columns: Vec<ColumnLayout>,
cell_measures: Vec<Vec<LogicalVec2<CellOrTrackMeasure>>>,
+ table_width: Au,
assignable_width: Au,
final_table_height: Au,
column_measures: Vec<CellOrTrackMeasure>,
@@ -143,6 +146,7 @@ impl<'a> TableLayout<'a> {
rows: Vec::new(),
columns: Vec::new(),
cell_measures: Vec::new(),
+ table_width: Au::zero(),
assignable_width: Au::zero(),
final_table_height: Au::zero(),
column_measures: Vec::new(),
@@ -660,11 +664,57 @@ impl<'a> TableLayout<'a> {
grid_min_max
}
+ /// Compute CAPMIN: <https://drafts.csswg.org/css-tables/#capmin>
+ fn compute_caption_minimum_inline_size(
+ &mut self,
+ layout_context: &LayoutContext,
+ writing_mode: WritingMode,
+ ) -> Au {
+ self.table
+ .captions
+ .iter()
+ .map(|caption| {
+ let padding = caption
+ .style
+ .padding(writing_mode)
+ .percentages_relative_to(Length::zero());
+ let border = caption.style.border_width(writing_mode);
+ let margin = caption
+ .style
+ .margin(writing_mode)
+ .percentages_relative_to(Length::zero())
+ .auto_is(Length::zero);
+
+ let padding_border_sums = LogicalVec2 {
+ inline: (padding.inline_sum() + border.inline_sum() + margin.inline_sum())
+ .into(),
+ block: (padding.block_sum() + border.block_sum() + margin.block_sum()).into(),
+ };
+
+ let (size, min_size, max_size) =
+ get_outer_sizes_from_style(&caption.style, writing_mode, &padding_border_sums);
+ let mut inline_content_sizes = caption
+ .contents
+ .contents
+ .inline_content_sizes(layout_context, writing_mode);
+
+ inline_content_sizes.min_content += padding_border_sums.inline;
+ inline_content_sizes
+ .min_content
+ .min(max_size.inline)
+ .max(size.inline)
+ .max(min_size.inline)
+ })
+ .max()
+ .unwrap_or_default()
+ }
+
fn compute_table_width(
&mut self,
containing_block_for_children: &ContainingBlock,
containing_block_for_table: &ContainingBlock,
grid_min_max: ContentSizes,
+ caption_minimum_inline_size: Au,
) {
let style = &self.table.style;
self.pbm = style.padding_border_margin(containing_block_for_table);
@@ -679,9 +729,9 @@ impl<'a> TableLayout<'a> {
// https://drafts.csswg.org/css-tables/#used-width-of-table
// * If table-root has a computed value for inline-size different than auto:
- // use the maximum of the resolved table width and GRIDMIN.
+ // use the maximum of the resolved table width, GRIDMIN and CAPMIN.
// * If auto: use the resolved_table_width, clamped between GRIDMIN and GRIDMAX,
- // but at least as big as min-inline-size.
+ // but at least as big as min-inline-size and CAPMIN.
// This diverges a little from the specification, but should be equivalent
// (other than using the stretch-fit size instead of the containing block width).
let used_width_of_table = match style
@@ -701,6 +751,13 @@ impl<'a> TableLayout<'a> {
},
};
+ // Padding and border should apply to the table grid, but they are properties of the
+ // parent element (the table wrapper). In order to account for this, we subtract the
+ // border and padding inline size from the caption size.
+ let caption_minimum_inline_size =
+ caption_minimum_inline_size - self.pbm.padding_border_sums.inline;
+ self.table_width = used_width_of_table.max(caption_minimum_inline_size);
+
// > The assignable table width is the used width of the table minus the total horizontal
// > border spacing (if any). This is the width that we will be able to allocate to the
// > columns.
@@ -1438,8 +1495,83 @@ impl<'a> TableLayout<'a> {
self.row_sizes = row_sizes;
}
- /// Lay out the table of this [`TableLayout`] into fragments. This should only be be called
- /// after calling [`TableLayout.compute_measures`].
+ fn layout_caption(
+ &mut self,
+ caption: &TableCaption,
+ table_pbm: &PaddingBorderMargin,
+ layout_context: &LayoutContext,
+ containing_block: &ContainingBlock,
+ parent_positioning_context: &mut PositioningContext,
+ ) -> BoxFragment {
+ let pbm = caption.style.padding_border_margin(containing_block);
+ let box_size = caption.style.content_box_size(containing_block, &pbm);
+ let max_box_size = caption.style.content_max_box_size(containing_block, &pbm);
+ let min_box_size = caption
+ .style
+ .content_min_box_size(containing_block, &pbm)
+ .auto_is(Length::zero);
+ let block_size = box_size.block.map(|block_size| {
+ block_size.clamp_between_extremums(min_box_size.block, max_box_size.block)
+ });
+
+ let table_inline_content_size = self.table_width - pbm.padding_border_sums.inline +
+ table_pbm.padding_border_sums.inline;
+ let inline_size = box_size
+ .inline
+ .auto_is(|| table_inline_content_size.into())
+ .clamp_between_extremums(min_box_size.inline, max_box_size.inline);
+
+ let containing_block_for_children = &ContainingBlock {
+ inline_size: inline_size.into(),
+ block_size: block_size.map(|t| t.into()),
+ style: &caption.style,
+ };
+
+ let mut positioning_context = PositioningContext::new_for_style(&caption.style);
+ let layout = caption.contents.layout(
+ layout_context,
+ positioning_context
+ .as_mut()
+ .unwrap_or(parent_positioning_context),
+ containing_block_for_children,
+ );
+
+ if let Some(positioning_context) = positioning_context.take() {
+ parent_positioning_context.append(positioning_context);
+ }
+
+ let ResolvedMargins {
+ margin,
+ effective_margin_inline_start,
+ } = solve_margins(containing_block, &pbm, containing_block.inline_size);
+ let content_rect = LogicalRect {
+ start_corner: LogicalVec2 {
+ inline: effective_margin_inline_start +
+ pbm.border.inline_start +
+ pbm.padding.inline_start,
+ block: margin.block_start + pbm.border.block_start + pbm.padding.block_start,
+ },
+ size: LogicalVec2 {
+ inline: inline_size.into(),
+ block: layout.content_block_size,
+ },
+ };
+
+ BoxFragment::new(
+ caption.base_fragment_info,
+ caption.style.clone(),
+ layout.fragments,
+ content_rect,
+ pbm.padding,
+ pbm.border,
+ margin,
+ None, /* clearance */
+ CollapsedBlockMargins::zero(),
+ )
+ }
+
+ /// Lay out the table (grid and captions) of this [`TableLayout`] into fragments. This should
+ /// only be be called after calling [`TableLayout.compute_measures`].
fn layout(
mut self,
layout_context: &LayoutContext,
@@ -1449,18 +1581,144 @@ impl<'a> TableLayout<'a> {
) -> IndependentLayout {
let writing_mode = containing_block_for_children.style.writing_mode;
let grid_min_max = self.compute_grid_min_max(layout_context, writing_mode);
+ let caption_minimum_inline_size =
+ self.compute_caption_minimum_inline_size(layout_context, writing_mode);
self.compute_table_width(
containing_block_for_children,
containing_block_for_table,
grid_min_max,
+ caption_minimum_inline_size,
);
- self.distributed_column_widths = self.distribute_width_to_columns();
+ // The table wrapper is the one that has the CSS properties for the grid's border and padding. This
+ // weirdness is difficult to express in Servo's layout system. We have the wrapper size itself as if
+ // those properties applied to it and then just account for the discrepency in sizing here. In reality,
+ // the wrapper does not draw borders / backgrounds and all of its content (grid and captions) are
+ // placed with a negative offset in the table wrapper's content box so that they overlap the undrawn
+ // border / padding area.
+ //
+ // TODO: This is a pretty large hack. It would be nicer to actually have the grid sized properly,
+ // but it works for now.
+ let table_pbm = self
+ .table
+ .style
+ .padding_border_margin(containing_block_for_table);
+ let offset_from_wrapper = -table_pbm.padding - table_pbm.border;
+ let mut current_block_offset = offset_from_wrapper.block_start;
+
+ let mut table_layout = IndependentLayout {
+ fragments: Vec::new(),
+ content_block_size: Zero::zero(),
+ content_inline_size_for_table: None,
+ baselines: Baselines::default(),
+ };
+
+ table_layout
+ .fragments
+ .extend(self.table.captions.iter().filter_map(|caption| {
+ if caption.style.clone_caption_side() != CaptionSide::Top {
+ return None;
+ }
+
+ let original_positioning_context_length = positioning_context.len();
+ let mut caption_fragment = self.layout_caption(
+ caption,
+ &table_pbm,
+ layout_context,
+ containing_block_for_children,
+ positioning_context,
+ );
+
+ caption_fragment.content_rect.start_corner.inline +=
+ offset_from_wrapper.inline_start;
+ caption_fragment.content_rect.start_corner.block += current_block_offset;
+ current_block_offset += caption_fragment.margin_rect().size.block;
+
+ let caption_fragment = Fragment::Box(caption_fragment);
+ positioning_context.adjust_static_position_of_hoisted_fragments(
+ &caption_fragment,
+ original_positioning_context_length,
+ );
+ Some(caption_fragment)
+ }));
+
+ let original_positioning_context_length = positioning_context.len();
+ let mut grid_fragment = self.layout_grid(
+ layout_context,
+ &table_pbm,
+ positioning_context,
+ containing_block_for_children,
+ containing_block_for_table,
+ );
+
+ // Take the baseline of the grid fragment, after adjusting it to be in the coordinate system
+ // of the table wrapper.
+ table_layout.baselines = grid_fragment
+ .baselines
+ .offset(current_block_offset + grid_fragment.content_rect.start_corner.block);
+
+ grid_fragment.content_rect.start_corner.inline += offset_from_wrapper.inline_start;
+ grid_fragment.content_rect.start_corner.block += current_block_offset;
+ current_block_offset += grid_fragment.border_rect().size.block;
+ table_layout.content_inline_size_for_table = Some(grid_fragment.content_rect.size.inline);
+
+ let grid_fragment = Fragment::Box(grid_fragment);
+ positioning_context.adjust_static_position_of_hoisted_fragments(
+ &grid_fragment,
+ original_positioning_context_length,
+ );
+ table_layout.fragments.push(grid_fragment);
+
+ table_layout
+ .fragments
+ .extend(self.table.captions.iter().filter_map(|caption| {
+ if caption.style.clone_caption_side() != CaptionSide::Bottom {
+ return None;
+ }
+
+ let original_positioning_context_length = positioning_context.len();
+ let mut caption_fragment = self.layout_caption(
+ caption,
+ &table_pbm,
+ layout_context,
+ containing_block_for_children,
+ positioning_context,
+ );
+
+ caption_fragment.content_rect.start_corner.inline +=
+ offset_from_wrapper.inline_start;
+ caption_fragment.content_rect.start_corner.block += current_block_offset;
+ current_block_offset += caption_fragment.margin_rect().size.block;
+
+ let caption_fragment = Fragment::Box(caption_fragment);
+ positioning_context.adjust_static_position_of_hoisted_fragments(
+ &caption_fragment,
+ original_positioning_context_length,
+ );
+ Some(caption_fragment)
+ }));
+
+ table_layout.content_block_size = current_block_offset + offset_from_wrapper.block_end;
+ table_layout
+ }
+
+ /// Lay out the grid portion of this [`TableLayout`] into fragments. This should only be be
+ /// called after calling [`TableLayout.compute_measures`].
+ fn layout_grid(
+ &mut self,
+ layout_context: &LayoutContext,
+ table_pbm: &PaddingBorderMargin,
+ positioning_context: &mut PositioningContext,
+ containing_block_for_children: &ContainingBlock,
+ containing_block_for_table: &ContainingBlock,
+ ) -> BoxFragment {
+ self.distributed_column_widths = self.distribute_width_to_columns();
self.layout_cells_in_row(
layout_context,
containing_block_for_children,
positioning_context,
);
+ let writing_mode = containing_block_for_children.style.writing_mode;
let first_layout_row_heights = self.do_first_row_layout(writing_mode);
self.compute_table_height_and_final_row_heights(
first_layout_row_heights,
@@ -1471,24 +1729,35 @@ 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 mut baselines = Baselines::default();
- let mut table_fragments = Vec::new();
-
if self.table.size.width == 0 && self.table.size.height == 0 {
- return IndependentLayout {
- fragments: table_fragments,
- content_block_size: self.final_table_height,
- content_inline_size_for_table: Some(self.assignable_width),
- baselines,
+ let content_rect = LogicalRect {
+ start_corner: table_pbm.border_padding_start(),
+ size: LogicalVec2 {
+ inline: self.table_width,
+ block: self.final_table_height,
+ },
};
+ return BoxFragment::new(
+ self.table.grid_base_fragment_info,
+ self.table.grid_style.clone(),
+ Vec::new(),
+ content_rect,
+ table_pbm.padding,
+ table_pbm.border,
+ LogicalSides::zero(),
+ None, /* clearance */
+ CollapsedBlockMargins::zero(),
+ );
}
- let table_and_track_dimensions = TableAndTrackDimensions::new(&self);
+ let mut table_fragments = Vec::new();
+ let table_and_track_dimensions = TableAndTrackDimensions::new(self);
self.make_fragments_for_columns_and_column_groups(
&table_and_track_dimensions,
&mut table_fragments,
);
+ let mut baselines = Baselines::default();
let mut row_group_fragment_layout = None;
for row_index in 0..self.table.size.height {
// From <https://drafts.csswg.org/css-align-3/#baseline-export>
@@ -1589,14 +1858,25 @@ impl<'a> TableLayout<'a> {
)));
}
- IndependentLayout {
- fragments: table_fragments,
- content_block_size: table_and_track_dimensions.table_rect.max_block_position(),
- content_inline_size_for_table: Some(
- table_and_track_dimensions.table_rect.max_inline_position(),
- ),
- baselines,
- }
+ let content_rect = LogicalRect {
+ start_corner: table_pbm.border_padding_start(),
+ size: LogicalVec2 {
+ inline: table_and_track_dimensions.table_rect.max_inline_position(),
+ block: table_and_track_dimensions.table_rect.max_block_position(),
+ },
+ };
+ BoxFragment::new(
+ self.table.grid_base_fragment_info,
+ self.table.grid_style.clone(),
+ table_fragments,
+ content_rect,
+ table_pbm.padding,
+ table_pbm.border,
+ LogicalSides::zero(),
+ None, /* clearance */
+ CollapsedBlockMargins::zero(),
+ )
+ .with_baselines(baselines)
}
fn is_row_collapsed(&self, row_index: usize) -> bool {
@@ -1928,6 +2208,7 @@ impl RowGroupFragmentLayout {
row_group_fragment
}
}
+
struct TableAndTrackDimensions {
/// The rect of the full table, not counting for borders, padding, and margin.
table_rect: LogicalRect<Au>,
@@ -2109,7 +2390,32 @@ impl Table {
layout_context: &LayoutContext,
writing_mode: WritingMode,
) -> ContentSizes {
- TableLayout::new(self).compute_grid_min_max(layout_context, writing_mode)
+ let mut layout = TableLayout::new(self);
+ let mut table_content_sizes = layout.compute_grid_min_max(layout_context, writing_mode);
+
+ let mut caption_minimum_inline_size =
+ layout.compute_caption_minimum_inline_size(layout_context, writing_mode);
+ if caption_minimum_inline_size > table_content_sizes.min_content ||
+ caption_minimum_inline_size > table_content_sizes.max_content
+ {
+ // 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
+ // this code removes their contribution from the inline content size of the caption.
+ let padding = self
+ .style
+ .padding(writing_mode)
+ .percentages_relative_to(Length::zero());
+ let border = self.style.border_width(writing_mode);
+ caption_minimum_inline_size -= (padding.inline_sum() + border.inline_sum()).into();
+ table_content_sizes
+ .min_content
+ .max_assign(caption_minimum_inline_size);
+ table_content_sizes
+ .max_content
+ .max_assign(caption_minimum_inline_size);
+ }
+
+ table_content_sizes
}
fn get_column_measure_for_column_at_index(
diff --git a/components/layout_2020/table/mod.rs b/components/layout_2020/table/mod.rs
index 470cf287f7d..43b3544be52 100644
--- a/components/layout_2020/table/mod.rs
+++ b/components/layout_2020/table/mod.rs
@@ -86,10 +86,24 @@ pub type TableSize = Size2D<usize, UnknownUnit>;
#[derive(Debug, Serialize)]
pub struct Table {
- /// The style of this table.
+ /// The style of this table. These are the properties that apply to the "wrapper" ie the element
+ /// that contains both the grid and the captions. Not all properties are actually used on the
+ /// wrapper though, such as background and borders, which apply to the grid.
#[serde(skip_serializing)]
style: Arc<ComputedValues>,
+ /// The style of this table's grid. This is an anonymous style based on the table's style, but
+ /// eliminating all the properties handled by the "wrapper."
+ #[serde(skip_serializing)]
+ grid_style: Arc<ComputedValues>,
+
+ /// The [`BaseFragmentInfo`] for this table's grid. This is necessary so that when the
+ /// grid has a background image, it can be associated with the table's node.
+ grid_base_fragment_info: BaseFragmentInfo,
+
+ /// The captions for this table.
+ pub captions: Vec<TableCaption>,
+
/// The column groups for this table.
pub column_groups: Vec<TableTrackGroup>,
@@ -114,9 +128,16 @@ pub struct Table {
}
impl Table {
- pub(crate) fn new(style: Arc<ComputedValues>) -> Self {
+ pub(crate) fn new(
+ style: Arc<ComputedValues>,
+ grid_style: Arc<ComputedValues>,
+ base_fragment_info: BaseFragmentInfo,
+ ) -> Self {
Self {
style,
+ grid_style,
+ grid_base_fragment_info: base_fragment_info,
+ captions: Vec::new(),
column_groups: Vec::new(),
columns: Vec::new(),
row_groups: Vec::new(),
@@ -291,3 +312,16 @@ impl TableTrackGroup {
self.track_range.is_empty()
}
}
+
+#[derive(Debug, Serialize)]
+pub struct TableCaption {
+ /// The contents of this cell, with its own layout.
+ contents: BlockFormattingContext,
+
+ /// The style of this table cell.
+ #[serde(skip_serializing)]
+ style: Arc<ComputedValues>,
+
+ /// The [`BaseFragmentInfo`] of this cell.
+ base_fragment_info: BaseFragmentInfo,
+}
diff --git a/resources/servo.css b/resources/servo.css
index e3d21e69665..372d8afcf9d 100644
--- a/resources/servo.css
+++ b/resources/servo.css
@@ -231,6 +231,41 @@ svg > * {
display: table-cell;
}
+*|*::-servo-table-grid {
+ all: inherit;
+ margin: unset;
+ float: unset;
+ clear: unset;
+ position: unset;
+ z-index: unset;
+ page-break-before: unset;
+ page-break-after: unset;
+ page-break-inside: unset;
+ vertical-align: unset;
+ line-height: unset;
+ transform: unset;
+ transform-origin: unset;
+ backface-visibility: unset;
+ clip: unset;
+ transform-style: unset;
+ rotate: unset;
+ scale: unset;
+ translate: unset;
+ align-self: unset;
+ justify-self: unset;
+ grid-column-start: unset;
+ grid-column-end: unset;
+ grid-row-start: unset;
+ grid-row-end: unset;
+ order: unset;
+ outline: unset;
+ outline-offset: unset;
+ column-span: unset;
+ contain: unset;
+ container: unset;
+ scroll-margin: unset;
+}
+
*|*::-servo-legacy-anonymous-block {
display: block;
position: static;
diff --git a/resources/user-agent.css b/resources/user-agent.css
index 923eeed7099..e7acd5fdf2c 100644
--- a/resources/user-agent.css
+++ b/resources/user-agent.css
@@ -204,7 +204,10 @@ dir, menu, ul { list-style-type: disc; }
table { display: table; }
-caption { display: table-caption; }
+caption {
+ display: table-caption;
+ text-align: center;
+}
colgroup, colgroup[hidden] { display: table-column-group; }
col, col[hidden] { display: table-column; }
thead, thead[hidden] { display: table-header-group; }
diff --git a/tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-015.xht.ini
deleted file mode 100644
index f74820c498c..00000000000
--- a/tests/wpt/meta/css/CSS2/borders/border-bottom-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[border-bottom-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-015.xht.ini
deleted file mode 100644
index 509621c7280..00000000000
--- a/tests/wpt/meta/css/CSS2/borders/border-bottom-color-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[border-bottom-color-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-015.xht.ini
deleted file mode 100644
index 04b83402508..00000000000
--- a/tests/wpt/meta/css/CSS2/borders/border-bottom-width-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[border-bottom-width-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/borders/border-top-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-top-applies-to-015.xht.ini
deleted file mode 100644
index 49fb61b624c..00000000000
--- a/tests/wpt/meta/css/CSS2/borders/border-top-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[border-top-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-015.xht.ini
deleted file mode 100644
index b628c8624cf..00000000000
--- a/tests/wpt/meta/css/CSS2/borders/border-top-color-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[border-top-color-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-015.xht.ini
deleted file mode 100644
index 1a04639f826..00000000000
--- a/tests/wpt/meta/css/CSS2/borders/border-top-width-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[border-top-width-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/box-display/display-015.xht.ini b/tests/wpt/meta/css/CSS2/box-display/display-015.xht.ini
deleted file mode 100644
index c8bd43b5722..00000000000
--- a/tests/wpt/meta/css/CSS2/box-display/display-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[display-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/colors/color-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/colors/color-applies-to-015.xht.ini
deleted file mode 100644
index c5be6b4fcad..00000000000
--- a/tests/wpt/meta/css/CSS2/colors/color-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[color-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/fonts/font-variant-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/fonts/font-variant-applies-to-015.xht.ini
deleted file mode 100644
index b12295ca545..00000000000
--- a/tests/wpt/meta/css/CSS2/fonts/font-variant-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[font-variant-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/fonts/font-weight-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/fonts/font-weight-applies-to-015.xht.ini
deleted file mode 100644
index 0a3c57259a4..00000000000
--- a/tests/wpt/meta/css/CSS2/fonts/font-weight-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[font-weight-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/generated-content/after-content-display-015.xht.ini b/tests/wpt/meta/css/CSS2/generated-content/after-content-display-015.xht.ini
deleted file mode 100644
index e9068264d75..00000000000
--- a/tests/wpt/meta/css/CSS2/generated-content/after-content-display-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[after-content-display-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/generated-content/before-content-display-015.xht.ini b/tests/wpt/meta/css/CSS2/generated-content/before-content-display-015.xht.ini
deleted file mode 100644
index 3ea1cad9ddd..00000000000
--- a/tests/wpt/meta/css/CSS2/generated-content/before-content-display-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[before-content-display-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/linebox/line-height-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/linebox/line-height-applies-to-015.xht.ini
deleted file mode 100644
index 965f8f2c7a1..00000000000
--- a/tests/wpt/meta/css/CSS2/linebox/line-height-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-height-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/linebox/vertical-align-baseline-009.xht.ini b/tests/wpt/meta/css/CSS2/linebox/vertical-align-baseline-009.xht.ini
deleted file mode 100644
index 458ab806e46..00000000000
--- a/tests/wpt/meta/css/CSS2/linebox/vertical-align-baseline-009.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[vertical-align-baseline-009.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/lists/list-style-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/lists/list-style-applies-to-015.xht.ini
deleted file mode 100644
index cff7cba4888..00000000000
--- a/tests/wpt/meta/css/CSS2/lists/list-style-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[list-style-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-015.xht.ini
deleted file mode 100644
index 1798a437e27..00000000000
--- a/tests/wpt/meta/css/CSS2/lists/list-style-type-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[list-style-type-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-top-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-top-applies-to-015.xht.ini
deleted file mode 100644
index a8b289dbfb7..00000000000
--- a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-top-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[margin-top-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-applies-to-015.xht.ini
deleted file mode 100644
index d8aa2ff7141..00000000000
--- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[padding-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-bottom-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-bottom-applies-to-015.xht.ini
deleted file mode 100644
index a5a1ac2c2de..00000000000
--- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-bottom-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[padding-bottom-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-left-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-left-applies-to-015.xht.ini
deleted file mode 100644
index 226ba35e787..00000000000
--- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-left-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[padding-left-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-applies-to-015.xht.ini
deleted file mode 100644
index c8c570931b3..00000000000
--- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[padding-right-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-top-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-top-applies-to-015.xht.ini
deleted file mode 100644
index 70fd090c766..00000000000
--- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-top-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[padding-top-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-001.html.ini b/tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-001.html.ini
deleted file mode 100644
index 8447f55fe0a..00000000000
--- a/tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-001.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[margin-collapsing-in-table-caption-001.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-002.html.ini b/tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-002.html.ini
deleted file mode 100644
index 770c5517817..00000000000
--- a/tests/wpt/meta/css/CSS2/normal-flow/margin-collapsing-in-table-caption-002.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[margin-collapsing-in-table-caption-002.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-position-001.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-position-001.xht.ini
deleted file mode 100644
index 4dbeae98742..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-position-001.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-position-001.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-006.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-006.xht.ini
deleted file mode 100644
index 6f29c8befb5..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-006.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-006.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-007.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-007.xht.ini
deleted file mode 100644
index fb449a5f070..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-007.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-007.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-008.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-008.xht.ini
deleted file mode 100644
index 1065189ac29..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-008.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-008.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-009.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-009.xht.ini
deleted file mode 100644
index 0eb716ec044..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-009.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-009.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-010.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-010.xht.ini
deleted file mode 100644
index ecd8fa88f55..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-010.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-010.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-011.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-011.xht.ini
deleted file mode 100644
index 5dd2590cb1c..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-011.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-011.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-012.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-012.xht.ini
deleted file mode 100644
index 65c46ff0a75..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-012.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-012.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-013.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-013.xht.ini
deleted file mode 100644
index b5471a03bda..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-013.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-013.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-014.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-014.xht.ini
deleted file mode 100644
index e0966065d5d..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-014.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-014.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-015.xht.ini
deleted file mode 100644
index 2f2675cece7..00000000000
--- a/tests/wpt/meta/css/CSS2/tables/caption-side-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[caption-side-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/text/letter-spacing-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/text/letter-spacing-applies-to-015.xht.ini
deleted file mode 100644
index e15edb39650..00000000000
--- a/tests/wpt/meta/css/CSS2/text/letter-spacing-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[letter-spacing-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/text/text-decoration-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/text/text-decoration-applies-to-015.xht.ini
deleted file mode 100644
index dd7caa8ee49..00000000000
--- a/tests/wpt/meta/css/CSS2/text/text-decoration-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-decoration-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/text/text-indent-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/text/text-indent-applies-to-015.xht.ini
deleted file mode 100644
index 2dcd790e658..00000000000
--- a/tests/wpt/meta/css/CSS2/text/text-indent-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-indent-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/text/text-transform-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/text/text-transform-applies-to-015.xht.ini
deleted file mode 100644
index ebd188fa5b6..00000000000
--- a/tests/wpt/meta/css/CSS2/text/text-transform-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[text-transform-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/CSS2/text/word-spacing-applies-to-015.xht.ini b/tests/wpt/meta/css/CSS2/text/word-spacing-applies-to-015.xht.ini
deleted file mode 100644
index dfb88f5b61b..00000000000
--- a/tests/wpt/meta/css/CSS2/text/word-spacing-applies-to-015.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[word-spacing-applies-to-015.xht]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/ortho-table-item-001.html.ini b/tests/wpt/meta/css/css-flexbox/ortho-table-item-001.html.ini
deleted file mode 100644
index daeef2a8126..00000000000
--- a/tests/wpt/meta/css/css-flexbox/ortho-table-item-001.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[ortho-table-item-001.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-as-item-auto-min-width.html.ini b/tests/wpt/meta/css/css-flexbox/table-as-item-auto-min-width.html.ini
deleted file mode 100644
index 36fcb74f5cc..00000000000
--- a/tests/wpt/meta/css/css-flexbox/table-as-item-auto-min-width.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[table-as-item-auto-min-width.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-as-item-fixed-min-width.html.ini b/tests/wpt/meta/css/css-flexbox/table-as-item-fixed-min-width.html.ini
deleted file mode 100644
index 5c4258e48f2..00000000000
--- a/tests/wpt/meta/css/css-flexbox/table-as-item-fixed-min-width.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[table-as-item-fixed-min-width.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-as-item-inflexible-in-row-1.html.ini b/tests/wpt/meta/css/css-flexbox/table-as-item-inflexible-in-row-1.html.ini
new file mode 100644
index 00000000000..7667ce7e1c1
--- /dev/null
+++ b/tests/wpt/meta/css/css-flexbox/table-as-item-inflexible-in-row-1.html.ini
@@ -0,0 +1,2 @@
+[table-as-item-inflexible-in-row-1.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-as-item-narrow-content.html.ini b/tests/wpt/meta/css/css-flexbox/table-as-item-narrow-content.html.ini
new file mode 100644
index 00000000000..194e30876c1
--- /dev/null
+++ b/tests/wpt/meta/css/css-flexbox/table-as-item-narrow-content.html.ini
@@ -0,0 +1,2 @@
+[table-as-item-narrow-content.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-as-item-specified-width-vertical.html.ini b/tests/wpt/meta/css/css-flexbox/table-as-item-specified-width-vertical.html.ini
new file mode 100644
index 00000000000..59aeed11f53
--- /dev/null
+++ b/tests/wpt/meta/css/css-flexbox/table-as-item-specified-width-vertical.html.ini
@@ -0,0 +1,2 @@
+[table-as-item-specified-width-vertical.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-as-item-wide-content.html.ini b/tests/wpt/meta/css/css-flexbox/table-as-item-wide-content.html.ini
deleted file mode 100644
index f6def90a63b..00000000000
--- a/tests/wpt/meta/css/css-flexbox/table-as-item-wide-content.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[table-as-item-wide-content.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-flexbox/table-item-flex-percentage-min-width.html.ini b/tests/wpt/meta/css/css-flexbox/table-item-flex-percentage-min-width.html.ini
new file mode 100644
index 00000000000..219a9e04af7
--- /dev/null
+++ b/tests/wpt/meta/css/css-flexbox/table-item-flex-percentage-min-width.html.ini
@@ -0,0 +1,2 @@
+[table-item-flex-percentage-min-width.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-logical/animations/caption-side-no-interpolation.html.ini b/tests/wpt/meta/css/css-logical/animations/caption-side-no-interpolation.html.ini
index a57ebc9aebe..286423af770 100644
--- a/tests/wpt/meta/css/css-logical/animations/caption-side-no-interpolation.html.ini
+++ b/tests/wpt/meta/css/css-logical/animations/caption-side-no-interpolation.html.ini
@@ -8,60 +8,6 @@
[CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (0.3) should be [initial\]]
expected: FAIL
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (0.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (0.6) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (1) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (1.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (-0.3) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (0) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (0.3) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (0.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (0.6) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (1) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition: all: property <caption-side> from [initial\] to [bottom\] at (1.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (-0.3) should be [initial\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (0) should be [initial\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (0.3) should be [initial\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (0.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (0.6) should be [bottom\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (1) should be [bottom\]]
- expected: FAIL
-
- [CSS Animations: property <caption-side> from [initial\] to [bottom\] at (1.5) should be [bottom\]]
- expected: FAIL
-
[Web Animations: property <caption-side> from [initial\] to [bottom\] at (-0.3) should be [initial\]]
expected: FAIL
@@ -83,15 +29,6 @@
[Web Animations: property <caption-side> from [initial\] to [bottom\] at (1.5) should be [bottom\]]
expected: FAIL
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (-0.3) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (0) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions: property <caption-side> from [initial\] to [bottom\] at (0.3) should be [bottom\]]
- expected: FAIL
-
[CSS Transitions with transition-behavior:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (-0.3) should be [initial\]]
expected: FAIL
@@ -101,18 +38,6 @@
[CSS Transitions with transition-behavior:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (0.3) should be [initial\]]
expected: FAIL
- [CSS Transitions with transition-behavior:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (0.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition-behavior:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (0.6) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition-behavior:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (1) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition-behavior:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (1.5) should be [bottom\]]
- expected: FAIL
-
[CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (-0.3) should be [initial\]]
expected: FAIL
@@ -121,15 +46,3 @@
[CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (0.3) should be [initial\]]
expected: FAIL
-
- [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (0.5) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (0.6) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (1) should be [bottom\]]
- expected: FAIL
-
- [CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <caption-side> from [initial\] to [bottom\] at (1.5) should be [bottom\]]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/caption-side-1.html.ini b/tests/wpt/meta/css/css-tables/caption-side-1.html.ini
deleted file mode 100644
index 66f828849f5..00000000000
--- a/tests/wpt/meta/css/css-tables/caption-side-1.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[caption-side-1.html]
- [Caption-side inherits and reorder captions properly]
- expected: FAIL
-
- [Multiple captions can be rendered]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/inheritance.html.ini b/tests/wpt/meta/css/css-tables/inheritance.html.ini
index 26943f34e40..62356a03798 100644
--- a/tests/wpt/meta/css/css-tables/inheritance.html.ini
+++ b/tests/wpt/meta/css/css-tables/inheritance.html.ini
@@ -2,12 +2,6 @@
[Property border-spacing has initial value 0px 0px]
expected: FAIL
- [Property caption-side has initial value top]
- expected: FAIL
-
- [Property caption-side inherits]
- expected: FAIL
-
[Property table-layout has initial value auto]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/parsing/caption-side-computed.html.ini b/tests/wpt/meta/css/css-tables/parsing/caption-side-computed.html.ini
deleted file mode 100644
index 2f104eb8501..00000000000
--- a/tests/wpt/meta/css/css-tables/parsing/caption-side-computed.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[caption-side-computed.html]
- [Property caption-side value 'top']
- expected: FAIL
-
- [Property caption-side value 'bottom']
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/parsing/caption-side-valid.html.ini b/tests/wpt/meta/css/css-tables/parsing/caption-side-valid.html.ini
deleted file mode 100644
index 8fe563c6a34..00000000000
--- a/tests/wpt/meta/css/css-tables/parsing/caption-side-valid.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[caption-side-valid.html]
- [e.style['caption-side'\] = "top" should set the property value]
- expected: FAIL
-
- [e.style['caption-side'\] = "bottom" should set the property value]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/table-model-fixup-2.html.ini b/tests/wpt/meta/css/css-tables/table-model-fixup-2.html.ini
index 0aff17eb1bd..42047b7a07c 100644
--- a/tests/wpt/meta/css/css-tables/table-model-fixup-2.html.ini
+++ b/tests/wpt/meta/css/css-tables/table-model-fixup-2.html.ini
@@ -31,3 +31,12 @@
[Replaced elements outside a table cannot be table-row-group and are considered inline -- input=button elements]
expected: FAIL
+
+ [Replaced elements outside a table cannot be table-caption and are considered inline -- input=text elements]
+ expected: FAIL
+
+ [Replaced elements outside a table cannot be table-caption and are considered inline -- input=button elements]
+ expected: FAIL
+
+ [Replaced elements outside a table cannot be table-caption and are considered inline -- input=file elements]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/table-model-fixup.html.ini b/tests/wpt/meta/css/css-tables/table-model-fixup.html.ini
index ddfbf98f98f..1320421ad7b 100644
--- a/tests/wpt/meta/css/css-tables/table-model-fixup.html.ini
+++ b/tests/wpt/meta/css/css-tables/table-model-fixup.html.ini
@@ -8,9 +8,6 @@
[2.2. An anonymous table-row box must be generated around each sequence of consecutive children of a table-row-grouping box which are not table-row boxes. (2/3)]
expected: FAIL
- [3.2. An anonymous table or inline-table box must be generated around each sequence of consecutive proper table child box which are misparented]
- expected: FAIL
-
[2.2. An anonymous table-row box must be generated around each sequence of consecutive children of a table-row-grouping box which are not table-row boxes. (3/3)]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/tentative/caption.html.ini b/tests/wpt/meta/css/css-tables/tentative/caption.html.ini
index 1d11aa17b5e..de18b1f2815 100644
--- a/tests/wpt/meta/css/css-tables/tentative/caption.html.ini
+++ b/tests/wpt/meta/css/css-tables/tentative/caption.html.ini
@@ -8,24 +8,6 @@
[table 3]
expected: FAIL
- [table 7]
- expected: FAIL
-
- [table 8]
- expected: FAIL
-
- [table 9]
- expected: FAIL
-
- [table 10]
- expected: FAIL
-
- [table 4]
- expected: FAIL
-
- [table 5]
- expected: FAIL
-
[table 12]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/tentative/table-minmax.html.ini b/tests/wpt/meta/css/css-tables/tentative/table-minmax.html.ini
index 7d91a220df5..8b849af0f55 100644
--- a/tests/wpt/meta/css/css-tables/tentative/table-minmax.html.ini
+++ b/tests/wpt/meta/css/css-tables/tentative/table-minmax.html.ini
@@ -5,9 +5,6 @@
[table 5]
expected: FAIL
- [table 16]
- expected: FAIL
-
[table 1]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/white-space/ws-break-spaces-applies-to-015.html.ini b/tests/wpt/meta/css/css-text/white-space/ws-break-spaces-applies-to-015.html.ini
deleted file mode 100644
index 9d9b0a4bf12..00000000000
--- a/tests/wpt/meta/css/css-text/white-space/ws-break-spaces-applies-to-015.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[ws-break-spaces-applies-to-015.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-transforms/transform-transformed-caption-contains-fixed-position.html.ini b/tests/wpt/meta/css/css-transforms/transform-transformed-caption-contains-fixed-position.html.ini
deleted file mode 100644
index c3b7ac8e5de..00000000000
--- a/tests/wpt/meta/css/css-transforms/transform-transformed-caption-contains-fixed-position.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[transform-transformed-caption-contains-fixed-position.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/cssom-view/offsetTopLeft-table-caption.html.ini b/tests/wpt/meta/css/cssom-view/offsetTopLeft-table-caption.html.ini
deleted file mode 100644
index 131155bb1ab..00000000000
--- a/tests/wpt/meta/css/cssom-view/offsetTopLeft-table-caption.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[offsetTopLeft-table-caption.html]
- [offset* APIs on tables with captions.]
- expected: FAIL
diff --git a/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini b/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini
index f0a5f50cb25..b8603ca2151 100644
--- a/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini
+++ b/tests/wpt/meta/css/cssom-view/table-scroll-props.html.ini
@@ -2,9 +2,6 @@
[Caption with margin]
expected: FAIL
- [Table with separated border]
- expected: FAIL
-
[Table with collapsed border]
expected: FAIL
diff --git a/tests/wpt/meta/css/cssom/serialize-values.html.ini b/tests/wpt/meta/css/cssom/serialize-values.html.ini
index 9cfeee8435b..4718741f2dd 100644
--- a/tests/wpt/meta/css/cssom/serialize-values.html.ini
+++ b/tests/wpt/meta/css/cssom/serialize-values.html.ini
@@ -83,15 +83,6 @@
[list-style-type: lower-roman]
expected: FAIL
- [caption-side: top]
- expected: FAIL
-
- [caption-side: bottom]
- expected: FAIL
-
- [caption-side: inherit]
- expected: FAIL
-
[direction: ltr]
expected: FAIL
diff --git a/tests/wpt/mozilla/meta/css/table_caption_bottom_a.html.ini b/tests/wpt/mozilla/meta/css/table_caption_bottom_a.html.ini
deleted file mode 100644
index 1eaa7b01e75..00000000000
--- a/tests/wpt/mozilla/meta/css/table_caption_bottom_a.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[table_caption_bottom_a.html]
- expected: FAIL
diff --git a/tests/wpt/mozilla/meta/css/table_caption_top_a.html.ini b/tests/wpt/mozilla/meta/css/table_caption_top_a.html.ini
deleted file mode 100644
index 8fd102e88ca..00000000000
--- a/tests/wpt/mozilla/meta/css/table_caption_top_a.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[table_caption_top_a.html]
- expected: FAIL