From 2a0e1cd9c9a6c13f6fc01c82c04fb521bd3c238b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 17:08:32 -0800 Subject: [PATCH 01/13] Assign table row block sizes in the parent table or rowgroup --- components/layout/table.rs | 15 +++-- components/layout/table_cell.rs | 11 ++++ components/layout/table_row.rs | 92 ++++++++++++++--------------- components/layout/table_rowgroup.rs | 4 +- 4 files changed, 68 insertions(+), 54 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 72916de36ed..7099c72ecdb 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -496,10 +496,10 @@ impl Flow for TableFlow { }); } - fn assign_block_size(&mut self, _: &LayoutContext) { + fn assign_block_size(&mut self, lc: &LayoutContext) { debug!("assign_block_size: assigning block_size for table"); let vertical_spacing = self.spacing().vertical(); - self.block_flow.assign_block_size_for_table_like_flow(vertical_spacing) + self.block_flow.assign_block_size_for_table_like_flow(vertical_spacing, lc) } fn compute_stacking_relative_position(&mut self, layout_context: &LayoutContext) { @@ -771,15 +771,22 @@ fn perform_border_collapse_for_row(child_table_row: &mut TableRowFlow, /// rowgroups. pub trait TableLikeFlow { /// Lays out the rows of a table. - fn assign_block_size_for_table_like_flow(&mut self, block_direction_spacing: Au); + fn assign_block_size_for_table_like_flow(&mut self, block_direction_spacing: Au, + layout_context: &LayoutContext); } impl TableLikeFlow for BlockFlow { - fn assign_block_size_for_table_like_flow(&mut self, block_direction_spacing: Au) { + fn assign_block_size_for_table_like_flow(&mut self, block_direction_spacing: Au, + layout_context: &LayoutContext) { debug_assert!(self.fragment.style.get_inheritedtable().border_collapse == border_collapse::T::Separate || block_direction_spacing == Au(0)); if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + for kid in self.base.child_iter_mut() { + if kid.is_table_row() { + kid.as_mut_table_row().assign_block_size_table_row_base(layout_context) + } + } // Our current border-box position. let block_start_border_padding = self.fragment.border_padding.block_start; let mut current_block_offset = block_start_border_padding; diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index f3bbe14f2e7..fe8d453cb0b 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -148,6 +148,17 @@ impl TableCellFlow { } } } + + // Total block size of child + // + // Call after block size calculation + pub fn total_block_size(&mut self) -> Au { + // TODO: Percentage block-size + let specified = MaybeAuto::from_style(self.fragment().style() + .content_block_size(), + Au(0)).specified_or_zero(); + specified + self.fragment().border_padding.block_start_end() + } } impl Flow for TableCellFlow { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 75fff53a969..03e1c9634fa 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -114,7 +114,7 @@ impl TableRowFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) { + pub fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) { if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of // all cells). @@ -132,15 +132,8 @@ impl TableRowFlow { } { - let child_fragment = kid.as_mut_table_cell().fragment(); - // TODO: Percentage block-size - let child_specified_block_size = - MaybeAuto::from_style(child_fragment.style().content_block_size(), - Au(0)).specified_or_zero(); max_block_size = - max(max_block_size, - child_specified_block_size + - child_fragment.border_padding.block_start_end()); + max(max_block_size, kid.as_mut_table_cell().total_block_size()); } let child_node = kid.mut_base(); child_node.position.start.b = Au(0); @@ -158,47 +151,51 @@ impl TableRowFlow { MaybeAuto::Specified(value) => max(value, block_size), }; - // Assign the block-size of own fragment - let mut position = self.block_flow.fragment.border_box; - position.size.block = block_size; - self.block_flow.fragment.border_box = position; - self.block_flow.base.position.size.block = block_size; - - // Assign the block-size of kid fragments, which is the same value as own block-size. - for kid in self.block_flow.base.child_iter_mut() { - let child_table_cell = kid.as_mut_table_cell(); - { - let kid_fragment = child_table_cell.mut_fragment(); - let mut position = kid_fragment.border_box; - position.size.block = block_size; - kid_fragment.border_box = position; - } - - // Assign the child's block size. - child_table_cell.block_flow.base.position.size.block = block_size; - - // Now we know the cell height, vertical align the cell's children. - child_table_cell.valign_children(); - - // Write in the size of the relative containing block for children. (This - // information is also needed to handle RTL.) - child_table_cell.block_flow.base.early_absolute_position_info = - EarlyAbsolutePositionInfo { - relative_containing_block_size: self.block_flow - .fragment - .content_box() - .size, - relative_containing_block_mode: self.block_flow - .fragment - .style() - .writing_mode, - }; - } + self.assign_block_size_to_self_and_children(block_size); } self.block_flow.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } + pub fn assign_block_size_to_self_and_children(&mut self, block_size: Au) { + // Assign the block-size of kid fragments, which is the same value as own block-size. + for kid in self.block_flow.base.child_iter_mut() { + let child_table_cell = kid.as_mut_table_cell(); + { + let kid_fragment = child_table_cell.mut_fragment(); + let mut position = kid_fragment.border_box; + position.size.block = block_size; + kid_fragment.border_box = position; + } + + // Assign the child's block size. + child_table_cell.block_flow.base.position.size.block = block_size; + + // Now we know the cell height, vertical align the cell's children. + child_table_cell.valign_children(); + + // Write in the size of the relative containing block for children. (This + // information is also needed to handle RTL.) + child_table_cell.block_flow.base.early_absolute_position_info = + EarlyAbsolutePositionInfo { + relative_containing_block_size: self.block_flow + .fragment + .content_box() + .size, + relative_containing_block_mode: self.block_flow + .fragment + .style() + .writing_mode, + }; + } + + // Assign the block-size of own fragment + let mut position = self.block_flow.fragment.border_box; + position.size.block = block_size; + self.block_flow.fragment.border_box = position; + self.block_flow.base.position.size.block = block_size; + } + pub fn populate_collapsed_border_spacing<'a, I>( &mut self, collapsed_inline_direction_border_widths_for_table: &[Au], @@ -449,9 +446,8 @@ impl Flow for TableRowFlow { }) } - fn assign_block_size(&mut self, layout_context: &LayoutContext) { - debug!("assign_block_size: assigning block_size for table_row"); - self.assign_block_size_table_row_base(layout_context); + fn assign_block_size(&mut self, _: &LayoutContext) { + // the surrounding table or rowgroup does this } fn compute_stacking_relative_position(&mut self, layout_context: &LayoutContext) { diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 49b0d427084..85bccb18ade 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -159,9 +159,9 @@ impl Flow for TableRowGroupFlow { }); } - fn assign_block_size(&mut self, _: &LayoutContext) { + fn assign_block_size(&mut self, lc: &LayoutContext) { debug!("assign_block_size: assigning block_size for table_rowgroup"); - self.block_flow.assign_block_size_for_table_like_flow(self.spacing.vertical()); + self.block_flow.assign_block_size_for_table_like_flow(self.spacing.vertical(), lc); } fn compute_stacking_relative_position(&mut self, layout_context: &LayoutContext) { From e894c8b1bf5080abf7ad05c4c0e9bec5eac1baf8 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 17:58:22 -0800 Subject: [PATCH 02/13] Hacky rowspan support --- components/layout/table.rs | 26 ++++++++++++++++++++++++- components/layout/table_row.rs | 35 ++++++++++++++++++++++++---------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 7099c72ecdb..8df43d0821d 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -781,10 +781,34 @@ impl TableLikeFlow for BlockFlow { debug_assert!(self.fragment.style.get_inheritedtable().border_collapse == border_collapse::T::Separate || block_direction_spacing == Au(0)); + if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + let mut sizes = vec![]; + for kid in self.base.child_iter_mut() { if kid.is_table_row() { - kid.as_mut_table_row().assign_block_size_table_row_base(layout_context) + sizes.push(kid.as_mut_table_row() + .compute_block_size_table_row_base(layout_context)) + } + } + + let mut effects_rows = 0; + let mut i = 0; + for kid in self.base.child_iter_mut() { + if kid.is_table_row() { + let row = kid.as_mut_table_row(); + if row.mut_base().restyle_damage.contains(ServoRestyleDamage::REFLOW) || + effects_rows != 0 { + row.assign_block_size_to_self_and_children(&sizes, i, &mut effects_rows); + row.mut_base().restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | + ServoRestyleDamage::REFLOW); + } + // may happen for empty rows + if effects_rows != 0 { + effects_rows -= 1; + } + i += 1; } } // Our current border-box position. diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 03e1c9634fa..8e9e94c6356 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -114,7 +114,7 @@ impl TableRowFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - pub fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) { + pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext) -> Au { if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of // all cells). @@ -123,6 +123,7 @@ impl TableRowFlow { let content_box = self.block_flow.base.position - self.block_flow.fragment.border_padding - self.block_flow.fragment.margin; + for kid in self.block_flow.base.child_iter_mut() { kid.place_float_if_applicable(); if !kid.base().flags.is_float() { @@ -131,14 +132,20 @@ impl TableRowFlow { content_box); } + let row_span; { + let cell = kid.as_mut_table_cell(); + row_span = cell.row_span as i32; max_block_size = - max(max_block_size, kid.as_mut_table_cell().total_block_size()); + max(max_block_size, cell.total_block_size() / row_span); + } + { + let child_node = kid.mut_base(); + child_node.position.start.b = Au(0); + max_block_size = max(max_block_size, child_node.position.size.block / row_span); } - let child_node = kid.mut_base(); - child_node.position.start.b = Au(0); - max_block_size = max(max_block_size, child_node.position.size.block); } + // XXXManishearth include overages from spanning cells from previous rows let mut block_size = max_block_size; // TODO: Percentage block-size @@ -150,17 +157,25 @@ impl TableRowFlow { MaybeAuto::Auto => block_size, MaybeAuto::Specified(value) => max(value, block_size), }; - - self.assign_block_size_to_self_and_children(block_size); + block_size + } else { + self.block_flow.base.position.size.block } - - self.block_flow.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } - pub fn assign_block_size_to_self_and_children(&mut self, block_size: Au) { + pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[Au], index: usize, effects_rows: &mut u32) { // Assign the block-size of kid fragments, which is the same value as own block-size. + let block_size = sizes[index]; for kid in self.block_flow.base.child_iter_mut() { let child_table_cell = kid.as_mut_table_cell(); + let block_size = if child_table_cell.row_span > 1 { + *effects_rows = max(*effects_rows, child_table_cell.row_span); + // XXXManishearth support border spacing and such + sizes[index..].iter().take(child_table_cell.row_span as usize) + .fold(Au(0), |accum, size| accum + *size) + } else { + block_size + }; { let kid_fragment = child_table_cell.mut_fragment(); let mut position = kid_fragment.border_box; From 216082c3428f1d032847f5db684f6574c2c28c58 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 18:54:30 -0800 Subject: [PATCH 03/13] Preserve information on incoming row sizes --- components/layout/table.rs | 4 ++-- components/layout/table_row.rs | 39 +++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 8df43d0821d..4f70c334dc7 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -784,14 +784,14 @@ impl TableLikeFlow for BlockFlow { if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { let mut sizes = vec![]; + let mut incoming_rowspan_data = vec![]; for kid in self.base.child_iter_mut() { if kid.is_table_row() { sizes.push(kid.as_mut_table_row() - .compute_block_size_table_row_base(layout_context)) + .compute_block_size_table_row_base(layout_context, &mut incoming_rowspan_data)) } } - let mut effects_rows = 0; let mut i = 0; for kid in self.base.child_iter_mut() { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 8e9e94c6356..3f8f5b54d4d 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -114,8 +114,20 @@ impl TableRowFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext) -> Au { + pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, incoming_rowspan_data: &mut Vec) -> Au { if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + fn include_sizes_from_previous_rows(col: &mut usize, + incoming_rowspan: &[u32], + incoming_rowspan_data: &mut Vec, + max_block_size: &mut Au) { + while let Some(span) = incoming_rowspan.get(*col) { + if *span <= 1 { + break; + } + *max_block_size = max(*max_block_size, incoming_rowspan_data[*col]); + *col += 1; + } + } // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of // all cells). let mut max_block_size = Au(0); @@ -124,7 +136,9 @@ impl TableRowFlow { - self.block_flow.fragment.border_padding - self.block_flow.fragment.margin; + let mut col = 0; for kid in self.block_flow.base.child_iter_mut() { + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); kid.place_float_if_applicable(); if !kid.base().flags.is_float() { kid.assign_block_size_for_inorder_child_if_necessary(layout_context, @@ -133,19 +147,28 @@ impl TableRowFlow { } let row_span; + let column_span; + let cell_total; { let cell = kid.as_mut_table_cell(); row_span = cell.row_span as i32; - max_block_size = - max(max_block_size, cell.total_block_size() / row_span); + column_span = cell.column_span as usize; + cell_total = cell.total_block_size(); } - { - let child_node = kid.mut_base(); - child_node.position.start.b = Au(0); - max_block_size = max(max_block_size, child_node.position.size.block / row_span); + let child_node = kid.mut_base(); + child_node.position.start.b = Au(0); + let cell_block_size = max(cell_total, child_node.position.size.block); + max_block_size = max(max_block_size, cell_block_size / row_span); + + if row_span > 1 { + if incoming_rowspan_data.len() <= col { + incoming_rowspan_data.resize(col + 1, Au(0)); + } + incoming_rowspan_data[col] = cell_block_size / row_span; } + col += column_span; } - // XXXManishearth include overages from spanning cells from previous rows + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); let mut block_size = max_block_size; // TODO: Percentage block-size From 7cd3daa76f6a94b38b774beb900fb07d8d3646f7 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 19:26:41 -0800 Subject: [PATCH 04/13] Always call compute_block_size_table_row_base --- components/layout/table_row.rs | 135 ++++++++++++++++----------------- 1 file changed, 67 insertions(+), 68 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 3f8f5b54d4d..ec06a19be55 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -27,7 +27,6 @@ use style::computed_values::border_spacing::T as BorderSpacing; use style::computed_values::border_top_style::T as BorderStyle; use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode}; use style::properties::ComputedValues; -use style::servo::restyle_damage::ServoRestyleDamage; use style::values::computed::{Color, LengthOrPercentageOrAuto}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt}; use table_cell::{CollapsedBordersForCell, TableCellFlow}; @@ -114,76 +113,76 @@ impl TableRowFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, incoming_rowspan_data: &mut Vec) -> Au { - if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { - fn include_sizes_from_previous_rows(col: &mut usize, - incoming_rowspan: &[u32], - incoming_rowspan_data: &mut Vec, - max_block_size: &mut Au) { - while let Some(span) = incoming_rowspan.get(*col) { - if *span <= 1 { - break; - } - *max_block_size = max(*max_block_size, incoming_rowspan_data[*col]); - *col += 1; + pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, + incoming_rowspan_data: &mut Vec) -> Au { + // XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other + // rows + fn include_sizes_from_previous_rows(col: &mut usize, + incoming_rowspan: &[u32], + incoming_rowspan_data: &mut Vec, + max_block_size: &mut Au) { + while let Some(span) = incoming_rowspan.get(*col) { + if *span <= 1 { + break; } + *max_block_size = max(*max_block_size, incoming_rowspan_data[*col]); + *col += 1; } - // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of - // all cells). - let mut max_block_size = Au(0); - let thread_id = self.block_flow.base.thread_id; - let content_box = self.block_flow.base.position - - self.block_flow.fragment.border_padding - - self.block_flow.fragment.margin; - - let mut col = 0; - for kid in self.block_flow.base.child_iter_mut() { - include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); - kid.place_float_if_applicable(); - if !kid.base().flags.is_float() { - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); - } - - let row_span; - let column_span; - let cell_total; - { - let cell = kid.as_mut_table_cell(); - row_span = cell.row_span as i32; - column_span = cell.column_span as usize; - cell_total = cell.total_block_size(); - } - let child_node = kid.mut_base(); - child_node.position.start.b = Au(0); - let cell_block_size = max(cell_total, child_node.position.size.block); - max_block_size = max(max_block_size, cell_block_size / row_span); - - if row_span > 1 { - if incoming_rowspan_data.len() <= col { - incoming_rowspan_data.resize(col + 1, Au(0)); - } - incoming_rowspan_data[col] = cell_block_size / row_span; - } - col += column_span; - } - include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); - - let mut block_size = max_block_size; - // TODO: Percentage block-size - block_size = match MaybeAuto::from_style(self.block_flow - .fragment - .style() - .content_block_size(), - Au(0)) { - MaybeAuto::Auto => block_size, - MaybeAuto::Specified(value) => max(value, block_size), - }; - block_size - } else { - self.block_flow.base.position.size.block } + // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of + // all cells). + let mut max_block_size = Au(0); + let thread_id = self.block_flow.base.thread_id; + let content_box = self.block_flow.base.position + - self.block_flow.fragment.border_padding + - self.block_flow.fragment.margin; + + let mut col = 0; + for kid in self.block_flow.base.child_iter_mut() { + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, + incoming_rowspan_data, &mut max_block_size); + kid.place_float_if_applicable(); + if !kid.base().flags.is_float() { + kid.assign_block_size_for_inorder_child_if_necessary(layout_context, + thread_id, + content_box); + } + + let row_span; + let column_span; + let cell_total; + { + let cell = kid.as_mut_table_cell(); + row_span = cell.row_span as i32; + column_span = cell.column_span as usize; + cell_total = cell.total_block_size(); + } + let child_node = kid.mut_base(); + child_node.position.start.b = Au(0); + let cell_block_size = max(cell_total, child_node.position.size.block); + max_block_size = max(max_block_size, cell_block_size / row_span); + + if row_span > 1 { + if incoming_rowspan_data.len() <= col { + incoming_rowspan_data.resize(col + 1, Au(0)); + } + incoming_rowspan_data[col] = cell_block_size / row_span; + } + col += column_span; + } + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); + + let mut block_size = max_block_size; + // TODO: Percentage block-size + block_size = match MaybeAuto::from_style(self.block_flow + .fragment + .style() + .content_block_size(), + Au(0)) { + MaybeAuto::Auto => block_size, + MaybeAuto::Specified(value) => max(value, block_size), + }; + block_size } pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[Au], index: usize, effects_rows: &mut u32) { From 108ecc1f4d1d4b7ab17a07a52d247d4cb208d6bf Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 22:20:26 -0800 Subject: [PATCH 05/13] Compute border spacing info beforehand --- components/layout/table.rs | 68 ++++++++++++++++++++++++++-------- components/layout/table_row.rs | 10 +++-- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 4f70c334dc7..61ab49f59cd 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -781,17 +781,54 @@ impl TableLikeFlow for BlockFlow { debug_assert!(self.fragment.style.get_inheritedtable().border_collapse == border_collapse::T::Separate || block_direction_spacing == Au(0)); - - if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { - let mut sizes = vec![]; - let mut incoming_rowspan_data = vec![]; - - for kid in self.base.child_iter_mut() { - if kid.is_table_row() { - sizes.push(kid.as_mut_table_row() - .compute_block_size_table_row_base(layout_context, &mut incoming_rowspan_data)) + fn border_spacing_for_row(fragment: &Fragment, row: &TableRowFlow, + block_direction_spacing: Au) -> Au { + match fragment.style.get_inheritedtable().border_collapse { + border_collapse::T::Separate => block_direction_spacing, + border_collapse::T::Collapse => { + row.collapsed_border_spacing.block_start } } + } + + if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + // (size, cumulative_border_spacing) + let mut sizes = vec![(Au(0), Au(0))]; + // The amount of border spacing up to and including this row, + // but not including the spacing beneath it + let mut cumulative_border = Au(0); + let mut incoming_rowspan_data = vec![]; + + // First pass: Compute block-direction border spacings + // XXXManishearth this can be done in tandem with the second pass, + // provided we never hit any rowspan cases + for kid in self.base.child_iter_mut() + .filter(|k| k.is_table_row()) + .skip(1) { + cumulative_border += + border_spacing_for_row(&self.fragment, kid.as_table_row(), + block_direction_spacing); + // we haven't calculated sizes yet + sizes.push((Au(0), cumulative_border)); + } + + // Second pass: Compute row block sizes + // [expensive: iterates over cells] + let mut i = 0; + for kid in self.base.child_iter_mut() { + if kid.is_table_row() { + let size = kid.as_mut_table_row() + .compute_block_size_table_row_base(layout_context, + &mut incoming_rowspan_data, + &sizes, + i); + sizes[i].0 = size; + i += 1; + } + } + + // Third pass: Assign block sizes to rows and cells + // [expensive: iterates over cells] let mut effects_rows = 0; let mut i = 0; for kid in self.base.child_iter_mut() { @@ -811,11 +848,15 @@ impl TableLikeFlow for BlockFlow { i += 1; } } + // Our current border-box position. let block_start_border_padding = self.fragment.border_padding.block_start; let mut current_block_offset = block_start_border_padding; let mut has_rows = false; + // Fourth pass: Compute block positions + // XXXManishearth this can be merged with the third pass + // At this point, `current_block_offset` is at the content edge of our box. Now iterate // over children. for kid in self.base.child_iter_mut() { @@ -824,12 +865,8 @@ impl TableLikeFlow for BlockFlow { has_rows = true; let child_table_row = kid.as_table_row(); current_block_offset = current_block_offset + - match self.fragment.style.get_inheritedtable().border_collapse { - border_collapse::T::Separate => block_direction_spacing, - border_collapse::T::Collapse => { - child_table_row.collapsed_border_spacing.block_start - } - } + border_spacing_for_row(&self.fragment, child_table_row, + block_direction_spacing) } // At this point, `current_block_offset` is at the border edge of the child. @@ -874,6 +911,7 @@ impl TableLikeFlow for BlockFlow { self.fragment.border_box.start.b = Au(0); self.base.position.size.block = current_block_offset; + // Fifth pass: Assign absolute position info // Write in the size of the relative containing block for children. (This information // is also needed to handle RTL.) for kid in self.base.child_iter_mut() { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index ec06a19be55..8d5da7130a0 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -114,7 +114,9 @@ impl TableRowFlow { /// methods #[inline(always)] pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, - incoming_rowspan_data: &mut Vec) -> Au { + incoming_rowspan_data: &mut Vec, + border_info: &[(Au, Au)], + row_index: usize) -> Au { // XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other // rows fn include_sizes_from_previous_rows(col: &mut usize, @@ -185,16 +187,16 @@ impl TableRowFlow { block_size } - pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[Au], index: usize, effects_rows: &mut u32) { + pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[(Au, Au)], index: usize, effects_rows: &mut u32) { // Assign the block-size of kid fragments, which is the same value as own block-size. - let block_size = sizes[index]; + let block_size = sizes[index].0; for kid in self.block_flow.base.child_iter_mut() { let child_table_cell = kid.as_mut_table_cell(); let block_size = if child_table_cell.row_span > 1 { *effects_rows = max(*effects_rows, child_table_cell.row_span); // XXXManishearth support border spacing and such sizes[index..].iter().take(child_table_cell.row_span as usize) - .fold(Au(0), |accum, size| accum + *size) + .fold(Au(0), |accum, size| accum + size.0) } else { block_size }; From f687be3878cf5ebcb3858b5738aa2e156fa200e3 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 22:33:55 -0800 Subject: [PATCH 06/13] Use computed border spacings when handling rowspans --- components/layout/table_row.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 8d5da7130a0..9557b000a39 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -115,7 +115,7 @@ impl TableRowFlow { #[inline(always)] pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, incoming_rowspan_data: &mut Vec, - border_info: &[(Au, Au)], + border_info: &[(Au, Au)], // (_, cumulative_border_size) row_index: usize) -> Au { // XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other // rows @@ -161,15 +161,25 @@ impl TableRowFlow { } let child_node = kid.mut_base(); child_node.position.start.b = Au(0); - let cell_block_size = max(cell_total, child_node.position.size.block); - max_block_size = max(max_block_size, cell_block_size / row_span); + let mut cell_block_size_pressure = max(cell_total, child_node.position.size.block); if row_span > 1 { if incoming_rowspan_data.len() <= col { incoming_rowspan_data.resize(col + 1, Au(0)); } - incoming_rowspan_data[col] = cell_block_size / row_span; + // XXXManishearth rowspan can overflow the table + let border_sizes_spanned = border_info[row_index + row_span as usize - 1].1 - + border_info[row_index].1; + cell_block_size_pressure -= border_sizes_spanned; + + // XXXManishearth in case this row covers more than cell_block_size_pressure / row_span + // anyway, we should use that to reduce the pressure on future rows. This will + // require an extra slow-path loop, sadly. + cell_block_size_pressure /= row_span; + incoming_rowspan_data[col] = cell_block_size_pressure; } + + max_block_size = max(max_block_size, cell_block_size_pressure); col += column_span; } include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); @@ -194,9 +204,12 @@ impl TableRowFlow { let child_table_cell = kid.as_mut_table_cell(); let block_size = if child_table_cell.row_span > 1 { *effects_rows = max(*effects_rows, child_table_cell.row_span); - // XXXManishearth support border spacing and such - sizes[index..].iter().take(child_table_cell.row_span as usize) - .fold(Au(0), |accum, size| accum + size.0) + let row_sizes = sizes[index..].iter() + .take(child_table_cell.row_span as usize) + .fold(Au(0), |accum, size| accum + size.0); + let border_sizes_spanned = sizes[index + child_table_cell.row_span as usize - 1].1 - + sizes[index].1; + row_sizes + border_sizes_spanned } else { block_size }; From 746acf7e2b7c2f8da7553568e0a9ea1c305c16bc Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 22:45:48 -0800 Subject: [PATCH 07/13] Don't crash on overflowing rows --- components/layout/table_row.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 9557b000a39..fb4531a2ef5 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -19,7 +19,7 @@ use gfx_traits::print_tree::PrintTree; use layout_debug; use model::MaybeAuto; use serde::{Serialize, Serializer}; -use std::cmp::max; +use std::cmp::{max, min}; use std::fmt; use std::iter::{Enumerate, IntoIterator, Peekable}; use style::computed_values::border_collapse::T as BorderCollapse; @@ -155,7 +155,7 @@ impl TableRowFlow { let cell_total; { let cell = kid.as_mut_table_cell(); - row_span = cell.row_span as i32; + row_span = cell.row_span; column_span = cell.column_span as usize; cell_total = cell.total_block_size(); } @@ -168,14 +168,13 @@ impl TableRowFlow { incoming_rowspan_data.resize(col + 1, Au(0)); } // XXXManishearth rowspan can overflow the table - let border_sizes_spanned = border_info[row_index + row_span as usize - 1].1 - - border_info[row_index].1; + let border_sizes_spanned = get_spanned_border_size(border_info, row_index, row_span); cell_block_size_pressure -= border_sizes_spanned; // XXXManishearth in case this row covers more than cell_block_size_pressure / row_span // anyway, we should use that to reduce the pressure on future rows. This will // require an extra slow-path loop, sadly. - cell_block_size_pressure /= row_span; + cell_block_size_pressure /= row_span as i32; incoming_rowspan_data[col] = cell_block_size_pressure; } @@ -207,8 +206,8 @@ impl TableRowFlow { let row_sizes = sizes[index..].iter() .take(child_table_cell.row_span as usize) .fold(Au(0), |accum, size| accum + size.0); - let border_sizes_spanned = sizes[index + child_table_cell.row_span as usize - 1].1 - - sizes[index].1; + let border_sizes_spanned = + get_spanned_border_size(sizes, index, child_table_cell.row_span); row_sizes + border_sizes_spanned } else { block_size @@ -271,6 +270,14 @@ impl TableRowFlow { } } +/// Given an array of (_, cumulative_border_size), the index of the +/// current row, and the >1 row_span of the cell, calculate the amount of +/// border-spacing spanned by the row +fn get_spanned_border_size(sizes: &[(Au, Au)], row_index: usize, row_span: u32) -> Au { + let last_row_idx = min(row_index + row_span as usize - 1, sizes.len() - 1); + sizes[last_row_idx].1 - sizes[row_index].1 +} + impl Flow for TableRowFlow { fn class(&self) -> FlowClass { FlowClass::TableRow From 0261762fa49b06681206920e6c7ff14bbf98108a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 23:32:39 -0800 Subject: [PATCH 08/13] Handle overlarge rowspans by keeping track of largest leftover incoming sizes --- components/layout/table.rs | 12 +++++++++++- components/layout/table_row.rs | 35 +++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 61ab49f59cd..05551639c6a 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -815,17 +815,27 @@ impl TableLikeFlow for BlockFlow { // Second pass: Compute row block sizes // [expensive: iterates over cells] let mut i = 0; + let mut overflow = Au(0); for kid in self.base.child_iter_mut() { if kid.is_table_row() { - let size = kid.as_mut_table_row() + let (size, oflo) = kid.as_mut_table_row() .compute_block_size_table_row_base(layout_context, &mut incoming_rowspan_data, &sizes, i); sizes[i].0 = size; + overflow = oflo; i += 1; + // new rowgroups stop rowspans + } else if kid.is_table_rowgroup() { + if i > 0 { + sizes[i - 1].0 = cmp::max(sizes[i - 1].0, overflow); + } } } + if i > 0 { + sizes[i - 1].0 = cmp::max(sizes[i - 1].0, overflow); + } // Third pass: Assign block sizes to rows and cells // [expensive: iterates over cells] diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index fb4531a2ef5..04948990dc7 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -106,34 +106,39 @@ impl TableRowFlow { } } - /// Assign block-size for table-row flow. + /// Compute block-size for table-row flow. /// /// TODO(pcwalton): This doesn't handle floats and positioned elements right. /// - /// inline(always) because this is only ever called by in-order or non-in-order top-level - /// methods - #[inline(always)] + /// Returns the block size, as well as the size this should be if this is the last row pub fn compute_block_size_table_row_base<'a>(&'a mut self, layout_context: &LayoutContext, incoming_rowspan_data: &mut Vec, border_info: &[(Au, Au)], // (_, cumulative_border_size) - row_index: usize) -> Au { + row_index: usize) -> (Au, Au) { // XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other // rows fn include_sizes_from_previous_rows(col: &mut usize, incoming_rowspan: &[u32], incoming_rowspan_data: &mut Vec, - max_block_size: &mut Au) { + max_block_size: &mut Au, + largest_leftover_incoming_size: &mut Au) { while let Some(span) = incoming_rowspan.get(*col) { if *span <= 1 { break; } - *max_block_size = max(*max_block_size, incoming_rowspan_data[*col]); + let incoming = incoming_rowspan_data[*col]; + *max_block_size = max(*max_block_size, incoming); + if *span > 2 { + *largest_leftover_incoming_size = max(*largest_leftover_incoming_size, + incoming * (*span - 1) as i32) + } *col += 1; } } // Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of // all cells). let mut max_block_size = Au(0); + let mut largest_leftover_incoming_size = Au(0); let thread_id = self.block_flow.base.thread_id; let content_box = self.block_flow.base.position - self.block_flow.fragment.border_padding @@ -142,7 +147,8 @@ impl TableRowFlow { let mut col = 0; for kid in self.block_flow.base.child_iter_mut() { include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, - incoming_rowspan_data, &mut max_block_size); + incoming_rowspan_data, &mut max_block_size, + &mut largest_leftover_incoming_size); kid.place_float_if_applicable(); if !kid.base().flags.is_float() { kid.assign_block_size_for_inorder_child_if_necessary(layout_context, @@ -167,8 +173,9 @@ impl TableRowFlow { if incoming_rowspan_data.len() <= col { incoming_rowspan_data.resize(col + 1, Au(0)); } - // XXXManishearth rowspan can overflow the table let border_sizes_spanned = get_spanned_border_size(border_info, row_index, row_span); + let pressure_copy = cell_block_size_pressure; + cell_block_size_pressure -= border_sizes_spanned; // XXXManishearth in case this row covers more than cell_block_size_pressure / row_span @@ -176,12 +183,18 @@ impl TableRowFlow { // require an extra slow-path loop, sadly. cell_block_size_pressure /= row_span as i32; incoming_rowspan_data[col] = cell_block_size_pressure; + + // If this ends up being the last row, it needs to cover + // *all* this space + largest_leftover_incoming_size = max(largest_leftover_incoming_size, + pressure_copy); } max_block_size = max(max_block_size, cell_block_size_pressure); col += column_span; } - include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size); + include_sizes_from_previous_rows(&mut col, &self.incoming_rowspan, incoming_rowspan_data, &mut max_block_size, + &mut largest_leftover_incoming_size); let mut block_size = max_block_size; // TODO: Percentage block-size @@ -193,7 +206,7 @@ impl TableRowFlow { MaybeAuto::Auto => block_size, MaybeAuto::Specified(value) => max(value, block_size), }; - block_size + (block_size, largest_leftover_incoming_size) } pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[(Au, Au)], index: usize, effects_rows: &mut u32) { From ef983c340fb37409c0a10fbe0eac29e16997ecc9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 26 Feb 2018 23:34:36 -0800 Subject: [PATCH 09/13] Remove outdated comment --- components/layout/table.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 05551639c6a..5cd007979ef 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -567,13 +567,6 @@ impl Flow for TableFlow { } #[derive(Debug)] -// XXXManishearth We might be able to avoid the Arcs if -// the table is structured such that the columns always come -// first in the flow tree, at which point we can -// reuse the iterator that we use for colgroups -// for rows (and have no borrowing issues between -// holding on to both ColumnStyle<'table> and -// the rows) struct ColumnStyle<'table> { span: u32, colgroup_style: Option<&'table ComputedValues>, From 19974e39c8128e5ba7d3bb76e093b169b3e5c14b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Feb 2018 09:43:38 -0800 Subject: [PATCH 10/13] Merge fourth and fifth (assign block sizes / positions) passes --- components/layout/table.rs | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 5cd007979ef..2e0df9f4c7e 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -830,12 +830,21 @@ impl TableLikeFlow for BlockFlow { sizes[i - 1].0 = cmp::max(sizes[i - 1].0, overflow); } - // Third pass: Assign block sizes to rows and cells + + // Our current border-box position. + let block_start_border_padding = self.fragment.border_padding.block_start; + let mut current_block_offset = block_start_border_padding; + let mut has_rows = false; + + // Third pass: Assign block sizes and positions to rows, cells, and other children // [expensive: iterates over cells] + // At this point, `current_block_offset` is at the content edge of our box. Now iterate + // over children. let mut effects_rows = 0; let mut i = 0; for kid in self.base.child_iter_mut() { if kid.is_table_row() { + has_rows = true; let row = kid.as_mut_table_row(); if row.mut_base().restyle_damage.contains(ServoRestyleDamage::REFLOW) || effects_rows != 0 { @@ -844,33 +853,15 @@ impl TableLikeFlow for BlockFlow { .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } + current_block_offset = current_block_offset + + border_spacing_for_row(&self.fragment, row, + block_direction_spacing); // may happen for empty rows if effects_rows != 0 { effects_rows -= 1; } i += 1; } - } - - // Our current border-box position. - let block_start_border_padding = self.fragment.border_padding.block_start; - let mut current_block_offset = block_start_border_padding; - let mut has_rows = false; - - // Fourth pass: Compute block positions - // XXXManishearth this can be merged with the third pass - - // At this point, `current_block_offset` is at the content edge of our box. Now iterate - // over children. - for kid in self.base.child_iter_mut() { - // Account for spacing or collapsed borders. - if kid.is_table_row() { - has_rows = true; - let child_table_row = kid.as_table_row(); - current_block_offset = current_block_offset + - border_spacing_for_row(&self.fragment, child_table_row, - block_direction_spacing) - } // At this point, `current_block_offset` is at the border edge of the child. kid.mut_base().position.start.b = current_block_offset; @@ -914,7 +905,7 @@ impl TableLikeFlow for BlockFlow { self.fragment.border_box.start.b = Au(0); self.base.position.size.block = current_block_offset; - // Fifth pass: Assign absolute position info + // Fourth pass: Assign absolute position info // Write in the size of the relative containing block for children. (This information // is also needed to handle RTL.) for kid in self.base.child_iter_mut() { From 98e53db289527803db269a2ced34b59ef8b6230f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Feb 2018 14:44:44 -0800 Subject: [PATCH 11/13] Assert that cells aren't floats --- components/layout/table_row.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 04948990dc7..0d779ac8f2f 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -150,11 +150,10 @@ impl TableRowFlow { incoming_rowspan_data, &mut max_block_size, &mut largest_leftover_incoming_size); kid.place_float_if_applicable(); - if !kid.base().flags.is_float() { - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); - } + debug_assert!(!kid.base().flags.is_float(), "table cells should never float"); + kid.assign_block_size_for_inorder_child_if_necessary(layout_context, + thread_id, + content_box); let row_span; let column_span; From cec37a492a8e27ed8c0c8e00157190a0a87cb882 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Feb 2018 14:47:22 -0800 Subject: [PATCH 12/13] Unconditionally layout rows when laying out tables If the reflow flag is set on a row it will be on the table anyway --- components/layout/table.rs | 16 ++++------------ components/layout/table_row.rs | 5 +---- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/components/layout/table.rs b/components/layout/table.rs index 2e0df9f4c7e..2f5de2aa1e4 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -840,26 +840,18 @@ impl TableLikeFlow for BlockFlow { // [expensive: iterates over cells] // At this point, `current_block_offset` is at the content edge of our box. Now iterate // over children. - let mut effects_rows = 0; let mut i = 0; for kid in self.base.child_iter_mut() { if kid.is_table_row() { has_rows = true; let row = kid.as_mut_table_row(); - if row.mut_base().restyle_damage.contains(ServoRestyleDamage::REFLOW) || - effects_rows != 0 { - row.assign_block_size_to_self_and_children(&sizes, i, &mut effects_rows); - row.mut_base().restyle_damage - .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | - ServoRestyleDamage::REFLOW); - } + row.assign_block_size_to_self_and_children(&sizes, i); + row.mut_base().restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | + ServoRestyleDamage::REFLOW); current_block_offset = current_block_offset + border_spacing_for_row(&self.fragment, row, block_direction_spacing); - // may happen for empty rows - if effects_rows != 0 { - effects_rows -= 1; - } i += 1; } diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 0d779ac8f2f..dbe0bf7b665 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -115,8 +115,6 @@ impl TableRowFlow { incoming_rowspan_data: &mut Vec, border_info: &[(Au, Au)], // (_, cumulative_border_size) row_index: usize) -> (Au, Au) { - // XXXManishearth skip this when the REFLOW flag is unset if it is not affected by other - // rows fn include_sizes_from_previous_rows(col: &mut usize, incoming_rowspan: &[u32], incoming_rowspan_data: &mut Vec, @@ -208,13 +206,12 @@ impl TableRowFlow { (block_size, largest_leftover_incoming_size) } - pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[(Au, Au)], index: usize, effects_rows: &mut u32) { + pub fn assign_block_size_to_self_and_children(&mut self, sizes: &[(Au, Au)], index: usize) { // Assign the block-size of kid fragments, which is the same value as own block-size. let block_size = sizes[index].0; for kid in self.block_flow.base.child_iter_mut() { let child_table_cell = kid.as_mut_table_cell(); let block_size = if child_table_cell.row_span > 1 { - *effects_rows = max(*effects_rows, child_table_cell.row_span); let row_sizes = sizes[index..].iter() .take(child_table_cell.row_span as usize) .fold(Au(0), |accum, size| accum + size.0); From ffe68e8010d58310b2fe79b0fabc08c24d3cb607 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 28 Feb 2018 14:18:25 -0800 Subject: [PATCH 13/13] Add reftest, update test expectations --- tests/wpt/mozilla/meta/MANIFEST.json | 25 +++++++++++++++++++ .../css/table_rowspan_rowgroup_a.html.ini | 2 ++ .../tests/css/table_rowspan_notequal_a.html | 18 +++++++++++++ .../tests/css/table_rowspan_notequal_ref.html | 17 +++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 tests/wpt/mozilla/meta/css/table_rowspan_rowgroup_a.html.ini create mode 100644 tests/wpt/mozilla/tests/css/table_rowspan_notequal_a.html create mode 100644 tests/wpt/mozilla/tests/css/table_rowspan_notequal_ref.html diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 892d423d807..48983914ea7 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5837,6 +5837,18 @@ {} ] ], + "css/table_rowspan_notequal_a.html": [ + [ + "/_mozilla/css/table_rowspan_notequal_a.html", + [ + [ + "/_mozilla/css/table_rowspan_notequal_ref.html", + "!=" + ] + ], + {} + ] + ], "css/table_rowspan_rowgroup_a.html": [ [ "/_mozilla/css/table_rowspan_rowgroup_a.html", @@ -9756,6 +9768,11 @@ {} ] ], + "css/table_rowspan_notequal_ref.html": [ + [ + {} + ] + ], "css/table_rowspan_rowgroup_ref.html": [ [ {} @@ -63932,6 +63949,14 @@ "e045db1f738850e516079b66f915ba314b54ed99", "support" ], + "css/table_rowspan_notequal_a.html": [ + "ec7ab6318a498f6b88369f097af53a0626c6fb1d", + "reftest" + ], + "css/table_rowspan_notequal_ref.html": [ + "2a07facbd9f417264b46f6419ab00593051dae56", + "support" + ], "css/table_rowspan_rowgroup_a.html": [ "aadc4cdd09585330446dd231452c04810833f586", "reftest" diff --git a/tests/wpt/mozilla/meta/css/table_rowspan_rowgroup_a.html.ini b/tests/wpt/mozilla/meta/css/table_rowspan_rowgroup_a.html.ini new file mode 100644 index 00000000000..8a07107a556 --- /dev/null +++ b/tests/wpt/mozilla/meta/css/table_rowspan_rowgroup_a.html.ini @@ -0,0 +1,2 @@ +[table_rowspan_rowgroup_a.html] + expected: FAIL diff --git a/tests/wpt/mozilla/tests/css/table_rowspan_notequal_a.html b/tests/wpt/mozilla/tests/css/table_rowspan_notequal_a.html new file mode 100644 index 00000000000..f37ad51c0ec --- /dev/null +++ b/tests/wpt/mozilla/tests/css/table_rowspan_notequal_a.html @@ -0,0 +1,18 @@ + + + + + + + + + +
  
 
+ + + diff --git a/tests/wpt/mozilla/tests/css/table_rowspan_notequal_ref.html b/tests/wpt/mozilla/tests/css/table_rowspan_notequal_ref.html new file mode 100644 index 00000000000..2b1e1b6bbcd --- /dev/null +++ b/tests/wpt/mozilla/tests/css/table_rowspan_notequal_ref.html @@ -0,0 +1,17 @@ + + + + + + + + +
  
 
+ + +