Bug 1174711 - patch 2 - Convert nsTableFrame to work with logical coordinates. r=dholbert
authorJonathan Kew <jkew@mozilla.com>
Mon, 22 Jun 2015 10:33:34 +0100
changeset 280777 f5cf0bdd0c1ad430508861f3e67413f49d5c25de
parent 280776 92ce2f6910196ae01353c828f1849d9bf4d0a8fa
child 280778 ca41ad40687f5d7c3f3d89c3e9b5c68e93f5d9f5
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1174711
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1174711 - patch 2 - Convert nsTableFrame to work with logical coordinates. r=dholbert
layout/reftests/table-bordercollapse/border-collapse-rtl-ref.html
layout/reftests/table-bordercollapse/border-collapse-rtl.html
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableRowFrame.cpp
layout/tables/nsTableRowGroupFrame.cpp
layout/tables/nsTableRowGroupFrame.h
--- a/layout/reftests/table-bordercollapse/border-collapse-rtl-ref.html
+++ b/layout/reftests/table-bordercollapse/border-collapse-rtl-ref.html
@@ -1,23 +1,23 @@
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset=utf-8>
 <style>
 table {
   margin: 10px;
-  border: 3px solid silver;
+  border: 8px solid silver;
   border-right-color: gray;
   border-bottom-color: gray;
   border-spacing: 5px;
   border-collapse: collapse;
 }
 td {
-  border: 5px solid black;
+  border: 4px solid black;
   width: 50px;
   height: 20px;
   text-align: center;
 }
 td.w1 {
   width: 80px;
 }
 td.w2 {
--- a/layout/reftests/table-bordercollapse/border-collapse-rtl.html
+++ b/layout/reftests/table-bordercollapse/border-collapse-rtl.html
@@ -1,23 +1,23 @@
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset=utf-8>
 <style>
 table {
   margin: 10px;
-  border: 3px solid silver;
+  border: 8px solid silver;
   border-right-color: gray;
   border-bottom-color: gray;
   border-spacing: 5px;
   border-collapse: collapse;
 }
 td {
-  border: 5px solid black;
+  border: 4px solid black;
   width: 50px;
   height: 20px;
   text-align: center;
 }
 td.w1 {
   width: 80px;
 }
 td.w2 {
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -56,55 +56,54 @@ using namespace mozilla::layout;
  ** nsTableReflowState                                                         **
  ********************************************************************************/
 
 struct nsTableReflowState {
 
   // the real reflow state
   const nsHTMLReflowState& reflowState;
 
-  // The table's available size
-  nsSize availSize;
-
-  // Stationary x-offset
-  nscoord x;
-
-  // Running y-offset
-  nscoord y;
+  // The table's available size (in reflowState's writing mode)
+  LogicalSize availSize;
+
+  // Stationary inline-offset
+  nscoord iCoord;
+
+  // Running block-offset
+  nscoord bCoord;
 
   nsTableReflowState(const nsHTMLReflowState& aReflowState,
-                     nscoord                  aAvailWidth,
-                     nscoord                  aAvailHeight)
+                     const LogicalSize& aAvailSize)
     : reflowState(aReflowState)
+    , availSize(aAvailSize)
   {
     MOZ_ASSERT(reflowState.frame->GetType() == nsGkAtoms::tableFrame,
                "nsTableReflowState should only be created for nsTableFrame");
     nsTableFrame* table =
       static_cast<nsTableFrame*>(reflowState.frame->FirstInFlow());
     WritingMode wm = aReflowState.GetWritingMode();
     LogicalMargin borderPadding = table->GetChildAreaOffset(wm, &reflowState);
 
-    x = borderPadding.IStart(wm) + table->GetColSpacing(-1);
-    y = borderPadding.BStart(wm); //cellspacing added during reflow
-
-    availSize.width  = aAvailWidth;
-    if (NS_UNCONSTRAINEDSIZE != availSize.width) {
+    iCoord = borderPadding.IStart(wm) + table->GetColSpacing(-1);
+    bCoord = borderPadding.BStart(wm); //cellspacing added during reflow
+
+    // XXX do we actually need to check for unconstrained inline-size here?
+    if (NS_UNCONSTRAINEDSIZE != availSize.ISize(wm)) {
       int32_t colCount = table->GetColCount();
-      availSize.width -= borderPadding.IStartEnd(wm) +
-                         table->GetColSpacing(-1) +
-                         table->GetColSpacing(colCount);
-      availSize.width = std::max(0, availSize.width);
-    }
-
-    availSize.height = aAvailHeight;
-    if (NS_UNCONSTRAINEDSIZE != availSize.height) {
-      availSize.height -= borderPadding.BStartEnd(wm) +
-                          table->GetRowSpacing(-1) +
-                          table->GetRowSpacing(table->GetRowCount());
-      availSize.height = std::max(0, availSize.height);
+      availSize.ISize(wm) -= borderPadding.IStartEnd(wm) +
+                             table->GetColSpacing(-1) +
+                             table->GetColSpacing(colCount);
+      availSize.ISize(wm) = std::max(0, availSize.ISize(wm));
+    }
+
+    if (NS_UNCONSTRAINEDSIZE != availSize.BSize(wm)) {
+      availSize.BSize(wm) -= borderPadding.BStartEnd(wm) +
+                             table->GetRowSpacing(-1) +
+                             table->GetRowSpacing(table->GetRowCount());
+      availSize.BSize(wm) = std::max(0, availSize.BSize(wm));
     }
   }
 };
 
 /********************************************************************************
  ** nsTableFrame                                                               **
  ********************************************************************************/
 
@@ -1478,19 +1477,19 @@ nsTableFrame::SetColumnDimensions(nscoor
 
     colGroupOrigin.I(aWM) += colGroupISize + cellSpacingI;
   }
 }
 
 // SEC: TODO need to worry about continuing frames prev/next in flow for splitting across pages.
 
 // XXX this could be made more general to handle row modifications that change the
-// table height, but first we need to scrutinize every Invalidate
+// table bsize, but first we need to scrutinize every Invalidate
 void
-nsTableFrame::ProcessRowInserted(nscoord aNewHeight)
+nsTableFrame::ProcessRowInserted(nscoord aNewBSize)
 {
   SetRowInserted(false); // reset the bit that got us here
   nsTableFrame::RowGroupArray rowGroups;
   OrderRowGroups(rowGroups);
   // find the row group containing the inserted row
   for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     NS_ASSERTION(rgFrame, "Must have rgFrame here");
@@ -1607,41 +1606,41 @@ nsTableFrame::ComputeSize(nsRenderingCon
   if (minISize > result.ISize(aWM)) {
     result.ISize(aWM) = minISize;
   }
 
   return result;
 }
 
 nscoord
-nsTableFrame::TableShrinkWidthToFit(nsRenderingContext *aRenderingContext,
-                                    nscoord aWidthInCB)
+nsTableFrame::TableShrinkISizeToFit(nsRenderingContext *aRenderingContext,
+                                    nscoord aISizeInCB)
 {
   // If we're a container for font size inflation, then shrink
   // wrapping inside of us should not apply font size inflation.
   AutoMaybeDisableFontInflation an(this);
 
   nscoord result;
-  nscoord minWidth = GetMinISize(aRenderingContext);
-  if (minWidth > aWidthInCB) {
-    result = minWidth;
+  nscoord minISize = GetMinISize(aRenderingContext);
+  if (minISize > aISizeInCB) {
+    result = minISize;
   } else {
-    // Tables shrink width to fit with a slightly different algorithm
-    // from the one they use for their intrinsic widths (the difference
-    // relates to handling of percentage widths on columns).  So this
+    // Tables shrink inline-size to fit with a slightly different algorithm
+    // from the one they use for their intrinsic isize (the difference
+    // relates to handling of percentage isizes on columns).  So this
     // function differs from nsFrame::ShrinkWidthToFit by only the
     // following line.
     // Since we've already called GetMinISize, we don't need to do any
     // of the other stuff GetPrefISize does.
-    nscoord prefWidth =
+    nscoord prefISize =
       LayoutStrategy()->GetPrefISize(aRenderingContext, true);
-    if (prefWidth > aWidthInCB) {
-      result = aWidthInCB;
+    if (prefISize > aISizeInCB) {
+      result = aISizeInCB;
     } else {
-      result = prefWidth;
+      result = prefISize;
     }
   }
   return result;
 }
 
 /* virtual */
 LogicalSize
 nsTableFrame::ComputeAutoSize(nsRenderingContext *aRenderingContext,
@@ -1651,17 +1650,17 @@ nsTableFrame::ComputeAutoSize(nsRenderin
                               const LogicalSize& aMargin,
                               const LogicalSize& aBorder,
                               const LogicalSize& aPadding,
                               bool aShrinkWrap)
 {
   // Tables always shrink-wrap.
   nscoord cbBased = aAvailableISize - aMargin.ISize(aWM) - aBorder.ISize(aWM) -
                     aPadding.ISize(aWM);
-  return LogicalSize(aWM, TableShrinkWidthToFit(aRenderingContext, cbBased),
+  return LogicalSize(aWM, TableShrinkISizeToFit(aRenderingContext, cbBased),
                      NS_UNCONSTRAINEDSIZE);
 }
 
 // Return true if aParentReflowState.frame or any of its ancestors within
 // the containing table have non-auto bsize. (e.g. pct or fixed bsize)
 bool
 nsTableFrame::AncestorsHaveStyleBSize(const nsHTMLReflowState& aParentReflowState)
 {
@@ -1703,98 +1702,100 @@ nsTableFrame::CheckRequestSpecialBSizeRe
        0                    == aReflowState.ComputedBSize()) &&
       eStyleUnit_Percent == aReflowState.mStylePosition->BSize(wm).GetUnit() && // pct bsize
       nsTableFrame::AncestorsHaveStyleBSize(*aReflowState.parentReflowState)) {
     nsTableFrame::RequestSpecialBSizeReflow(aReflowState);
   }
 }
 
 // Notify the frame and its ancestors (up to the containing table) that a special
-// height reflow will occur. During a special height reflow, a table, row group,
+// bsize reflow will occur. During a special bsize reflow, a table, row group,
 // row, or cell returns the last size it was reflowed at. However, the table may
-// change the height of row groups, rows, cells in DistributeHeightToRows after.
-// And the row group can change the height of rows, cells in CalculateRowHeights.
+// change the bsize of row groups, rows, cells in DistributeBSizeToRows after.
+// And the row group can change the bsize of rows, cells in CalculateRowBSizes.
 void
 nsTableFrame::RequestSpecialBSizeReflow(const nsHTMLReflowState& aReflowState)
 {
   // notify the frame and its ancestors of the special reflow, stopping at the containing table
   for (const nsHTMLReflowState* rs = &aReflowState; rs && rs->frame; rs = rs->parentReflowState) {
     nsIAtom* frameType = rs->frame->GetType();
     NS_ASSERTION(IS_TABLE_CELL(frameType) ||
                  nsGkAtoms::tableRowFrame == frameType ||
                  nsGkAtoms::tableRowGroupFrame == frameType ||
                  nsGkAtoms::tableFrame == frameType,
                  "unexpected frame type");
 
     rs->frame->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
     if (nsGkAtoms::tableFrame == frameType) {
       NS_ASSERTION(rs != &aReflowState,
-                   "should not request special height reflow for table");
+                   "should not request special bsize reflow for table");
       // always stop when we reach a table
       break;
     }
   }
 }
 
 /******************************************************************************************
- * Before reflow, intrinsic width calculation is done using GetMinISize
+ * Before reflow, intrinsic inline-size calculation is done using GetMinISize
  * and GetPrefISize.  This used to be known as pass 1 reflow.
  *
- * After the intrinsic width calculation, the table determines the
- * column widths using BalanceColumnWidths() and
- * then reflows each child again with a constrained avail width. This reflow is referred to
+ * After the intrinsic isize calculation, the table determines the
+ * column widths using BalanceColumnISizes() and
+ * then reflows each child again with a constrained avail isize. This reflow is referred to
  * as the pass 2 reflow.
  *
- * A special height reflow (pass 3 reflow) can occur during an initial or resize reflow
- * if (a) a row group, row, cell, or a frame inside a cell has a percent height but no computed
- * height or (b) in paginated mode, a table has a height. (a) supports percent nested tables
- * contained inside cells whose heights aren't known until after the pass 2 reflow. (b) is
+ * A special bsize reflow (pass 3 reflow) can occur during an initial or resize reflow
+ * if (a) a row group, row, cell, or a frame inside a cell has a percent bsize but no computed
+ * bsize or (b) in paginated mode, a table has a bsize. (a) supports percent nested tables
+ * contained inside cells whose bsizes aren't known until after the pass 2 reflow. (b) is
  * necessary because the table cannot split until after the pass 2 reflow. The mechanics of
- * the special height reflow (variety a) are as follows:
+ * the special bsize reflow (variety a) are as follows:
  *
  * 1) Each table related frame (table, row group, row, cell) implements NeedsSpecialReflow()
- *    to indicate that it should get the reflow. It does this when it has a percent height but
- *    no computed height by calling CheckRequestSpecialBSizeReflow(). This method calls
+ *    to indicate that it should get the reflow. It does this when it has a percent bsize but
+ *    no computed bsize by calling CheckRequestSpecialBSizeReflow(). This method calls
  *    RequestSpecialBSizeReflow() which calls SetNeedSpecialReflow() on its ancestors until
  *    it reaches the containing table and calls SetNeedToInitiateSpecialReflow() on it. For
- *    percent height frames inside cells, during DidReflow(), the cell's NotifyPercentBSize()
+ *    percent bsize frames inside cells, during DidReflow(), the cell's NotifyPercentBSize()
  *    is called (the cell is the reflow state's mPercentBSizeObserver in this case).
  *    NotifyPercentBSize() calls RequestSpecialBSizeReflow().
  *
+ * XXX (jfkthame) This comment appears to be out of date; it refers to methods/flags
+ *                that are no longer present in the code.
  * 2) After the pass 2 reflow, if the table's NeedToInitiateSpecialReflow(true) was called, it
- *    will do the special height reflow, setting the reflow state's mFlags.mSpecialHeightReflow
+ *    will do the special bsize reflow, setting the reflow state's mFlags.mSpecialHeightReflow
  *    to true and mSpecialHeightInitiator to itself. It won't do this if IsPrematureSpecialHeightReflow()
- *    returns true because in that case another special height reflow will be coming along with the
+ *    returns true because in that case another special bsize reflow will be coming along with the
  *    containing table as the mSpecialHeightInitiator. It is only relevant to do the reflow when
  *    the mSpecialHeightInitiator is the containing table, because if it is a remote ancestor, then
- *    appropriate heights will not be known.
+ *    appropriate bsizes will not be known.
  *
- * 3) Since the heights of the table, row groups, rows, and cells was determined during the pass 2
- *    reflow, they return their last desired sizes during the special height reflow. The reflow only
- *    permits percent height frames inside the cells to resize based on the cells height and that height
+ * 3) Since the bsizes of the table, row groups, rows, and cells was determined during the pass 2
+ *    reflow, they return their last desired sizes during the special bsize reflow. The reflow only
+ *    permits percent bsize frames inside the cells to resize based on the cells bsize and that bsize
  *    was determined during the pass 2 reflow.
  *
  * So, in the case of deeply nested tables, all of the tables that were told to initiate a special
  * reflow will do so, but if a table is already in a special reflow, it won't inititate the reflow
  * until the current initiator is its containing table. Since these reflows are only received by
  * frames that need them and they don't cause any rebalancing of tables, the extra overhead is minimal.
  *
  * The type of special reflow that occurs during printing (variety b) follows the same mechanism except
  * that all frames will receive the reflow even if they don't really need them.
  *
- * Open issues with the special height reflow:
+ * Open issues with the special bsize reflow:
  *
- * 1) At some point there should be 2 kinds of special height reflows because (a) and (b) above are
+ * 1) At some point there should be 2 kinds of special bsize reflows because (a) and (b) above are
  *    really quite different. This would avoid unnecessary reflows during printing.
- * 2) When a cell contains frames whose percent heights > 100%, there is data loss (see bug 115245).
- *    However, this can also occur if a cell has a fixed height and there is no special height reflow.
+ * 2) When a cell contains frames whose percent bsizes > 100%, there is data loss (see bug 115245).
+ *    However, this can also occur if a cell has a fixed bsize and there is no special bsize reflow.
  *
- * XXXldb Special height reflow should really be its own method, not
+ * XXXldb Special bsize reflow should really be its own method, not
  * part of nsIFrame::Reflow.  It should then call nsIFrame::Reflow on
- * the contents of the cells to do the necessary vertical resizing.
+ * the contents of the cells to do the necessary block-axis resizing.
  *
  ******************************************************************************************/
 
 /* Layout the entire inner table. */
 void
 nsTableFrame::Reflow(nsPresContext*           aPresContext,
                      nsHTMLReflowMetrics&     aDesiredSize,
                      const nsHTMLReflowState& aReflowState,
@@ -1823,80 +1824,81 @@ nsTableFrame::Reflow(nsPresContext*     
   MoveOverflowToChildList();
 
   bool haveDesiredBSize = false;
   SetHaveReflowedColGroups(false);
 
   // Reflow the entire table (pass 2 and possibly pass 3). This phase is necessary during a
   // constrained initial reflow and other reflows which require either a strategy init or balance.
   // This isn't done during an unconstrained reflow, because it will occur later when the parent
-  // reflows with a constrained width.
+  // reflows with a constrained isize.
   if (NS_SUBTREE_DIRTY(this) ||
       aReflowState.ShouldReflowAllKids() ||
       IsGeometryDirty() ||
       aReflowState.IsBResize()) {
 
     if (aReflowState.ComputedBSize() != NS_UNCONSTRAINEDSIZE ||
-        // Also check IsBResize, to handle the first Reflow preceding a
-        // special height Reflow, when we've already had a special bsize
-        // Reflow (where ComputedBSize would not be
+        // Also check IsBResize(), to handle the first Reflow preceding a
+        // special bsize Reflow, when we've already had a special bsize
+        // Reflow (where ComputedBSize() would not be
         // NS_UNCONSTRAINEDSIZE, but without a style change in between).
         aReflowState.IsBResize()) {
-      // XXX Eventually, we should modify DistributeHeightToRows to use
-      // nsTableRowFrame::GetHeight instead of nsIFrame::GetSize().height.
+      // XXX Eventually, we should modify DistributeBSizeToRows to use
+      // nsTableRowFrame::GetBSize instead of nsIFrame::BSize().
       // That way, it will make its calculations based on internal table
-      // frame heights as they are before they ever had any extra height
+      // frame bsizes as they are before they ever had any extra bsize
       // distributed to them.  In the meantime, this reflows all the
       // internal table frames, which restores them to their state before
-      // DistributeHeightToRows was called.
+      // DistributeBSizeToRows was called.
       SetGeometryDirty();
     }
 
     bool needToInitiateSpecialReflow =
       !!(GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE);
     // see if an extra reflow will be necessary in pagination mode
     // when there is a specified table bsize
     if (isPaginated && !GetPrevInFlow() && (NS_UNCONSTRAINEDSIZE != aReflowState.AvailableBSize())) {
-      nscoord tableSpecifiedBSize = CalcBorderBoxHeight(aReflowState);
+      nscoord tableSpecifiedBSize = CalcBorderBoxBSize(aReflowState);
       if ((tableSpecifiedBSize > 0) &&
           (tableSpecifiedBSize != NS_UNCONSTRAINEDSIZE)) {
         needToInitiateSpecialReflow = true;
       }
     }
     nsIFrame* lastChildReflowed = nullptr;
 
     NS_ASSERTION(!aReflowState.mFlags.mSpecialHeightReflow,
-                 "Shouldn't be in special height reflow here!");
-
-    // do the pass 2 reflow unless this is a special height reflow and we will be
-    // initiating a special height reflow
+                 "Shouldn't be in special bsize reflow here!");
+
+    // do the pass 2 reflow unless this is a special bsize reflow and we will be
+    // initiating a special bsize reflow
     // XXXldb I changed this.  Should I change it back?
 
-    // if we need to initiate a special height reflow, then don't constrain the
-    // height of the reflow before that
+    // if we need to initiate a special bsize reflow, then don't constrain the
+    // bsize of the reflow before that
     nscoord availBSize = needToInitiateSpecialReflow
-                          ? NS_UNCONSTRAINEDSIZE : aReflowState.AvailableBSize();
+                         ? NS_UNCONSTRAINEDSIZE
+                         : aReflowState.AvailableBSize();
 
     ReflowTable(aDesiredSize, aReflowState, availBSize,
                 lastChildReflowed, aStatus);
 
     // reevaluate special bsize reflow conditions
     if (GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE) {
       needToInitiateSpecialReflow = true;
     }
 
     // XXXldb Are all these conditions correct?
     if (needToInitiateSpecialReflow && NS_FRAME_IS_COMPLETE(aStatus)) {
-      // XXXldb Do we need to set the mVResize flag on any reflow states?
+      // XXXldb Do we need to set the IsBResize flag on any reflow states?
 
       nsHTMLReflowState &mutable_rs =
         const_cast<nsHTMLReflowState&>(aReflowState);
 
-      // distribute extra vertical space to rows
-      CalcDesiredHeight(aReflowState, aDesiredSize);
+      // distribute extra block-direction space to rows
+      CalcDesiredBSize(aReflowState, aDesiredSize);
       mutable_rs.mFlags.mSpecialHeightReflow = true;
 
       ReflowTable(aDesiredSize, aReflowState, aReflowState.AvailableBSize(),
                   lastChildReflowed, aStatus);
 
       if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
         // if there is an incomplete child, then set the desired bsize
         // to include it but not the next one
@@ -1915,17 +1917,17 @@ nsTableFrame::Reflow(nsPresContext*     
     for (nsIFrame* kid : mFrames) {
       ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kid);
     }
   }
 
   aDesiredSize.ISize(wm) = aReflowState.ComputedISize() +
     aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm);
   if (!haveDesiredBSize) {
-    CalcDesiredHeight(aReflowState, aDesiredSize);
+    CalcDesiredBSize(aReflowState, aDesiredSize);
   }
   if (IsRowInserted()) {
     ProcessRowInserted(aDesiredSize.BSize(wm));
   }
 
   LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
   SetColumnDimensions(aDesiredSize.BSize(wm), wm, borderPadding,
                       aDesiredSize.Width());
@@ -1990,17 +1992,17 @@ nsTableFrame::FixupPositionedTableParts(
     LogicalSize availSize(wm, size);
     availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
     nsHTMLReflowState reflowState(aPresContext, positionedPart,
                                   aReflowState.rendContext, availSize,
                                   nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
     nsReflowStatus reflowStatus = NS_FRAME_COMPLETE;
 
     // Reflow absolutely-positioned descendants of the positioned part.
-    // FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the height and
+    // FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the bsize and
     // ignoring any change to the reflow status aren't correct. We'll never
     // paginate absolutely positioned frames.
     nsFrame* positionedFrame = static_cast<nsFrame*>(positionedPart);
     positionedFrame->FinishReflowWithAbsoluteFrames(PresContext(),
                                                     desiredSize,
                                                     reflowState,
                                                     reflowStatus,
                                                     true);
@@ -2041,31 +2043,33 @@ nsTableFrame::UpdateOverflow()
   nsLayoutUtils::UnionChildOverflow(this, overflowAreas);
 
   return FinishAndStoreOverflow(overflowAreas, GetSize());
 }
 
 void
 nsTableFrame::ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
-                          nscoord                  aAvailHeight,
+                          nscoord                  aAvailBSize,
                           nsIFrame*&               aLastChildReflowed,
                           nsReflowStatus&          aStatus)
 {
   aLastChildReflowed = nullptr;
 
   if (!GetPrevInFlow()) {
     mTableLayoutStrategy->ComputeColumnISizes(aReflowState);
   }
-  // Constrain our reflow width to the computed table width (of the 1st in flow).
-  // and our reflow height to our avail height minus border, padding, cellspacing
-  aDesiredSize.Width() = aReflowState.ComputedWidth() +
-                       aReflowState.ComputedPhysicalBorderPadding().LeftRight();
+  // Constrain our reflow isize to the computed table isize (of the 1st in flow).
+  // and our reflow bsize to our avail bsize minus border, padding, cellspacing
+  WritingMode wm = aReflowState.GetWritingMode();
+  aDesiredSize.ISize(wm) = aReflowState.ComputedISize() +
+                     aReflowState.ComputedLogicalBorderPadding().IStartEnd(wm);
   nsTableReflowState reflowState(aReflowState,
-                                 aDesiredSize.Width(), aAvailHeight);
+                                 LogicalSize(wm, aDesiredSize.ISize(wm),
+                                             aAvailBSize));
   ReflowChildren(reflowState, aStatus, aLastChildReflowed,
                  aDesiredSize.mOverflowAreas);
 
   ReflowColGroups(aReflowState.rendContext);
 }
 
 nsIFrame*
 nsTableFrame::GetFirstBodyRowGroupFrame()
@@ -2147,79 +2151,80 @@ nsTableFrame::PushChildren(const RowGrou
 
 // collapsing row groups, rows, col groups and cols are accounted for after both passes of
 // reflow so that it has no effect on the calculations of reflow.
 void
 nsTableFrame::AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
                                           const WritingMode aWM,
                                           const LogicalMargin& aBorderPadding)
 {
-  nscoord yTotalOffset = 0; // total offset among all rows in all row groups
+  nscoord bTotalOffset = 0; // total offset among all rows in all row groups
 
   // reset the bit, it will be set again if row/rowgroup or col/colgroup are
   // collapsed
   SetNeedToCollapse(false);
 
   // collapse the rows and/or row groups as necessary
   // Get the ordered children
   RowGroupArray rowGroups;
   OrderRowGroups(rowGroups);
 
   nsTableFrame* firstInFlow = static_cast<nsTableFrame*>(FirstInFlow());
-  nscoord width = firstInFlow->GetCollapsedWidth(aWM, aBorderPadding);
-  nscoord rgWidth = width - GetColSpacing(-1) -
+  nscoord iSize = firstInFlow->GetCollapsedISize(aWM, aBorderPadding);
+  nscoord rgISize = iSize - GetColSpacing(-1) -
                     GetColSpacing(GetColCount());
   nsOverflowAreas overflow;
   // Walk the list of children
   for (uint32_t childX = 0; childX < rowGroups.Length(); childX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[childX];
     NS_ASSERTION(rgFrame, "Must have row group frame here");
-    yTotalOffset += rgFrame->CollapseRowGroupIfNecessary(yTotalOffset, rgWidth);
+    bTotalOffset += rgFrame->CollapseRowGroupIfNecessary(bTotalOffset, rgISize,
+                                                         aWM);
     ConsiderChildOverflow(overflow, rgFrame);
   }
 
-  aDesiredSize.Height() -= yTotalOffset;
-  aDesiredSize.Width() = width;
+  aDesiredSize.BSize(aWM) -= bTotalOffset;
+  aDesiredSize.ISize(aWM) = iSize;
   overflow.UnionAllWith(nsRect(0, 0, aDesiredSize.Width(), aDesiredSize.Height()));
   FinishAndStoreOverflow(overflow,
                          nsSize(aDesiredSize.Width(), aDesiredSize.Height()));
 }
 
 
 nscoord
-nsTableFrame::GetCollapsedWidth(const WritingMode aWM,
+nsTableFrame::GetCollapsedISize(const WritingMode aWM,
                                 const LogicalMargin& aBorderPadding)
 {
-  NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedWidth called on next in flow");
-  nscoord width = GetColSpacing(GetColCount());
-  width += aBorderPadding.IStartEnd(aWM);
+  NS_ASSERTION(!GetPrevInFlow(), "GetCollapsedISize called on next in flow");
+  nscoord iSize = GetColSpacing(GetColCount());
+  iSize += aBorderPadding.IStartEnd(aWM);
   for (nsIFrame* groupFrame : mColGroups) {
     const nsStyleVisibility* groupVis = groupFrame->StyleVisibility();
     bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
     nsTableColGroupFrame* cgFrame = (nsTableColGroupFrame*)groupFrame;
     for (nsTableColFrame* colFrame = cgFrame->GetFirstColumn(); colFrame;
          colFrame = colFrame->GetNextCol()) {
       const nsStyleDisplay* colDisplay = colFrame->StyleDisplay();
       int32_t colX = colFrame->GetColIndex();
       if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
         const nsStyleVisibility* colVis = colFrame->StyleVisibility();
         bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
-        int32_t colWidth = GetColumnISize(colX);
+        int32_t colISize = GetColumnISize(colX);
         if (!collapseGroup && !collapseCol) {
-          width += colWidth;
+          iSize += colISize;
           if (ColumnHasCellSpacingBefore(colX))
-            width += GetColSpacing(colX-1);
+            iSize += GetColSpacing(colX-1);
         }
         else {
           SetNeedToCollapse(true);
         }
       }
     }
   }
-  return width;
+  return iSize;
 }
 
 /* virtual */ void
 nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   nsContainerFrame::DidSetStyleContext(aOldStyleContext);
 
   if (!aOldStyleContext) //avoid this on init
@@ -2706,48 +2711,49 @@ nsTableFrame::InitChildReflowState(nsHTM
     LogicalMargin border = rgFrame->GetBCBorderWidth(wm);
     collapseBorder = border.GetPhysicalMargin(wm);
     pCollapseBorder = &collapseBorder;
   }
   aReflowState.Init(presContext, nullptr, pCollapseBorder, &padding);
 
   NS_ASSERTION(!mBits.mResizedColumns ||
                !aReflowState.parentReflowState->mFlags.mSpecialHeightReflow,
-               "should not resize columns on special height reflow");
+               "should not resize columns on special bsize reflow");
   if (mBits.mResizedColumns) {
     aReflowState.SetHResize(true);
   }
 }
 
 // Position and size aKidFrame and update our reflow state. The origin of
 // aKidRect is relative to the upper-left origin of our frame
 void
 nsTableFrame::PlaceChild(nsTableReflowState&  aReflowState,
                          nsIFrame*            aKidFrame,
                          nsPoint              aKidPosition,
                          nsHTMLReflowMetrics& aKidDesiredSize,
                          const nsRect&        aOriginalKidRect,
                          const nsRect&        aOriginalKidVisualOverflow)
 {
+  WritingMode wm = aReflowState.reflowState.GetWritingMode();
   bool isFirstReflow =
     (aKidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
 
   // Place and size the child
   FinishReflowChild(aKidFrame, PresContext(), aKidDesiredSize, nullptr,
                     aKidPosition.x, aKidPosition.y, 0);
 
   InvalidateTableFrame(aKidFrame, aOriginalKidRect, aOriginalKidVisualOverflow,
                        isFirstReflow);
 
-  // Adjust the running y-offset
-  aReflowState.y += aKidDesiredSize.Height();
-
-  // If our height is constrained, then update the available height
-  if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) {
-    aReflowState.availSize.height -= aKidDesiredSize.Height();
+  // Adjust the running block-offset
+  aReflowState.bCoord += aKidDesiredSize.BSize(wm);
+
+  // If our bsize is constrained, then update the available bsize
+  if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(wm)) {
+    aReflowState.availSize.BSize(wm) -= aKidDesiredSize.BSize(wm);
   }
 }
 
 void
 nsTableFrame::OrderRowGroups(RowGroupArray& aChildren,
                              nsTableRowGroupFrame** aHead,
                              nsTableRowGroupFrame** aFoot) const
 {
@@ -2868,86 +2874,117 @@ nsTableFrame::SetupHeaderFooterChild(con
                                      nscoord* aDesiredHeight)
 {
   nsPresContext* presContext = PresContext();
   nscoord pageHeight = presContext->GetPageSize().height;
 
   // Reflow the child with unconstrained height
   WritingMode wm = aFrame->GetWritingMode();
   LogicalSize availSize = aReflowState.reflowState.AvailableSize(wm);
+
+  nscoord containerWidth = availSize.Width(wm);
+  // XXX check for containerWidth == NS_UNCONSTRAINEDSIZE
+
   availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE;
   nsHTMLReflowState kidReflowState(presContext, aReflowState.reflowState,
                                    aFrame, availSize, nullptr,
                                    nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(kidReflowState);
   kidReflowState.mFlags.mIsTopOfPage = true;
   nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
   desiredSize.ClearSize();
   nsReflowStatus status;
   ReflowChild(aFrame, presContext, desiredSize, kidReflowState,
-              aReflowState.x, aReflowState.y, 0, status);
+              wm, LogicalPoint(wm, aReflowState.iCoord, aReflowState.bCoord),
+              containerWidth, 0, status);
   // The child will be reflowed again "for real" so no need to place it now
 
   aFrame->SetRepeatable(IsRepeatable(desiredSize.Height(), pageHeight));
   *aDesiredHeight = desiredSize.Height();
   return NS_OK;
 }
 
 void
 nsTableFrame::PlaceRepeatedFooter(nsTableReflowState& aReflowState,
                                   nsTableRowGroupFrame *aTfoot,
                                   nscoord aFooterHeight)
 {
   nsPresContext* presContext = PresContext();
   WritingMode wm = aTfoot->GetWritingMode();
-  LogicalSize kidAvailSize(wm, aReflowState.availSize);
+  LogicalSize kidAvailSize = aReflowState.availSize;
+
+  nscoord containerWidth = kidAvailSize.Width(wm);
+  // XXX check for containerWidth == NS_UNCONSTRAINEDSIZE
+
   kidAvailSize.BSize(wm) = aFooterHeight;
   nsHTMLReflowState footerReflowState(presContext,
                                       aReflowState.reflowState,
                                       aTfoot, kidAvailSize,
                                       nullptr,
                                       nsHTMLReflowState::CALLER_WILL_INIT);
   InitChildReflowState(footerReflowState);
-  aReflowState.y += GetRowSpacing(GetRowCount());
+  aReflowState.bCoord += GetRowSpacing(GetRowCount());
 
   nsRect origTfootRect = aTfoot->GetRect();
   nsRect origTfootVisualOverflow = aTfoot->GetVisualOverflowRect();
 
   nsReflowStatus footerStatus;
   nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
   desiredSize.ClearSize();
+  LogicalPoint kidPosition(wm, aReflowState.iCoord, aReflowState.bCoord);
   ReflowChild(aTfoot, presContext, desiredSize, footerReflowState,
-              aReflowState.x, aReflowState.y, 0, footerStatus);
-  nsPoint kidPosition(aReflowState.x, aReflowState.y);
-  footerReflowState.ApplyRelativePositioning(&kidPosition);
-
-  PlaceChild(aReflowState, aTfoot, kidPosition, desiredSize, origTfootRect,
-             origTfootVisualOverflow);
+              wm, kidPosition, containerWidth, 0, footerStatus);
+  footerReflowState.ApplyRelativePositioning(&kidPosition, containerWidth);
+
+  PlaceChild(aReflowState, aTfoot,
+             // We subtract desiredSize.Width() from containerWidth here
+             // to account for the fact that in RTL modes, the origin is
+             // on the right-hand side so we're not simply converting a
+             // point, we're also swapping the child's origin side.
+             kidPosition.GetPhysicalPoint(wm, containerWidth - desiredSize.Width()),
+             desiredSize, origTfootRect, origTfootVisualOverflow);
 }
 
 // Reflow the children based on the avail size and reason in aReflowState
 // update aReflowMetrics a aStatus
 void
 nsTableFrame::ReflowChildren(nsTableReflowState& aReflowState,
                              nsReflowStatus&     aStatus,
                              nsIFrame*&          aLastChildReflowed,
                              nsOverflowAreas&    aOverflowAreas)
 {
   aStatus = NS_FRAME_COMPLETE;
   aLastChildReflowed = nullptr;
 
   nsIFrame* prevKidFrame = nullptr;
+  WritingMode wm = aReflowState.reflowState.GetWritingMode();
+  nscoord containerWidth = aReflowState.reflowState.ComputedWidth();
+  if (containerWidth == NS_UNCONSTRAINEDSIZE) {
+    NS_WARN_IF_FALSE(wm.IsVertical(),
+                     "shouldn't have unconstrained width in horizontal mode");
+    if (wm.IsVerticalRL()) {
+      nsHTMLReflowMetrics desiredSize(wm);
+      CalcDesiredBSize(aReflowState.reflowState, desiredSize);
+      containerWidth = desiredSize.Width();
+    } else {
+      // in vertical-lr mode, containerWidth won't actually be used
+      containerWidth = 0;
+    }
+  } else {
+    containerWidth +=
+      aReflowState.reflowState.ComputedPhysicalBorderPadding().LeftRight();
+  }
 
   nsPresContext* presContext = PresContext();
   // XXXldb Should we be checking constrained height instead?
   // tables are not able to pull back children from its next inflow, so even
   // under paginated contexts tables are should not paginate if they are inside
   // column set
   bool isPaginated = presContext->IsPaginated() &&
-                       NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height &&
+                       NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(wm) &&
                        aReflowState.reflowState.mFlags.mTableIsSplittable;
 
   aOverflowAreas.Clear();
 
   bool reflowAllKids = aReflowState.reflowState.ShouldReflowAllKids() ||
                          mBits.mResizedColumns ||
                          IsGeometryDirty();
 
@@ -2978,17 +3015,17 @@ nsTableFrame::ReflowChildren(nsTableRefl
         return;
     }
   }
    // if the child is a tbody in paginated mode reduce the height by a repeated footer
   bool allowRepeatedFooter = false;
   for (size_t childX = 0; childX < rowGroups.Length(); childX++) {
     nsIFrame* kidFrame = rowGroups[childX];
     nsTableRowGroupFrame* rowGroupFrame = rowGroups[childX];
-    nscoord cellSpacingY = GetRowSpacing(rowGroupFrame->GetStartRowIndex()+
+    nscoord cellSpacingB = GetRowSpacing(rowGroupFrame->GetStartRowIndex()+
                                          rowGroupFrame->GetRowCount());
     // Get the frame state bits
     // See if we should only reflow the dirty child frames
     if (reflowAllKids ||
         NS_SUBTREE_DIRTY(kidFrame) ||
         (aReflowState.reflowState.mFlags.mSpecialHeightReflow &&
          (isPaginated || (kidFrame->GetStateBits() &
                           NS_FRAME_CONTAINS_RELATIVE_BSIZE)))) {
@@ -2999,68 +3036,67 @@ nsTableFrame::ReflowChildren(nsTableRefl
         else if (tfoot && tfoot->IsRepeatable()) {
           tfoot->SetRepeatable(false);
         }
         PushChildren(rowGroups, childX);
         aStatus = NS_FRAME_NOT_COMPLETE;
         break;
       }
 
-      nsSize kidAvailSize(aReflowState.availSize);
+      LogicalSize kidAvailSize(aReflowState.availSize);
       allowRepeatedFooter = false;
-      if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.height)) {
+      if (isPaginated && (NS_UNCONSTRAINEDSIZE != kidAvailSize.BSize(wm))) {
         nsTableRowGroupFrame* kidRG =
           static_cast<nsTableRowGroupFrame*>(kidFrame);
         if (kidRG != thead && kidRG != tfoot && tfoot && tfoot->IsRepeatable()) {
           // the child is a tbody and there is a repeatable footer
           NS_ASSERTION(tfoot == rowGroups[rowGroups.Length() - 1], "Missing footer!");
-          if (footerHeight + cellSpacingY < kidAvailSize.height) {
+          if (footerHeight + cellSpacingB < kidAvailSize.BSize(wm)) {
             allowRepeatedFooter = true;
-            kidAvailSize.height -= footerHeight + cellSpacingY;
+            kidAvailSize.BSize(wm) -= footerHeight + cellSpacingB;
           }
         }
       }
 
       nsRect oldKidRect = kidFrame->GetRect();
       nsRect oldKidVisualOverflow = kidFrame->GetVisualOverflowRect();
 
       nsHTMLReflowMetrics desiredSize(aReflowState.reflowState);
       desiredSize.ClearSize();
 
       // Reflow the child into the available space
       nsHTMLReflowState kidReflowState(presContext, aReflowState.reflowState,
                                        kidFrame,
-                                       LogicalSize(kidFrame->GetWritingMode(),
-                                                   kidAvailSize),
+                                       kidAvailSize,
                                        nullptr,
                                        nsHTMLReflowState::CALLER_WILL_INIT);
       InitChildReflowState(kidReflowState);
 
       // If this isn't the first row group, and the previous row group has a
       // nonzero YMost, then we can't be at the top of the page.
       // We ignore a repeated head row group in this check to avoid causing
       // infinite loops in some circumstances - see bug 344883.
       if (childX > ((thead && IsRepeatedFrame(thead)) ? 1u : 0u) &&
           (rowGroups[childX - 1]->GetNormalRect().YMost() > 0)) {
         kidReflowState.mFlags.mIsTopOfPage = false;
       }
-      aReflowState.y += cellSpacingY;
-      if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) {
-        aReflowState.availSize.height -= cellSpacingY;
+      aReflowState.bCoord += cellSpacingB;
+      if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(wm)) {
+        aReflowState.availSize.BSize(wm) -= cellSpacingB;
       }
       // record the presence of a next in flow, it might get destroyed so we
       // need to reorder the row group array
       bool reorder = false;
       if (kidFrame->GetNextInFlow())
         reorder = true;
 
+      LogicalPoint kidPosition(wm, aReflowState.iCoord, aReflowState.bCoord);
       ReflowChild(kidFrame, presContext, desiredSize, kidReflowState,
-                  aReflowState.x, aReflowState.y, 0, aStatus);
-      nsPoint kidPosition(aReflowState.x, aReflowState.y);
-      kidReflowState.ApplyRelativePositioning(&kidPosition);
+                  wm, kidPosition, containerWidth, 0, aStatus);
+      kidReflowState.ApplyRelativePositioning(&kidPosition, containerWidth);
 
       if (reorder) {
         // reorder row groups the reflow may have changed the nextinflows
         OrderRowGroups(rowGroups, &thead, &tfoot);
         childX = rowGroups.IndexOf(kidFrame);
         if (childX == RowGroupArray::NoIndex) {
           // XXXbz can this happen?
           childX = rowGroups.Length();
@@ -3082,18 +3118,20 @@ nsTableFrame::ReflowChildren(nsTableRefl
           aStatus = NS_INLINE_LINE_BREAK_BEFORE();
           break;
         }
         // if we are on top of the page place with dataloss
         if (kidReflowState.mFlags.mIsTopOfPage) {
           if (childX+1 < rowGroups.Length()) {
             nsIFrame* nextRowGroupFrame = rowGroups[childX + 1];
             if (nextRowGroupFrame) {
-              PlaceChild(aReflowState, kidFrame, kidPosition, desiredSize,
-                         oldKidRect, oldKidVisualOverflow);
+              PlaceChild(aReflowState, kidFrame,
+                         kidPosition.GetPhysicalPoint(wm, containerWidth -
+                                                          desiredSize.Width()),
+                         desiredSize, oldKidRect, oldKidVisualOverflow);
               if (allowRepeatedFooter) {
                 PlaceRepeatedFooter(aReflowState, tfoot, footerHeight);
               }
               else if (tfoot && tfoot->IsRepeatable()) {
                 tfoot->SetRepeatable(false);
               }
               aStatus = NS_FRAME_NOT_COMPLETE;
               PushChildren(rowGroups, childX + 1);
@@ -3111,18 +3149,20 @@ nsTableFrame::ReflowChildren(nsTableRefl
               tfoot->SetRepeatable(false);
             }
             aStatus = NS_FRAME_NOT_COMPLETE;
             PushChildren(rowGroups, childX);
             aLastChildReflowed = prevKidFrame;
             break;
           }
           else { // we can't push so lets make clear how much space we need
-            PlaceChild(aReflowState, kidFrame, kidPosition, desiredSize,
-                       oldKidRect, oldKidVisualOverflow);
+            PlaceChild(aReflowState, kidFrame,
+                       kidPosition.GetPhysicalPoint(wm, containerWidth -
+                                                        desiredSize.Width()),
+                       desiredSize, oldKidRect, oldKidVisualOverflow);
             aLastChildReflowed = kidFrame;
             if (allowRepeatedFooter) {
               PlaceRepeatedFooter(aReflowState, tfoot, footerHeight);
               aLastChildReflowed = tfoot;
             }
             break;
           }
         }
@@ -3135,18 +3175,20 @@ nsTableFrame::ReflowChildren(nsTableRefl
       if (NS_FRAME_IS_COMPLETE(aStatus) && isPaginated &&
           (NS_UNCONSTRAINEDSIZE != kidReflowState.AvailableHeight())) {
         nsIFrame* nextKid =
           (childX + 1 < rowGroups.Length()) ? rowGroups[childX + 1] : nullptr;
         pageBreak = PageBreakAfter(kidFrame, nextKid);
       }
 
       // Place the child
-      PlaceChild(aReflowState, kidFrame, kidPosition, desiredSize, oldKidRect,
-                 oldKidVisualOverflow);
+      PlaceChild(aReflowState, kidFrame,
+                 kidPosition.GetPhysicalPoint(wm, containerWidth -
+                                                  desiredSize.Width()),
+                 desiredSize, oldKidRect, oldKidVisualOverflow);
 
       // Remember where we just were in case we end up pushing children
       prevKidFrame = kidFrame;
 
       // Special handling for incomplete children
       if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) {
         nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow();
         if (!kidNextInFlow) {
@@ -3181,32 +3223,33 @@ nsTableFrame::ReflowChildren(nsTableRefl
         nsIFrame* nextSibling = kidFrame->GetNextSibling();
         if (nextSibling) {
           PushChildren(rowGroups, childX + 1);
         }
         break;
       }
     }
     else { // it isn't being reflowed
-      aReflowState.y += cellSpacingY;
-      nsRect kidRect = kidFrame->GetNormalRect();
-      if (kidRect.y != aReflowState.y) {
+      aReflowState.bCoord += cellSpacingB;
+      LogicalRect kidRect(wm, kidFrame->GetNormalRect(), containerWidth);
+      if (kidRect.BStart(wm) != aReflowState.bCoord) {
         // invalidate the old position
         kidFrame->InvalidateFrameSubtree();
         // move to the new position
-        kidFrame->MovePositionBy(nsPoint(0, aReflowState.y - kidRect.y));
+        kidFrame->MovePositionBy(wm, LogicalPoint(wm, 0, aReflowState.bCoord -
+                                                         kidRect.BStart(wm)));
         RePositionViews(kidFrame);
         // invalidate the new position
         kidFrame->InvalidateFrameSubtree();
       }
-      aReflowState.y += kidRect.height;
-
-      // If our height is constrained then update the available height.
-      if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height) {
-        aReflowState.availSize.height -= cellSpacingY + kidRect.height;
+      aReflowState.bCoord += kidRect.BSize(wm);
+
+      // If our bsize is constrained then update the available bsize.
+      if (NS_UNCONSTRAINEDSIZE != aReflowState.availSize.BSize(wm)) {
+        aReflowState.availSize.BSize(wm) -= cellSpacingB + kidRect.BSize(wm);
       }
     }
     ConsiderChildOverflow(aOverflowAreas, kidFrame);
   }
 
   // We've now propagated the column resizes and geometry changes to all
   // the children.
   mBits.mResizedColumns = false;
@@ -3231,73 +3274,73 @@ nsTableFrame::ReflowColGroups(nsRenderin
         FinishReflowChild(kidFrame, presContext, kidMet, nullptr, 0, 0, 0);
       }
     }
     SetHaveReflowedColGroups(true);
   }
 }
 
 void
-nsTableFrame::CalcDesiredHeight(const nsHTMLReflowState& aReflowState,
-                                nsHTMLReflowMetrics& aDesiredSize)
-{
+nsTableFrame::CalcDesiredBSize(const nsHTMLReflowState& aReflowState,
+                               nsHTMLReflowMetrics& aDesiredSize)
+{
+  WritingMode wm = aReflowState.GetWritingMode();
   nsTableCellMap* cellMap = GetCellMap();
   if (!cellMap) {
     NS_ERROR("never ever call me until the cell map is built!");
-    aDesiredSize.Height() = 0;
+    aDesiredSize.BSize(wm) = 0;
     return;
   }
-  WritingMode wm = aReflowState.GetWritingMode();
   LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
 
-  // get the natural height based on the last child's (row group) rect
+  // get the natural bsize based on the last child's (row group) rect
   RowGroupArray rowGroups;
   OrderRowGroups(rowGroups);
   if (rowGroups.IsEmpty()) {
     // tables can be used as rectangular items without content
-    nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState);
-    if ((NS_UNCONSTRAINEDSIZE != tableSpecifiedHeight) &&
-        (tableSpecifiedHeight > 0) &&
+    nscoord tableSpecifiedBSize = CalcBorderBoxBSize(aReflowState);
+    if ((NS_UNCONSTRAINEDSIZE != tableSpecifiedBSize) &&
+        (tableSpecifiedBSize > 0) &&
         eCompatibility_NavQuirks != PresContext()->CompatibilityMode()) {
           // empty tables should not have a size in quirks mode
-      aDesiredSize.Height() = tableSpecifiedHeight;
-    }
-    else
-      aDesiredSize.Height() = 0;
+      aDesiredSize.BSize(wm) = tableSpecifiedBSize;
+    } else {
+      aDesiredSize.BSize(wm) = 0;
+    }
     return;
   }
   int32_t rowCount = cellMap->GetRowCount();
   int32_t colCount = cellMap->GetColCount();
-  nscoord desiredHeight = borderPadding.BStartEnd(wm);
+  nscoord desiredBSize = borderPadding.BStartEnd(wm);
   if (rowCount > 0 && colCount > 0) {
-    desiredHeight += GetRowSpacing(-1);
+    desiredBSize += GetRowSpacing(-1);
     for (uint32_t rgX = 0; rgX < rowGroups.Length(); rgX++) {
-      desiredHeight += rowGroups[rgX]->GetSize().height +
+      desiredBSize += rowGroups[rgX]->BSize(wm) +
                        GetRowSpacing(rowGroups[rgX]->GetRowCount() +
                                      rowGroups[rgX]->GetStartRowIndex());
     }
   }
 
-  // see if a specified table height requires dividing additional space to rows
+  // see if a specified table bsize requires dividing additional space to rows
   if (!GetPrevInFlow()) {
-    nscoord tableSpecifiedHeight = CalcBorderBoxHeight(aReflowState);
-    if ((tableSpecifiedHeight > 0) &&
-        (tableSpecifiedHeight != NS_UNCONSTRAINEDSIZE) &&
-        (tableSpecifiedHeight > desiredHeight)) {
-      // proportionately distribute the excess height to unconstrained rows in each
+    nscoord tableSpecifiedBSize = CalcBorderBoxBSize(aReflowState);
+    if ((tableSpecifiedBSize > 0) &&
+        (tableSpecifiedBSize != NS_UNCONSTRAINEDSIZE) &&
+        (tableSpecifiedBSize > desiredBSize)) {
+      // proportionately distribute the excess bsize to unconstrained rows in each
       // unconstrained row group.
-      DistributeHeightToRows(aReflowState, tableSpecifiedHeight - desiredHeight);
+      DistributeBSizeToRows(aReflowState, tableSpecifiedBSize - desiredBSize);
       // this might have changed the overflow area incorporate the childframe overflow area.
       for (nsIFrame* kidFrame : mFrames) {
         ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame);
       }
-      desiredHeight = tableSpecifiedHeight;
-    }
-  }
-  aDesiredSize.Height() = desiredHeight;
+      desiredBSize = tableSpecifiedBSize;
+    }
+  }
+  aDesiredSize.BSize(wm) = desiredBSize;
 }
 
 static
 void ResizeCells(nsTableFrame& aTableFrame)
 {
   nsTableFrame::RowGroupArray rowGroups;
   aTableFrame.OrderRowGroups(rowGroups);
   WritingMode wm = aTableFrame.GetWritingMode();
@@ -3321,109 +3364,116 @@ void ResizeCells(nsTableFrame& aTableFra
     rgFrame->FinishAndStoreOverflow(&groupDesiredSize);
     tableDesiredSize.mOverflowAreas.UnionWith(groupDesiredSize.mOverflowAreas +
                                               rgFrame->GetPosition());
   }
   aTableFrame.FinishAndStoreOverflow(&tableDesiredSize);
 }
 
 void
-nsTableFrame::DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
-                                     nscoord                  aAmount)
+nsTableFrame::DistributeBSizeToRows(const nsHTMLReflowState& aReflowState,
+                                    nscoord                  aAmount)
 {
   WritingMode wm = aReflowState.GetWritingMode();
   LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowState);
 
   RowGroupArray rowGroups;
   OrderRowGroups(rowGroups);
 
   nscoord amountUsed = 0;
