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

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

Issue 2701163002: Avoid pathological layout on nested percent height tables (Closed)
Patch Set: Created 3 years, 10 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, 2007, 2008, 2009, 2010, 2013 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 m_firstBody(nullptr), 59 m_firstBody(nullptr),
60 m_collapsedBordersValid(false), 60 m_collapsedBordersValid(false),
61 m_hasColElements(false), 61 m_hasColElements(false),
62 m_needsSectionRecalc(false), 62 m_needsSectionRecalc(false),
63 m_columnLogicalWidthChanged(false), 63 m_columnLogicalWidthChanged(false),
64 m_columnLayoutObjectsValid(false), 64 m_columnLayoutObjectsValid(false),
65 m_noCellColspanAtLeast(0), 65 m_noCellColspanAtLeast(0),
66 m_hSpacing(0), 66 m_hSpacing(0),
67 m_vSpacing(0), 67 m_vSpacing(0),
68 m_borderStart(0), 68 m_borderStart(0),
69 m_borderEnd(0) { 69 m_borderEnd(0),
70 m_oldAvailableLogicalHeight(0) {
mstensho (USE GERRIT) 2017/02/20 13:01:31 No need (actually surprisingly expensive if you do
70 ASSERT(!childrenInline()); 71 ASSERT(!childrenInline());
71 m_effectiveColumnPositions.fill(0, 1); 72 m_effectiveColumnPositions.fill(0, 1);
72 } 73 }
73 74
74 LayoutTable::~LayoutTable() {} 75 LayoutTable::~LayoutTable() {}
75 76
76 void LayoutTable::styleDidChange(StyleDifference diff, 77 void LayoutTable::styleDidChange(StyleDifference diff,
77 const ComputedStyle* oldStyle) { 78 const ComputedStyle* oldStyle) {
78 LayoutBlock::styleDidChange(diff, oldStyle); 79 LayoutBlock::styleDidChange(diff, oldStyle);
79 80
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (!selfNeedsLayout()) 439 if (!selfNeedsLayout())
439 caption.setMayNeedPaintInvalidation(); 440 caption.setMayNeedPaintInvalidation();
440 441
441 setLogicalHeight(logicalHeight() + caption.logicalHeight() + 442 setLogicalHeight(logicalHeight() + caption.logicalHeight() +
442 collapsedMarginBeforeForChild(caption) + 443 collapsedMarginBeforeForChild(caption) +
443 collapsedMarginAfterForChild(caption)); 444 collapsedMarginAfterForChild(caption));
444 } 445 }
445 446
446 void LayoutTable::layoutSection(LayoutTableSection& section, 447 void LayoutTable::layoutSection(LayoutTableSection& section,
447 SubtreeLayoutScope& layouter, 448 SubtreeLayoutScope& layouter,
448 LayoutUnit logicalLeft) { 449 LayoutUnit logicalLeft,
450 TableHeightChangingValue tableHeightChanging) {
449 section.setLogicalLocation(LayoutPoint(logicalLeft, logicalHeight())); 451 section.setLogicalLocation(LayoutPoint(logicalLeft, logicalHeight()));
450 if (m_columnLogicalWidthChanged) 452 if (m_columnLogicalWidthChanged)
451 layouter.setChildNeedsLayout(&section); 453 layouter.setChildNeedsLayout(&section);
452 if (!section.needsLayout()) 454 if (!section.needsLayout())
453 markChildForPaginationRelayoutIfNeeded(section, layouter); 455 markChildForPaginationRelayoutIfNeeded(section, layouter);
454 section.layoutIfNeeded(); 456 bool neededLayout = section.needsLayout();
455 int sectionLogicalHeight = section.calcRowLogicalHeight(); 457 if (neededLayout)
456 section.setLogicalHeight(LayoutUnit(sectionLogicalHeight)); 458 section.layout();
459 if (neededLayout || tableHeightChanging == TableHeightChanging)
460 section.setLogicalHeight(LayoutUnit(section.calcRowLogicalHeight()));
461
457 if (view()->layoutState()->isPaginated()) 462 if (view()->layoutState()->isPaginated())
458 updateFragmentationInfoForChild(section); 463 updateFragmentationInfoForChild(section);
459 setLogicalHeight(logicalHeight() + sectionLogicalHeight); 464 setLogicalHeight(logicalHeight() + section.logicalHeight());
460 } 465 }
461 466
462 LayoutUnit LayoutTable::logicalHeightFromStyle() const { 467 LayoutUnit LayoutTable::logicalHeightFromStyle() const {
463 LayoutUnit computedLogicalHeight; 468 LayoutUnit computedLogicalHeight;
464 Length logicalHeightLength = style()->logicalHeight(); 469 Length logicalHeightLength = style()->logicalHeight();
465 if (logicalHeightLength.isIntrinsic() || 470 if (logicalHeightLength.isIntrinsic() ||
466 (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive())) { 471 (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive())) {
467 computedLogicalHeight = 472 computedLogicalHeight =
468 convertStyleLogicalHeightToComputedHeight(logicalHeightLength); 473 convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
469 } 474 }
(...skipping 24 matching lines...) Expand all
494 void LayoutTable::distributeExtraLogicalHeight(int extraLogicalHeight) { 499 void LayoutTable::distributeExtraLogicalHeight(int extraLogicalHeight) {
495 if (extraLogicalHeight <= 0) 500 if (extraLogicalHeight <= 0)
496 return; 501 return;
497 502
498 // FIXME: Distribute the extra logical height between all table sections 503 // FIXME: Distribute the extra logical height between all table sections
499 // instead of giving it all to the first one. 504 // instead of giving it all to the first one.
500 if (LayoutTableSection* section = firstBody()) 505 if (LayoutTableSection* section = firstBody())
501 extraLogicalHeight -= 506 extraLogicalHeight -=
502 section->distributeExtraLogicalHeightToRows(extraLogicalHeight); 507 section->distributeExtraLogicalHeightToRows(extraLogicalHeight);
503 508
504 // FIXME: We really would like to enable this ASSERT to ensure that all the 509 // crbug.com/690087: We really would like to enable this ASSERT to ensure that
505 // extra space has been distributed. 510 // all the extra space has been distributed.
506 // However our current distribution algorithm does not round properly and thus 511 // However our current distribution algorithm does not round properly and thus
507 // we can have some remaining height. 512 // we can have some remaining height.
508 // ASSERT(!topSection() || !extraLogicalHeight); 513 // ASSERT(!topSection() || !extraLogicalHeight);
509 } 514 }
510 515
511 void LayoutTable::simplifiedNormalFlowLayout() { 516 void LayoutTable::simplifiedNormalFlowLayout() {
512 // FIXME: We should walk through the items in the tree in tree order to do the 517 // FIXME: We should walk through the items in the tree in tree order to do the
513 // layout here instead of walking through individual parts of the tree. 518 // layout here instead of walking through individual parts of the tree.
514 // crbug.com/442737 519 // crbug.com/442737
515 for (auto& caption : m_captions) 520 for (auto& caption : m_captions)
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 borderAfter() + (collapsing ? LayoutUnit() : paddingAfter()); 621 borderAfter() + (collapsing ? LayoutUnit() : paddingAfter());
617 622
618 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore); 623 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore);
619 624
620 LayoutUnit sectionLogicalLeft = LayoutUnit( 625 LayoutUnit sectionLogicalLeft = LayoutUnit(
621 style()->isLeftToRightDirection() ? borderStart() : borderEnd()); 626 style()->isLeftToRightDirection() ? borderStart() : borderEnd());
622 if (!collapsing) { 627 if (!collapsing) {
623 sectionLogicalLeft += 628 sectionLogicalLeft +=
624 style()->isLeftToRightDirection() ? paddingStart() : paddingEnd(); 629 style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
625 } 630 }
631 LayoutUnit currentAvailableLogicalHeight =
632 availableLogicalHeight(IncludeMarginBorderPadding);
633 TableHeightChangingValue tableHeightChanging =
634 m_oldAvailableLogicalHeight &&
635 m_oldAvailableLogicalHeight != currentAvailableLogicalHeight
636 ? TableHeightChanging
637 : TableHeightNotChanging;
638 m_oldAvailableLogicalHeight = currentAvailableLogicalHeight;
626 639
627 // Lay out table header group. 640 // Lay out table header group.
628 if (LayoutTableSection* section = header()) { 641 if (LayoutTableSection* section = header()) {
629 layoutSection(*section, layouter, sectionLogicalLeft); 642 layoutSection(*section, layouter, sectionLogicalLeft,
643 tableHeightChanging);
630 if (state.isPaginated()) { 644 if (state.isPaginated()) {
631 // If the repeating header group allows at least one row of content, 645 // If the repeating header group allows at least one row of content,
632 // then store the offset for other sections to offset their rows 646 // then store the offset for other sections to offset their rows
633 // against. 647 // against.
634 LayoutUnit sectionLogicalHeight = section->logicalHeight(); 648 LayoutUnit sectionLogicalHeight = section->logicalHeight();
635 if (sectionLogicalHeight < 649 if (sectionLogicalHeight <
636 section->pageLogicalHeightForOffset(section->logicalTop()) && 650 section->pageLogicalHeightForOffset(section->logicalTop()) &&
637 section->getPaginationBreakability() != AllowAnyBreaks) { 651 section->getPaginationBreakability() != AllowAnyBreaks) {
638 // Don't include any strut in the header group - we only want the 652 // Don't include any strut in the header group - we only want the
639 // height from its content. 653 // height from its content.
640 LayoutUnit offsetForTableHeaders = sectionLogicalHeight; 654 LayoutUnit offsetForTableHeaders = sectionLogicalHeight;
641 if (LayoutTableRow* row = section->firstRow()) 655 if (LayoutTableRow* row = section->firstRow())
642 offsetForTableHeaders -= row->paginationStrut(); 656 offsetForTableHeaders -= row->paginationStrut();
643 setRowOffsetFromRepeatingHeader(offsetForTableHeaders); 657 setRowOffsetFromRepeatingHeader(offsetForTableHeaders);
644 } 658 }
645 } 659 }
646 } 660 }
647 661
648 // Lay out table body groups, and column groups. 662 // Lay out table body groups, and column groups.
649 for (LayoutObject* child = firstChild(); child; 663 for (LayoutObject* child = firstChild(); child;
650 child = child->nextSibling()) { 664 child = child->nextSibling()) {
651 if (child->isTableSection()) { 665 if (child->isTableSection()) {
652 if (child != header() && child != footer()) { 666 if (child != header() && child != footer()) {
653 LayoutTableSection& section = *toLayoutTableSection(child); 667 LayoutTableSection& section = *toLayoutTableSection(child);
654 layoutSection(section, layouter, sectionLogicalLeft); 668 layoutSection(section, layouter, sectionLogicalLeft,
669 tableHeightChanging);
655 } 670 }
656 } else if (child->isLayoutTableCol()) { 671 } else if (child->isLayoutTableCol()) {
657 child->layoutIfNeeded(); 672 child->layoutIfNeeded();
658 } else { 673 } else {
659 DCHECK(child->isTableCaption()); 674 DCHECK(child->isTableCaption());
660 } 675 }
661 } 676 }
662 677
663 // Lay out table footer. 678 // Lay out table footer.
664 if (LayoutTableSection* section = footer()) 679 if (LayoutTableSection* section = footer()) {
665 layoutSection(*section, layouter, sectionLogicalLeft); 680 layoutSection(*section, layouter, sectionLogicalLeft,
681 tableHeightChanging);
682 }
666 683
667 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore); 684 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore);
668 685
669 LayoutUnit computedLogicalHeight = logicalHeightFromStyle(); 686 LayoutUnit computedLogicalHeight = logicalHeightFromStyle();
670 LayoutUnit totalSectionLogicalHeight; 687 LayoutUnit totalSectionLogicalHeight;
671 if (topSection) { 688 if (topSection) {
672 totalSectionLogicalHeight = 689 totalSectionLogicalHeight =
673 bottomSection->logicalBottom() - topSection->logicalTop(); 690 bottomSection->logicalBottom() - topSection->logicalTop();
674 } 691 }
675 692
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 } 1712 }
1696 1713
1697 LayoutUnit LayoutTable::paddingRight() const { 1714 LayoutUnit LayoutTable::paddingRight() const {
1698 if (collapseBorders()) 1715 if (collapseBorders())
1699 return LayoutUnit(); 1716 return LayoutUnit();
1700 1717
1701 return LayoutBlock::paddingRight(); 1718 return LayoutBlock::paddingRight();
1702 } 1719 }
1703 1720
1704 } // namespace blink 1721 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698