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); |