-  // distribute space to each pct height row whose row group doesn't have a computed
-  // height, and base the pct on the table height. If the row group had a computed
-  // height, then this was already done in nsTableRowGroupFrame::CalculateRowHeights
-  nscoord pctBasis = aReflowState.ComputedHeight() - GetRowSpacing(-1, GetRowCount());
-  nscoord yOriginRG = borderPadding.BStart(wm) + GetRowSpacing(0);
-  nscoord yEndRG = yOriginRG;
+  // distribute space to each pct bsize row whose row group doesn't have a computed
+  // bsize, and base the pct on the table bsize. If the row group had a computed
+  // bsize, then this was already done in nsTableRowGroupFrame::CalculateRowBSizes
+  nscoord pctBasis = aReflowState.ComputedBSize() - GetRowSpacing(-1, GetRowCount());
+  nscoord bOriginRG = borderPadding.BStart(wm) + GetRowSpacing(0);
+  nscoord bEndRG = bOriginRG;
   uint32_t rgX;
   for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     nscoord amountUsedByRG = 0;
-    nscoord yOriginRow = 0;
-    nsRect rgNormalRect = rgFrame->GetNormalRect();
+    nscoord bOriginRow = 0;
+    // We pass containerWidth of zero when constructing the LogicalRect here,
+    // and similarly below. This is OK because these rects will be used to make
+    // relative adjustments, not for actual conversion to physical coords.
+    LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), 0);
     if (!rgFrame->HasStyleBSize()) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
