Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTableSection.cpp

Issue 2882043002: Update our treatment of repeating headers in tables (Closed)
Patch Set: bug 720620 Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org) 3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org) 4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
10 * 10 *
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 : LayoutTableBoxComponent(element), 90 : LayoutTableBoxComponent(element),
91 c_col_(0), 91 c_col_(0),
92 c_row_(0), 92 c_row_(0),
93 outer_border_start_(0), 93 outer_border_start_(0),
94 outer_border_end_(0), 94 outer_border_end_(0),
95 outer_border_before_(0), 95 outer_border_before_(0),
96 outer_border_after_(0), 96 outer_border_after_(0),
97 needs_cell_recalc_(false), 97 needs_cell_recalc_(false),
98 force_full_paint_(false), 98 force_full_paint_(false),
99 has_multiple_cell_levels_(false), 99 has_multiple_cell_levels_(false),
100 has_spanning_cells_(false) { 100 has_spanning_cells_(false),
101 is_repeating_header_group_(false) {
101 // init LayoutObject attributes 102 // init LayoutObject attributes
102 SetInline(false); // our object is not Inline 103 SetInline(false); // our object is not Inline
103 } 104 }
104 105
105 LayoutTableSection::~LayoutTableSection() {} 106 LayoutTableSection::~LayoutTableSection() {}
106 107
107 void LayoutTableSection::StyleDidChange(StyleDifference diff, 108 void LayoutTableSection::StyleDidChange(StyleDifference diff,
108 const ComputedStyle* old_style) { 109 const ComputedStyle* old_style) {
109 DCHECK(Style()->Display() == EDisplay::kTableFooterGroup || 110 DCHECK(Style()->Display() == EDisplay::kTableFooterGroup ||
110 Style()->Display() == EDisplay::kTableRowGroup || 111 Style()->Display() == EDisplay::kTableRowGroup ||
(...skipping 1935 matching lines...) Expand 10 before | Expand all | Expand 10 after
2046 } 2047 }
2047 2048
2048 if (!row_is_at_top_of_column) 2049 if (!row_is_at_top_of_column)
2049 return; 2050 return;
2050 } 2051 }
2051 // We need to push this row to the next fragmentainer. If there are repeated 2052 // We need to push this row to the next fragmentainer. If there are repeated
2052 // table headers, we need to make room for those at the top of the next 2053 // table headers, we need to make room for those at the top of the next
2053 // fragmentainer, above this row. Otherwise, this row will just go at the top 2054 // fragmentainer, above this row. Otherwise, this row will just go at the top
2054 // of the next fragmentainer. 2055 // of the next fragmentainer.
2055 2056
2056 LayoutTableSection* header = Table()->Header();
2057 if (row_object.IsFirstRowInSectionAfterHeader())
2058 Table()->SetRowOffsetFromRepeatingHeader(LayoutUnit());
2059 // Border spacing from the previous row has pushed this row just past the top 2057 // Border spacing from the previous row has pushed this row just past the top
2060 // of the page, so we must reposition it to the top of the page and avoid any 2058 // of the page, so we must reposition it to the top of the page and avoid any
2061 // repeating header. 2059 // repeating header.
2062 if (row_is_at_top_of_column && offset_from_top_of_page) 2060 if (row_is_at_top_of_column && offset_from_top_of_page)
2063 pagination_strut -= offset_from_top_of_page.ToInt(); 2061 pagination_strut -= offset_from_top_of_page.ToInt();
2064 2062
2065 // If we have a header group we will paint it at the top of each page, 2063 // If we have a header group we will paint it at the top of each page,
2066 // move the rows down to accomodate it. 2064 // move the rows down to accomodate it.
2065 LayoutTableSection* header = Table()->Header();
2067 if (header && header != this) 2066 if (header && header != this)
2068 pagination_strut += Table()->RowOffsetFromRepeatingHeader().ToInt(); 2067 pagination_strut += Table()->RowOffsetFromRepeatingHeader().ToInt();
2069 row_object.SetPaginationStrut(LayoutUnit(pagination_strut)); 2068 row_object.SetPaginationStrut(LayoutUnit(pagination_strut));
2070 2069
2071 // We have inserted a pagination strut before the row. Adjust the logical top 2070 // We have inserted a pagination strut before the row. Adjust the logical top
2072 // and re-lay out. We no longer want to break inside the row, but rather 2071 // and re-lay out. We no longer want to break inside the row, but rather
2073 // *before* it. From the previous layout pass, there are most likely 2072 // *before* it. From the previous layout pass, there are most likely
2074 // pagination struts inside some cell in this row that we need to get rid of. 2073 // pagination struts inside some cell in this row that we need to get rid of.
2075 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut); 2074 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut);
2076 layouter.SetChildNeedsLayout(&row_object); 2075 layouter.SetChildNeedsLayout(&row_object);
2077 row_object.LayoutIfNeeded(); 2076 row_object.LayoutIfNeeded();
2078 2077
2079 // It's very likely that re-laying out (and nuking pagination struts inside 2078 // It's very likely that re-laying out (and nuking pagination struts inside
2080 // cells) gave us a new height. 2079 // cells) gave us a new height.
2081 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); 2080 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object)));
2082 } 2081 }
2083 2082
2084 bool LayoutTableSection::IsRepeatingHeaderGroup() const { 2083 bool LayoutTableSection::HeaderGroupShouldRepeat() const {
2085 if (GetPaginationBreakability() == LayoutBox::kAllowAnyBreaks) 2084 if (Table()->Header() != this)
2086 return false; 2085 return false;
2087 // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? 2086
2087 if (GetPaginationBreakability() == kAllowAnyBreaks)
2088 return false;
2089 // TODO(rhogan): Sections can be self-painting.
2088 if (HasSelfPaintingLayer()) 2090 if (HasSelfPaintingLayer())
2089 return false; 2091 return false;
2090 LayoutUnit page_height = Table()->PageLogicalHeightForOffset(LayoutUnit()); 2092 LayoutUnit page_height = PageLogicalHeightForOffset(LayoutUnit());
2093 // If we don't know the page height yet, just assume we fit.
2091 if (!page_height) 2094 if (!page_height)
2092 return false; 2095 return true;
2093 2096
2094 if (LogicalHeight() > page_height) 2097 if (LogicalHeight() > page_height)
2095 return false; 2098 return false;
2096 2099
2097 // If the first row of the section after the header group doesn't fit on the 2100 // See https://drafts.csswg.org/css-tables-3/#repeated-headers which says
2098 // page, then don't repeat the header on each page. 2101 // a header/footer can repeat if it takes up less than a quarter of the page.
2099 // See https://drafts.csswg.org/css-tables-3/#repeated-headers 2102 if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4)
2100 LayoutTableSection* section_below = Table()->SectionBelow(this); 2103 return false;
2101 if (!section_below)
2102 return true;
2103 if (LayoutTableRow* first_row = section_below->FirstRow()) {
2104 if (first_row->PaginationStrut() ||
2105 first_row->LogicalHeight() > page_height)
2106 return false;
2107 }
2108 2104
2109 return true; 2105 return true;
2110 } 2106 }
2111 2107
2112 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( 2108 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal(
2113 const LayoutBoxModelObject* ancestor, 2109 const LayoutBoxModelObject* ancestor,
2114 TransformState& transform_state, 2110 TransformState& transform_state,
2115 VisualRectFlags flags) const { 2111 VisualRectFlags flags) const {
2116 if (ancestor == this) 2112 if (ancestor == this)
2117 return true; 2113 return true;
2118 // Repeating table headers are painted once per fragmentation page/column. 2114 // Repeating table headers are painted once per fragmentation page/column.
2119 // This does not go through the regular fragmentation machinery, so we need 2115 // This does not go through the regular fragmentation machinery, so we need
2120 // special code to expand the invalidation rect to contain all positions of 2116 // special code to expand the invalidation rect to contain all positions of
2121 // the header in all columns. 2117 // the header in all columns.
2122 // Note that this is in flow thread coordinates, not visual coordinates. The 2118 // Note that this is in flow thread coordinates, not visual coordinates. The
2123 // enclosing LayoutFlowThread will convert to visual coordinates. 2119 // enclosing LayoutFlowThread will convert to visual coordinates.
2124 if (Table()->Header() == this && IsRepeatingHeaderGroup()) { 2120 if (IsRepeatingHeaderGroup()) {
2125 transform_state.Flatten(); 2121 transform_state.Flatten();
2126 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); 2122 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox();
2127 rect.SetHeight(Table()->LogicalHeight()); 2123 rect.SetHeight(Table()->LogicalHeight());
2128 transform_state.SetQuad(FloatQuad(rect)); 2124 transform_state.SetQuad(FloatQuad(rect));
2129 } 2125 }
2130 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal( 2126 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal(
2131 ancestor, transform_state, flags); 2127 ancestor, transform_state, flags);
2132 } 2128 }
2133 2129
2134 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() 2130 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize()
2135 const { 2131 const {
2136 // LayoutTableSection paints background from columns. 2132 // LayoutTableSection paints background from columns.
2137 if (Table()->HasColElements()) 2133 if (Table()->HasColElements())
2138 return false; 2134 return false;
2139 return LayoutTableBoxComponent:: 2135 return LayoutTableBoxComponent::
2140 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); 2136 PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
2141 } 2137 }
2142 2138
2143 } // namespace blink 2139 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698