Bug 1150021 - Make sure that boxes inside vertical RTL boxes are placed on the right. r=roc, a=sledru
☠☠ backed out by 830034fc6613 ☠ ☠
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 07 Apr 2015 02:28:57 -0500
changeset 266933 4a3f72dfdfaccfcb19f2cd241aa2ff3394477fc5
parent 266932 f90e5f251eec53d416ed8091991a7e3fb328860f
child 266934 5b448d48857f763843392d525f82cf13f172a719
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, sledru
bugs1150021
milestone39.0a2
Bug 1150021 - Make sure that boxes inside vertical RTL boxes are placed on the right. r=roc, a=sledru nsSprocketLayout::Layout lays out its children by looping from first child to last child updating local variables x, y as it goes that keep track of the position where to layout the current child. If the box is horizontal it works left-to-right or right-to-left according to wheather the direction of the box is normal or not. Vertical boxes work similarly top-to-bottom or bottom-to-top. Vertical boxes also respond to CSS direction styles, so that in an LTR box the child boxes are laid out flush left, but flush right in an RTL box. Herein lies the bug, some code assumes the child boxes are laid out flush right in RTL, but the code to actually position the children positions them flush left. The code that assumes the child are laid out flush right is HandleBoxPack, which determines the origin to start laying out children at, and the code which uses HandleBoxPack to determine if the origin changed during the laying out of the children, and then shifts the children by the amount the origin shifted. The size of our box changing will, in general, change the position of the origin. So the children aren't laid out to the origin that HandleBoxPack expects they will get moved to wrong positions.
layout/reftests/bugs/1150021-1-ref.css
layout/reftests/bugs/1150021-1-ref.xul
layout/reftests/bugs/1150021-1.css
layout/reftests/bugs/1150021-1.xul
layout/reftests/bugs/reftest.list
layout/xul/nsSprocketLayout.cpp
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1150021-1-ref.css
@@ -0,0 +1,9 @@
+.wide { background: red; width: 800px; height: 30px; display: inline-block;}
+
+#container {
+  background-color: yellow;
+}
+
+#rightBox {
+  margin-left: 1000px;
+}
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1150021-1-ref.xul
@@ -0,0 +1,20 @@
+<?xml version="1.0"?> <!-- -*- Mode: HTML -*- --> 
+
+<?xml-stylesheet type="text/css" href="1150021-1-ref.css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
+        title="gsg"
+        >
+
+  <vbox id="container">
+    <vbox id="rightBox">
+      <html:span>
+        <html:div class="wide"></html:div><html:div class="wide"></html:div>
+      </html:span>
+    </vbox>
+  </vbox>
+
+
+
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1150021-1.css
@@ -0,0 +1,10 @@
+window { direction: rtl; }
+.wide { background: red; width: 800px; height: 30px; display: inline-block;}
+
+#container {
+  background-color: yellow;
+}
+
+#rightBox {
+  margin-left: 1000px;
+}
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1150021-1.xul
@@ -0,0 +1,20 @@
+<?xml version="1.0"?> <!-- -*- Mode: HTML -*- --> 
+
+<?xml-stylesheet type="text/css" href="1150021-1.css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        xmlns:html="http://www.w3.org/1999/xhtml"
+        title="gsg"
+        >
+
+  <vbox id="container">
+    <vbox id="rightBox">
+      <html:span>
+        <html:div class="wide"></html:div><html:div class="wide"></html:div>
+      </html:span>
+    </vbox>
+  </vbox>
+
+
+
+</window>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1867,8 +1867,9 @@ skip-if(Mulet) == 1120431-2.html 1120431
 == 1121748-2.html 1121748-2-ref.html
 == 1127107-1a-nowrap.html 1127107-1-ref.html
 == 1127107-1b-pre.html 1127107-1-ref.html
 == 1127107-2-capitalize.html 1127107-2-capitalize-ref.html
 == 1127679-1a-inline-flex-relpos.html 1127679-1b-inline-flex-relpos.html
 == 1128354-1.html 1128354-1-ref.html
 == 1130231-1-button-padding-rtl.html 1130231-1-button-padding-rtl-ref.html
 == 1130231-2-button-padding-rtl.html 1130231-2-button-padding-rtl-ref.html
+skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul
--- a/layout/xul/nsSprocketLayout.cpp
+++ b/layout/xul/nsSprocketLayout.cpp
@@ -392,17 +392,22 @@ nsSprocketLayout::Layout(nsIFrame* aBox,
           nextX -= (childBoxSize->left);
         childRect.y = originalClientRect.y;
       }
       else {
         if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
           nextY += (childBoxSize->right);
         else 
           nextY -= (childBoxSize->left);
-        childRect.x = originalClientRect.x;
+        if (GetFrameDirection(aBox) == NS_STYLE_DIRECTION_LTR) {
+          childRect.x = originalClientRect.x;
+        } else {
+          // keep the right edge of the box the same
+          childRect.x = clientRect.x + originalClientRect.width - childRect.width;
+        }
       }
       
       // If we encounter a completely bogus box size, we just leave this child completely
       // alone and continue through the loop to the next child.
       if (childBoxSize->bogus) 
       {
         childComputedBoxSize = childComputedBoxSize->next;
         childBoxSize = childBoxSize->next;
@@ -524,16 +529,23 @@ nsSprocketLayout::Layout(nsIFrame* aBox,
           // width/height between childRect and newChildRect.  So we don't need
           // to reaccount for the left and right of the box layout state again.
           if (frameState & NS_STATE_IS_HORIZONTAL)
             newChildRect.x = childRect.XMost() - newChildRect.width;
           else
             newChildRect.y = childRect.YMost() - newChildRect.height;
         }
 
+        if (!(frameState & NS_STATE_IS_HORIZONTAL)) {
+          if (GetFrameDirection(aBox) != NS_STYLE_DIRECTION_LTR) {
+            // keep the right edge the same
+            newChildRect.x = childRect.XMost() - newChildRect.width;
+          }
+        }
+
         // If the child resized then recompute its position.
         ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect);
 
         if (newChildRect.width >= margin.left + margin.right && newChildRect.height >= margin.top + margin.bottom) 
           newChildRect.Deflate(margin);
 
         if (childRect.width >= margin.left + margin.right && childRect.height >= margin.top + margin.bottom) 
           childRect.Deflate(margin);