-        nsRect rowNormalRect = rowFrame->GetNormalRect();
-        nscoord cellSpacingY = GetRowSpacing(rowFrame->GetRowIndex());
+        LogicalRect rowNormalRect(wm, rowFrame->GetNormalRect(), 0);
+        nscoord cellSpacingB = GetRowSpacing(rowFrame->GetRowIndex());
         if ((amountUsed < aAmount) && rowFrame->HasPctBSize()) {
-          nscoord pctHeight = rowFrame->GetBSize(pctBasis);
+          nscoord pctBSize = rowFrame->GetBSize(pctBasis);
           nscoord amountForRow = std::min(aAmount - amountUsed,
-                                          pctHeight - rowNormalRect.height);
+                                          pctBSize - rowNormalRect.BSize(wm));
           if (amountForRow > 0) {
-            // XXXbz we don't need to move the row's y position to yOriginRow?
+            // XXXbz we don't need to move the row's b-position to bOriginRow?
             nsRect origRowRect = rowFrame->GetRect();
-            nscoord newRowHeight = rowNormalRect.height + amountForRow;
-            rowFrame->SetSize(nsSize(rowNormalRect.width, newRowHeight));
-            yOriginRow += newRowHeight + cellSpacingY;
-            yEndRG += newRowHeight + cellSpacingY;
+            nscoord newRowBSize = rowNormalRect.BSize(wm) + amountForRow;
+            rowFrame->SetSize(wm, LogicalSize(wm, rowNormalRect.ISize(wm),
+                              newRowBSize));
+            bOriginRow += newRowBSize + cellSpacingB;
+            bEndRG += newRowBSize + cellSpacingB;
             amountUsed += amountForRow;
             amountUsedByRG += amountForRow;
             //rowFrame->DidResize();
             nsTableFrame::RePositionViews(rowFrame);
 
             rgFrame->InvalidateFrameWithRect(origRowRect);
             rgFrame->InvalidateFrame();
           }
         }
         else {
-          if (amountUsed > 0 && yOriginRow != rowNormalRect.y &&
+          if (amountUsed > 0 && bOriginRow != rowNormalRect.BStart(wm) &&
               !(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
             rowFrame->InvalidateFrameSubtree();
-            rowFrame->MovePositionBy(nsPoint(0, yOriginRow - rowNormalRect.y));
+            rowFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRow -
+                                                    rowNormalRect.BStart(wm)));
             nsTableFrame::RePositionViews(rowFrame);
             rowFrame->InvalidateFrameSubtree();
           }
-          yOriginRow += rowNormalRect.height + cellSpacingY;
-          yEndRG += rowNormalRect.height + cellSpacingY;
+          bOriginRow += rowNormalRect.BSize(wm) + cellSpacingB;
+          bEndRG += rowNormalRect.BSize(wm) + cellSpacingB;
         }
         rowFrame = rowFrame->GetNextRow();
       }
       if (amountUsed > 0) {
-        if (rgNormalRect.y != yOriginRG) {
+        if (rgNormalRect.BStart(wm) != bOriginRG) {
           rgFrame->InvalidateFrameSubtree();
         }
 
         nsRect origRgNormalRect = rgFrame->GetRect();
         nsRect origRgVisualOverflow = rgFrame->GetVisualOverflowRect();
 
-        rgFrame->MovePositionBy(nsPoint(0, yOriginRG - rgNormalRect.y));
-        rgFrame->SetSize(nsSize(rgNormalRect.width,
-                                rgNormalRect.height + amountUsedByRG));
+        rgFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRG -
+                                                 rgNormalRect.BStart(wm)));
+        rgFrame->SetSize(wm, LogicalSize(wm, rgNormalRect.ISize(wm),
+                                rgNormalRect.BSize(wm) + amountUsedByRG));
 
         nsTableFrame::InvalidateTableFrame(rgFrame, origRgNormalRect,
                                            origRgVisualOverflow, false);
       }
     }
