From b77a0a89cf76a15346345c74e712a8d56b6ee517 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Wed, 7 Dec 2016 18:25:01 -0800 Subject: [PATCH 1/5] Propagate column info to rows sequentially This avoids storing it in the rowgroup (which doesn't need it) and ensures that it is done sequentially, which will be important when rowspan support is added to this function. Note that this does not reduce parallelism in the common case where all rows are in the same rowgroup. --- components/layout/table_row.rs | 9 ++++++--- components/layout/table_rowgroup.rs | 24 ++---------------------- 2 files changed, 8 insertions(+), 25 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 272bf85337f..acb052a7134 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -726,10 +726,13 @@ pub fn propagate_column_inline_sizes_to_child( } FlowClass::TableRowGroup => { let child_table_rowgroup_flow = child_flow.as_mut_table_rowgroup(); - child_table_rowgroup_flow.column_computed_inline_sizes = - column_computed_inline_sizes.to_vec(); child_table_rowgroup_flow.spacing = *border_spacing; - child_table_rowgroup_flow.table_writing_mode = table_writing_mode; + for kid in child_table_rowgroup_flow.block_flow.base.child_iter_mut() { + propagate_column_inline_sizes_to_child(kid, + table_writing_mode, + column_computed_inline_sizes, + border_spacing); + } } FlowClass::TableRow => { let child_table_row_flow = child_flow.as_mut_table_row(); diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 9c7ace68260..a76d7a82ccf 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -23,10 +23,9 @@ use std::iter::{IntoIterator, Iterator, Peekable}; use std::sync::Arc; use style::computed_values::{border_collapse, border_spacing}; use style::context::SharedStyleContext; -use style::logical_geometry::{LogicalSize, WritingMode}; +use style::logical_geometry::LogicalSize; use style::properties::ServoComputedValues; -use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow}; -use table_row; +use table::{ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow}; /// A table formatting context. pub struct TableRowGroupFlow { @@ -36,16 +35,9 @@ pub struct TableRowGroupFlow { /// Information about the intrinsic inline-sizes of each column. pub column_intrinsic_inline_sizes: Vec, - /// Information about the actual inline sizes of each column. - pub column_computed_inline_sizes: Vec, - /// The spacing for this rowgroup. pub spacing: border_spacing::T, - /// The direction of the columns, propagated down from the table during the inline-size - /// assignment phase. - pub table_writing_mode: WritingMode, - /// The final width of the borders in the inline direction for each cell, computed by the /// entire table and pushed down into each row during inline size computation. pub collapsed_inline_direction_border_widths_for_table: Vec, @@ -63,16 +55,13 @@ impl Serialize for TableRowGroupFlow { impl TableRowGroupFlow { pub fn from_fragment(fragment: Fragment) -> TableRowGroupFlow { - let writing_mode = fragment.style().writing_mode; TableRowGroupFlow { block_flow: BlockFlow::from_fragment(fragment), column_intrinsic_inline_sizes: Vec::new(), - column_computed_inline_sizes: Vec::new(), spacing: border_spacing::T { horizontal: Au(0), vertical: Au(0), }, - table_writing_mode: writing_mode, collapsed_inline_direction_border_widths_for_table: Vec::new(), collapsed_block_direction_border_widths_for_table: Vec::new(), } @@ -150,9 +139,6 @@ impl Flow for TableRowGroupFlow { shared_context, containing_block_inline_size); - let column_computed_inline_sizes = &self.column_computed_inline_sizes; - let border_spacing = self.spacing; - let table_writing_mode = self.table_writing_mode; let collapsed_inline_direction_border_widths_for_table = &self.collapsed_inline_direction_border_widths_for_table; let mut collapsed_block_direction_border_widths_for_table = @@ -167,12 +153,6 @@ impl Flow for TableRowGroupFlow { _writing_mode, _inline_start_margin_edge, _inline_end_margin_edge| { - table_row::propagate_column_inline_sizes_to_child( - child_flow, - table_writing_mode, - column_computed_inline_sizes, - &border_spacing); - if border_collapse == border_collapse::T::collapse { let child_table_row = child_flow.as_mut_table_row(); child_table_row.populate_collapsed_border_spacing( From e982d6003fb0e4bc0a26cb5cf488bc8c2bc117f8 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 22 Nov 2016 13:24:06 -0800 Subject: [PATCH 2/5] Add the HTMLTableCellElement::rowspan property --- components/layout/table_cell.rs | 5 + components/layout/table_row.rs | 5 + components/script/dom/element.rs | 13 + components/script/dom/htmltablecellelement.rs | 17 + .../dom/webidls/HTMLTableCellElement.webidl | 4 +- components/script/layout_wrapper.rs | 6 + .../script_layout_interface/wrapper_traits.rs | 2 + components/style/matching.rs | 4 +- .../wpt/metadata/html/dom/interfaces.html.ini | 9 - .../html/dom/reflection-tabular.html.ini | 750 ------------------ 10 files changed, 52 insertions(+), 763 deletions(-) diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index abdcf03cb2b..5e20f195078 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -41,6 +41,9 @@ pub struct TableCellFlow { /// The column span of this cell. pub column_span: u32, + /// The rows spanned by this cell. + pub row_span: u32, + /// Whether this cell is visible. If false, the value of `empty-cells` means that we must not /// display this cell. pub visible: bool, @@ -52,6 +55,7 @@ impl TableCellFlow { block_flow: BlockFlow::from_fragment(fragment), collapsed_borders: CollapsedBordersForCell::new(), column_span: 1, + row_span: 1, visible: true, } } @@ -62,6 +66,7 @@ impl TableCellFlow { block_flow: BlockFlow::from_fragment(fragment), collapsed_borders: CollapsedBordersForCell::new(), column_span: node.get_colspan(), + row_span: node.get_rowspan(), visible: visible, } } diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index acb052a7134..4f8af643846 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -78,6 +78,8 @@ pub struct CellIntrinsicInlineSize { pub column_size: ColumnIntrinsicInlineSize, /// The column span of this cell. pub column_span: u32, + /// The row span of this cell. + pub row_span: u32, } @@ -268,6 +270,7 @@ impl Flow for TableRowFlow { // fixed and automatic table layout calculation. let child_specified_inline_size; let child_column_span; + let child_row_span; { let child_table_cell = kid.as_mut_table_cell(); child_specified_inline_size = child_table_cell.block_flow @@ -275,6 +278,7 @@ impl Flow for TableRowFlow { .style .content_inline_size(); child_column_span = child_table_cell.column_span; + child_row_span = child_table_cell.row_span; // Perform border collapse if necessary. if collapsing_borders { @@ -319,6 +323,7 @@ impl Flow for TableRowFlow { self.cell_intrinsic_inline_sizes.push(CellIntrinsicInlineSize { column_size: child_column_inline_size, column_span: child_column_span, + row_span: child_row_span, }); } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index d9831d79a69..4a94f345b02 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -324,6 +324,8 @@ pub trait LayoutElementHelpers { #[allow(unsafe_code)] unsafe fn get_colspan(self) -> u32; #[allow(unsafe_code)] + unsafe fn get_rowspan(self) -> u32; + #[allow(unsafe_code)] unsafe fn html_element_in_html_document_for_layout(&self) -> bool; fn id_attribute(&self) -> *const Option; fn style_attribute(&self) -> *const Option>>; @@ -627,6 +629,17 @@ impl LayoutElementHelpers for LayoutJS { } } + #[allow(unsafe_code)] + unsafe fn get_rowspan(self) -> u32 { + if let Some(this) = self.downcast::() { + this.get_rowspan().unwrap_or(1) + } else { + // Don't panic since `display` can cause this to be called on arbitrary + // elements. + 1 + } + } + #[inline] #[allow(unsafe_code)] unsafe fn html_element_in_html_document_for_layout(&self) -> bool { diff --git a/components/script/dom/htmltablecellelement.rs b/components/script/dom/htmltablecellelement.rs index 1ec389d9977..b4bd885d4ed 100644 --- a/components/script/dom/htmltablecellelement.rs +++ b/components/script/dom/htmltablecellelement.rs @@ -18,6 +18,7 @@ use html5ever_atoms::LocalName; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; const DEFAULT_COLSPAN: u32 = 1; +const DEFAULT_ROWSPAN: u32 = 1; #[dom_struct] pub struct HTMLTableCellElement { @@ -47,6 +48,12 @@ impl HTMLTableCellElementMethods for HTMLTableCellElement { // https://html.spec.whatwg.org/multipage/#dom-tdth-colspan make_uint_setter!(SetColSpan, "colspan", DEFAULT_COLSPAN); + // https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan + make_uint_getter!(RowSpan, "rowspan", DEFAULT_ROWSPAN); + + // https://html.spec.whatwg.org/multipage/#dom-tdth-rowspan + make_uint_setter!(SetRowSpan, "rowspan", DEFAULT_ROWSPAN); + // https://html.spec.whatwg.org/multipage/#dom-tdth-bgcolor make_getter!(BgColor, "bgcolor"); @@ -80,6 +87,7 @@ impl HTMLTableCellElementMethods for HTMLTableCellElement { pub trait HTMLTableCellElementLayoutHelpers { fn get_background_color(&self) -> Option; fn get_colspan(&self) -> Option; + fn get_rowspan(&self) -> Option; fn get_width(&self) -> LengthOrPercentageOrAuto; } @@ -102,6 +110,14 @@ impl HTMLTableCellElementLayoutHelpers for LayoutJS { } } + fn get_rowspan(&self) -> Option { + unsafe { + (&*self.upcast::().unsafe_get()) + .get_attr_for_layout(&ns!(), &local_name!("rowspan")) + .map(AttrValue::as_uint) + } + } + fn get_width(&self) -> LengthOrPercentageOrAuto { unsafe { (&*self.upcast::().unsafe_get()) @@ -121,6 +137,7 @@ impl VirtualMethods for HTMLTableCellElement { fn parse_plain_attribute(&self, local_name: &LocalName, value: DOMString) -> AttrValue { match *local_name { local_name!("colspan") => AttrValue::from_u32(value.into(), DEFAULT_COLSPAN), + local_name!("rowspan") => AttrValue::from_u32(value.into(), DEFAULT_ROWSPAN), local_name!("bgcolor") => AttrValue::from_legacy_color(value.into()), local_name!("width") => AttrValue::from_nonzero_dimension(value.into()), _ => self.super_type().unwrap().parse_plain_attribute(local_name, value), diff --git a/components/script/dom/webidls/HTMLTableCellElement.webidl b/components/script/dom/webidls/HTMLTableCellElement.webidl index 33863b3dc20..8ac135170ec 100644 --- a/components/script/dom/webidls/HTMLTableCellElement.webidl +++ b/components/script/dom/webidls/HTMLTableCellElement.webidl @@ -5,8 +5,8 @@ // https://html.spec.whatwg.org/multipage/#htmltablecellelement [Abstract] interface HTMLTableCellElement : HTMLElement { - attribute unsigned long colSpan; - // attribute unsigned long rowSpan; + attribute unsigned long colSpan; + attribute unsigned long rowSpan; // attribute DOMString headers; readonly attribute long cellIndex; diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 338edc19730..290ebeb2312 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -913,6 +913,12 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { self.get_jsmanaged().downcast::().unwrap().get_colspan() } } + + fn get_rowspan(&self) -> u32 { + unsafe { + self.get_jsmanaged().downcast::().unwrap().get_rowspan() + } + } } pub struct ThreadSafeLayoutNodeChildrenIterator { diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index 1d1f32bf4b6..cf3e3e4c7c5 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -265,6 +265,8 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo fn get_colspan(&self) -> u32; + fn get_rowspan(&self) -> u32; + fn fragment_type(&self) -> FragmentType { match self.get_pseudo_element_type() { PseudoElementType::Normal => FragmentType::FragmentBody, diff --git a/components/style/matching.rs b/components/style/matching.rs index 3b0a396507d..f88df07e980 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -266,8 +266,8 @@ pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo /// Attributes that, if present, disable style sharing. All legacy HTML attributes must be in /// either this list or `common_style_affecting_attributes`. See the comment in /// `synthesize_presentational_hints_for_legacy_attributes`. -pub fn rare_style_affecting_attributes() -> [LocalName; 3] { - [ local_name!("bgcolor"), local_name!("border"), local_name!("colspan") ] +pub fn rare_style_affecting_attributes() -> [LocalName; 4] { + [local_name!("bgcolor"), local_name!("border"), local_name!("colspan"), local_name!("rowspan")] } fn have_same_class(element: &E, diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini index 4961fca1f35..24f7bf07de4 100644 --- a/tests/wpt/metadata/html/dom/interfaces.html.ini +++ b/tests/wpt/metadata/html/dom/interfaces.html.ini @@ -2973,9 +2973,6 @@ [HTMLTableDataCellElement interface: document.createElement("td") must inherit property "abbr" with the proper type (0)] expected: FAIL - [HTMLTableCellElement interface: document.createElement("td") must inherit property "rowSpan" with the proper type (1)] - expected: FAIL - [HTMLTableCellElement interface: document.createElement("td") must inherit property "headers" with the proper type (2)] expected: FAIL @@ -3024,9 +3021,6 @@ [HTMLTableHeaderCellElement interface: document.createElement("th") must inherit property "sort" with the proper type (3)] expected: FAIL - [HTMLTableCellElement interface: document.createElement("th") must inherit property "rowSpan" with the proper type (1)] - expected: FAIL - [HTMLTableCellElement interface: document.createElement("th") must inherit property "headers" with the proper type (2)] expected: FAIL @@ -3051,9 +3045,6 @@ [HTMLTableCellElement interface: document.createElement("th") must inherit property "vAlign" with the proper type (11)] expected: FAIL - [HTMLTableCellElement interface: attribute rowSpan] - expected: FAIL - [HTMLTableCellElement interface: attribute headers] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/reflection-tabular.html.ini b/tests/wpt/metadata/html/dom/reflection-tabular.html.ini index abb903f2da3..44589149715 100644 --- a/tests/wpt/metadata/html/dom/reflection-tabular.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-tabular.html.ini @@ -11127,189 +11127,6 @@ [td.tabIndex: IDL set to -2147483648 followed by getAttribute()] expected: FAIL - [td.rowSpan: typeof IDL attribute] - expected: FAIL - - [td.rowSpan: IDL get with DOM attribute unset] - expected: FAIL - - [td.rowSpan: setAttribute() to -2147483649 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to -2147483648 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to -36 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to -1 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 0 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 1 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 257 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 2147483647 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 2147483648 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 4294967295 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 4294967296 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "-1" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "-0" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "0" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "1" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\t7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\v7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\f7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\n7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\r7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "
7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "
7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "᠎7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to true followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to false followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to object "2" followed by IDL get] - expected: FAIL - - [td.rowSpan: setAttribute() to object "3" followed by IDL get] - expected: FAIL - - [td.rowSpan: IDL set to 0 followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to 1 followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to 257 followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to 2147483647 followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to "-0" followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to "-0" followed by IDL get] - expected: FAIL - [td.align: typeof IDL attribute] expected: FAIL @@ -13050,189 +12867,6 @@ [th.tabIndex: IDL set to -2147483648 followed by getAttribute()] expected: FAIL - [th.rowSpan: typeof IDL attribute] - expected: FAIL - - [th.rowSpan: IDL get with DOM attribute unset] - expected: FAIL - - [th.rowSpan: setAttribute() to -2147483649 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to -2147483648 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to -36 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to -1 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 0 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 1 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 257 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 2147483647 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 2147483648 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 4294967295 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 4294967296 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "-1" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "-0" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "0" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "1" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\t7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\v7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\f7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\n7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\r7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "
7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "
7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "᠎7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to true followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to false followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to object "2" followed by IDL get] - expected: FAIL - - [th.rowSpan: setAttribute() to object "3" followed by IDL get] - expected: FAIL - - [th.rowSpan: IDL set to 0 followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to 1 followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to 257 followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to 2147483647 followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to "-0" followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to "-0" followed by IDL get] - expected: FAIL - [th.align: typeof IDL attribute] expected: FAIL @@ -17007,30 +16641,6 @@ [col.span: IDL set to 4294967295 followed by IDL get] expected: FAIL - [td.rowSpan: IDL set to 2147483648 followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to 2147483648 followed by IDL get] - expected: FAIL - - [td.rowSpan: IDL set to 4294967295 followed by getAttribute()] - expected: FAIL - - [td.rowSpan: IDL set to 4294967295 followed by IDL get] - expected: FAIL - - [th.rowSpan: IDL set to 2147483648 followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to 2147483648 followed by IDL get] - expected: FAIL - - [th.rowSpan: IDL set to 4294967295 followed by getAttribute()] - expected: FAIL - - [th.rowSpan: IDL set to 4294967295 followed by IDL get] - expected: FAIL - [td.scope: typeof IDL attribute] expected: FAIL @@ -23796,186 +23406,6 @@ [td.tabIndex: IDL set to -2147483648] expected: FAIL - [td.rowSpan: setAttribute() to -2147483649] - expected: FAIL - - [td.rowSpan: setAttribute() to -2147483648] - expected: FAIL - - [td.rowSpan: setAttribute() to -36] - expected: FAIL - - [td.rowSpan: setAttribute() to -1] - expected: FAIL - - [td.rowSpan: setAttribute() to 0] - expected: FAIL - - [td.rowSpan: setAttribute() to 1] - expected: FAIL - - [td.rowSpan: setAttribute() to 257] - expected: FAIL - - [td.rowSpan: setAttribute() to 2147483647] - expected: FAIL - - [td.rowSpan: setAttribute() to 2147483648] - expected: FAIL - - [td.rowSpan: setAttribute() to 4294967295] - expected: FAIL - - [td.rowSpan: setAttribute() to 4294967296] - expected: FAIL - - [td.rowSpan: setAttribute() to ""] - expected: FAIL - - [td.rowSpan: setAttribute() to "-1"] - expected: FAIL - - [td.rowSpan: setAttribute() to "-0"] - expected: FAIL - - [td.rowSpan: setAttribute() to "0"] - expected: FAIL - - [td.rowSpan: setAttribute() to "1"] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\t7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\v7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\f7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\n7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\r7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "
7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "
7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to "᠎7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [td.rowSpan: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [td.rowSpan: setAttribute() to undefined] - expected: FAIL - - [td.rowSpan: setAttribute() to 1.5] - expected: FAIL - - [td.rowSpan: setAttribute() to true] - expected: FAIL - - [td.rowSpan: setAttribute() to false] - expected: FAIL - - [td.rowSpan: setAttribute() to object "[object Object\]"] - expected: FAIL - - [td.rowSpan: setAttribute() to NaN] - expected: FAIL - - [td.rowSpan: setAttribute() to Infinity] - expected: FAIL - - [td.rowSpan: setAttribute() to -Infinity] - expected: FAIL - - [td.rowSpan: setAttribute() to "\\0"] - expected: FAIL - - [td.rowSpan: setAttribute() to object "2"] - expected: FAIL - - [td.rowSpan: setAttribute() to object "3"] - expected: FAIL - - [td.rowSpan: IDL set to 0] - expected: FAIL - - [td.rowSpan: IDL set to 1] - expected: FAIL - - [td.rowSpan: IDL set to 257] - expected: FAIL - - [td.rowSpan: IDL set to 2147483647] - expected: FAIL - - [td.rowSpan: IDL set to "-0"] - expected: FAIL - - [td.rowSpan: IDL set to 2147483648] - expected: FAIL - - [td.rowSpan: IDL set to 4294967295] - expected: FAIL - [td.scope: setAttribute() to ""] expected: FAIL @@ -25245,186 +24675,6 @@ [th.tabIndex: IDL set to -2147483648] expected: FAIL - [th.rowSpan: setAttribute() to -2147483649] - expected: FAIL - - [th.rowSpan: setAttribute() to -2147483648] - expected: FAIL - - [th.rowSpan: setAttribute() to -36] - expected: FAIL - - [th.rowSpan: setAttribute() to -1] - expected: FAIL - - [th.rowSpan: setAttribute() to 0] - expected: FAIL - - [th.rowSpan: setAttribute() to 1] - expected: FAIL - - [th.rowSpan: setAttribute() to 257] - expected: FAIL - - [th.rowSpan: setAttribute() to 2147483647] - expected: FAIL - - [th.rowSpan: setAttribute() to 2147483648] - expected: FAIL - - [th.rowSpan: setAttribute() to 4294967295] - expected: FAIL - - [th.rowSpan: setAttribute() to 4294967296] - expected: FAIL - - [th.rowSpan: setAttribute() to ""] - expected: FAIL - - [th.rowSpan: setAttribute() to "-1"] - expected: FAIL - - [th.rowSpan: setAttribute() to "-0"] - expected: FAIL - - [th.rowSpan: setAttribute() to "0"] - expected: FAIL - - [th.rowSpan: setAttribute() to "1"] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\t7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\v7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\f7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\n7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\r7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "
7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "
7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to "᠎7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " 7"] - expected: FAIL - - [th.rowSpan: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [th.rowSpan: setAttribute() to undefined] - expected: FAIL - - [th.rowSpan: setAttribute() to 1.5] - expected: FAIL - - [th.rowSpan: setAttribute() to true] - expected: FAIL - - [th.rowSpan: setAttribute() to false] - expected: FAIL - - [th.rowSpan: setAttribute() to object "[object Object\]"] - expected: FAIL - - [th.rowSpan: setAttribute() to NaN] - expected: FAIL - - [th.rowSpan: setAttribute() to Infinity] - expected: FAIL - - [th.rowSpan: setAttribute() to -Infinity] - expected: FAIL - - [th.rowSpan: setAttribute() to "\\0"] - expected: FAIL - - [th.rowSpan: setAttribute() to object "2"] - expected: FAIL - - [th.rowSpan: setAttribute() to object "3"] - expected: FAIL - - [th.rowSpan: IDL set to 0] - expected: FAIL - - [th.rowSpan: IDL set to 1] - expected: FAIL - - [th.rowSpan: IDL set to 257] - expected: FAIL - - [th.rowSpan: IDL set to 2147483647] - expected: FAIL - - [th.rowSpan: IDL set to "-0"] - expected: FAIL - - [th.rowSpan: IDL set to 2147483648] - expected: FAIL - - [th.rowSpan: IDL set to 4294967295] - expected: FAIL - [th.scope: setAttribute() to ""] expected: FAIL From 9700b0e8b35b6d9f4d0f29ec60c225fdf1aeb796 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 8 Dec 2016 15:47:22 -0800 Subject: [PATCH 3/5] Account for rowspan in inline layout of table columns/cells --- components/layout/table.rs | 22 ++++- components/layout/table_row.rs | 90 +++++++++++++++++-- components/layout/table_wrapper.rs | 3 +- tests/wpt/mozilla/meta/MANIFEST.json | 36 ++++++++ .../tests/css/table_rowspan_simple_a.html | 20 +++++ .../tests/css/table_rowspan_simple_ref.html | 20 +++++ 6 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 tests/wpt/mozilla/tests/css/table_rowspan_simple_a.html create mode 100644 tests/wpt/mozilla/tests/css/table_rowspan_simple_ref.html diff --git a/components/layout/table.rs b/components/layout/table.rs index 6d95ff0b1e0..031cf2ab197 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -94,7 +94,16 @@ impl TableFlow { preferred_inline_size: surrounding_size, }; let mut column_index = 0; + let mut incoming_rowspan = vec![]; + for child_cell_inline_size in child_cell_inline_sizes { + // Skip any column occupied by a cell from a previous row. + while column_index < incoming_rowspan.len() && incoming_rowspan[column_index] != 1 { + if incoming_rowspan[column_index] > 1 { + incoming_rowspan[column_index] -= 1; + } + column_index += 1; + } for _ in 0..child_cell_inline_size.column_span { if column_index < parent_inline_sizes.len() { // We already have some intrinsic size information for this column. Merge it in @@ -130,6 +139,14 @@ impl TableFlow { total_inline_sizes.preferred_inline_size += parent_inline_sizes[column_index].preferred; + // If this cell spans later rows, record its rowspan. + if child_cell_inline_size.row_span > 1 { + if incoming_rowspan.len() < column_index + 1 { + incoming_rowspan.resize(column_index + 1, 0); + } + incoming_rowspan[column_index] = child_cell_inline_size.row_span; + } + column_index += 1 } } @@ -418,6 +435,7 @@ impl Flow for TableFlow { &self.collapsed_inline_direction_border_widths_for_table; let mut collapsed_block_direction_border_widths_for_table = self.collapsed_block_direction_border_widths_for_table.iter().peekable(); + let mut incoming_rowspan = vec![]; self.block_flow.propagate_assigned_inline_size_to_children(shared_context, inline_start_content_edge, inline_end_content_edge, @@ -432,7 +450,8 @@ impl Flow for TableFlow { child_flow, writing_mode, column_computed_inline_sizes, - &spacing_per_cell); + &spacing_per_cell, + &mut incoming_rowspan); if child_flow.is_table_row() { let child_table_row = child_flow.as_mut_table_row(); child_table_row.populate_collapsed_border_spacing( @@ -647,6 +666,7 @@ fn perform_border_collapse_for_row(child_table_row: &mut TableRowFlow, next_block_borders: NextBlockCollapsedBorders, inline_spacing: &mut Vec, block_spacing: &mut Vec) { + // TODO mbrubeck: Take rowspan and colspan into account. let number_of_borders_inline_direction = child_table_row.preliminary_collapsed_borders.inline.len(); // Compute interior inline borders. for (i, this_inline_border) in child_table_row.preliminary_collapsed_borders diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 4f8af643846..6db82388d0a 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -45,6 +45,12 @@ pub struct TableRowFlow { /// Information about the computed inline-sizes of each column. pub column_computed_inline_sizes: Vec, + /// The number of remaining rows spanned by cells in previous rows, indexed by column. + /// + /// Columns that are not included in this vector have the default rowspan of "1". If there are + /// no cells with rowspan != 1 in previous rows, this vector may be empty. + pub incoming_rowspan: Vec, + /// The spacing for this row, propagated down from the table during the inline-size assignment /// phase. pub spacing: border_spacing::T, @@ -90,6 +96,7 @@ impl TableRowFlow { block_flow: BlockFlow::from_fragment(fragment), cell_intrinsic_inline_sizes: Vec::new(), column_computed_inline_sizes: Vec::new(), + incoming_rowspan: Vec::new(), spacing: border_spacing::T { horizontal: Au(0), vertical: Au(0), @@ -353,12 +360,23 @@ impl Flow for TableRowFlow { containing_block_inline_size); // Spread out the completed inline sizes among columns with spans > 1. - let mut computed_inline_size_for_cells = Vec::new(); - let mut column_computed_inline_size_iterator = self.column_computed_inline_sizes.iter(); + let num_columns = self.column_computed_inline_sizes.len(); + let mut computed_inline_size_for_cells = Vec::with_capacity(num_columns); + let mut col = 0; + for cell_intrinsic_inline_size in &self.cell_intrinsic_inline_sizes { + // Skip any column occupied by a cell from a previous row. + while col < self.incoming_rowspan.len() && self.incoming_rowspan[col] != 1 { + let size = match self.column_computed_inline_sizes.get(col) { + Some(column_computed_inline_size) => *column_computed_inline_size, + None => ColumnComputedInlineSize { size: Au(0) } // See FIXME below. + }; + computed_inline_size_for_cells.push(size); + col += 1; + } // Start with the computed inline size for the first column in the span. let mut column_computed_inline_size = - match column_computed_inline_size_iterator.next() { + match self.column_computed_inline_sizes.get(col) { Some(column_computed_inline_size) => *column_computed_inline_size, None => { // We're in fixed layout mode and there are more cells in this row than @@ -371,16 +389,18 @@ impl Flow for TableRowFlow { } } }; + col += 1; // Add in computed inline sizes for any extra columns in the span. for _ in 1..cell_intrinsic_inline_size.column_span { let extra_column_computed_inline_size = - match column_computed_inline_size_iterator.next() { + match self.column_computed_inline_sizes.get(col) { Some(column_computed_inline_size) => column_computed_inline_size, None => break, }; column_computed_inline_size.size = column_computed_inline_size.size + extra_column_computed_inline_size.size + self.spacing.horizontal; + col += 1; } computed_inline_size_for_cells.push(column_computed_inline_size) @@ -402,6 +422,9 @@ impl Flow for TableRowFlow { let spacing = self.spacing; let row_writing_mode = self.block_flow.base.writing_mode; let table_writing_mode = self.table_writing_mode; + let incoming_rowspan = &self.incoming_rowspan; + let mut column_index = 0; + self.block_flow.propagate_assigned_inline_size_to_children(shared_context, inline_start_content_edge, inline_end_content_edge, @@ -415,6 +438,8 @@ impl Flow for TableRowFlow { set_inline_position_of_child_flow( child_flow, child_index, + &mut column_index, + incoming_rowspan, row_writing_mode, table_writing_mode, &computed_inline_size_for_cells, @@ -714,13 +739,14 @@ impl CollapsedBorder { } } -/// Pushes column inline size and border collapse info down to a child. +/// Pushes column inline size, incoming rowspan, and border collapse info down to a child. pub fn propagate_column_inline_sizes_to_child( child_flow: &mut Flow, table_writing_mode: WritingMode, column_computed_inline_sizes: &[ColumnComputedInlineSize], - border_spacing: &border_spacing::T) { - // If the child is a row group or a row, the column inline-size info should be copied from its + border_spacing: &border_spacing::T, + incoming_rowspan: &mut Vec) { + // If the child is a row group or a row, the column inline-size and rowspan info should be copied from its // parent. // // FIXME(pcwalton): This seems inefficient. Reference count it instead? @@ -736,7 +762,8 @@ pub fn propagate_column_inline_sizes_to_child( propagate_column_inline_sizes_to_child(kid, table_writing_mode, column_computed_inline_sizes, - border_spacing); + border_spacing, + incoming_rowspan); } } FlowClass::TableRow => { @@ -745,6 +772,32 @@ pub fn propagate_column_inline_sizes_to_child( column_computed_inline_sizes.to_vec(); child_table_row_flow.spacing = *border_spacing; child_table_row_flow.table_writing_mode = table_writing_mode; + child_table_row_flow.incoming_rowspan = incoming_rowspan.clone(); + + // Update the incoming rowspan for the next row. + let mut col = 0; + for cell in &child_table_row_flow.cell_intrinsic_inline_sizes { + // Skip any column occupied by a cell from a previous row. + while col < incoming_rowspan.len() && incoming_rowspan[col] != 1 { + if incoming_rowspan[col] > 1 { + incoming_rowspan[col] -= 1; + } + col += 1; + } + for _ in 0..cell.column_span { + if col < incoming_rowspan.len() && incoming_rowspan[col] > 1 { + incoming_rowspan[col] -= 1; + } + // If this cell spans later rows, record its rowspan. + if cell.row_span != 1 { + if incoming_rowspan.len() < col + 1 { + incoming_rowspan.resize(col + 1, 1); + } + incoming_rowspan[col] = max(cell.row_span, incoming_rowspan[col]); + } + col += 1; + } + } } c => warn!("unexpected flow in table {:?}", c) } @@ -754,6 +807,8 @@ pub fn propagate_column_inline_sizes_to_child( fn set_inline_position_of_child_flow( child_flow: &mut Flow, child_index: usize, + column_index: &mut usize, + incoming_rowspan: &[u32], row_writing_mode: WritingMode, table_writing_mode: WritingMode, column_computed_inline_sizes: &[ColumnComputedInlineSize], @@ -768,6 +823,21 @@ fn set_inline_position_of_child_flow( let reverse_column_order = table_writing_mode.is_bidi_ltr() != row_writing_mode.is_bidi_ltr(); + // Advance past any column occupied by a cell from a previous row. + while *column_index < incoming_rowspan.len() && incoming_rowspan[*column_index] != 1 { + let column_inline_size = column_computed_inline_sizes[*column_index].size; + let border_inline_size = match *border_collapse_info { + Some(_) => Au(0), // FIXME: Make collapsed borders account for colspan/rowspan. + None => border_spacing.horizontal, + }; + if reverse_column_order { + *inline_end_margin_edge += column_inline_size + border_inline_size; + } else { + *inline_start_margin_edge += column_inline_size + border_inline_size; + } + *column_index += 1; + } + // Handle border collapsing, if necessary. let child_table_cell = child_flow.as_mut_table_cell(); match *border_collapse_info { @@ -822,7 +892,9 @@ fn set_inline_position_of_child_flow( } } - let column_inline_size = column_computed_inline_sizes[child_index].size; + let column_inline_size = column_computed_inline_sizes[*column_index].size; + *column_index += 1; + let kid_base = &mut child_table_cell.block_flow.base; kid_base.block_container_inline_size = column_inline_size; diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 372fdbd086f..62f4d76b1b2 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -420,7 +420,8 @@ impl Flow for TableWrapperFlow { child_flow, writing_mode, assigned_column_inline_sizes, - &border_spacing); + &border_spacing, + &mut vec![]); }) } } diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 23b77f9ed85..e91bdccb049 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5292,6 +5292,18 @@ "url": "/_mozilla/css/table_row_direction_a.html" } ], + "css/table_rowspan_simple_a.html": [ + { + "path": "css/table_rowspan_simple_a.html", + "references": [ + [ + "/_mozilla/css/table_rowspan_simple_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/table_rowspan_simple_a.html" + } + ], "css/table_specified_width_a.html": [ { "path": "css/table_specified_width_a.html", @@ -20328,6 +20340,30 @@ "url": "/_mozilla/css/table_row_direction_a.html" } ], + "css/table_rowspan_simple_a.html": [ + { + "path": "css/table_rowspan_simple_a.html", + "references": [ + [ + "/_mozilla/css/table_rowspan_simple_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/table_rowspan_simple_a.html" + } + ], + "css/table_rowspan_simple_ref.html": [ + { + "path": "css/table_rowspan_simple_ref.html", + "references": [ + [ + "/_mozilla/css/table_rowspan_simple_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/table_rowspan_simple_ref.html" + } + ], "css/table_specified_width_a.html": [ { "path": "css/table_specified_width_a.html", diff --git a/tests/wpt/mozilla/tests/css/table_rowspan_simple_a.html b/tests/wpt/mozilla/tests/css/table_rowspan_simple_a.html new file mode 100644 index 00000000000..8a0df11a942 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/table_rowspan_simple_a.html @@ -0,0 +1,20 @@ + + + + + + + + + +
  
 
+ + + diff --git a/tests/wpt/mozilla/tests/css/table_rowspan_simple_ref.html b/tests/wpt/mozilla/tests/css/table_rowspan_simple_ref.html new file mode 100644 index 00000000000..83580dd1d39 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/table_rowspan_simple_ref.html @@ -0,0 +1,20 @@ + + + + + + + + + +
  
  
+ + + From 622d43da8aa18c195b8a3f0370689a262c364ba3 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 8 Dec 2016 15:49:42 -0800 Subject: [PATCH 4/5] Simplify propagation of column sizes from TableWrapperFlow --- components/layout/table_row.rs | 4 ---- components/layout/table_wrapper.rs | 19 +++++-------------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 6db82388d0a..20ba8736265 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -751,10 +751,6 @@ pub fn propagate_column_inline_sizes_to_child( // // FIXME(pcwalton): This seems inefficient. Reference count it instead? match child_flow.class() { - FlowClass::Table => { - let child_table_flow = child_flow.as_mut_table(); - child_table_flow.column_computed_inline_sizes = column_computed_inline_sizes.to_vec(); - } FlowClass::TableRowGroup => { let child_table_rowgroup_flow = child_flow.as_mut_table_rowgroup(); child_table_rowgroup_flow.spacing = *border_spacing; diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 62f4d76b1b2..7510ae3988a 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -37,7 +37,6 @@ use style::properties::ServoComputedValues; use style::values::CSSFloat; use style::values::computed::LengthOrPercentageOrAuto; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize}; -use table_row; #[derive(Copy, Clone, Serialize, Debug)] pub enum TableLayout { @@ -394,7 +393,6 @@ impl Flow for TableWrapperFlow { } }; - let border_spacing = self.block_flow.fragment.style().get_inheritedtable().border_spacing; match assigned_column_inline_sizes { None => { self.block_flow @@ -410,18 +408,11 @@ impl Flow for TableWrapperFlow { inline_start_content_edge, inline_end_content_edge, content_inline_size, - |child_flow, - _child_index, - _content_inline_size, - writing_mode, - _inline_start_margin_edge, - _inline_end_margin_edge| { - table_row::propagate_column_inline_sizes_to_child( - child_flow, - writing_mode, - assigned_column_inline_sizes, - &border_spacing, - &mut vec![]); + |child_flow, _, _, _, _, _| { + if child_flow.class() == FlowClass::Table { + child_flow.as_mut_table().column_computed_inline_sizes = + assigned_column_inline_sizes.to_vec(); + } }) } } From ef7bdaa3e37cb00091a19c30a405327d3091c6ff Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Thu, 8 Dec 2016 15:54:33 -0800 Subject: [PATCH 5/5] Minor code cleanup in table_row --- components/layout/table_row.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 20ba8736265..45ac5fbdb3f 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -871,19 +871,17 @@ fn set_inline_position_of_child_flow( // Move over past the collapsed border. if reverse_column_order { - *inline_end_margin_edge = *inline_end_margin_edge + - child_table_cell.collapsed_borders.inline_start_width + *inline_end_margin_edge += child_table_cell.collapsed_borders.inline_start_width; } else { - *inline_start_margin_edge = *inline_start_margin_edge + - child_table_cell.collapsed_borders.inline_start_width + *inline_start_margin_edge += child_table_cell.collapsed_borders.inline_start_width; } } None => { // Take spacing into account. if reverse_column_order { - *inline_end_margin_edge = *inline_end_margin_edge + border_spacing.horizontal + *inline_end_margin_edge += border_spacing.horizontal; } else { - *inline_start_margin_edge = *inline_start_margin_edge + border_spacing.horizontal + *inline_start_margin_edge += border_spacing.horizontal; } } } @@ -898,11 +896,11 @@ fn set_inline_position_of_child_flow( // Columns begin from the inline-end edge. kid_base.position.start.i = parent_content_inline_size - *inline_end_margin_edge - column_inline_size; - *inline_end_margin_edge = *inline_end_margin_edge + column_inline_size; + *inline_end_margin_edge += column_inline_size; } else { // Columns begin from the inline-start edge. kid_base.position.start.i = *inline_start_margin_edge; - *inline_start_margin_edge = *inline_start_margin_edge + column_inline_size; + *inline_start_margin_edge += column_inline_size; } }