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

Side by Side Diff: Source/core/layout/LayoutFlexibleBox.cpp

Issue 1295933003: Add overflow:auto scrollbars to child flex basis. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Add entries to SlowTests Created 5 years, 3 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 if (isColumnFlow()) 347 if (isColumnFlow())
348 return style()->writingMode() == TopToBottomWritingMode || style()->writ ingMode() == LeftToRightWritingMode; 348 return style()->writingMode() == TopToBottomWritingMode || style()->writ ingMode() == LeftToRightWritingMode;
349 return style()->isLeftToRightDirection() ^ (style()->flexDirection() == Flow RowReverse); 349 return style()->isLeftToRightDirection() ^ (style()->flexDirection() == Flow RowReverse);
350 } 350 }
351 351
352 bool LayoutFlexibleBox::isMultiline() const 352 bool LayoutFlexibleBox::isMultiline() const
353 { 353 {
354 return style()->flexWrap() != FlexNoWrap; 354 return style()->flexWrap() != FlexNoWrap;
355 } 355 }
356 356
357 Length LayoutFlexibleBox::flexBasisForChild(LayoutBox& child) const 357 Length LayoutFlexibleBox::flexBasisForChild(const LayoutBox& child) const
358 { 358 {
359 Length flexLength = child.style()->flexBasis(); 359 Length flexLength = child.style()->flexBasis();
360 if (flexLength.isAuto()) 360 if (flexLength.isAuto())
361 flexLength = isHorizontalFlow() ? child.style()->width() : child.style() ->height(); 361 flexLength = isHorizontalFlow() ? child.style()->width() : child.style() ->height();
362 return flexLength; 362 return flexLength;
363 } 363 }
364 364
365 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const 365 LayoutUnit LayoutFlexibleBox::crossAxisExtentForChild(LayoutBox& child) const
366 { 366 {
367 return isHorizontalFlow() ? child.size().height() : child.size().width(); 367 return isHorizontalFlow() ? child.size().height() : child.size().width();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 428
429 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si zeType sizeType, const Length& size) 429 LayoutUnit LayoutFlexibleBox::computeMainAxisExtentForChild(LayoutBox& child, Si zeType sizeType, const Length& size)
430 { 430 {
431 // If we have a horizontal flow, that means the main size is the width. 431 // If we have a horizontal flow, that means the main size is the width.
432 // That's the logical width for horizontal writing modes, and the logical he ight in vertical writing modes. 432 // That's the logical width for horizontal writing modes, and the logical he ight in vertical writing modes.
433 // For a vertical flow, main size is the height, so it's the inverse. 433 // For a vertical flow, main size is the height, so it's the inverse.
434 // So we need the logical width if we have a horizontal flow and horizontal writing mode, or vertical flow and vertical writing mode. 434 // So we need the logical width if we have a horizontal flow and horizontal writing mode, or vertical flow and vertical writing mode.
435 // Otherwise we need the logical height. 435 // Otherwise we need the logical height.
436 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) { 436 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) {
437 // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway. 437 // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway.
438 if (size.isIntrinsic()) 438 // It's safe to access scrollbarLogicalHeight here because computeNextFl exLine will have already
439 child.layoutIfNeeded(); 439 // forced layout on the child.
440 return child.computeContentLogicalHeight(sizeType, size, child.logicalHe ight() - child.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight() ; 440 return child.computeContentLogicalHeight(sizeType, size, child.logicalHe ight() - child.borderAndPaddingLogicalHeight()) + child.scrollbarLogicalHeight() ;
441 } 441 }
442 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child.borderAndPaddingLogicalWidth(); 442 return child.computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child.borderAndPaddingLogicalWidth();
443 } 443 }
444 444
445 WritingMode LayoutFlexibleBox::transformedWritingMode() const 445 WritingMode LayoutFlexibleBox::transformedWritingMode() const
446 { 446 {
447 WritingMode mode = style()->writingMode(); 447 WritingMode mode = style()->writingMode();
448 if (!isColumnFlow()) 448 if (!isColumnFlow())
449 return mode; 449 return mode;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 if (flexBasis.hasPercent()) { 622 if (flexBasis.hasPercent()) {
623 return isColumnFlow() ? 623 return isColumnFlow() ?
624 child.computePercentageLogicalHeight(flexBasis) != -1 : 624 child.computePercentageLogicalHeight(flexBasis) != -1 :
625 hasDefiniteLogicalWidth(); 625 hasDefiniteLogicalWidth();
626 } 626 }
627 return true; 627 return true;
628 } 628 }
629 629
630 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(LayoutBox& child) const 630 bool LayoutFlexibleBox::childFlexBaseSizeRequiresLayout(LayoutBox& child) const
631 { 631 {
632 return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && hasOrth ogonalFlow(child); 632 return !mainAxisLengthIsDefinite(child, flexBasisForChild(child)) && (
633 hasOrthogonalFlow(child) || crossAxisOverflowForChild(child) == OAUTO);
633 } 634 }
634 635
635 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType childLayoutType) 636 LayoutUnit LayoutFlexibleBox::computeInnerFlexBaseSizeForChild(LayoutBox& child, ChildLayoutType childLayoutType)
636 { 637 {
637 child.clearOverrideSize(); 638 child.clearOverrideSize();
638 639
639 if (child.isImage() || child.isVideo() || child.isCanvas()) 640 if (child.isImage() || child.isVideo() || child.isCanvas())
640 UseCounter::count(document(), UseCounter::AspectRatioFlexItem); 641 UseCounter::count(document(), UseCounter::AspectRatioFlexItem);
641 642
642 Length flexBasis = flexBasisForChild(child); 643 Length flexBasis = flexBasisForChild(child);
643 if (!mainAxisLengthIsDefinite(child, flexBasis)) { 644 if (!mainAxisLengthIsDefinite(child, flexBasis)) {
644 LayoutUnit mainAxisExtent; 645 LayoutUnit mainAxisExtent;
645 if (hasOrthogonalFlow(child)) { 646 if (childFlexBaseSizeRequiresLayout(child)) {
646 if (childLayoutType == NeverLayout) 647 if (childLayoutType == NeverLayout)
647 return LayoutUnit(); 648 return LayoutUnit();
648 649
649 if (child.needsLayout() || childLayoutType == ForceLayout || !m_intr insicSizeAlongMainAxis.contains(&child)) { 650 if (child.needsLayout() || childLayoutType == ForceLayout || !m_intr insicSizeAlongMainAxis.contains(&child)) {
650 m_intrinsicSizeAlongMainAxis.remove(&child); 651 m_intrinsicSizeAlongMainAxis.remove(&child);
651 child.forceChildLayout(); 652 child.forceChildLayout();
652 m_intrinsicSizeAlongMainAxis.set(&child, child.logicalHeight()); 653 m_intrinsicSizeAlongMainAxis.set(&child, hasOrthogonalFlow(child ) ? child.logicalHeight() : child.logicalWidth());
653 } 654 }
654 mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(&child); 655 mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(&child);
655 } else { 656 } else {
656 mainAxisExtent = child.maxPreferredLogicalWidth(); 657 mainAxisExtent = child.maxPreferredLogicalWidth();
657 } 658 }
658 ASSERT(mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child) >= 0); 659 ASSERT(mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child) >= 0);
659 return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child); 660 return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child);
660 } 661 }
661 return std::max(LayoutUnit(), computeMainAxisExtentForChild(child, MainOrPre ferredSize, flexBasis)); 662 return std::max(LayoutUnit(), computeMainAxisExtentForChild(child, MainOrPre ferredSize, flexBasis));
662 } 663 }
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max()); 916 LayoutUnit lineBreakLength = mainAxisContentExtent(LayoutUnit::max());
916 917
917 bool lineHasInFlowItem = false; 918 bool lineHasInFlowItem = false;
918 919
919 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) { 920 for (LayoutBox* child = m_orderIterator.currentChild(); child; child = m_ord erIterator.next()) {
920 if (child->isOutOfFlowPositioned()) { 921 if (child->isOutOfFlowPositioned()) {
921 orderedChildren.append(child); 922 orderedChildren.append(child);
922 continue; 923 continue;
923 } 924 }
924 925
926 // If this condition is true, then computeMainAxisExtentForChild will ca ll child.contentLogicalHeight()
927 // and child.scrollbarLogicalHeight(), so if the child has intrinsic min /max/preferred size,
928 // run layout on it now to make sure its logical height and scroll bars are up-to-date.
929 if (childHasIntrinsicMainAxisSize(*child))
930 child->layoutIfNeeded();
931
925 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*ch ild, relayoutChildren ? ForceLayout : LayoutIfNeeded); 932 LayoutUnit childInnerFlexBaseSize = computeInnerFlexBaseSizeForChild(*ch ild, relayoutChildren ? ForceLayout : LayoutIfNeeded);
926 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child) 933 LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingEx tentForChild(*child)
927 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() ); 934 + (isHorizontalFlow() ? child->marginWidth() : child->marginHeight() );
928 LayoutUnit childOuterFlexBaseSize = childInnerFlexBaseSize + childMainAx isMarginBorderPadding; 935 LayoutUnit childOuterFlexBaseSize = childInnerFlexBaseSize + childMainAx isMarginBorderPadding;
929 936
930 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childInnerFlexBaseSize); 937 LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMa x(*child, childInnerFlexBaseSize);
931 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding; 938 LayoutUnit childHypotheticalMainSize = childMinMaxAppliedMainAxisExtent + childMainAxisMarginBorderPadding;
932 939
933 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem) 940 if (isMultiline() && sumHypotheticalMainSize + childHypotheticalMainSize > lineBreakLength && lineHasInFlowItem)
934 break; 941 break;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 // "stretch" themselves in their inline axis, i.e. a <div> has an implicit w idth: 100%. 1119 // "stretch" themselves in their inline axis, i.e. a <div> has an implicit w idth: 100%.
1113 // Therefore, we never need to stretch an item if we're a vertical flow, bec ause the child 1120 // Therefore, we never need to stretch an item if we're a vertical flow, bec ause the child
1114 // will automatically stretch itself. 1121 // will automatically stretch itself.
1115 // TODO(cbiesinger): this code is wrong when the child has an orthogonal flo w and we're vertical. crbug.com/482766 1122 // TODO(cbiesinger): this code is wrong when the child has an orthogonal flo w and we're vertical. crbug.com/482766
1116 if (alignmentForChild(child) != ItemPositionStretch) 1123 if (alignmentForChild(child) != ItemPositionStretch)
1117 return false; 1124 return false;
1118 1125
1119 return isHorizontalFlow() && child.style()->height().isAuto(); 1126 return isHorizontalFlow() && child.style()->height().isAuto();
1120 } 1127 }
1121 1128
1129 bool LayoutFlexibleBox::childHasIntrinsicMainAxisSize(const LayoutBox& child) co nst
1130 {
1131 bool result = false;
1132 if (isHorizontalFlow() != child.styleRef().isHorizontalWritingMode()) {
1133 Length childFlexBasis = flexBasisForChild(child);
1134 Length childMinSize = isHorizontalFlow() ? child.style()->minWidth() : c hild.style()->minHeight();
1135 Length childMaxSize = isHorizontalFlow() ? child.style()->maxWidth() : c hild.style()->maxHeight();
1136 if (childFlexBasis.isIntrinsic() || childMinSize.isIntrinsic() || childM axSize.isIntrinsic())
1137 result = true;
1138 }
1139 return result;
1140 }
1141
1122 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(LayoutBox& child) const 1142 EOverflow LayoutFlexibleBox::mainAxisOverflowForChild(LayoutBox& child) const
1123 { 1143 {
1124 if (isHorizontalFlow()) 1144 if (isHorizontalFlow())
1125 return child.styleRef().overflowX(); 1145 return child.styleRef().overflowX();
1126 return child.styleRef().overflowY(); 1146 return child.styleRef().overflowY();
1127 } 1147 }
1128 1148
1149 EOverflow LayoutFlexibleBox::crossAxisOverflowForChild(LayoutBox& child) const
1150 {
1151 if (isHorizontalFlow())
1152 return child.styleRef().overflowY();
1153 return child.styleRef().overflowX();
1154 }
1129 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope , Vector<LineContext>& lineContexts) 1155 void LayoutFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons t OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, Layou tUnit availableFreeSpace, bool relayoutChildren, SubtreeLayoutScope& layoutScope , Vector<LineContext>& lineContexts)
1130 { 1156 {
1131 ASSERT(childSizes.size() == children.size()); 1157 ASSERT(childSizes.size() == children.size());
1132 1158
1133 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children); 1159 size_t numberOfChildrenForJustifyContent = numberOfInFlowPositionedChildren( children);
1134 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace); 1160 LayoutUnit autoMarginOffset = autoMarginOffsetInMainAxis(children, available FreeSpace);
1135 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ; 1161 LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart() ;
1136 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContentPosition(), style()->justifyContentDistribution(), numberOfChildren ForJustifyContent); 1162 mainAxisOffset += initialJustifyContentOffset(availableFreeSpace, style()->j ustifyContentPosition(), style()->justifyContentDistribution(), numberOfChildren ForJustifyContent);
1137 if (style()->flexDirection() == FlowRowReverse) 1163 if (style()->flexDirection() == FlowRowReverse)
1138 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight(); 1164 mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizo ntalScrollbarHeight();
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 ASSERT(child); 1496 ASSERT(child);
1471 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent; 1497 LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisE xtent;
1472 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge; 1498 LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
1473 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent; 1499 LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxi sExtent;
1474 adjustAlignmentForChild(*child, newOffset - originalOffset); 1500 adjustAlignmentForChild(*child, newOffset - originalOffset);
1475 } 1501 }
1476 } 1502 }
1477 } 1503 }
1478 1504
1479 } 1505 }
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutFlexibleBox.h ('k') | Source/core/paint/DeprecatedPaintLayerScrollableArea.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698