-    else if (amountUsed > 0 && yOriginRG != rgNormalRect.y) {
+    else if (amountUsed > 0 && bOriginRG != rgNormalRect.BStart(wm)) {
       rgFrame->InvalidateFrameSubtree();
-      rgFrame->MovePositionBy(nsPoint(0, yOriginRG - rgNormalRect.y));
+      rgFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRG -
+                                               rgNormalRect.BStart(wm)));
       // Make sure child views are properly positioned
       nsTableFrame::RePositionViews(rgFrame);
       rgFrame->InvalidateFrameSubtree();
     }
-    yOriginRG = yEndRG;
+    bOriginRG = bEndRG;
   }
 
   if (amountUsed >= aAmount) {
     ResizeCells(*this);
     return;
   }
 
-  // get the first row without a style height where its row group has an
-  // unconstrained height
+  // get the first row without a style bsize where its row group has an
+  // unconstrained bsize
   nsTableRowGroupFrame* firstUnStyledRG  = nullptr;
   nsTableRowFrame*      firstUnStyledRow = nullptr;
   for (rgX = 0; rgX < rowGroups.Length() && !firstUnStyledRG; rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     if (!rgFrame->HasStyleBSize()) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
         if (!rowFrame->HasStyleBSize()) {
@@ -3432,38 +3482,38 @@ nsTableFrame::DistributeHeightToRows(con
           break;
         }
         rowFrame = rowFrame->GetNextRow();
       }
     }
   }
 
   nsTableRowFrame* lastEligibleRow = nullptr;
