Use correct container width as base for percentage margins.

Blocks establishing a new BFC need to avoid floats in its parent BFC. Also,
computing used values for auto margins for such blocks is affected by the
available line width constrained by these floats. However, percentage sized
margins must be calculated based on the full containing block width, not the
available line width.

R=jchaffraix@chromium.org
BUG=348927

Review URL: https://codereview.chromium.org/185723005

git-svn-id: svn://svn.chromium.org/blink/trunk@169030 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/LayoutTests/fast/css/bfc-percentage-margin-expected.html b/LayoutTests/fast/css/bfc-percentage-margin-expected.html
new file mode 100644
index 0000000..648ef8b
--- /dev/null
+++ b/LayoutTests/fast/css/bfc-percentage-margin-expected.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+#container {
+    position: relative;
+}
+.square {
+    width: 100px;
+    height: 100px;
+    background-color: blue;
+    position: absolute;
+}
+.right {
+    left: 120px;
+}
+</style>
+<p>You should see two blue squares below.</p>
+<div id="container">
+    <div class="square"></div>
+    <div class="square right"></div>
+</div>
diff --git a/LayoutTests/fast/css/bfc-percentage-margin.html b/LayoutTests/fast/css/bfc-percentage-margin.html
new file mode 100644
index 0000000..d8c7883
--- /dev/null
+++ b/LayoutTests/fast/css/bfc-percentage-margin.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+#container {
+    width: 400px;
+}
+
+.square {
+    width: 100px;
+    height: 100px;
+    background-color: blue;
+}
+
+#float {
+    float: left;
+}
+
+#bfc {
+    margin-left: 30%;
+    overflow: hidden;
+}
+</style>
+<p>You should see two blue squares below.</p>
+<div id="container">
+    <div id="float" class="square"></div>
+    <div id="bfc" class="square"></div>
+</div>
diff --git a/LayoutTests/fast/css/vertical-lr-bfc-auto-margins-beside-float-expected.html b/LayoutTests/fast/css/vertical-lr-bfc-auto-margins-beside-float-expected.html
new file mode 100644
index 0000000..8215c14
--- /dev/null
+++ b/LayoutTests/fast/css/vertical-lr-bfc-auto-margins-beside-float-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+#container {
+    width: 200px; height: 50px;
+    background-color: orange;
+    position: relative;
+}
+
+.square {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 50px;
+    height: 50px;
+    background-color: blue;
+}
+
+.second {
+    left: 100px;
+}
+</style>
+<p>You should see four equally sized squares below. Two blue, and two orange.</p>
+<div id="container">
+    <div class="square"></div>
+    <div class="second square"></div>
+</div>
diff --git a/LayoutTests/fast/css/vertical-lr-bfc-auto-margins-beside-float.html b/LayoutTests/fast/css/vertical-lr-bfc-auto-margins-beside-float.html
new file mode 100644
index 0000000..b2014d2
--- /dev/null
+++ b/LayoutTests/fast/css/vertical-lr-bfc-auto-margins-beside-float.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+#container {
+    width: 200px; height: 50px;
+    background-color: orange;
+}
+
+#float {
+    float: left;
+    width: 50px; height: 50px; background: blue;
+}
+
+#vertical {
+    width: 50px; height: 50px;
+    -webkit-writing-mode: vertical-rl;
+    overflow: hidden;
+    margin: 0 auto;
+    background: blue;
+}
+</style>
+<p>You should see four equally sized squares below. Two blue, and two orange.</p>
+<div id="container">
+    <div id="float"></div>
+    <div id="vertical"></div>
+</div>
diff --git a/LayoutTests/fast/css/vertical-lr-table-percent-margins-beside-float-expected.html b/LayoutTests/fast/css/vertical-lr-table-percent-margins-beside-float-expected.html
new file mode 100644
index 0000000..8215c14
--- /dev/null
+++ b/LayoutTests/fast/css/vertical-lr-table-percent-margins-beside-float-expected.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+#container {
+    width: 200px; height: 50px;
+    background-color: orange;
+    position: relative;
+}
+
+.square {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 50px;
+    height: 50px;
+    background-color: blue;
+}
+
+.second {
+    left: 100px;
+}
+</style>
+<p>You should see four equally sized squares below. Two blue, and two orange.</p>
+<div id="container">
+    <div class="square"></div>
+    <div class="second square"></div>
+</div>
diff --git a/LayoutTests/fast/css/vertical-lr-table-percent-margins-beside-float.html b/LayoutTests/fast/css/vertical-lr-table-percent-margins-beside-float.html
new file mode 100644
index 0000000..5559dd14
--- /dev/null
+++ b/LayoutTests/fast/css/vertical-lr-table-percent-margins-beside-float.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+#container {
+    width: 200px; height: 50px;
+    background-color: orange;
+}
+
+#float {
+    float: left;
+    width: 50px; height: 50px; background: blue;
+}
+
+#verticalTable {
+    display: table;
+    width: 50px; height: 50px;
+    -webkit-writing-mode: vertical-rl;
+    overflow: hidden;
+    margin-left: 50%;
+    background: blue;
+}
+</style>
+<p>You should see four equally sized squares below. Two blue, and two orange.</p>
+<div id="container">
+    <div id="float"></div>
+    <div id="verticalTable"></div>
+</div>
diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
index 63da47d..496c4e8 100644
--- a/Source/core/rendering/RenderBox.cpp
+++ b/Source/core/rendering/RenderBox.cpp
@@ -2250,11 +2250,8 @@
         computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth);
         computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth);
     } else {
-        LayoutUnit containerLogicalWidthForAutoMargins = containerLogicalWidth;
-        if (avoidsFloats() && cb->containsFloats())
-            containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidth();
         bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
-        computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, computedValues.m_extent,
+        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);
     }
