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

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: bug 687061 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 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 if (!selfNeedsLayout()) 438 if (!selfNeedsLayout())
439 caption.setMayNeedPaintInvalidation(); 439 caption.setMayNeedPaintInvalidation();
440 440
441 setLogicalHeight(logicalHeight() + caption.logicalHeight() + 441 setLogicalHeight(logicalHeight() + caption.logicalHeight() +
442 collapsedMarginBeforeForChild(caption) + 442 collapsedMarginBeforeForChild(caption) +
443 collapsedMarginAfterForChild(caption)); 443 collapsedMarginAfterForChild(caption));
444 } 444 }
445 445
446 void LayoutTable::layoutSection(LayoutTableSection& section, 446 void LayoutTable::layoutSection(LayoutTableSection& section,
447 SubtreeLayoutScope& layouter, 447 SubtreeLayoutScope& layouter,
448 LayoutUnit logicalLeft) { 448 LayoutUnit logicalLeft,
449 TableHeightChangingValue tableHeightChanging) {
449 section.setLogicalLocation(LayoutPoint(logicalLeft, logicalHeight())); 450 section.setLogicalLocation(LayoutPoint(logicalLeft, logicalHeight()));
450 if (m_columnLogicalWidthChanged) 451 if (m_columnLogicalWidthChanged)
451 layouter.setChildNeedsLayout(&section); 452 layouter.setChildNeedsLayout(&section);
452 if (!section.needsLayout()) 453 if (!section.needsLayout())
453 markChildForPaginationRelayoutIfNeeded(section, layouter); 454 markChildForPaginationRelayoutIfNeeded(section, layouter);
454 section.layoutIfNeeded(); 455 bool neededLayout = section.needsLayout();
455 int sectionLogicalHeight = section.calcRowLogicalHeight(); 456 if (neededLayout)
456 section.setLogicalHeight(LayoutUnit(sectionLogicalHeight)); 457 section.layout();
458 if (neededLayout || tableHeightChanging == TableHeightChanging)
459 section.setLogicalHeight(LayoutUnit(section.calcRowLogicalHeight()));
460
457 if (view()->layoutState()->isPaginated()) 461 if (view()->layoutState()->isPaginated())
458 updateFragmentationInfoForChild(section); 462 updateFragmentationInfoForChild(section);
459 setLogicalHeight(logicalHeight() + sectionLogicalHeight); 463 setLogicalHeight(logicalHeight() + section.logicalHeight());
460 } 464 }
461 465
462 LayoutUnit LayoutTable::logicalHeightFromStyle() const { 466 LayoutUnit LayoutTable::logicalHeightFromStyle() const {
463 LayoutUnit computedLogicalHeight; 467 LayoutUnit computedLogicalHeight;
464 Length logicalHeightLength = style()->logicalHeight(); 468 Length logicalHeightLength = style()->logicalHeight();
465 if (logicalHeightLength.isIntrinsic() || 469 if (logicalHeightLength.isIntrinsic() ||
466 (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive())) { 470 (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive())) {
467 computedLogicalHeight = 471 computedLogicalHeight =
468 convertStyleLogicalHeightToComputedHeight(logicalHeightLength); 472 convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
469 } 473 }
(...skipping 24 matching lines...) Expand all
494 void LayoutTable::distributeExtraLogicalHeight(int extraLogicalHeight) { 498 void LayoutTable::distributeExtraLogicalHeight(int extraLogicalHeight) {
495 if (extraLogicalHeight <= 0) 499 if (extraLogicalHeight <= 0)
496 return; 500 return;
497 501
498 // FIXME: Distribute the extra logical height between all table sections 502 // FIXME: Distribute the extra logical height between all table sections
499 // instead of giving it all to the first one. 503 // instead of giving it all to the first one.
500 if (LayoutTableSection* section = firstBody()) 504 if (LayoutTableSection* section = firstBody())
501 extraLogicalHeight -= 505 extraLogicalHeight -=
502 section->distributeExtraLogicalHeightToRows(extraLogicalHeight); 506 section->distributeExtraLogicalHeightToRows(extraLogicalHeight);
503 507
504 // FIXME: We really would like to enable this ASSERT to ensure that all the 508 // crbug.com/690087: We really would like to enable this ASSERT to ensure that
505 // extra space has been distributed. 509 // all the extra space has been distributed.
506 // However our current distribution algorithm does not round properly and thus 510 // However our current distribution algorithm does not round properly and thus
507 // we can have some remaining height. 511 // we can have some remaining height.
508 // ASSERT(!topSection() || !extraLogicalHeight); 512 // ASSERT(!topSection() || !extraLogicalHeight);
509 } 513 }
510 514
511 void LayoutTable::simplifiedNormalFlowLayout() { 515 void LayoutTable::simplifiedNormalFlowLayout() {
512 // FIXME: We should walk through the items in the tree in tree order to do the 516 // 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. 517 // layout here instead of walking through individual parts of the tree.
514 // crbug.com/442737 518 // crbug.com/442737
515 for (auto& caption : m_captions) 519 for (auto& caption : m_captions)
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 borderAfter() + (collapsing ? LayoutUnit() : paddingAfter()); 620 borderAfter() + (collapsing ? LayoutUnit() : paddingAfter());
617 621
618 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore); 622 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore);
619 623
620 LayoutUnit sectionLogicalLeft = LayoutUnit( 624 LayoutUnit sectionLogicalLeft = LayoutUnit(
621 style()->isLeftToRightDirection() ? borderStart() : borderEnd()); 625 style()->isLeftToRightDirection() ? borderStart() : borderEnd());
622 if (!collapsing) { 626 if (!collapsing) {
623 sectionLogicalLeft += 627 sectionLogicalLeft +=
624 style()->isLeftToRightDirection() ? paddingStart() : paddingEnd(); 628 style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
625 } 629 }
630 LayoutUnit currentAvailableLogicalHeight =
631 availableLogicalHeight(IncludeMarginBorderPadding);
632 TableHeightChangingValue tableHeightChanging =
633 m_oldAvailableLogicalHeight &&
634 m_oldAvailableLogicalHeight != currentAvailableLogicalHeight
635 ? TableHeightChanging
636 : TableHeightNotChanging;
637 m_oldAvailableLogicalHeight = currentAvailableLogicalHeight;
626 638
627 // Lay out table header group. 639 // Lay out table header group.
628 if (LayoutTableSection* section = header()) { 640 if (LayoutTableSection* section = header()) {
629 layoutSection(*section, layouter, sectionLogicalLeft); 641 layoutSection(*section, layouter, sectionLogicalLeft,
642 tableHeightChanging);
630 if (state.isPaginated()) { 643 if (state.isPaginated()) {
631 // If the repeating header group allows at least one row of content, 644 // If the repeating header group allows at least one row of content,
632 // then store the offset for other sections to offset their rows 645 // then store the offset for other sections to offset their rows
633 // against. 646 // against.
634 LayoutUnit sectionLogicalHeight = section->logicalHeight(); 647 LayoutUnit sectionLogicalHeight = section->logicalHeight();
635 if (sectionLogicalHeight < 648 if (sectionLogicalHeight <
636 section->pageLogicalHeightForOffset(section->logicalTop()) && 649 section->pageLogicalHeightForOffset(section->logicalTop()) &&
637 section->getPaginationBreakability() != AllowAnyBreaks) { 650 section->getPaginationBreakability() != AllowAnyBreaks) {
638 // Don't include any strut in the header group - we only want the 651 // Don't include any strut in the header group - we only want the
639 // height from its content. 652 // height from its content.
640 LayoutUnit offsetForTableHeaders = sectionLogicalHeight; 653 LayoutUnit offsetForTableHeaders = sectionLogicalHeight;
641 if (LayoutTableRow* row = section->firstRow()) 654 if (LayoutTableRow* row = section->firstRow())
642 offsetForTableHeaders -= row->paginationStrut(); 655 offsetForTableHeaders -= row->paginationStrut();
643 setRowOffsetFromRepeatingHeader(offsetForTableHeaders); 656 setRowOffsetFromRepeatingHeader(offsetForTableHeaders);
644 } 657 }
645 } 658 }
646 } 659 }
647 660
648 // Lay out table body groups, and column groups. 661 // Lay out table body groups, and column groups.
649 for (LayoutObject* child = firstChild(); child; 662 for (LayoutObject* child = firstChild(); child;
650 child = child->nextSibling()) { 663 child = child->nextSibling()) {
651 if (child->isTableSection()) { 664 if (child->isTableSection()) {
652 if (child != header() && child != footer()) { 665 if (child != header() && child != footer()) {
653 LayoutTableSection& section = *toLayoutTableSection(child); 666 LayoutTableSection& section = *toLayoutTableSection(child);
654 layoutSection(section, layouter, sectionLogicalLeft); 667 layoutSection(section, layouter, sectionLogicalLeft,
668 tableHeightChanging);
655 } 669 }
656 } else if (child->isLayoutTableCol()) { 670 } else if (child->isLayoutTableCol()) {
657 child->layoutIfNeeded(); 671 child->layoutIfNeeded();
658 } else { 672 } else {
659 DCHECK(child->isTableCaption()); 673 DCHECK(child->isTableCaption());
660 } 674 }
661 } 675 }
662 676
663 // Lay out table footer. 677 // Lay out table footer.
664 if (LayoutTableSection* section = footer()) 678 if (LayoutTableSection* section = footer()) {
665 layoutSection(*section, layouter, sectionLogicalLeft); 679 layoutSection(*section, layouter, sectionLogicalLeft,
680 tableHeightChanging);
681 }
666 682
667 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore); 683 setLogicalHeight(tableBoxLogicalTop + borderAndPaddingBefore);
668 684
669 LayoutUnit computedLogicalHeight = logicalHeightFromStyle(); 685 LayoutUnit computedLogicalHeight = logicalHeightFromStyle();
670 LayoutUnit totalSectionLogicalHeight; 686 LayoutUnit totalSectionLogicalHeight;
671 if (topSection) { 687 if (topSection) {
672 totalSectionLogicalHeight = 688 totalSectionLogicalHeight =
673 bottomSection->logicalBottom() - topSection->logicalTop(); 689 bottomSection->logicalBottom() - topSection->logicalTop();
674 } 690 }
675 691
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 } 1711 }
1696 1712
1697 LayoutUnit LayoutTable::paddingRight() const { 1713 LayoutUnit LayoutTable::paddingRight() const {
1698 if (collapseBorders()) 1714 if (collapseBorders())
1699 return LayoutUnit(); 1715 return LayoutUnit();
1700 1716
1701 return LayoutBlock::paddingRight(); 1717 return LayoutBlock::paddingRight();
1702 } 1718 }
1703 1719
1704 } // namespace blink 1720 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutTable.h ('k') | third_party/WebKit/Source/core/layout/LayoutTableSection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698