-  // Accumulate the correct divisor. This will be the total total height of all
+  // Accumulate the correct divisor. This will be the total bsize of all
   // unstyled rows inside unstyled row groups, unless there are none, in which
   // case, it will be number of all rows. If the unstyled rows don't have a
-  // height, divide the space equally among them.
+  // bsize, divide the space equally among them.
   nscoord divisor = 0;
   int32_t eligibleRows = 0;
   bool expandEmptyRows = false;
 
   if (!firstUnStyledRow) {
     // there is no unstyled row
     divisor = GetRowCount();
   }
   else {
     for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
       nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
       if (!firstUnStyledRG || !rgFrame->HasStyleBSize()) {
         nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
         while (rowFrame) {
           if (!firstUnStyledRG || !rowFrame->HasStyleBSize()) {
-            NS_ASSERTION(rowFrame->GetSize().height >= 0,
-                         "negative row frame height");
-            divisor += rowFrame->GetSize().height;
+            NS_ASSERTION(rowFrame->BSize(wm) >= 0,
+                         "negative row frame block-size");
+            divisor += rowFrame->BSize(wm);
             eligibleRows++;
             lastEligibleRow = rowFrame;
           }
           rowFrame = rowFrame->GetNextRow();
         }
       }
     }
     if (divisor <= 0) {
@@ -3471,113 +3521,120 @@ nsTableFrame::DistributeHeightToRows(con
         expandEmptyRows = true;
       }
       else {
         NS_ERROR("invalid divisor");
         return;
       }
     }
   }
