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

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, 7 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 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 } 2040 }
2040 2041
2041 if (!row_is_at_top_of_column) 2042 if (!row_is_at_top_of_column)
2042 return; 2043 return;
2043 } 2044 }
2044 // We need to push this row to the next fragmentainer. If there are repeated 2045 // We need to push this row to the next fragmentainer. If there are repeated
2045 // table headers, we need to make room for those at the top of the next 2046 // table headers, we need to make room for those at the top of the next
2046 // fragmentainer, above this row. Otherwise, this row will just go at the top 2047 // fragmentainer, above this row. Otherwise, this row will just go at the top
2047 // of the next fragmentainer. 2048 // of the next fragmentainer.
2048 2049
2049 LayoutTableSection* header = Table()->Header();
2050 if (row_object.IsFirstRowInSectionAfterHeader())
2051 Table()->SetRowOffsetFromRepeatingHeader(LayoutUnit());
2052 // Border spacing from the previous row has pushed this row just past the top 2050 // Border spacing from the previous row has pushed this row just past the top
2053 // of the page, so we must reposition it to the top of the page and avoid any 2051 // of the page, so we must reposition it to the top of the page and avoid any
2054 // repeating header. 2052 // repeating header.
2055 if (row_is_at_top_of_column && offset_from_top_of_page) 2053 if (row_is_at_top_of_column && offset_from_top_of_page)
2056 pagination_strut -= offset_from_top_of_page.ToInt(); 2054 pagination_strut -= offset_from_top_of_page.ToInt();
2057 2055
2058 // If we have a header group we will paint it at the top of each page, 2056 // If we have a header group we will paint it at the top of each page,
2059 // move the rows down to accomodate it. 2057 // move the rows down to accomodate it.
2058 LayoutTableSection* header = Table()->Header();
2060 if (header && header != this) 2059 if (header && header != this)
2061 pagination_strut += Table()->RowOffsetFromRepeatingHeader().ToInt(); 2060 pagination_strut += Table()->RowOffsetFromRepeatingHeader().ToInt();
2062 row_object.SetPaginationStrut(LayoutUnit(pagination_strut)); 2061 row_object.SetPaginationStrut(LayoutUnit(pagination_strut));
2063 2062
2064 // We have inserted a pagination strut before the row. Adjust the logical top 2063 // We have inserted a pagination strut before the row. Adjust the logical top
2065 // and re-lay out. We no longer want to break inside the row, but rather 2064 // and re-lay out. We no longer want to break inside the row, but rather
2066 // *before* it. From the previous layout pass, there are most likely 2065 // *before* it. From the previous layout pass, there are most likely
2067 // pagination struts inside some cell in this row that we need to get rid of. 2066 // pagination struts inside some cell in this row that we need to get rid of.
2068 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut); 2067 row_object.SetLogicalTop(row_object.LogicalTop() + pagination_strut);
2069 layouter.SetChildNeedsLayout(&row_object); 2068 layouter.SetChildNeedsLayout(&row_object);
2070 row_object.LayoutIfNeeded(); 2069 row_object.LayoutIfNeeded();
2071 2070
2072 // It's very likely that re-laying out (and nuking pagination struts inside 2071 // It's very likely that re-laying out (and nuking pagination struts inside
2073 // cells) gave us a new height. 2072 // cells) gave us a new height.
2074 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object))); 2073 row_object.SetLogicalHeight(LayoutUnit(LogicalHeightForRow(row_object)));
2075 } 2074 }
2076 2075
2077 bool LayoutTableSection::IsRepeatingHeaderGroup() const { 2076 bool LayoutTableSection::HeaderGroupShouldRepeat() const {
2078 if (GetPaginationBreakability() == LayoutBox::kAllowAnyBreaks) 2077 if (Table()->Header() != this)
2079 return false; 2078 return false;
2080 // TODO(rhogan): Should we paint a header repeatedly if it's self-painting? 2079
2080 if (GetPaginationBreakability() == kAllowAnyBreaks)
2081 return false;
2082 // TODO(rhogan): Sections can be self-painting.
2081 if (HasSelfPaintingLayer()) 2083 if (HasSelfPaintingLayer())
2082 return false; 2084 return false;
2083 LayoutUnit page_height = Table()->PageLogicalHeightForOffset(LayoutUnit()); 2085 LayoutUnit page_height = PageLogicalHeightForOffset(LayoutUnit());
2086 // If we don't know the page height yet, just assume we fit.
2084 if (!page_height) 2087 if (!page_height)
2085 return false; 2088 return true;
2086 2089
2087 if (LogicalHeight() > page_height) 2090 if (LogicalHeight() > page_height)
2088 return false; 2091 return false;
2089 2092
2090 // If the first row of the section after the header group doesn't fit on the 2093 // See https://drafts.csswg.org/css-tables-3/#repeated-headers which says
2091 // page, then don't repeat the header on each page. 2094 // a header/footer can repeat if it takes up less than a quarter of the page.
2092 // See https://drafts.csswg.org/css-tables-3/#repeated-headers 2095 if (LogicalHeight() > 0 && page_height / LogicalHeight() < 4)
2093 LayoutTableSection* section_below = Table()->SectionBelow(this); 2096 return false;
2094 if (!section_below)
2095 return true;
2096 if (LayoutTableRow* first_row = section_below->FirstRow()) {
2097 if (first_row->PaginationStrut() ||
2098 first_row->LogicalHeight() > page_height)
2099 return false;
2100 }
2101 2097
2102 return true; 2098 return true;
2103 } 2099 }
2104 2100
2105 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal( 2101 bool LayoutTableSection::MapToVisualRectInAncestorSpaceInternal(
2106 const LayoutBoxModelObject* ancestor, 2102 const LayoutBoxModelObject* ancestor,
2107 TransformState& transform_state, 2103 TransformState& transform_state,
2108 VisualRectFlags flags) const { 2104 VisualRectFlags flags) const {
2109 if (ancestor == this) 2105 if (ancestor == this)
2110 return true; 2106 return true;
2111 // Repeating table headers are painted once per fragmentation page/column. 2107 // Repeating table headers are painted once per fragmentation page/column.
2112 // This does not go through the regular fragmentation machinery, so we need 2108 // This does not go through the regular fragmentation machinery, so we need
2113 // special code to expand the invalidation rect to contain all positions of 2109 // special code to expand the invalidation rect to contain all positions of
2114 // the header in all columns. 2110 // the header in all columns.
2115 // Note that this is in flow thread coordinates, not visual coordinates. The 2111 // Note that this is in flow thread coordinates, not visual coordinates. The
2116 // enclosing LayoutFlowThread will convert to visual coordinates. 2112 // enclosing LayoutFlowThread will convert to visual coordinates.
2117 if (Table()->Header() == this && IsRepeatingHeaderGroup()) { 2113 if (IsRepeatingHeaderGroup()) {
2118 transform_state.Flatten(); 2114 transform_state.Flatten();
2119 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox(); 2115 FloatRect rect = transform_state.LastPlanarQuad().BoundingBox();
2120 rect.SetHeight(Table()->LogicalHeight()); 2116 rect.SetHeight(Table()->LogicalHeight());
2121 transform_state.SetQuad(FloatQuad(rect)); 2117 transform_state.SetQuad(FloatQuad(rect));
2122 } 2118 }
2123 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal( 2119 return LayoutTableBoxComponent::MapToVisualRectInAncestorSpaceInternal(
2124 ancestor, transform_state, flags); 2120 ancestor, transform_state, flags);
2125 } 2121 }
2126 2122
2127 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize() 2123 bool LayoutTableSection::PaintedOutputOfObjectHasNoEffectRegardlessOfSize()
2128 const { 2124 const {
2129 // LayoutTableSection paints background from columns. 2125 // LayoutTableSection paints background from columns.
2130 if (Table()->HasColElements()) 2126 if (Table()->HasColElements())
2131 return false; 2127 return false;
2132 return LayoutTableBoxComponent:: 2128 return LayoutTableBoxComponent::
2133 PaintedOutputOfObjectHasNoEffectRegardlessOfSize(); 2129 PaintedOutputOfObjectHasNoEffectRegardlessOfSize();
2134 } 2130 }
2135 2131
2136 } // namespace blink 2132 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698