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

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

Issue 2545243002: Don't repeat thead if the first row exceeds the height of the page (Closed)
Patch Set: bug 669690 Created 4 years 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 LayoutTableSection::LayoutTableSection(Element* element) 99 LayoutTableSection::LayoutTableSection(Element* element)
100 : LayoutTableBoxComponent(element), 100 : LayoutTableBoxComponent(element),
101 m_cCol(0), 101 m_cCol(0),
102 m_cRow(0), 102 m_cRow(0),
103 m_outerBorderStart(0), 103 m_outerBorderStart(0),
104 m_outerBorderEnd(0), 104 m_outerBorderEnd(0),
105 m_outerBorderBefore(0), 105 m_outerBorderBefore(0),
106 m_outerBorderAfter(0), 106 m_outerBorderAfter(0),
107 m_needsCellRecalc(false), 107 m_needsCellRecalc(false),
108 m_forceSlowPaintPathWithOverflowingCell(false), 108 m_forceSlowPaintPathWithOverflowingCell(false),
109 m_hasMultipleCellLevels(false), 109 m_hasMultipleCellLevels(false) {
110 m_offsetForRepeatingHeader(LayoutUnit()) {
111 // init LayoutObject attributes 110 // init LayoutObject attributes
112 setInline(false); // our object is not Inline 111 setInline(false); // our object is not Inline
113 } 112 }
114 113
115 LayoutTableSection::~LayoutTableSection() {} 114 LayoutTableSection::~LayoutTableSection() {}
116 115
117 void LayoutTableSection::styleDidChange(StyleDifference diff, 116 void LayoutTableSection::styleDidChange(StyleDifference diff,
118 const ComputedStyle* oldStyle) { 117 const ComputedStyle* oldStyle) {
119 DCHECK(style()->display() == EDisplay::TableFooterGroup || 118 DCHECK(style()->display() == EDisplay::TableFooterGroup ||
120 style()->display() == EDisplay::TableRowGroup || 119 style()->display() == EDisplay::TableRowGroup ||
(...skipping 1855 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 if (m_grid[rowIndex].logicalHeight.isSpecified()) { 1975 if (m_grid[rowIndex].logicalHeight.isSpecified()) {
1977 LayoutUnit specifiedLogicalHeight = 1976 LayoutUnit specifiedLogicalHeight =
1978 minimumValueForLength(m_grid[rowIndex].logicalHeight, LayoutUnit()); 1977 minimumValueForLength(m_grid[rowIndex].logicalHeight, LayoutUnit());
1979 logicalHeight = std::max(logicalHeight, specifiedLogicalHeight.toInt()); 1978 logicalHeight = std::max(logicalHeight, specifiedLogicalHeight.toInt());
1980 } 1979 }
1981 return logicalHeight; 1980 return logicalHeight;
1982 } 1981 }
1983 1982
1984 void LayoutTableSection::adjustRowForPagination(LayoutTableRow& rowObject, 1983 void LayoutTableSection::adjustRowForPagination(LayoutTableRow& rowObject,
1985 SubtreeLayoutScope& layouter) { 1984 SubtreeLayoutScope& layouter) {
1986 LayoutState& state = *view()->layoutState();
1987 rowObject.setPaginationStrut(LayoutUnit()); 1985 rowObject.setPaginationStrut(LayoutUnit());
1988 rowObject.setLogicalHeight(LayoutUnit(logicalHeightForRow(rowObject))); 1986 rowObject.setLogicalHeight(LayoutUnit(logicalHeightForRow(rowObject)));
1989 int paginationStrut = 1987 int paginationStrut =
1990 paginationStrutForRow(&rowObject, rowObject.logicalTop()); 1988 paginationStrutForRow(&rowObject, rowObject.logicalTop());
1991 bool rowIsAtTopOfColumn = false; 1989 bool rowIsAtTopOfColumn = false;
1992 LayoutUnit offsetFromTopOfPage; 1990 LayoutUnit offsetFromTopOfPage;
1993 if (!paginationStrut) { 1991 if (!paginationStrut) {
1994 if (state.heightOffsetForTableHeaders()) { 1992 LayoutUnit pageLogicalHeight =
1993 pageLogicalHeightForOffset(rowObject.logicalTop());
1994 if (pageLogicalHeight && table()->header() &&
1995 table()->rowOffsetFromRepeatingHeader()) {
1995 offsetFromTopOfPage = 1996 offsetFromTopOfPage =
1996 pageLogicalHeightForOffset(rowObject.logicalTop()) - 1997 pageLogicalHeight -
1997 pageRemainingLogicalHeightForOffset(rowObject.logicalTop(), 1998 pageRemainingLogicalHeightForOffset(rowObject.logicalTop(),
1998 AssociateWithLatterPage); 1999 AssociateWithLatterPage);
1999 rowIsAtTopOfColumn = !offsetFromTopOfPage || 2000 rowIsAtTopOfColumn = !offsetFromTopOfPage ||
2000 offsetFromTopOfPage <= table()->vBorderSpacing(); 2001 offsetFromTopOfPage <= table()->vBorderSpacing();
2001 } 2002 }
2002 2003
2003 if (!rowIsAtTopOfColumn) 2004 if (!rowIsAtTopOfColumn)
2004 return; 2005 return;
2005 } 2006 }
2006 // We need to push this row to the next fragmentainer. If there are repeated 2007 // We need to push this row to the next fragmentainer. If there are repeated
2007 // table headers, we need to make room for those at the top of the next 2008 // table headers, we need to make room for those at the top of the next
2008 // fragmentainer, above this row. Otherwise, this row will just go at the top 2009 // fragmentainer, above this row. Otherwise, this row will just go at the top
2009 // of the next fragmentainer. 2010 // of the next fragmentainer.
2010 2011
2011 // If there isn't room for at least one content row on a page with a 2012 // If there isn't room for at least one content row on a page with a
2012 // header group, then we won't repeat the header on each page. 2013 // header group, then we won't repeat the header on each page.
2013 LayoutTableSection* header = table()->header(); 2014 LayoutTableSection* header = table()->header();
2014 if (!rowObject.rowIndex() && header && 2015 if (!rowObject.rowIndex() && header &&
2015 table()->sectionAbove(this) == header && 2016 table()->sectionAbove(this) == header &&
2016 header->getPaginationBreakability() != AllowAnyBreaks) { 2017 header->getPaginationBreakability() != AllowAnyBreaks) {
2017 state.setHeightOffsetForTableHeaders(state.heightOffsetForTableHeaders() - 2018 table()->setRowOffsetFromRepeatingHeader(LayoutUnit());
2018 header->logicalHeight());
2019 } 2019 }
2020 // Border spacing from the previous row has pushed this row just past the top 2020 // Border spacing from the previous row has pushed this row just past the top
2021 // of the page, so we must reposition it to the top of the page and avoid any 2021 // of the page, so we must reposition it to the top of the page and avoid any
2022 // repeating header. 2022 // repeating header.
2023 if (rowIsAtTopOfColumn && offsetFromTopOfPage) 2023 if (rowIsAtTopOfColumn && offsetFromTopOfPage)
2024 paginationStrut -= offsetFromTopOfPage.toInt(); 2024 paginationStrut -= offsetFromTopOfPage.toInt();
2025 2025
2026 // If we have a header group we will paint it at the top of each page, 2026 // If we have a header group we will paint it at the top of each page,
2027 // move the rows down to accomodate it. 2027 // move the rows down to accomodate it.
2028 paginationStrut += state.heightOffsetForTableHeaders().toInt(); 2028 if (header)
2029 paginationStrut += table()->rowOffsetFromRepeatingHeader().toInt();
2029 rowObject.setPaginationStrut(LayoutUnit(paginationStrut)); 2030 rowObject.setPaginationStrut(LayoutUnit(paginationStrut));
2030 2031
2031 // We have inserted a pagination strut before the row. Adjust the logical top 2032 // We have inserted a pagination strut before the row. Adjust the logical top
2032 // and re-lay out. We no longer want to break inside the row, but rather 2033 // and re-lay out. We no longer want to break inside the row, but rather
2033 // *before* it. From the previous layout pass, there are most likely 2034 // *before* it. From the previous layout pass, there are most likely
2034 // pagination struts inside some cell in this row that we need to get rid of. 2035 // pagination struts inside some cell in this row that we need to get rid of.
2035 rowObject.setLogicalTop(rowObject.logicalTop() + paginationStrut); 2036 rowObject.setLogicalTop(rowObject.logicalTop() + paginationStrut);
2036 layouter.setChildNeedsLayout(&rowObject); 2037 layouter.setChildNeedsLayout(&rowObject);
2037 rowObject.layoutIfNeeded(); 2038 rowObject.layoutIfNeeded();
2038 2039
(...skipping 12 matching lines...) Expand all
2051 if (!pageHeight) 2052 if (!pageHeight)
2052 return false; 2053 return false;
2053 2054
2054 if (logicalHeight() > pageHeight) 2055 if (logicalHeight() > pageHeight)
2055 return false; 2056 return false;
2056 2057
2057 // If the first row of the section after the header group doesn't fit on the 2058 // If the first row of the section after the header group doesn't fit on the
2058 // page, then don't repeat the header on each page. 2059 // page, then don't repeat the header on each page.
2059 // See https://drafts.csswg.org/css-tables-3/#repeated-headers 2060 // See https://drafts.csswg.org/css-tables-3/#repeated-headers
2060 LayoutTableSection* sectionBelow = table()->sectionBelow(this); 2061 LayoutTableSection* sectionBelow = table()->sectionBelow(this);
2061 if (sectionBelow && sectionBelow->firstRow() && 2062 if (!sectionBelow)
2062 sectionBelow->firstRow()->paginationStrut()) 2063 return true;
2063 return false; 2064 if (LayoutTableRow* firstRow = sectionBelow->firstRow()) {
2065 if (firstRow->paginationStrut() || firstRow->logicalHeight() > pageHeight)
2066 return false;
2067 }
2064 2068
2065 return true; 2069 return true;
2066 } 2070 }
2067 2071
2068 bool LayoutTableSection::mapToVisualRectInAncestorSpace( 2072 bool LayoutTableSection::mapToVisualRectInAncestorSpace(
2069 const LayoutBoxModelObject* ancestor, 2073 const LayoutBoxModelObject* ancestor,
2070 LayoutRect& rect, 2074 LayoutRect& rect,
2071 VisualRectFlags flags) const { 2075 VisualRectFlags flags) const {
2072 if (ancestor == this) 2076 if (ancestor == this)
2073 return true; 2077 return true;
2074 // Repeating table headers are painted once per fragmentation page/column. 2078 // Repeating table headers are painted once per fragmentation page/column.
2075 // This does not go through the regular fragmentation machinery, so we need 2079 // This does not go through the regular fragmentation machinery, so we need
2076 // special code to expand the invalidation rect to contain all positions of 2080 // special code to expand the invalidation rect to contain all positions of
2077 // the header in all columns. 2081 // the header in all columns.
2078 // Note that this is in flow thread coordinates, not visual coordinates. The 2082 // Note that this is in flow thread coordinates, not visual coordinates. The
2079 // enclosing LayoutFlowThread will convert to visual coordinates. 2083 // enclosing LayoutFlowThread will convert to visual coordinates.
2080 if (table()->header() == this && isRepeatingHeaderGroup()) 2084 if (table()->header() == this && isRepeatingHeaderGroup())
2081 rect.setHeight(table()->logicalHeight()); 2085 rect.setHeight(table()->logicalHeight());
2082 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect, 2086 return LayoutTableBoxComponent::mapToVisualRectInAncestorSpace(ancestor, rect,
2083 flags); 2087 flags);
2084 } 2088 }
2085 2089
2086 } // namespace blink 2090 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698