Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| index 275532bb4fd737759e67a6f72a4a27292d04d4dc..37d39c1e62b5e22c3a02c9f95c13a9c443ea70b5 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| +++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp |
| @@ -1254,6 +1254,14 @@ int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, |
| if (row_logical_height > page_logical_height) |
| return 0; |
| + LayoutTableSection* footer = Table()->Footer(); |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
This one can be const, I guess?
rhogan
2017/05/09 19:57:16
Done.
|
| + bool footer_wants_to_repeat = |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
make_room_for_repeating_footer?
rhogan
2017/05/09 19:57:16
Done.
|
| + footer && footer != this && |
| + footer->IsRepeatingFooterGroup(const_cast<LayoutTableSection*>(this)) && |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
Ugh. But is there really any reason not to let the
rhogan
2017/05/09 19:57:16
Done.
|
| + row->RowIndex(); |
| + if (footer_wants_to_repeat) |
| + row_logical_height += footer->LogicalHeight(); |
| + |
| LayoutUnit remaining_logical_height = PageRemainingLogicalHeightForOffset( |
| logical_offset, LayoutBlock::kAssociateWithLatterPage); |
| if (remaining_logical_height >= row_logical_height) |
| @@ -1266,6 +1274,7 @@ int LayoutTableSection::PaginationStrutForRow(LayoutTableRow* row, |
| // content completely. No point in leaving a page completely blank. |
| return 0; |
| } |
| + |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
Back out this?
rhogan
2017/05/09 19:57:16
Done.
|
| // Table layout parts only work on integers, so we have to round. Round up, to |
| // make sure that no fraction ever gets left behind in the previous |
| // fragmentainer. |
| @@ -2063,6 +2072,7 @@ void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object, |
| row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); |
| int pagination_strut = |
| PaginationStrutForRow(&row_object, row_object.LogicalTop()); |
| + LayoutTableSection* footer = Table()->Footer(); |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
Can you push it a few lines down, next to where it
rhogan
2017/05/09 19:57:16
Done.
|
| bool row_is_at_top_of_column = false; |
| LayoutUnit offset_from_top_of_page; |
| if (!pagination_strut) { |
| @@ -2096,6 +2106,19 @@ void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object, |
| if (row_is_at_top_of_column && offset_from_top_of_page) |
| pagination_strut -= offset_from_top_of_page.ToInt(); |
| + if (footer && footer != this && header != this && |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
If the header isn't repeating, there should be no
rhogan
2017/05/09 19:57:16
Done.
|
| + footer->IsRepeatingFooterGroup(this)) { |
| + DCHECK(PageLogicalHeightForOffset(LayoutUnit())); |
| + LayoutUnit offset_from_top = LogicalTop() + row_object.LogicalTop(); |
| + unsigned page = |
| + FloorToInt(offset_from_top / PageLogicalHeightForOffset(LayoutUnit())); |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
To cope with non-uniform page heights, you should
rhogan
2017/05/09 19:57:15
Done.
|
| + LayoutUnit remaining_logical_height = PageRemainingLogicalHeightForOffset( |
| + row_object.LogicalTop(), LayoutBlock::kAssociateWithLatterPage); |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
LayoutBlock:: scope should be unnecessary. This on
rhogan
2017/05/09 19:57:16
Done.
|
| + if (remaining_logical_height >= |
| + (footer->LogicalHeight() - Table()->VBorderSpacing())) |
| + Table()->SetPositionOfRepeatingFooterGroupOnPage(page, offset_from_top); |
| + } |
| + |
| // If we have a header group we will paint it at the top of each page, |
| // move the rows down to accomodate it. |
| if (header && header != this) |
| @@ -2115,22 +2138,47 @@ void LayoutTableSection::AdjustRowForPagination(LayoutTableRow& row_object, |
| row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); |
| } |
| +bool LayoutTableSection::IsRepeatingFooterGroup( |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
This belongs AFTER IsRepeatingHeaderGroup().
rhogan
2017/05/09 19:57:16
Done.
|
| + LayoutTableSection* section_for_page) const { |
| + if (GetPaginationBreakability() == kAllowAnyBreaks) |
| + return false; |
| + |
| + // TODO(rhogan): Sections can be self-painting. |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
Can you tell me how they can be self-painting?
rhogan
2017/05/09 19:57:16
Yes, if you put an opacity: 0.5 on them for exampl
mstensho (USE GERRIT)
2017/05/10 10:59:03
Ah, thanks!
|
| + if (HasSelfPaintingLayer()) |
| + return false; |
| + |
| + LayoutUnit page_height = section_for_page |
| + ? section_for_page->PageLogicalHeightForOffset( |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
This is to avoid assertion failures and the bugs t
rhogan
2017/05/09 19:57:16
Correct.
|
| + section_for_page->LogicalTop()) |
| + : PageLogicalHeightForOffset(LogicalTop()); |
| + if (!page_height) |
| + return false; |
| + |
| + if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4) |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
The code looks fine, but I'd like a comment that m
rhogan
2017/05/09 19:57:16
Done.
|
| + return false; |
| + |
| + return true; |
| +} |
| + |
| bool LayoutTableSection::IsRepeatingHeaderGroup() const { |
| - if (GetPaginationBreakability() == LayoutBox::kAllowAnyBreaks) |
| + if (GetPaginationBreakability() == kAllowAnyBreaks) |
| return false; |
| - // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? |
| + |
| + // TODO(rhogan): Sections can be self-painting. |
| if (HasSelfPaintingLayer()) |
| return false; |
| - LayoutUnit page_height = Table()->PageLogicalHeightForOffset(LayoutUnit()); |
| + |
| + LayoutUnit page_height = PageLogicalHeightForOffset(LogicalTop()); |
| if (!page_height) |
| return false; |
| - if (LogicalHeight() > page_height) |
| + if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4) |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
The code looks fine, but I'd like a comment that m
rhogan
2017/05/09 19:57:16
Done.
|
| return false; |
| - // If the first row of the section after the header group doesn't fit on the |
| - // page, then don't repeat the header on each page. |
| - // See https://drafts.csswg.org/css-tables-3/#repeated-headers |
| + // TODO(crbug.com/710387): If the first row of the section after the header |
| + // group doesn't fit on the page, then we don't repeat the header on each page |
| + // and by extension only support repeating headers on the innermost table in a |
| + // set of nested tables. |
| LayoutTableSection* section_below = Table()->SectionBelow(this); |
| if (!section_below) |
| return true; |
| @@ -2149,17 +2197,21 @@ bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( |
| VisualRectFlags flags) const { |
| if (ancestor == this) |
| return true; |
| - // Repeating table headers are painted once per fragmentation page/column. |
| - // This does not go through the regular fragmentation machinery, so we need |
| - // special code to expand the invalidation rect to contain all positions of |
| - // the header in all columns. |
| - // Note that this is in flow thread coordinates, not visual coordinates. The |
| - // enclosing LayoutFlowThread will convert to visual coordinates. |
| - if (Table()->Header() == this && IsRepeatingHeaderGroup()) { |
| + |
| + // Repeating table headers and footers are painted once per fragmentation |
| + // page/column. This does not go through the regular fragmentation machinery, |
| + // so we need special code to expand the invalidation rect to contain all |
| + // positions of the header in all columns. Note that this is in flow thread |
| + // coordinates, not visual coordinates. The enclosing LayoutFlowThread will |
| + // convert to visual coordinates. |
| + if ((Table()->Header() == this && IsRepeatingHeaderGroup()) || |
| + (Table()->Footer() == this && IsRepeatingFooterGroup())) { |
| transform_state.Flatten(); |
| FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); |
| rect.SetHeight(Table()->LogicalHeight()); |
| transform_state.SetQuad(FloatQuad(rect)); |
| + return Table()->MapToVisualRectInAncestorSpaceInternal( |
|
mstensho (USE GERRIT)
2017/05/08 13:55:59
How can we just skip one ancestor in the chain lik
rhogan
2017/05/09 19:57:16
I've updated the comment to explain this. For both
|
| + ancestor, transform_state, flags); |
| } |
| return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal( |
| ancestor, transform_state, flags); |