| Index: Source/core/rendering/RenderBox.cpp
|
| diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
|
| index a4c6ee4959fc72952435c005a70dae0949d5d077..243bf9a00fb97c80ed3eb8336363dd33484edfeb 100644
|
| --- a/Source/core/rendering/RenderBox.cpp
|
| +++ b/Source/core/rendering/RenderBox.cpp
|
| @@ -2213,8 +2213,15 @@
|
| }
|
|
|
| // Margin calculations.
|
| - computeMarginsForDirection(InlineDirection, cb, containerLogicalWidth, computedValues.m_extent, computedValues.m_margins.m_start,
|
| - computedValues.m_margins.m_end, style()->marginStart(), style()->marginEnd());
|
| + if (hasPerpendicularContainingBlock || isFloating() || isInline()) {
|
| + computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth);
|
| + computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth);
|
| + } else {
|
| + bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
|
| + computeInlineDirectionMargins(cb, containerLogicalWidth, computedValues.m_extent,
|
| + hasInvertedDirection ? computedValues.m_margins.m_end : computedValues.m_margins.m_start,
|
| + hasInvertedDirection ? computedValues.m_margins.m_start : computedValues.m_margins.m_end);
|
| + }
|
|
|
| if (!hasPerpendicularContainingBlock && containerLogicalWidth && containerLogicalWidth != (computedValues.m_extent + computedValues.m_margins.m_start + computedValues.m_margins.m_end)
|
| && !isFloating() && !isInline() && !cb->isFlexibleBoxIncludingDeprecated() && !cb->isRenderGrid()) {
|
| @@ -2382,19 +2389,13 @@
|
| || isHTMLTextAreaElement(*node()) || (isHTMLLegendElement(*node()) && !style()->hasOutOfFlowPosition()));
|
| }
|
|
|
| -void RenderBox::computeMarginsForDirection(MarginDirection forDirection, const RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd, Length marginStartLength, Length marginEndLength) const
|
| -{
|
| - if (forDirection == BlockDirection || isFloating() || isInline()) {
|
| - if (isTableCell() && forDirection == BlockDirection) {
|
| - // FIXME: Not right if we allow cells to have different directionality than the table. If we do allow this, though,
|
| - // we may just do it with an extra anonymous block inside the cell.
|
| - marginStart = 0;
|
| - marginEnd = 0;
|
| - return;
|
| - }
|
| -
|
| - // Margins are calculated with respect to the logical width of
|
| - // the containing block (8.3)
|
| +void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const
|
| +{
|
| + const RenderStyle* containingBlockStyle = containingBlock->style();
|
| + Length marginStartLength = style()->marginStartUsing(containingBlockStyle);
|
| + Length marginEndLength = style()->marginEndUsing(containingBlockStyle);
|
| +
|
| + if (isFloating() || isInline()) {
|
| // Inline blocks/tables and floats don't have their margins increased.
|
| marginStart = minimumValueForLength(marginStartLength, containerWidth);
|
| marginEnd = minimumValueForLength(marginEndLength, containerWidth);
|
| @@ -2430,9 +2431,8 @@
|
|
|
| // CSS 2.1: "If both 'margin-left' and 'margin-right' are 'auto', their used values are equal. This horizontally centers the element
|
| // with respect to the edges of the containing block."
|
| - const RenderStyle* containingBlockStyle = containingBlock->style();
|
| if ((marginStartLength.isAuto() && marginEndLength.isAuto() && marginBoxWidth < availableWidth)
|
| - || (!marginStartLength.isAuto() && !marginEndLength.isAuto() && containingBlockStyle->textAlign() == WEBKIT_CENTER)) {
|
| + || (!marginStartLength.isAuto() && !marginEndLength.isAuto() && containingBlock->style()->textAlign() == WEBKIT_CENTER)) {
|
| // Other browsers center the margin box for align=center elements so we match them here.
|
| LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (availableWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
|
| marginStart = centeredMarginBoxStart + marginStartWidth;
|
| @@ -2460,6 +2460,32 @@
|
| marginEnd = marginEndWidth;
|
| }
|
|
|
| +static bool shouldFlipBeforeAfterMargins(const RenderStyle* containingBlockStyle, const RenderStyle* childStyle)
|
| +{
|
| + ASSERT(containingBlockStyle->isHorizontalWritingMode() != childStyle->isHorizontalWritingMode());
|
| + WritingMode childWritingMode = childStyle->writingMode();
|
| + bool shouldFlip = false;
|
| + switch (containingBlockStyle->writingMode()) {
|
| + case TopToBottomWritingMode:
|
| + shouldFlip = (childWritingMode == RightToLeftWritingMode);
|
| + break;
|
| + case BottomToTopWritingMode:
|
| + shouldFlip = (childWritingMode == RightToLeftWritingMode);
|
| + break;
|
| + case RightToLeftWritingMode:
|
| + shouldFlip = (childWritingMode == BottomToTopWritingMode);
|
| + break;
|
| + case LeftToRightWritingMode:
|
| + shouldFlip = (childWritingMode == BottomToTopWritingMode);
|
| + break;
|
| + }
|
| +
|
| + if (!containingBlockStyle->isLeftToRightDirection())
|
| + shouldFlip = !shouldFlip;
|
| +
|
| + return shouldFlip;
|
| +}
|
| +
|
| void RenderBox::updateLogicalHeight()
|
| {
|
| m_intrinsicContentLogicalHeight = contentLogicalHeight();
|
| @@ -2487,11 +2513,23 @@
|
| computePositionedLogicalHeight(computedValues);
|
| else {
|
| RenderBlock* cb = containingBlock();
|
| + bool hasPerpendicularContainingBlock = cb->isHorizontalWritingMode() != isHorizontalWritingMode();
|
| +
|
| + if (!hasPerpendicularContainingBlock) {
|
| + bool shouldFlipBeforeAfter = cb->style()->writingMode() != style()->writingMode();
|
| + computeBlockDirectionMargins(cb,
|
| + shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
|
| + shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
|
| + }
|
|
|
| // For tables, calculate margins only.
|
| if (isTable()) {
|
| - computeMarginsForDirection(BlockDirection, cb, containingBlockLogicalWidthForContent(), computedValues.m_extent, computedValues.m_margins.m_before,
|
| - computedValues.m_margins.m_after, style()->marginBefore(), style()->marginAfter());
|
| + if (hasPerpendicularContainingBlock) {
|
| + bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), style());
|
| + computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), computedValues.m_extent,
|
| + shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
|
| + shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
|
| + }
|
| return;
|
| }
|
|
|
| @@ -2538,13 +2576,13 @@
|
| }
|
|
|
| computedValues.m_extent = heightResult;
|
| - // If we are perpendicular to our containing block then we need to resolve our block-start and block-end margins so that if they
|
| - // are 'auto' we are centred or aligned within the inline flow containing block: this is done by computing the margins as though they are inline.
|
| - // Note that in this 'sizing phase' we are using our own writing mode rather than the containing block's.
|
| - // See http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-flows
|
| - MarginDirection forDirection = isHorizontalWritingMode() != cb->isHorizontalWritingMode() ? InlineDirection : BlockDirection;
|
| - computeMarginsForDirection(forDirection, cb, containingBlockLogicalWidthForContent(), computedValues.m_extent, computedValues.m_margins.m_before,
|
| - computedValues.m_margins.m_after, style()->marginBefore(), style()->marginAfter());
|
| +
|
| + if (hasPerpendicularContainingBlock) {
|
| + bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), style());
|
| + computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), heightResult,
|
| + shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
|
| + shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
|
| + }
|
| }
|
|
|
| // WinIE quirk: The <html> block always fills the entire canvas in quirks mode. The <body> always fills the
|
| @@ -2897,15 +2935,29 @@
|
| return availableHeight;
|
| }
|
|
|
| +void RenderBox::computeBlockDirectionMargins(const RenderBlock* containingBlock, LayoutUnit& marginBefore, LayoutUnit& marginAfter) const
|
| +{
|
| + if (isTableCell()) {
|
| + // FIXME: Not right if we allow cells to have different directionality than the table. If we do allow this, though,
|
| + // we may just do it with an extra anonymous block inside the cell.
|
| + marginBefore = 0;
|
| + marginAfter = 0;
|
| + return;
|
| + }
|
| +
|
| + // Margins are calculated with respect to the logical width of
|
| + // the containing block (8.3)
|
| + LayoutUnit cw = containingBlockLogicalWidthForContent();
|
| + RenderStyle* containingBlockStyle = containingBlock->style();
|
| + marginBefore = minimumValueForLength(style()->marginBeforeUsing(containingBlockStyle), cw);
|
| + marginAfter = minimumValueForLength(style()->marginAfterUsing(containingBlockStyle), cw);
|
| +}
|
| +
|
| void RenderBox::computeAndSetBlockDirectionMargins(const RenderBlock* containingBlock)
|
| {
|
| LayoutUnit marginBefore;
|
| LayoutUnit marginAfter;
|
| - computeMarginsForDirection(BlockDirection, containingBlock, containingBlockLogicalWidthForContent(), logicalHeight(), marginBefore, marginAfter,
|
| - style()->marginBeforeUsing(containingBlock->style()),
|
| - style()->marginAfterUsing(containingBlock->style()));
|
| - // Note that in this 'positioning phase' of the layout we are using the containing block's writing mode rather than our own when calculating margins.
|
| - // See http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-flows
|
| + computeBlockDirectionMargins(containingBlock, marginBefore, marginAfter);
|
| containingBlock->setMarginBeforeForChild(this, marginBefore);
|
| containingBlock->setMarginAfterForChild(this, marginAfter);
|
| }
|
|
|