-  // allocate the extra height to the unstyled row groups and rows
-  nscoord heightToDistribute = aAmount - amountUsed;
-  yOriginRG = borderPadding.BStart(wm) + GetRowSpacing(-1);
-  yEndRG = yOriginRG;
+  // allocate the extra bsize to the unstyled row groups and rows
+  nscoord bSizeToDistribute = aAmount - amountUsed;
+  bOriginRG = borderPadding.BStart(wm) + GetRowSpacing(-1);
+  bEndRG = bOriginRG;
   for (rgX = 0; rgX < rowGroups.Length(); rgX++) {
     nsTableRowGroupFrame* rgFrame = rowGroups[rgX];
     nscoord amountUsedByRG = 0;
-    nscoord yOriginRow = 0;
-    nsRect rgNormalRect = rgFrame->GetNormalRect();
+    nscoord bOriginRow = 0;
+    LogicalRect rgNormalRect(wm, rgFrame->GetNormalRect(), 0);
     nsRect rgVisualOverflow = rgFrame->GetVisualOverflowRect();
     // see if there is an eligible row group or we distribute to all rows
     if (!firstUnStyledRG || !rgFrame->HasStyleBSize() || !eligibleRows) {
       nsTableRowFrame* rowFrame = rgFrame->GetFirstRow();
       while (rowFrame) {
-        nscoord cellSpacingY = GetRowSpacing(rowFrame->GetRowIndex());
-        nsRect rowNormalRect = rowFrame->GetNormalRect();
+        nscoord cellSpacingB = GetRowSpacing(rowFrame->GetRowIndex());
+        LogicalRect rowNormalRect(wm, rowFrame->GetNormalRect(), 0);
         nsRect rowVisualOverflow = rowFrame->GetVisualOverflowRect();
         // see if there is an eligible row or we distribute to all rows
         if (!firstUnStyledRow || !rowFrame->HasStyleBSize() || !eligibleRows) {
           float ratio;
           if (eligibleRows) {
             if (!expandEmptyRows) {
-              // The amount of additional space each row gets is proportional to
-              // its height
-              ratio = float(rowNormalRect.height) / float(divisor);
+              // The amount of additional space each row gets is proportional
+              // to its bsize
+              ratio = float(rowNormalRect.BSize(wm)) / float(divisor);
             } else {
               // empty rows get all the same additional space
               ratio = 1.0f / float(eligibleRows);
             }
           }
           else {
             // all rows get the same additional space
             ratio = 1.0f / float(divisor);
           }
           // give rows their additional space, except for the last row which
           // gets the remainder
-          nscoord amountForRow = (rowFrame == lastEligibleRow)
-                                 ? aAmount - amountUsed : NSToCoordRound(((float)(heightToDistribute)) * ratio);
+          nscoord amountForRow =
+            (rowFrame == lastEligibleRow)
+              ? aAmount - amountUsed
+              : NSToCoordRound(((float)(bSizeToDistribute)) * ratio);
           amountForRow = std::min(amountForRow, aAmount - amountUsed);
 
-          if (yOriginRow != rowNormalRect.y) {
+          if (bOriginRow != rowNormalRect.BStart(wm)) {
             rowFrame->InvalidateFrameSubtree();
           }
 
-          // update the row height
+          // update the row bsize
           nsRect origRowRect = rowFrame->GetRect();
-          nscoord newRowHeight = rowNormalRect.height + amountForRow;
-          rowFrame->MovePositionBy(nsPoint(0, yOriginRow - rowNormalRect.y));
-          rowFrame->SetSize(nsSize(rowNormalRect.width, newRowHeight));
-
-          yOriginRow += newRowHeight + cellSpacingY;
-          yEndRG += newRowHeight + cellSpacingY;
+          nscoord newRowBSize = rowNormalRect.BSize(wm) + amountForRow;
+          rowFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRow -
+                                                    rowNormalRect.BStart(wm)));
+          rowFrame->SetSize(wm, LogicalSize(wm, rowNormalRect.ISize(wm),
+                                            newRowBSize));
+
+          bOriginRow += newRowBSize + cellSpacingB;
+          bEndRG += newRowBSize + cellSpacingB;
 
           amountUsed += amountForRow;
           amountUsedByRG += amountForRow;
           NS_ASSERTION((amountUsed <= aAmount), "invalid row allocation");
           //rowFrame->DidResize();
           nsTableFrame::RePositionViews(rowFrame);
 
           nsTableFrame::InvalidateTableFrame(rowFrame, origRowRect,
                                              rowVisualOverflow, false);
         }
         else {
-          if (amountUsed > 0 && yOriginRow != rowNormalRect.y) {
+          if (amountUsed > 0 && bOriginRow != rowNormalRect.BStart(wm)) {
             rowFrame->InvalidateFrameSubtree();
-            rowFrame->MovePositionBy(nsPoint(0, yOriginRow - rowNormalRect.y));
+            rowFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRow -
+                                                    rowNormalRect.BStart(wm)));
             nsTableFrame::RePositionViews(rowFrame);
             rowFrame->InvalidateFrameSubtree();
           }
-          yOriginRow += rowNormalRect.height + cellSpacingY;
-          yEndRG += rowNormalRect.height + cellSpacingY;
+          bOriginRow += rowNormalRect.BSize(wm) + cellSpacingB;
+          bEndRG += rowNormalRect.BSize(wm) + cellSpacingB;
         }
         rowFrame = rowFrame->GetNextRow();
       }
       if (amountUsed > 0) {
-        if (rgNormalRect.y != yOriginRG) {
+        if (rgNormalRect.BStart(wm) != bOriginRG) {
           rgFrame->InvalidateFrameSubtree();
         }
 
         nsRect origRgNormalRect = rgFrame->GetRect();
-        rgFrame->MovePositionBy(nsPoint(0, yOriginRG - rgNormalRect.y));
-        rgFrame->SetSize(nsSize(rgNormalRect.width,
-                                rgNormalRect.height + amountUsedByRG));
+        rgFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRG -
+                                                 rgNormalRect.BStart(wm)));
+        rgFrame->SetSize(wm, LogicalSize(wm, rgNormalRect.ISize(wm),
+                                rgNormalRect.BSize(wm) + amountUsedByRG));
 
         nsTableFrame::InvalidateTableFrame(rgFrame, origRgNormalRect,
                                            rgVisualOverflow, false);
       }
       // Make sure child views are properly positioned
     }