@@ -2451,31 +2448,35 @@
             marginEndLength.setValue(0);
     }
 
+    LayoutUnit availableWidth = containerWidth;
+    if (avoidsFloats() && containingBlock->containsFloats())
+        availableWidth = containingBlockAvailableLineWidth();
+
     // Case One: The object is being centered in the containing block's available logical width.
-    if ((marginStartLength.isAuto() && marginEndLength.isAuto() && childWidth < containerWidth)
+    if ((marginStartLength.isAuto() && marginEndLength.isAuto() && childWidth < availableWidth)
         || (!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 marginStartWidth = minimumValueForLength(marginStartLength, containerWidth);
         LayoutUnit marginEndWidth = minimumValueForLength(marginEndLength, containerWidth);
-        LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (containerWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
+        LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (availableWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
         marginStart = centeredMarginBoxStart + marginStartWidth;
-        marginEnd = containerWidth - childWidth - marginStart + marginEndWidth;
+        marginEnd = availableWidth - childWidth - marginStart + marginEndWidth;
         return;
     }
 
     // Case Two: The object is being pushed to the start of the containing block's available logical width.
-    if (marginEndLength.isAuto() && childWidth < containerWidth) {
+    if (marginEndLength.isAuto() && childWidth < availableWidth) {
         marginStart = valueForLength(marginStartLength, containerWidth);
-        marginEnd = containerWidth - childWidth - marginStart;
+        marginEnd = availableWidth - childWidth - marginStart;
         return;
     }
 
     // Case Three: The object is being pushed to the end of the containing block's available logical width.
     bool pushToEndFromTextAlign = !marginEndLength.isAuto() && ((!containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_LEFT)
         || (containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_RIGHT));
-    if ((marginStartLength.isAuto() && childWidth < containerWidth) || pushToEndFromTextAlign) {
+    if ((marginStartLength.isAuto() && childWidth < availableWidth) || pushToEndFromTextAlign) {
         marginEnd = valueForLength(marginEndLength, containerWidth);
-        marginStart = containerWidth - childWidth - marginEnd;
+        marginStart = availableWidth - childWidth - marginEnd;
         return;
     }
 
diff --git a/Source/core/rendering/RenderTable.cpp b/Source/core/rendering/RenderTable.cpp
index acc0f32..589ea2d 100644
--- a/Source/core/rendering/RenderTable.cpp
+++ b/Source/core/rendering/RenderTable.cpp
@@ -305,12 +305,9 @@
     setMarginStart(0);
     setMarginEnd(0);
     if (!hasPerpendicularContainingBlock) {
-        LayoutUnit containerLogicalWidthForAutoMargins = availableLogicalWidth;
-        if (avoidsFloats() && cb->containsFloats())
-            containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidth();
         ComputedMarginValues marginValues;
         bool hasInvertedDirection =  cb->style()->isLeftToRightDirection() == style()->isLeftToRightDirection();
-        computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth(),
+        computeInlineDirectionMargins(cb, availableLogicalWidth, logicalWidth(),
             hasInvertedDirection ? marginValues.m_start : marginValues.m_end,
             hasInvertedDirection ? marginValues.m_end : marginValues.m_start);
         setMarginStart(marginValues.m_start);