-    else if (amountUsed > 0 && yOriginRG != rgNormalRect.y) {
+    else if (amountUsed > 0 && bOriginRG != rgNormalRect.BStart(wm)) {
       rgFrame->InvalidateFrameSubtree();
-      rgFrame->MovePositionBy(nsPoint(0, yOriginRG - rgNormalRect.y));
+      rgFrame->MovePositionBy(wm, LogicalPoint(wm, 0, bOriginRG -
+                                               rgNormalRect.BStart(wm)));
       // Make sure child views are properly positioned
       nsTableFrame::RePositionViews(rgFrame);
       rgFrame->InvalidateFrameSubtree();
     }
-    yOriginRG = yEndRG;
+    bOriginRG = bEndRG;
   }
 
   ResizeCells(*this);
 }
 
 int32_t
 nsTableFrame::GetColumnISize(int32_t aColIndex)
 {
@@ -3736,37 +3793,37 @@ nsTableFrame::GetTableFramePassingThroug
     }
   }
 
   MOZ_ASSERT(tableFrame, "Should have a table frame here");
   return hitPassThroughFrame ? tableFrame : nullptr;
 }
 
 bool
-nsTableFrame::IsAutoHeight()
-{
-  const nsStyleCoord &height = StylePosition()->mHeight;
+nsTableFrame::IsAutoBSize(WritingMode aWM)
+{
+  const nsStyleCoord &bsize = StylePosition()->BSize(aWM);
   // Don't consider calc() here like this quirk for percent.
-  return height.GetUnit() == eStyleUnit_Auto ||
-         (height.GetUnit() == eStyleUnit_Percent &&
-          height.GetPercentValue() <= 0.0f);
+  return bsize.GetUnit() == eStyleUnit_Auto ||
+         (bsize.GetUnit() == eStyleUnit_Percent &&
+          bsize.GetPercentValue() <= 0.0f);
 }
 
 nscoord
-nsTableFrame::CalcBorderBoxHeight(const nsHTMLReflowState& aState)
-{
-  nscoord height = aState.ComputedHeight();
-  if (NS_AUTOHEIGHT != height) {
+nsTableFrame::CalcBorderBoxBSize(const nsHTMLReflowState& aState)
+{
+  nscoord bSize = aState.ComputedBSize();
+  if (NS_AUTOHEIGHT != bSize) {
     WritingMode wm = aState.GetWritingMode();
     LogicalMargin borderPadding = GetChildAreaOffset(wm, &aState);
-    height += borderPadding.BStartEnd(wm);
-  }
-  height = std::max(0, height);
-
-  return height;
+    bSize += borderPadding.BStartEnd(wm);
+  }
+  bSize = std::max(0, bSize);
+
+  return bSize;
 }
 
 bool
 nsTableFrame::IsAutoLayout()
 {
   if (StyleTable()->mLayoutStrategy == NS_STYLE_TABLE_LAYOUT_AUTO)
     return true;
   // a fixed-layout inline-table must have a width
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -248,17 +248,17 @@ public:
                                       nsDisplayTableItem* aDisplayItem,
                                       DisplayGenericTablePartTraversal aTraversal = GenericTraversal);
 
   // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
   // of type aChildType.
   static nsIFrame* GetFrameAtOrBefore(nsIFrame*       aParentFrame,
                                       nsIFrame*       aPriorChildFrame,
                                       nsIAtom*        aChildType);
-  bool IsAutoHeight();
+  bool IsAutoBSize(mozilla::WritingMode aWM);
 
   /** @return true if aDisplayType represents a rowgroup of any sort
     * (header, footer, or body)
     */
   bool IsRowGroup(int32_t aDisplayType) const;
 
   virtual const nsFrameList& GetChildList(ChildListID aListID) const override;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
@@ -340,17 +340,17 @@ public:
                   const mozilla::LogicalSize& aBorder,
                   const mozilla::LogicalSize& aPadding,
                   bool aShrinkWrap) override;
 
   /**
    * A copy of nsFrame::ShrinkWidthToFit that calls a different
    * GetPrefISize, since tables have two different ones.
    */
-  nscoord TableShrinkWidthToFit(nsRenderingContext *aRenderingContext,
+  nscoord TableShrinkISizeToFit(nsRenderingContext *aRenderingContext,
                                 nscoord aWidthInCB);
 
   // XXXldb REWRITE THIS COMMENT!
   /** inner tables are reflowed in two steps.
     * <pre>
     * if mFirstPassValid is false, this is our first time through since content was last changed
     *   set pass to 1
     *   do pass 1
@@ -365,17 +365,17 @@ public:
     */
   virtual void Reflow(nsPresContext*           aPresContext,
                       nsHTMLReflowMetrics&     aDesiredSize,
                       const nsHTMLReflowState& aReflowState,
                       nsReflowStatus&          aStatus) override;
 
   void ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
                    const nsHTMLReflowState& aReflowState,
-                   nscoord                  aAvailHeight,
+                   nscoord                  aAvailBSize,
                    nsIFrame*&               aLastChildReflowed,
                    nsReflowStatus&          aStatus);
 
   nsFrameList& GetColGroups();
 
   virtual nsStyleContext*
   GetParentStyleContext(nsIFrame** aProviderFrame) const override;
 
@@ -629,21 +629,21 @@ protected:
                       nsIFrame*&           aLastChildReflowed,
                       nsOverflowAreas&     aOverflowAreas);
 
   // This calls the col group and column reflow methods, which do two things:
   //  (1) set all the dimensions to 0
   //  (2) notify the table about colgroups or columns with hidden visibility
   void ReflowColGroups(nsRenderingContext* aRenderingContext);
 
-  /** return the width of the table taking into account visibility collapse
+  /** return the isize of the table taking into account visibility collapse
     * on columns and colgroups
     * @param aBorderPadding  the border and padding of the table
     */
-  nscoord GetCollapsedWidth(const WritingMode aWM,
+  nscoord GetCollapsedISize(const WritingMode aWM,
                             const LogicalMargin& aBorderPadding);
 
 
   /** Adjust the table for visibility.collapse set on rowgroups, rows,
     * colgroups and cols
     * @param aDesiredSize    the metrics of the table
     * @param aBorderPadding  the border and padding of the table
     */
@@ -676,31 +676,32 @@ private:
   /* Handle a row that got inserted during reflow.  aNewHeight is the
      new height of the table after reflow. */
   void ProcessRowInserted(nscoord aNewHeight);
 
   // WIDTH AND HEIGHT CALCULATION
 
 public:
 
-  // calculate the computed height of aFrame including its border and padding given
-  // its reflow state.
-  nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
+  // calculate the computed block-size of aFrame including its border and
+  // padding given its reflow state.
+  nscoord CalcBorderBoxBSize(const nsHTMLReflowState& aReflowState);
 
 protected:
 
-  // update the  desired height of this table taking into account the current
-  // reflow state, the table attributes and the content driven rowgroup heights
+  // update the  desired block-size of this table taking into account the current
+  // reflow state, the table attributes and the content driven rowgroup bsizes
   // this function can change the overflow area
-  void CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize);
+  void CalcDesiredBSize(const nsHTMLReflowState& aReflowState,
+                        nsHTMLReflowMetrics& aDesiredSize);
 
-  // The following is a helper for CalcDesiredHeight
+  // The following is a helper for CalcDesiredBSize
 
-  void DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
-                              nscoord                  aAmount);
+  void DistributeBSizeToRows(const nsHTMLReflowState& aReflowState,
+                             nscoord                  aAmount);
 
   void PlaceChild(nsTableReflowState&  aReflowState,
                   nsIFrame*            aKidFrame,
                   nsPoint              aKidPosition,
                   nsHTMLReflowMetrics& aKidDesiredSize,
                   const nsRect&        aOriginalKidRect,
                   const nsRect&        aOriginalKidVisualOverflow);
    void PlaceRepeatedFooter(nsTableReflowState& aReflowState,
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -853,17 +853,20 @@ nsTableRowFrame::ReflowChildren(nsPresCo
     prevColIndex = cellColIndex + (cellColSpan - 1);
 
     // Reflow the child frame
     nsRect kidRect = kidFrame->GetRect();
     LogicalPoint origKidNormalPosition =
       kidFrame->GetLogicalNormalPosition(wm, containerWidth);
     // All cells' no-relative-positioning position should be snapped to the
     // row's bstart edge.
-    MOZ_ASSERT(origKidNormalPosition.B(wm) == 0);
+    // XXX This currently doesn't hold in vertical-rl mode, which is probably
+    // a bug, but to enable progress with testing I'm temporarily neutering
+    // the assertion in that case (bug 1174711).
+    MOZ_ASSERT(origKidNormalPosition.B(wm) == 0 || wm.IsVerticalRL());
     nsRect kidVisualOverflow = kidFrame->GetVisualOverflowRect();
     LogicalPoint kidPosition(wm, iCoord, 0);
     bool firstReflow =
       (kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
 
     if (doReflowChild) {
       // Calculate the available isize for the table cell using the known
       // column isizes
@@ -1079,17 +1082,17 @@ nsTableRowFrame::Reflow(nsPresContext*  
 
   nsTableFrame* tableFrame = GetTableFrame();
   const nsStyleVisibility* rowVis = StyleVisibility();
   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
   if (collapseRow) {
     tableFrame->SetNeedToCollapse(true);
   }
 
-  // see if a special height reflow needs to occur due to having a pct height
+  // see if a special bsize reflow needs to occur due to having a pct bsize
   nsTableFrame::CheckRequestSpecialBSizeReflow(aReflowState);
 
   // See if we have a cell with specified/pct bsize
   InitHasCellWithStyleBSize(tableFrame);
 
   ReflowChildren(aPresContext, aDesiredSize, aReflowState, *tableFrame, aStatus);
 
   if (aPresContext->IsPaginated() && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) &&
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -419,17 +419,17 @@ nsTableRowGroupFrame::ReflowChildren(nsP
 
       if (!reflowAllKids) {
         if (IsSimpleRowFrame(aReflowState.tableFrame, kidFrame)) {
           // Inform the row of its new bsize.
           rowFrame->DidResize();
           // the overflow area may have changed inflate the overflow area
           const nsStylePosition *stylePos = StylePosition();
           nsStyleUnit unit = stylePos->BSize(wm).GetUnit();
-          if (aReflowState.tableFrame->IsAutoHeight() &&
+          if (aReflowState.tableFrame->IsAutoBSize(wm) &&
               unit != eStyleUnit_Coord) {
             // Because other cells in the row may need to be aligned
             // differently, repaint the entire row
             InvalidateFrame();
           } else if (oldKidRect.BSize(wm) != desiredSize.BSize(wm)) {
             needToCalcRowBSizes = true;
           }
         } else {
@@ -832,19 +832,19 @@ nsTableRowGroupFrame::CalculateRowBSizes
 
   DidResizeRows(aDesiredSize);
 
   aDesiredSize.BSize(wm) = rowGroupBSize; // Adjust our desired size
 }
 
 nscoord
 nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aBTotalOffset,
-                                                  nscoord aISize)
+                                                  nscoord aISize,
+                                                  WritingMode aWM)
 {
-  WritingMode wm = GetWritingMode(); // XXX pass from caller
   nsTableFrame* tableFrame = GetTableFrame();
   nscoord containerWidth = tableFrame->GetRect().width;
   const nsStyleVisibility* groupVis = StyleVisibility();
   bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
   if (collapseGroup) {
     tableFrame->SetNeedToCollapse(true);
   }
 
@@ -856,38 +856,38 @@ nsTableRowGroupFrame::CollapseRowGroupIf
   while (rowFrame) {
     bGroupOffset += rowFrame->CollapseRowIfNecessary(bGroupOffset,
                                                      aISize, collapseGroup,
                                                      didCollapse);
     ConsiderChildOverflow(overflow, rowFrame);
     rowFrame = rowFrame->GetNextRow();
   }
 
-  LogicalRect groupRect = GetLogicalRect(wm, containerWidth);
+  LogicalRect groupRect = GetLogicalRect(aWM, containerWidth);
   nsRect oldGroupRect = GetRect();
   nsRect oldGroupVisualOverflow = GetVisualOverflowRect();
 
-  groupRect.BSize(wm) -= bGroupOffset;
+  groupRect.BSize(aWM) -= bGroupOffset;
   if (didCollapse) {
     // add back the cellspacing between rowgroups
-    groupRect.BSize(wm) += tableFrame->GetRowSpacing(GetStartRowIndex() +
-                                                     GetRowCount());
+    groupRect.BSize(aWM) += tableFrame->GetRowSpacing(GetStartRowIndex() +
+                                                      GetRowCount());
   }
 
-  groupRect.BStart(wm) -= aBTotalOffset;
-  groupRect.ISize(wm) = aISize;
+  groupRect.BStart(aWM) -= aBTotalOffset;
+  groupRect.ISize(aWM) = aISize;
 
   if (aBTotalOffset != 0) {
     InvalidateFrameSubtree();
   }
 
-  SetRect(wm, groupRect, containerWidth);
-  overflow.UnionAllWith(nsRect(0, 0, groupRect.Width(wm),
-                               groupRect.Height(wm)));
-  FinishAndStoreOverflow(overflow, groupRect.Size(wm).GetPhysicalSize(wm));
+  SetRect(aWM, groupRect, containerWidth);
+  overflow.UnionAllWith(nsRect(0, 0, groupRect.Width(aWM),
+                               groupRect.Height(aWM)));
+  FinishAndStoreOverflow(overflow, groupRect.Size(aWM).GetPhysicalSize(aWM));
   nsTableFrame::RePositionViews(this);
   nsTableFrame::InvalidateTableFrame(this, oldGroupRect, oldGroupVisualOverflow,
                                      false);
 
   return bGroupOffset;
 }
 
 // Move a child that was skipped during a reflow.
@@ -1325,17 +1325,17 @@ nsTableRowGroupFrame::Reflow(nsPresConte
   DO_GLOBAL_REFLOW_COUNT("nsTableRowGroupFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
   aStatus     = NS_FRAME_COMPLETE;
 
   // Row geometry may be going to change so we need to invalidate any row cursor.
   ClearRowCursor();
 
-  // see if a special height reflow needs to occur due to having a pct height
+  // see if a special bsize reflow needs to occur due to having a pct bsize
   nsTableFrame::CheckRequestSpecialBSizeReflow(aReflowState);
 
   nsTableFrame* tableFrame = GetTableFrame();
   nsRowGroupReflowState state(aReflowState, tableFrame);
   const nsStyleVisibility* groupVis = StyleVisibility();
   bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
   if (collapseGroup) {
     tableFrame->SetNeedToCollapse(true);
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -177,26 +177,28 @@ public:
 
   /**
    * Sets full border widths before collapsing with cell borders
    * @param aForSide - side to set; only IEnd, IStart, BEnd are valid
    */
   void SetContinuousBCBorderWidth(mozilla::LogicalSide aForSide,
                                   BCPixelSize aPixelValue);
   /**
-    * Adjust to the effect of visibibility:collapse on the row group and
+    * Adjust to the effect of visibility:collapse on the row group and
     * its children
     * @return              additional shift bstart-wards that should be applied
     *                      to subsequent rowgroups due to rows and this
     *                      rowgroup being collapsed
     * @param aBTotalOffset the total amount that the rowgroup is shifted
     * @param aISize        new isize of the rowgroup
+    * @param aWM           the table's writing mode
     */
   nscoord CollapseRowGroupIfNecessary(nscoord aBTotalOffset,
-                                      nscoord aISize);
+                                      nscoord aISize,
+                                      mozilla::WritingMode aWM);
 
 // nsILineIterator methods
 public:
   virtual void DisposeLineIterator() override { }
 
   // The table row is the equivalent to a line in block layout.
   // The nsILineIterator assumes that a line resides in a block, this role is
   // fullfilled by the row group. Rows in table are counted relative to the