bug 781409 - remove nsITableLayout r=roc,davidb
authorTrevor Saunders <trev.saunders@gmail.com>
Wed, 08 Aug 2012 09:05:17 -0400
changeset 125144 3d898c39d05e155caab76d6635f8ecf4de3ad35a
parent 125143 6fe5b65e41ed5a97665838b0fd03e0c7f254631a
child 125145 fe5784e9e50bb6eddfa7afda5b4d3e854638ea88
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, davidb
bugs781409
milestone20.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 781409 - remove nsITableLayout r=roc,davidb
accessible/src/html/HTMLTableAccessible.cpp
accessible/src/html/HTMLTableAccessible.h
accessible/src/html/Makefile.in
editor/libeditor/html/Makefile.in
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/html/nsTableEditor.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsFrame.cpp
layout/generic/nsFrameSelection.h
layout/generic/nsSelection.cpp
layout/mathml/nsMathMLmtableFrame.cpp
layout/tables/Makefile.in
layout/tables/nsCellMap.cpp
layout/tables/nsITableLayout.h
layout/tables/nsTableCellFrame.cpp
layout/tables/nsTableCellFrame.h
layout/tables/nsTableColFrame.h
layout/tables/nsTableColGroupFrame.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -25,22 +25,23 @@
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDOMHTMLTableCellElement.h"
 #include "nsIDOMHTMLTableElement.h"
 #include "nsIDOMHTMLTableRowElement.h"
 #include "nsIDOMHTMLTableSectionElem.h"
 #include "nsIDocument.h"
 #include "nsIMutableArray.h"
 #include "nsIPresShell.h"
-#include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
 #include "nsFrameSelection.h"
 #include "nsError.h"
 #include "nsArrayUtils.h"
 #include "nsComponentManagerUtils.h"
+#include "nsTableCellFrame.h"
+#include "nsTableOuterFrame.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -466,62 +467,45 @@ HTMLTableAccessible::Summary(nsString& a
 
   if (table)
     table->GetSummary(aSummary);
 }
 
 uint32_t
 HTMLTableAccessible::ColCount()
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-  if (!tableLayout)
-    return 0;
-
-  int32_t rowCount = 0, colCount = 0;
-  tableLayout->GetTableSize(rowCount, colCount);
-  return colCount;
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  return tableFrame ? tableFrame->GetColCount() : 0;
 }
 
 uint32_t
 HTMLTableAccessible::RowCount()
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-  if (!tableLayout)
-    return 0;
-
-  int32_t rowCount = 0, colCount = 0;
-  tableLayout->GetTableSize(rowCount, colCount);
-  return rowCount;
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  return tableFrame ? tableFrame->GetRowCount() : 0;
 }
 
 uint32_t
 HTMLTableAccessible::SelectedCellCount()
 {
-  nsITableLayout *tableLayout = GetTableLayout();
-  if (!tableLayout)
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return 0;
 
   uint32_t count = 0, rowCount = RowCount(), colCount = ColCount();
-
-  nsCOMPtr<nsIDOMElement> domElement;
-  int32_t startRowIndex = 0, startColIndex = 0,
-    rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool isSelected = false;
-
   for (uint32_t rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (uint32_t colIdx = 0; colIdx < colCount; colIdx++) {
-      nsresult rv = tableLayout->GetCellDataAt(rowIdx, colIdx,
-                                               *getter_AddRefs(domElement),
-                                               startRowIndex, startColIndex,
-                                               rowSpan, colSpan,
-                                               actualRowSpan, actualColSpan,
-                                               isSelected);
+      nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(rowIdx, colIdx);
+      if (!cellFrame || !cellFrame->IsSelected())
+        continue;
 
-      if (NS_SUCCEEDED(rv) && startRowIndex == rowIdx &&
-          startColIndex == colIdx && isSelected)
+      int32_t startRow = -1, startCol = -1;
+      cellFrame->GetRowIndex(startRow);
+      cellFrame->GetColIndex(startCol);
+      if (startRow == rowIdx && startCol == colIdx)
         count++;
     }
   }
 
   return count;
 }
 
 uint32_t
@@ -546,71 +530,57 @@ HTMLTableAccessible::SelectedRowCount()
       count++;
 
   return count;
 }
 
 void
 HTMLTableAccessible::SelectedCells(nsTArray<Accessible*>* aCells)
 {
-  uint32_t rowCount = RowCount(), colCount = ColCount();
-
-  nsITableLayout *tableLayout = GetTableLayout();
-  if (!tableLayout) 
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return;
 
-  nsCOMPtr<nsIDOMElement> cellElement;
-  int32_t startRowIndex = 0, startColIndex = 0,
-    rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool isSelected = false;
-
+  uint32_t rowCount = RowCount(), colCount = ColCount();
   for (uint32_t rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (uint32_t colIdx = 0; colIdx < colCount; colIdx++) {
-      nsresult rv = tableLayout->GetCellDataAt(rowIdx, colIdx,
-                                      *getter_AddRefs(cellElement),
-                                      startRowIndex, startColIndex,
-                                      rowSpan, colSpan,
-                                      actualRowSpan, actualColSpan,
-                                      isSelected);
+      nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(rowIdx, colIdx);
+      if (!cellFrame || !cellFrame->IsSelected())
+        continue;
 
-      if (NS_SUCCEEDED(rv) && startRowIndex == rowIdx &&
-          startColIndex == colIdx && isSelected) {
-        nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
-        Accessible* cell = mDoc->GetAccessible(cellContent);
+      int32_t startCol = -1, startRow = -1;
+      cellFrame->GetRowIndex(startRow);
+      cellFrame->GetColIndex(startCol);
+      if (startRow != rowIdx || startCol != colIdx)
+        continue;
+
+      Accessible* cell = mDoc->GetAccessible(cellFrame->GetContent());
         aCells->AppendElement(cell);
-      }
     }
   }
 }
 
 void
 HTMLTableAccessible::SelectedCellIndices(nsTArray<uint32_t>* aCells)
 {
-  nsITableLayout *tableLayout = GetTableLayout();
-  if (!tableLayout)
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return;
 
   uint32_t rowCount = RowCount(), colCount = ColCount();
-
-  nsCOMPtr<nsIDOMElement> domElement;
-  int32_t startRowIndex = 0, startColIndex = 0,
-    rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool isSelected = false;
-
   for (uint32_t rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (uint32_t colIdx = 0; colIdx < colCount; colIdx++) {
-      nsresult rv = tableLayout->GetCellDataAt(rowIdx, colIdx,
-                                               *getter_AddRefs(domElement),
-                                               startRowIndex, startColIndex,
-                                               rowSpan, colSpan,
-                                               actualRowSpan, actualColSpan,
-                                               isSelected);
+      nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(rowIdx, colIdx);
+      if (!cellFrame || !cellFrame->IsSelected())
+        continue;
 
-      if (NS_SUCCEEDED(rv) && startRowIndex == rowIdx &&
-          startColIndex == colIdx && isSelected)
+      int32_t startRow = -1, startCol = -1;
+      cellFrame->GetColIndex(startCol);
+      cellFrame->GetRowIndex(startRow);
+      if (startRow == rowIdx && startCol == colIdx)
         aCells->AppendElement(CellIndexAt(rowIdx, colIdx));
     }
   }
 }
 
 void
 HTMLTableAccessible::SelectedColIndices(nsTArray<uint32_t>* aCols)
 {
@@ -625,118 +595,91 @@ HTMLTableAccessible::SelectedRowIndices(
 {
   uint32_t rowCount = RowCount();
   for (uint32_t rowIdx = 0; rowIdx < rowCount; rowIdx++)
     if (IsRowSelected(rowIdx))
       aRows->AppendElement(rowIdx);
 }
 
 Accessible*
-HTMLTableAccessible::CellAt(uint32_t aRowIndex, uint32_t aColumnIndex)
-{ 
-  nsCOMPtr<nsIDOMElement> cellElement;
-  GetCellAt(aRowIndex, aColumnIndex, *getter_AddRefs(cellElement));
-  if (!cellElement)
+HTMLTableAccessible::CellAt(uint32_t aRowIdx, uint32_t aColIdx)
+{
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return nullptr;
 
-  nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
-  if (!cellContent)
-    return nullptr;
-
+  nsIContent* cellContent = tableFrame->GetCellAt(aRowIdx, aColIdx);
   Accessible* cell = mDoc->GetAccessible(cellContent);
 
   // XXX bug 576838: crazy tables (like table6 in tables/test_table2.html) may
   // return itself as a cell what makes Orca hang.
   return cell == this ? nullptr : cell;
 }
 
 int32_t
 HTMLTableAccessible::CellIndexAt(uint32_t aRowIdx, uint32_t aColIdx)
 {
-  nsITableLayout* tableLayout = GetTableLayout();
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
+    return -1;
 
-  int32_t index = -1;
-  tableLayout->GetIndexByRowAndColumn(aRowIdx, aColIdx, &index);
-  return index;
+  return tableFrame->GetIndexByRowAndColumn(aRowIdx, aColIdx);
 }
 
 int32_t
 HTMLTableAccessible::ColIndexAt(uint32_t aCellIdx)
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-  if (!tableLayout) 
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return -1;
 
   int32_t rowIdx = -1, colIdx = -1;
-  tableLayout->GetRowAndColumnByIndex(aCellIdx, &rowIdx, &colIdx);
+  tableFrame->GetRowAndColumnByIndex(aCellIdx, &rowIdx, &colIdx);
   return colIdx;
 }
 
 int32_t
 HTMLTableAccessible::RowIndexAt(uint32_t aCellIdx)
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-  if (!tableLayout) 
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return -1;
 
   int32_t rowIdx = -1, colIdx = -1;
-  tableLayout->GetRowAndColumnByIndex(aCellIdx, &rowIdx, &colIdx);
+  tableFrame->GetRowAndColumnByIndex(aCellIdx, &rowIdx, &colIdx);
   return rowIdx;
 }
 
 void
 HTMLTableAccessible::RowAndColIndicesAt(uint32_t aCellIdx, int32_t* aRowIdx,
                                         int32_t* aColIdx)
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-
-  if (tableLayout)
-    tableLayout->GetRowAndColumnByIndex(aCellIdx, aRowIdx, aColIdx);
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (tableFrame)
+    tableFrame->GetRowAndColumnByIndex(aCellIdx, aRowIdx, aColIdx);
 }
 
 uint32_t
 HTMLTableAccessible::ColExtentAt(uint32_t aRowIdx, uint32_t aColIdx)
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-  if (!tableLayout)
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return 0;
 
-  nsCOMPtr<nsIDOMElement> domElement;
-  int32_t startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan;
-  bool isSelected;
-  int32_t columnExtent = 0;
-
-  DebugOnly<nsresult> rv = tableLayout->
-    GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
-                  startRowIndex, startColIndex, rowSpan, colSpan,
-                  actualRowSpan, columnExtent, isSelected);
-  NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get cell data");
-
-  return columnExtent;
+  return tableFrame->GetEffectiveColSpanAt(aRowIdx, aColIdx);
 }
 
 uint32_t
 HTMLTableAccessible::RowExtentAt(uint32_t aRowIdx, uint32_t aColIdx)
 {
-  nsITableLayout* tableLayout = GetTableLayout();
-  if (!tableLayout)
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return 0;
 
-  nsCOMPtr<nsIDOMElement> domElement;
-  int32_t startRowIndex, startColIndex, rowSpan, colSpan, actualColSpan;
-  bool isSelected;
-  int32_t rowExtent = 0;
-
-  DebugOnly<nsresult> rv = tableLayout->
-    GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
-                  startRowIndex, startColIndex, rowSpan, colSpan,
-                  rowExtent, actualColSpan, isSelected);
-  NS_ASSERTION(NS_SUCCEEDED(rv), "Could not get cell data");
-
-  return rowExtent;
+  return tableFrame->GetEffectiveRowSpanAt(aRowIdx, aColIdx);
 }
 
 bool
 HTMLTableAccessible::IsColSelected(uint32_t aColIdx)
 {
   bool isSelected = false;
 
   uint32_t rowCount = RowCount();
@@ -762,30 +705,22 @@ HTMLTableAccessible::IsRowSelected(uint3
   }
 
   return isSelected;
 }
 
 bool
 HTMLTableAccessible::IsCellSelected(uint32_t aRowIdx, uint32_t aColIdx)
 {
-  nsITableLayout *tableLayout = GetTableLayout();
-  if (!tableLayout)
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
     return false;
 
-  nsCOMPtr<nsIDOMElement> domElement;
-  int32_t startRowIndex = 0, startColIndex = 0,
-          rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool isSelected = false;
-
-  tableLayout->GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
-                             startRowIndex, startColIndex, rowSpan, colSpan,
-                             actualRowSpan, actualColSpan, isSelected);
-
-  return isSelected;
+  nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(aRowIdx, aColIdx);
+  return cellFrame ? cellFrame->IsSelected() : false;
 }
 
 void
 HTMLTableAccessible::SelectRow(uint32_t aRowIdx)
 {
   nsresult rv =
     RemoveRowsOrColumnsFromSelection(aRowIdx,
                                      nsISelectionPrivate::TABLESELECTION_ROW,
@@ -825,120 +760,74 @@ HTMLTableAccessible::UnselectCol(uint32_
                                    false);
 }
 
 nsresult
 HTMLTableAccessible::AddRowOrColumnToSelection(int32_t aIndex, uint32_t aTarget)
 {
   bool doSelectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
 
-  nsITableLayout *tableLayout = GetTableLayout();
-  NS_ENSURE_STATE(tableLayout);
-
-  nsCOMPtr<nsIDOMElement> cellElm;
-  int32_t startRowIdx, startColIdx, rowSpan, colSpan,
-    actualRowSpan, actualColSpan;
-  bool isSelected = false;
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
+    return NS_OK;
 
-  nsresult rv = NS_OK;
-  int32_t count = 0;
+  uint32_t count = 0;
   if (doSelectRow)
-    rv = GetColumnCount(&count);
+    count = ColCount();
   else
-    rv = GetRowCount(&count);
-
-  NS_ENSURE_SUCCESS(rv, rv);
+    count = RowCount();
 
   nsIPresShell* presShell(mDoc->PresShell());
   nsRefPtr<nsFrameSelection> tableSelection =
     const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
-  for (int32_t idx = 0; idx < count; idx++) {
+  for (uint32_t idx = 0; idx < count; idx++) {
     int32_t rowIdx = doSelectRow ? aIndex : idx;
     int32_t colIdx = doSelectRow ? idx : aIndex;
-    rv = tableLayout->GetCellDataAt(rowIdx, colIdx,
-                                    *getter_AddRefs(cellElm),
-                                    startRowIdx, startColIdx,
-                                    rowSpan, colSpan,
-                                    actualRowSpan, actualColSpan,
-                                    isSelected);
-
-    if (NS_SUCCEEDED(rv) && !isSelected) {
-      nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElm));
-      rv = tableSelection->SelectCellElement(cellContent);
+    nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(rowIdx, colIdx);
+    if (cellFrame && !cellFrame->IsSelected()) {
+      nsresult rv = tableSelection->SelectCellElement(cellFrame->GetContent());
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 HTMLTableAccessible::RemoveRowsOrColumnsFromSelection(int32_t aIndex,
                                                       uint32_t aTarget,
                                                       bool aIsOuter)
 {
-  nsITableLayout *tableLayout = GetTableLayout();
-  NS_ENSURE_STATE(tableLayout);
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
+    return NS_OK;
 
   nsIPresShell* presShell(mDoc->PresShell());
   nsRefPtr<nsFrameSelection> tableSelection =
     const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
   bool doUnselectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
-  int32_t count = 0;
-  nsresult rv = doUnselectRow ? GetColumnCount(&count) : GetRowCount(&count);
-  NS_ENSURE_SUCCESS(rv, rv);
+  uint32_t count = doUnselectRow ? ColCount() : RowCount();
 
   int32_t startRowIdx = doUnselectRow ? aIndex : 0;
   int32_t endRowIdx = doUnselectRow ? aIndex : count - 1;
   int32_t startColIdx = doUnselectRow ? 0 : aIndex;
   int32_t endColIdx = doUnselectRow ? count - 1 : aIndex;
 
   if (aIsOuter)
     return tableSelection->RestrictCellsToSelection(mContent,
                                                     startRowIdx, startColIdx,
                                                     endRowIdx, endColIdx);
 
   return tableSelection->RemoveCellsFromSelection(mContent,
                                                   startRowIdx, startColIdx,
                                                   endRowIdx, endColIdx);
 }
 
-nsITableLayout*
-HTMLTableAccessible::GetTableLayout()
-{
-  nsIFrame *frame = mContent->GetPrimaryFrame();
-  if (!frame)
-    return nullptr;
-
-  nsITableLayout *tableLayout = do_QueryFrame(frame);
-  return tableLayout;
-}
-
-nsresult
-HTMLTableAccessible::GetCellAt(int32_t aRowIndex, int32_t aColIndex,
-                               nsIDOMElement*& aCell)
-{
-  int32_t startRowIndex = 0, startColIndex = 0,
-          rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool isSelected;
-
-  nsITableLayout *tableLayout = GetTableLayout();
-  NS_ENSURE_STATE(tableLayout);
-
-  nsresult rv = tableLayout->
-    GetCellDataAt(aRowIndex, aColIndex, aCell, startRowIndex, startColIndex,
-                  rowSpan, colSpan, actualRowSpan, actualColSpan, isSelected);
-
-  if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
-    return NS_ERROR_INVALID_ARG;
-  return rv;
-}
-
 void
 HTMLTableAccessible::Description(nsString& aDescription)
 {
   // Helpful for debugging layout vs. data tables
   aDescription.Truncate();
   Accessible::Description(aDescription);
   if (!aDescription.IsEmpty())
     return;
@@ -1135,26 +1024,24 @@ HTMLTableAccessible::IsProbablyLayoutTab
   // Check for many columns
   if (columns >= 5) {
     RETURN_LAYOUT_ANSWER(false, ">=5 columns");
   }
 
   // Now we know there are 2-4 columns and 2 or more rows
   // Check to see if there are visible borders on the cells
   // XXX currently, we just check the first cell -- do we really need to do more?
-  nsCOMPtr<nsIDOMElement> cellElement;
-  nsresult rv = GetCellAt(0, 0, *getter_AddRefs(cellElement));
-  NS_ENSURE_SUCCESS(rv, false);
+  nsTableOuterFrame* tableFrame = do_QueryFrame(mContent->GetPrimaryFrame());
+  if (!tableFrame)
+    RETURN_LAYOUT_ANSWER(false, "table with no frame!");
 
-  nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
-  NS_ENSURE_TRUE(cellContent, false);
-  nsIFrame *cellFrame = cellContent->GetPrimaryFrame();
-  if (!cellFrame) {
-    RETURN_LAYOUT_ANSWER(false, "Could not get frame for cellContent");
-  }
+  nsIFrame* cellFrame = tableFrame->GetCellFrameAt(0, 0);
+  if (!cellFrame)
+    RETURN_LAYOUT_ANSWER(false, "table's first cell has no frame!");
+
   nsMargin border;
   cellFrame->GetBorder(border);
   if (border.top && border.bottom && border.left && border.right) {
     RETURN_LAYOUT_ANSWER(false, "Has nonzero border-width on table cell");
   }
 
   /**
    * Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -161,29 +161,16 @@ public:
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
   virtual void Description(nsString& aDescription);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual Relation RelationByType(uint32_t aRelationType);
 
-  // HTMLTableAccessible
-
-  /**
-   * Retun cell element at the given row and column index.
-   */
-  nsresult GetCellAt(int32_t aRowIndex, int32_t aColIndex,
-                     nsIDOMElement* &aCell);
-
-  /**
-   * Return nsITableLayout for the frame of the accessible table.
-   */
-  nsITableLayout* GetTableLayout();
-
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren();
 
   // HTMLTableAccessible
 
   /**
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -34,16 +34,17 @@ include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../base \
   -I$(srcdir)/../generic \
   -I$(srcdir)/../xpcom \
   -I$(srcdir)/../../../content/base/src \
   -I$(srcdir)/../../../content/html/content/src \
   -I$(srcdir)/../../../layout/generic \
+  -I$(srcdir)/../../../layout/tables \
   -I$(srcdir)/../../../layout/xul/base/src \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 LOCAL_INCLUDES += \
   -I$(srcdir)/../atk \
   $(NULL)
 else
--- a/editor/libeditor/html/Makefile.in
+++ b/editor/libeditor/html/Makefile.in
@@ -55,8 +55,14 @@ FORCE_STATIC_LIB = 1
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES        += -I$(topsrcdir)/editor/libeditor/base \
                    -I$(topsrcdir)/editor/libeditor/text \
                    -I$(topsrcdir)/editor/txmgr/src \
                    -I$(topsrcdir)/content/base/src \
                    -I$(topsrcdir)/layout/style \
                    $(NULL)
+
+LOCAL_INCLUDES += \
+  -I$(topsrcdir)/layout/generic \
+  -I$(topsrcdir)/layout/tables \
+  -I$(topsrcdir)/layout/xul/base/src \
+  $(null)
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -15,17 +15,16 @@
 #include "nsIEditorMailSupport.h"
 #include "nsIEditorStyleSheets.h"
 #include "nsITextServicesDocument.h"
 
 #include "nsEditor.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEventListener.h"
 #include "nsICSSLoaderObserver.h"
-#include "nsITableLayout.h"
 
 #include "nsEditRules.h"
 
 #include "nsEditProperty.h"
 #include "nsHTMLCSSUtils.h"
 
 #include "nsHTMLObjectResizer.h"
 #include "nsIHTMLAbsPosEditor.h"
@@ -47,16 +46,17 @@
 class nsIDOMKeyEvent;
 class nsITransferable;
 class nsIDocumentEncoder;
 class nsIClipboard;
 class TypeInState;
 class nsIContentFilter;
 class nsIURL;
 class nsILinkHandler;
+class nsTableOuterFrame;
 struct PropItem;
 
 namespace mozilla {
 namespace widget {
 struct IMEState;
 } // namespace widget
 } // namespace mozilla
 
@@ -436,18 +436,18 @@ protected:
 
   // Move all contents from aCellToMerge into aTargetCell (append at end)
   NS_IMETHOD MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell, nsCOMPtr<nsIDOMElement> aCellToMerge, bool aDeleteCellToMerge);
 
   NS_IMETHOD DeleteTable2(nsIDOMElement *aTable, nsISelection *aSelection);
   NS_IMETHOD SetColSpan(nsIDOMElement *aCell, int32_t aColSpan);
   NS_IMETHOD SetRowSpan(nsIDOMElement *aCell, int32_t aRowSpan);
 
-  // Helper used to get nsITableLayout interface for methods implemented in nsTableFrame
-  NS_IMETHOD GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **tableLayoutObject);
+  // Helper used to get nsTableOuterFrame for a table.
+  nsTableOuterFrame* GetTableFrame(nsIDOMElement* aTable);
   // Needed to do appropriate deleting when last cell or row is about to be deleted
   // This doesn't count cells that don't start in the given row (are spanning from row above)
   int32_t  GetNumberOfCellsInRow(nsIDOMElement* aTable, int32_t rowIndex);
   // Test if all cells in row or column at given index are selected
   bool AllCellsInRowSelected(nsIDOMElement *aTable, int32_t aRowIndex, int32_t aNumberOfColumns);
   bool AllCellsInColumnSelected(nsIDOMElement *aTable, int32_t aColIndex, int32_t aNumberOfRows);
 
   bool IsEmptyCell(mozilla::dom::Element* aCell);
--- a/editor/libeditor/html/nsTableEditor.cpp
+++ b/editor/libeditor/html/nsTableEditor.cpp
@@ -27,21 +27,22 @@
 #include "nsIEditor.h"
 #include "nsIFrame.h"
 #include "nsIHTMLEditor.h"
 #include "nsINode.h"
 #include "nsIPresShell.h"
 #include "nsISupportsUtils.h"
 #include "nsITableCellLayout.h" // For efficient access to table cell
 #include "nsITableEditor.h"
-#include "nsITableLayout.h"     //  data owned by the table and cell frames
 #include "nsLiteralString.h"
 #include "nsQueryFrame.h"
 #include "nsString.h"
 #include "nsTArray.h"
+#include "nsTableCellFrame.h"
+#include "nsTableOuterFrame.h"
 #include "nscore.h"
 
 using namespace mozilla;
 
 /***************************************************************************
  * stack based helper class for restoring selection after table edit
  */
 class NS_STACK_CLASS nsSetSelectionAfterTableEdit
@@ -2602,33 +2603,24 @@ nsHTMLEditor::GetCellIndexes(nsIDOMEleme
   nsIFrame *layoutObject = nodeAsContent->GetPrimaryFrame();
   NS_ENSURE_TRUE(layoutObject, NS_ERROR_FAILURE);
 
   nsITableCellLayout *cellLayoutObject = do_QueryFrame(layoutObject);
   NS_ENSURE_TRUE(cellLayoutObject, NS_ERROR_FAILURE);
   return cellLayoutObject->GetCellIndexes(*aRowIndex, *aColIndex);
 }
 
-NS_IMETHODIMP
-nsHTMLEditor::GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **tableLayoutObject)
+nsTableOuterFrame*
+nsHTMLEditor::GetTableFrame(nsIDOMElement* aTable)
 {
-  *tableLayoutObject = nullptr;
-  NS_ENSURE_TRUE(aTable, NS_ERROR_NOT_INITIALIZED);
-  NS_ENSURE_TRUE(mDocWeak, NS_ERROR_NOT_INITIALIZED);
-  nsCOMPtr<nsIPresShell> ps = GetPresShell();
-  NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
+  NS_ENSURE_TRUE(aTable, nullptr);
 
   nsCOMPtr<nsIContent> nodeAsContent( do_QueryInterface(aTable) );
-  NS_ENSURE_TRUE(nodeAsContent, NS_ERROR_FAILURE);
-  // frames are not ref counted, so don't use an nsCOMPtr
-  nsIFrame *layoutObject = nodeAsContent->GetPrimaryFrame();
-  NS_ENSURE_TRUE(layoutObject, NS_ERROR_FAILURE);
-
-  *tableLayoutObject = do_QueryFrame(layoutObject);
-  return *tableLayoutObject ? NS_OK : NS_NOINTERFACE;
+  NS_ENSURE_TRUE(nodeAsContent, nullptr);
+  return do_QueryFrame(nodeAsContent->GetPrimaryFrame());
 }
 
 //Return actual number of cells (a cell with colspan > 1 counts as just 1)
 int32_t nsHTMLEditor::GetNumberOfCellsInRow(nsIDOMElement* aTable, int32_t rowIndex)
 {
   int32_t cellCount = 0;
   nsCOMPtr<nsIDOMElement> cell;
   int32_t colIndex = 0;
@@ -2670,23 +2662,23 @@ nsHTMLEditor::GetTableSize(nsIDOMElement
   *aRowCount = 0;
   *aColCount = 0;
   nsCOMPtr<nsIDOMElement> table;
   // Get the selected talbe or the table enclosing the selection anchor
   res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(table, NS_ERROR_FAILURE);
   
-  // frames are not ref counted, so don't use an nsCOMPtr
-  nsITableLayout *tableLayoutObject;
-  res = GetTableLayoutObject(table.get(), &tableLayoutObject);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(tableLayoutObject, NS_ERROR_FAILURE);
-
-  return tableLayoutObject->GetTableSize(*aRowCount, *aColCount); 
+  nsTableOuterFrame* tableFrame = GetTableFrame(table.get());
+  NS_ENSURE_TRUE(tableFrame, NS_ERROR_FAILURE);
+
+  *aRowCount = tableFrame->GetRowCount();
+  *aColCount = tableFrame->GetColCount();
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLEditor::GetCellDataAt(nsIDOMElement* aTable, int32_t aRowIndex,
                             int32_t aColIndex, nsIDOMElement **aCell, 
                             int32_t* aStartRowIndex, int32_t* aStartColIndex, 
                             int32_t* aRowSpan, int32_t* aColSpan, 
                             int32_t* aActualRowSpan, int32_t* aActualColSpan, 
@@ -2719,63 +2711,68 @@ nsHTMLEditor::GetCellDataAt(nsIDOMElemen
     res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), nullptr, getter_AddRefs(table));
     NS_ENSURE_SUCCESS(res, res);
     if (table)
       aTable = table;
     else
       return NS_ERROR_FAILURE;
   }
   
-  // frames are not ref counted, so don't use an nsCOMPtr
-  nsITableLayout *tableLayoutObject;
-  res = GetTableLayoutObject(aTable, &tableLayoutObject);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(tableLayoutObject, NS_ERROR_FAILURE);
-
-  // Note that this returns NS_TABLELAYOUT_CELL_NOT_FOUND when
-  //  the index(es) are out of bounds
-  nsCOMPtr<nsIDOMElement> cell;
-  res = tableLayoutObject->GetCellDataAt(aRowIndex, aColIndex,
-                                         *getter_AddRefs(cell), 
-                                         *aStartRowIndex, *aStartColIndex,
-                                         *aRowSpan, *aColSpan, 
-                                         *aActualRowSpan, *aActualColSpan, 
-                                         *aIsSelected);
-  if (cell)
-  {
-    *aCell = cell.get();
-    NS_ADDREF(*aCell);
-  }
-  // Convert to editor's generic "not found" return value
-  if (res == NS_TABLELAYOUT_CELL_NOT_FOUND) res = NS_EDITOR_ELEMENT_NOT_FOUND;
-  return res;
+  nsTableOuterFrame* tableFrame = GetTableFrame(aTable);
+  NS_ENSURE_TRUE(tableFrame, NS_ERROR_FAILURE);
+
+  nsTableCellFrame* cellFrame =
+    tableFrame->GetCellFrameAt(aRowIndex, aColIndex);
+  if (!cellFrame)
+    return NS_ERROR_FAILURE;
+
+  *aIsSelected = cellFrame->IsSelected();
+  cellFrame->GetRowIndex(*aStartRowIndex);
+  cellFrame->GetColIndex(*aStartColIndex);
+  *aRowSpan = cellFrame->GetRowSpan();
+  *aColSpan = cellFrame->GetColSpan();
+  *aActualRowSpan = tableFrame->GetEffectiveRowSpanAt(aRowIndex, aColIndex);
+  *aActualColSpan = tableFrame->GetEffectiveColSpanAt(aRowIndex, aColIndex);
+  nsCOMPtr<nsIDOMElement> domCell = do_QueryInterface(cellFrame->GetContent());
+  domCell.forget(aCell);
+
+  return NS_OK;
 }
 
 // When all you want is the cell
 NS_IMETHODIMP 
 nsHTMLEditor::GetCellAt(nsIDOMElement* aTable, int32_t aRowIndex, int32_t aColIndex, nsIDOMElement **aCell)
 {
-  int32_t startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool    isSelected;
-  return GetCellDataAt(aTable, aRowIndex, aColIndex, aCell, 
-                       &startRowIndex, &startColIndex, &rowSpan, &colSpan, 
-                       &actualRowSpan, &actualColSpan, &isSelected);
+  NS_ENSURE_ARG_POINTER(aCell);
+  *aCell = nullptr;
+
+  nsTableOuterFrame* tableFrame = GetTableFrame(aTable);
+  if (!tableFrame)
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMElement> domCell =
+    do_QueryInterface(tableFrame->GetCellAt(aRowIndex, aColIndex));
+  domCell.forget(aCell);
+
+  return NS_OK;
 }
 
 // When all you want are the rowspan and colspan (not exposed in nsITableEditor)
 NS_IMETHODIMP
 nsHTMLEditor::GetCellSpansAt(nsIDOMElement* aTable, int32_t aRowIndex, int32_t aColIndex, 
                              int32_t& aActualRowSpan, int32_t& aActualColSpan)
 {
-  nsCOMPtr<nsIDOMElement> cell;    
-  int32_t startRowIndex, startColIndex, rowSpan, colSpan;
-  bool    isSelected;
-  return GetCellDataAt(aTable, aRowIndex, aColIndex, getter_AddRefs(cell), 
-                       &startRowIndex, &startColIndex, &rowSpan, &colSpan, 
-                       &aActualRowSpan, &aActualColSpan, &isSelected);
+  nsTableOuterFrame* tableFrame = GetTableFrame(aTable);
+  if (!tableFrame)
+    return NS_ERROR_FAILURE;
+
+  aActualRowSpan = tableFrame->GetEffectiveRowSpanAt(aRowIndex, aColIndex);
+  aActualColSpan = tableFrame->GetEffectiveColSpanAt(aRowIndex, aColIndex);
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::GetCellContext(nsISelection **aSelection,
                              nsIDOMElement   **aTable,
                              nsIDOMElement   **aCell,
                              nsIDOMNode      **aCellParent, int32_t *aCellOffset,
                              int32_t *aRowIndex, int32_t *aColIndex)
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -9,16 +9,17 @@
  * tree and updating of that tree in response to dynamic changes
  */
 
 #include "mozilla/Util.h"
 #include "mozilla/Likely.h"
 #include "mozilla/LinkedList.h"
 
 #include "nsCSSFrameConstructor.h"
+#include "nsAbsoluteContainingBlock.h"
 #include "nsCRT.h"
 #include "nsIAtom.h"
 #include "nsIURL.h"
 #include "nsHashtable.h"
 #include "nsIHTMLDocument.h"
 #include "nsIStyleRule.h"
 #include "nsIFrame.h"
 #include "nsGkAtoms.h"
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -6,16 +6,17 @@
 
 /*
  * rendering object for CSS display:block, inline-block, and list-item
  * boxes, also used for various anonymous boxes
  */
 
 #include "nsCOMPtr.h"
 #include "nsBlockFrame.h"
+#include "nsAbsoluteContainingBlock.h"
 #include "nsBlockReflowContext.h"
 #include "nsBlockReflowState.h"
 #include "nsBulletFrame.h"
 #include "nsLineBox.h"
 #include "nsInlineFrame.h"
 #include "nsLineLayout.h"
 #include "nsPlaceholderFrame.h"
 #include "nsStyleConsts.h"
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -9,17 +9,16 @@
  * boxes, also used for various anonymous boxes
  */
 
 #ifndef nsBlockFrame_h___
 #define nsBlockFrame_h___
 
 #include "nsContainerFrame.h"
 #include "nsHTMLParts.h"
-#include "nsAbsoluteContainingBlock.h"
 #include "nsLineBox.h"
 #include "nsCSSPseudoElements.h"
 #include "nsStyleSet.h"
 #include "nsFloatManager.h"
 
 enum LineReflowStatus {
   // The line was completely reflowed and fit in available width, and we should
   // try to pull up content from the next line if possible.
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* base class #1 for rendering objects that have child lists */
 
 #include "nsContainerFrame.h"
 
+#include "nsAbsoluteContainingBlock.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsRect.h"
 #include "nsPoint.h"
 #include "nsGUIEvent.h"
 #include "nsStyleConsts.h"
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -15,16 +15,17 @@
 #include "nsPlaceholderFrame.h"
 #include "nsLineLayout.h"
 #include "nsIContent.h"
 #include "nsContentUtils.h"
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsStyleContext.h"
+#include "nsTableOuterFrame.h"
 #include "nsIView.h"
 #include "nsIViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsPresContext.h"
 #include "nsCRT.h"
 #include "nsGUIEvent.h"
 #include "nsIDOMEvent.h"
 #include "nsAsyncDOMEvent.h"
@@ -48,17 +49,16 @@
 #include "nsCSSAnonBoxes.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCSSFrameConstructor.h"
 
 #include "nsFrameTraversal.h"
 #include "nsStyleChangeList.h"
 #include "nsIDOMRange.h"
 #include "nsRange.h"
-#include "nsITableLayout.h"    //selection necessity
 #include "nsITableCellLayout.h"//  "
 #include "nsITextControlFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsIPercentHeightObserver.h"
 #include "nsStyleStructInlines.h"
 
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
@@ -2497,18 +2497,18 @@ nsFrame::GetDataForTableSelection(const 
       //      for row and column selection, this is the place to do it
       break;
     }
     else
     {
       // If not a cell, check for table
       // This will happen when starting frame is the table or child of a table,
       //  such as a row (we were inbetween cells or in table border)
-      nsITableLayout *tableElement = do_QueryFrame(frame);
-      if (tableElement)
+      nsTableOuterFrame *tableFrame = do_QueryFrame(frame);
+      if (tableFrame)
       {
         foundTable = true;
         //TODO: How can we select row when along left table edge
         //  or select column when along top edge?
         break;
       } else {
         frame = frame->GetParent();
         // Stop if we have hit the selection's limiting content node
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -5,22 +5,23 @@
 #ifndef nsFrameSelection_h___
 #define nsFrameSelection_h___
 
 #include "mozilla/Attributes.h"
 
 #include "nsIFrame.h"
 #include "nsIContent.h"
 #include "nsISelectionController.h"
-#include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
 #include "nsIDOMElement.h"
 #include "nsGUIEvent.h"
 #include "nsRange.h"
 
+class nsTableOuterFrame;
+
 // IID for the nsFrameSelection interface
 // 3c6ae2d0-4cf1-44a1-9e9d-2411867f19c6
 #define NS_FRAME_SELECTION_IID      \
 { 0x3c6ae2d0, 0x4cf1, 0x44a1, \
   { 0x9e, 0x9d, 0x24, 0x11, 0x86, 0x7f, 0x19, 0xc6 } }
 
 #ifdef IBMBIDI // Constant for Set/Get CaretBidiLevel
 #define BIDI_LEVEL_UNDEFINED 0x80
@@ -645,18 +646,16 @@ private:
 
   // nsFrameSelection may get deleted when calling this,
   // so remember to use nsCOMPtr when needed.
   nsresult     NotifySelectionListeners(SelectionType aType);     // add parameters to say collapsed etc?
 
   nsRefPtr<mozilla::Selection> mDomSelections[nsISelectionController::NUM_SELECTIONTYPES];
 
   // Table selection support.
-  // Interfaces that let us get info based on cellmap locations
-  nsITableLayout* GetTableLayout(nsIContent *aTableContent) const;
   nsITableCellLayout* GetCellLayout(nsIContent *aCellContent) const;
 
   nsresult SelectBlockOfCells(nsIContent *aStartNode, nsIContent *aEndNode);
   nsresult SelectRowOrColumn(nsIContent *aCellContent, uint32_t aTarget);
   nsresult UnselectCells(nsIContent *aTable,
                          int32_t aStartRowIndex, int32_t aStartColumnIndex,
                          int32_t aEndRowIndex, int32_t aEndColumnIndex,
                          bool aRemoveOutsideOfCellRange);
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -24,20 +24,21 @@
 #include "nsContentCID.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
 #include "nsRange.h"
 #include "nsCOMArray.h"
 #include "nsGUIEvent.h"
 #include "nsIDOMKeyEvent.h"
-#include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
 #include "nsIDOMNodeList.h"
 #include "nsTArray.h"
+#include "nsTableOuterFrame.h"
+#include "nsTableCellFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsIContentIterator.h"
 #include "nsIDocumentEncoder.h"
 #include "nsTextFragment.h"
 
 // for IBMBIDI
 #include "nsFrameTraversal.h"
@@ -2072,25 +2073,16 @@ nsITableCellLayout*
 nsFrameSelection::GetCellLayout(nsIContent *aCellContent) const
 {
   NS_ENSURE_TRUE(mShell, nullptr);
   nsITableCellLayout *cellLayoutObject =
     do_QueryFrame(aCellContent->GetPrimaryFrame());
   return cellLayoutObject;
 }
 
-nsITableLayout* 
-nsFrameSelection::GetTableLayout(nsIContent *aTableContent) const
-{
-  NS_ENSURE_TRUE(mShell, nullptr);
-  nsITableLayout *tableLayoutObject =
-    do_QueryFrame(aTableContent->GetPrimaryFrame());
-  return tableLayoutObject;
-}
-
 nsresult
 nsFrameSelection::ClearNormalSelection()
 {
   int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
   return mDomSelections[index]->RemoveAllRanges();
@@ -2475,18 +2467,18 @@ nsFrameSelection::UnselectCells(nsIConte
                                 int32_t aEndColumnIndex,
                                 bool aRemoveOutsideOfCellRange)
 {
   int8_t index =
     GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
-  nsITableLayout *tableLayout = GetTableLayout(aTableContent);
-  if (!tableLayout)
+  nsTableOuterFrame* tableFrame = do_QueryFrame(aTableContent->GetPrimaryFrame());
+  if (!tableFrame)
     return NS_ERROR_FAILURE;
 
   int32_t minRowIndex = NS_MIN(aStartRowIndex, aEndRowIndex);
   int32_t maxRowIndex = NS_MAX(aStartRowIndex, aEndRowIndex);
   int32_t minColIndex = NS_MIN(aStartColumnIndex, aEndColumnIndex);
   int32_t maxColIndex = NS_MAX(aStartColumnIndex, aEndColumnIndex);
 
   // Strong reference because we sometimes remove the range
@@ -2514,34 +2506,30 @@ nsFrameSelection::UnselectCells(nsIConte
           mDomSelections[index]->RemoveRange(range);
           // Since we've removed the range, decrement pointer to next range
           mSelectedCellIndex--;
         }
 
       } else {
         // Remove cell from selection if it belongs to the given cells range or
         // it is spanned onto the cells range.
-        nsCOMPtr<nsIDOMElement> cellElement;
-        int32_t origRowIndex, origColIndex, rowSpan, colSpan,
-          actualRowSpan, actualColSpan;
-        bool isSelected;
-
-        result = tableLayout->GetCellDataAt(curRowIndex, curColIndex,
-                                            *getter_AddRefs(cellElement),
-                                            origRowIndex, origColIndex,
-                                            rowSpan, colSpan, 
-                                            actualRowSpan, actualColSpan,
-                                            isSelected);
-        if (NS_FAILED(result))
-          return result;
-
-        if (origRowIndex <= maxRowIndex &&
-            origRowIndex + actualRowSpan - 1 >= minRowIndex &&
-            origColIndex <= maxColIndex &&
-            origColIndex + actualColSpan - 1 >= minColIndex) {
+        nsTableCellFrame* cellFrame =
+          tableFrame->GetCellFrameAt(curRowIndex, curColIndex);
+
+        int32_t origRowIndex, origColIndex;
+        cellFrame->GetRowIndex(origRowIndex);
+        cellFrame->GetColIndex(origColIndex);
+        uint32_t actualRowSpan =
+          tableFrame->GetEffectiveRowSpanAt(origRowIndex, origColIndex);
+        uint32_t actualColSpan =
+          tableFrame->GetEffectiveColSpanAt(curRowIndex, curColIndex);
+        if (origRowIndex <= maxRowIndex && maxRowIndex >= 0 &&
+            origRowIndex + actualRowSpan - 1 >= static_cast<uint32_t>(minRowIndex) &&
+            origColIndex <= maxColIndex && maxColIndex >= 0 &&
+            origColIndex + actualColSpan - 1 >= static_cast<uint32_t>(minColIndex)) {
 
           mDomSelections[index]->RemoveRange(range);
           // Since we've removed the range, decrement pointer to next range
           mSelectedCellIndex--;
         }
       }
     }
 
@@ -2559,47 +2547,38 @@ nsFrameSelection::AddCellsToSelection(ns
                                       int32_t aStartColumnIndex,
                                       int32_t aEndRowIndex,
                                       int32_t aEndColumnIndex)
 {
   int8_t index = GetIndexFromSelectionType(nsISelectionController::SELECTION_NORMAL);
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
 
-  // Get TableLayout interface to access cell data based on cellmap location
-  // frames are not ref counted, so don't use an nsCOMPtr
-  nsITableLayout *tableLayoutObject = GetTableLayout(aTableContent);
-  if (!tableLayoutObject) // Check that |table| is a table.
+  nsTableOuterFrame* tableFrame = do_QueryFrame(aTableContent->GetPrimaryFrame());
+  if (!tableFrame) // Check that |table| is a table.
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDOMElement> cellElement;
-  int32_t rowSpan, colSpan, actualRowSpan, actualColSpan,
-    curRowIndex, curColIndex;
-  bool isSelected;
   nsresult result = NS_OK;
-
   int32_t row = aStartRowIndex;
   while(true)
   {
     int32_t col = aStartColumnIndex;
     while(true)
     {
-      result = tableLayoutObject->GetCellDataAt(row, col, *getter_AddRefs(cellElement),
-                                                curRowIndex, curColIndex, rowSpan, colSpan, 
-                                                actualRowSpan, actualColSpan, isSelected);
-      if (NS_FAILED(result)) return result;
-
-      NS_ASSERTION(actualColSpan, "!actualColSpan is 0!");
+      nsTableCellFrame* cellFrame = tableFrame->GetCellFrameAt(row, col);
 
       // Skip cells that are spanned from previous locations or are already selected
-      if (!isSelected && cellElement && row == curRowIndex && col == curColIndex)
-      {
-        nsCOMPtr<nsIContent> cellContent = do_QueryInterface(cellElement);
-        result = SelectCellElement(cellContent);
-        if (NS_FAILED(result)) return result;
+      if (cellFrame) {
+        int32_t origRow, origCol;
+        cellFrame->GetRowIndex(origRow);
+        cellFrame->GetColIndex(origCol);
+        if (origRow == row && origCol == col && !cellFrame->IsSelected()) {
+          result = SelectCellElement(cellFrame->GetContent());
+          if (NS_FAILED(result)) return result;
+        }
       }
       // Done when we reach end column
       if (col == aEndColumnIndex) break;
 
       if (aStartColumnIndex < aEndColumnIndex)
         col ++;
       else
         col--;
@@ -2642,61 +2621,52 @@ nsFrameSelection::SelectRowOrColumn(nsIC
   if (!aCellContent) return NS_ERROR_NULL_POINTER;
 
   nsIContent* table = GetParentTable(aCellContent);
   if (!table) return NS_ERROR_NULL_POINTER;
 
   // Get table and cell layout interfaces to access 
   //   cell data based on cellmap location
   // Frames are not ref counted, so don't use an nsCOMPtr
-  nsITableLayout *tableLayout = GetTableLayout(table);
-  if (!tableLayout) return NS_ERROR_FAILURE;
+  nsTableOuterFrame* tableFrame = do_QueryFrame(table->GetPrimaryFrame());
+  if (!tableFrame) return NS_ERROR_FAILURE;
   nsITableCellLayout *cellLayout = GetCellLayout(aCellContent);
   if (!cellLayout) return NS_ERROR_FAILURE;
 
   // Get location of target cell:      
-  int32_t rowIndex, colIndex, curRowIndex, curColIndex;
+  int32_t rowIndex, colIndex;
   nsresult result = cellLayout->GetCellIndexes(rowIndex, colIndex);
   if (NS_FAILED(result)) return result;
 
   // Be sure we start at proper beginning
   // (This allows us to select row or col given ANY cell!)
   if (aTarget == nsISelectionPrivate::TABLESELECTION_ROW)
     colIndex = 0;
   if (aTarget == nsISelectionPrivate::TABLESELECTION_COLUMN)
     rowIndex = 0;
 
-  nsCOMPtr<nsIDOMElement> cellElement;
-  nsCOMPtr<nsIContent> firstCell;
-  nsCOMPtr<nsIDOMElement> lastCell;
-  int32_t rowSpan, colSpan, actualRowSpan, actualColSpan;
-  bool isSelected;
-
-  do {
+  nsCOMPtr<nsIContent> firstCell, lastCell;
+  while (true) {
     // Loop through all cells in column or row to find first and last
-    result = tableLayout->GetCellDataAt(rowIndex, colIndex, *getter_AddRefs(cellElement),
-                                        curRowIndex, curColIndex, rowSpan, colSpan, 
-                                        actualRowSpan, actualColSpan, isSelected);
-    if (NS_FAILED(result)) return result;
-    if (cellElement)
-    {
-      NS_ASSERTION(actualRowSpan > 0 && actualColSpan> 0, "SelectRowOrColumn: Bad rowspan or colspan\n");
-      if (!firstCell)
-        firstCell = do_QueryInterface(cellElement);
-
-      lastCell = cellElement;
-
-      // Move to next cell in cellmap, skipping spanned locations
-      if (aTarget == nsISelectionPrivate::TABLESELECTION_ROW)
-        colIndex += actualColSpan;
-      else
-        rowIndex += actualRowSpan;
-    }
-  }
-  while (cellElement);
+    nsCOMPtr<nsIContent> curCellContent =
+      tableFrame->GetCellAt(rowIndex, colIndex);
+    if (!curCellContent)
+      break;
+
+    if (!firstCell)
+      firstCell = curCellContent;
+
+    lastCell = curCellContent.forget();
+
+    // Move to next cell in cellmap, skipping spanned locations
+    if (aTarget == nsISelectionPrivate::TABLESELECTION_ROW)
+      colIndex += tableFrame->GetEffectiveRowSpanAt(rowIndex, colIndex);
+    else
+      rowIndex += tableFrame->GetEffectiveRowSpanAt(rowIndex, colIndex);
+  }
 
   // Use SelectBlockOfCells:
   // This will replace existing selection,
   //  but allow unselecting by dragging out of selected region
   if (firstCell && lastCell)
   {
     if (!mStartSelectedCell)
     {
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
 #include "nsBlockFrame.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
+#include "nsTableRowFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsRenderingContext.h"
 
 #include "nsTArray.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsTableOuterFrame.h"
 #include "nsTableFrame.h"
 #include "nsTableCellFrame.h"
@@ -506,18 +507,17 @@ nsMathMLmtableOuterFrame::AttributeChang
 
   return NS_OK;
 }
 
 nsIFrame*
 nsMathMLmtableOuterFrame::GetRowFrameAt(nsPresContext* aPresContext,
                                         int32_t         aRowIndex)
 {
-  int32_t rowCount, colCount;
-  GetTableSize(rowCount, colCount);
+  int32_t rowCount = GetRowCount();
 
   // Negative indices mean to find upwards from the end.
   if (aRowIndex < 0) {
     aRowIndex = rowCount + aRowIndex;
   } else {
     // aRowIndex is 1-based, so convert it to a 0-based index
     --aRowIndex;
   }
--- a/layout/tables/Makefile.in
+++ b/layout/tables/Makefile.in
@@ -14,17 +14,16 @@ MODULE		= layout
 LIBRARY_NAME	= gktable_s
 LIBXUL_LIBRARY	= 1
 FAIL_ON_WARNINGS = 1
 
 
 
 EXPORTS		= \
 		nsITableCellLayout.h \
-		nsITableLayout.h \
 		$(NULL)
 
 CPPSRCS		= \
 		BasicTableLayoutStrategy.cpp \
 		FixedTableLayoutStrategy.cpp \
 		SpanningCellSorter.cpp \
 		nsCellMap.cpp \
 		nsTableCellFrame.cpp \
--- a/layout/tables/nsCellMap.cpp
+++ b/layout/tables/nsCellMap.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsTArray.h"
 #include "nsCellMap.h"
 #include "nsTableFrame.h"
 #include "nsTableCellFrame.h"
+#include "nsTableRowFrame.h"
 #include "nsTableRowGroupFrame.h"
 
 
 static void
 SetDamageArea(int32_t aXOrigin,
               int32_t aYOrigin,
               int32_t aWidth,
               int32_t aHeight,
deleted file mode 100644
--- a/layout/tables/nsITableLayout.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef nsITableLayout_h__
-#define nsITableLayout_h__
-
-#include "nsQueryFrame.h"
-class nsIDOMElement;
-
-/**
- * nsITableLayout
- * interface for layout objects that act like tables.
- * initially, we use this to get cell info 
- *
- * @author  sclark
- */
-class nsITableLayout
-{
-public:
-
-  NS_DECL_QUERYFRAME_TARGET(nsITableLayout)
-
-  /** return all the relevant layout information about a cell.
-   *  @param aRowIndex       a row which the cell intersects
-   *  @param aColIndex       a col which the cell intersects
-   *  @param aCell           [OUT] the content representing the cell at (aRowIndex, aColIndex)
-   *  @param aStartRowIndex  [IN/OUT] the row in which aCell starts
-   *  @param aStartColIndex  [IN/OUT] the col in which aCell starts
-   *                         Initialize these with the "candidate" start indexes to use
-   *                           for searching through the table when a cell isn't found 
-   *                           because of "holes" in the cellmap
-   *                           when ROWSPAN and/or COLSPAN > 1
-   *  @param aRowSpan        [OUT] the value of the ROWSPAN attribute (may be 0 or actual number)
-   *  @param aColSpan        [OUT] the value of the COLSPAN attribute (may be 0 or actual number)
-   *  @param aActualRowSpan  [OUT] the actual number of rows aCell spans
-   *  @param aActualColSpan  [OUT] the acutal number of cols aCell spans
-   *  @param aIsSelected     [OUT] true if the frame that maps aCell is selected
-   *                               in the presentation shell that owns this.
-   */
-  NS_IMETHOD GetCellDataAt(int32_t aRowIndex, int32_t aColIndex,
-                           nsIDOMElement* &aCell,   //out params
-                           int32_t& aStartRowIndex, int32_t& aStartColIndex, 
-                           int32_t& aRowSpan, int32_t& aColSpan,
-                           int32_t& aActualRowSpan, int32_t& aActualColSpan,
-                           bool& aIsSelected)=0;
-
-  /** Get the number of rows and column for a table from the frame's cellmap 
-   *  Some rows may not have enough cells (the number returned is the maximum possible),
-   *  which displays as a ragged-right edge table
-   */
-  NS_IMETHOD GetTableSize(int32_t& aRowCount, int32_t& aColCount)=0;
-
-  /**
-   * Retrieves the index of the cell at the given coordinates.
-   *
-   * @note  The index is the order number of the cell calculated from top left
-   *        cell to the right bottom cell of the table.
-   *
-   * @param aRow     [in] the row the cell is in
-   * @param aColumn  [in] the column the cell is in
-   * @param aIndex   [out] the index to be returned
-   */
-  NS_IMETHOD GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn,
-                                    int32_t *aIndex) = 0;
-
-  /**
-   * Retrieves the coordinates of the cell at the given index.
-   *
-   * @see  nsITableLayout::GetIndexByRowAndColumn()
-   *
-   * @param aIndex  [in] the index for which the coordinates are to be retrieved
-   * @param aRow    [out] the resulting row coordinate
-   * @param aColumn [out] the resulting column coordinate
-   */
-  NS_IMETHOD GetRowAndColumnByIndex(int32_t aIndex,
-                                    int32_t *aRow, int32_t *aColumn) = 0;
-};
-
-#endif
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsTableFrame.h"
 #include "nsTableColFrame.h"
 #include "nsTableCellFrame.h"
+#include "nsTableRowFrame.h"
 #include "nsTableRowGroupFrame.h"
 #include "nsTablePainter.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include "nsCSSRendering.h"
 #include "nsIContent.h"
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -1,20 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsTableCellFrame_h__
 #define nsTableCellFrame_h__
 
 #include "mozilla/Attributes.h"
+#include "celldata.h"
 #include "nsITableCellLayout.h"
 #include "nscore.h"
 #include "nsContainerFrame.h"
-#include "nsTableRowFrame.h"  // need to actually include this here to inline GetRowIndex
 #include "nsStyleContext.h"
 #include "nsIPercentHeightObserver.h"
 #include "nsGkAtoms.h"
 #include "nsLayoutUtils.h"
 #include "nsTArray.h"
 
 class nsTableFrame;
 
--- a/layout/tables/nsTableColFrame.h
+++ b/layout/tables/nsTableColFrame.h
@@ -1,19 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsTableColFrame_h__
 #define nsTableColFrame_h__
 
 #include "mozilla/Attributes.h"
+#include "celldata.h"
 #include "nscore.h"
 #include "nsContainerFrame.h"
-#include "nsTablePainter.h"
 #include "nsTArray.h"
 
 class nsTableCellFrame;
 
 enum nsTableColType {
   eColContent            = 0, // there is real col content associated   
   eColAnonymousCol       = 1, // the result of a span on a col
   eColAnonymousColGroup  = 2, // the result of a span on a col group
--- a/layout/tables/nsTableColGroupFrame.h
+++ b/layout/tables/nsTableColGroupFrame.h
@@ -4,18 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsTableColGroupFrame_h__
 #define nsTableColGroupFrame_h__
 
 #include "mozilla/Attributes.h"
 #include "nscore.h"
 #include "nsContainerFrame.h"
 #include "nsTableColFrame.h"
-#include "nsTablePainter.h"
 
+class nsTableFrame;
 class nsTableColFrame;
 
 enum nsTableColGroupType {
   eColGroupContent            = 0, // there is real col group content associated   
   eColGroupAnonymousCol       = 1, // the result of a col
   eColGroupAnonymousCell      = 2  // the result of a cell alone
 };
 
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -155,17 +155,16 @@ nsTableFrame::nsTableFrame(nsStyleContex
   : nsContainerFrame(aContext),
     mCellMap(nullptr),
     mTableLayoutStrategy(nullptr)
 {
   memset(&mBits, 0, sizeof(mBits));
 }
 
 NS_QUERYFRAME_HEAD(nsTableFrame)
-  NS_QUERYFRAME_ENTRY(nsITableLayout)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 NS_IMETHODIMP
 nsTableFrame::Init(nsIContent*      aContent,
                    nsIFrame*        aParent,
                    nsIFrame*        aPrevInFlow)
 {
   NS_PRECONDITION(!mCellMap, "Init called twice");
@@ -3686,118 +3685,16 @@ int32_t nsTableIterator::Count()
     while (nullptr != child) {
       mCount++;
       child = child->GetNextSibling();
     }
   }
   return mCount;
 }
 
-/*------------------ nsITableLayout methods ------------------------------*/
-NS_IMETHODIMP
-nsTableFrame::GetCellDataAt(int32_t        aRowIndex,
-                            int32_t        aColIndex,
-                            nsIDOMElement* &aCell,   //out params
-                            int32_t&       aStartRowIndex,
-                            int32_t&       aStartColIndex,
-                            int32_t&       aRowSpan,
-                            int32_t&       aColSpan,
-                            int32_t&       aActualRowSpan,
-                            int32_t&       aActualColSpan,
-                            bool&          aIsSelected)
-{
-  // Initialize out params
-  aCell = nullptr;
-  aStartRowIndex = 0;
-  aStartColIndex = 0;
-  aRowSpan = 0;
-  aColSpan = 0;
-  aIsSelected = false;
-
-  nsTableCellMap* cellMap = GetCellMap();
-  if (!cellMap) { return NS_ERROR_NOT_INITIALIZED;}
-
-  bool originates;
-  int32_t colSpan; // Is this the "effective" or "html" value?
-
-  nsTableCellFrame *cellFrame = cellMap->GetCellInfoAt(aRowIndex, aColIndex, &originates, &colSpan);
-  if (!cellFrame) return NS_TABLELAYOUT_CELL_NOT_FOUND;
-
-  nsresult result= cellFrame->GetRowIndex(aStartRowIndex);
-  if (NS_FAILED(result)) return result;
-  result = cellFrame->GetColIndex(aStartColIndex);
-  if (NS_FAILED(result)) return result;
-  //This returns HTML value, which may be 0
-  aRowSpan = cellFrame->GetRowSpan();
-  aColSpan = cellFrame->GetColSpan();
-  aActualRowSpan = GetEffectiveRowSpan(*cellFrame);
-  aActualColSpan = GetEffectiveColSpan(*cellFrame);
-
-  // If these aren't at least 1, we have a cellmap error
-  if (aActualRowSpan == 0 || aActualColSpan == 0)
-    return NS_ERROR_FAILURE;
-
-  aIsSelected = cellFrame->IsSelected();
-
-  // do this last, because it addrefs,
-  // and we don't want the caller leaking it on error
-  nsIContent* content = cellFrame->GetContent();
-  if (!content) return NS_ERROR_FAILURE;
-
-  return CallQueryInterface(content, &aCell);
-}
-
-NS_IMETHODIMP nsTableFrame::GetTableSize(int32_t& aRowCount, int32_t& aColCount)
-{
-  nsTableCellMap* cellMap = GetCellMap();
-  // Initialize out params
-  aRowCount = 0;
-  aColCount = 0;
-  if (!cellMap) { return NS_ERROR_NOT_INITIALIZED;}
-
-  aRowCount = cellMap->GetRowCount();
-  aColCount = cellMap->GetColCount();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTableFrame::GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn,
-                                     int32_t *aIndex)
-{
-  NS_ENSURE_ARG_POINTER(aIndex);
-  *aIndex = -1;
-
-  nsTableCellMap* cellMap = GetCellMap();
-  if (!cellMap)
-    return NS_ERROR_NOT_INITIALIZED;
-
-  *aIndex = cellMap->GetIndexByRowAndColumn(aRow, aColumn);
-  return (*aIndex == -1) ? NS_TABLELAYOUT_CELL_NOT_FOUND : NS_OK;
-}
-
-NS_IMETHODIMP
-nsTableFrame::GetRowAndColumnByIndex(int32_t aIndex,
-                                    int32_t *aRow, int32_t *aColumn)
-{
-  NS_ENSURE_ARG_POINTER(aRow);
-  *aRow = -1;
-
-  NS_ENSURE_ARG_POINTER(aColumn);
-  *aColumn = -1;
-
-  nsTableCellMap* cellMap = GetCellMap();
-  if (!cellMap)
-    return NS_ERROR_NOT_INITIALIZED;
-
-  cellMap->GetRowAndColumnByIndex(aIndex, aRow, aColumn);
-  return NS_OK;
-}
-
-/*---------------- end of nsITableLayout implementation ------------------*/
-
 bool
 nsTableFrame::ColumnHasCellSpacingBefore(int32_t aColIndex) const
 {
   // Since fixed-layout tables should not have their column sizes change
   // as they load, we assume that all columns are significant.
   if (LayoutStrategy()->GetType() == nsITableLayoutStrategy::Fixed)
     return true;
   // the first column is always significant
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -1,28 +1,30 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsTableFrame_h__
 #define nsTableFrame_h__
 
+#include "celldata.h"
 #include "nscore.h"
 #include "nsContainerFrame.h"
 #include "nsStyleCoord.h"
 #include "nsStyleConsts.h"
-#include "nsITableLayout.h"
 #include "nsTableColFrame.h"
 #include "nsTableColGroupFrame.h"
 #include "nsCellMap.h"
 #include "nsGkAtoms.h"
 #include "nsDisplayList.h"
 
 class nsTableCellFrame;
+class nsTableCellMap;
 class nsTableColFrame;
+class nsColGroupFrame;
 class nsTableRowGroupFrame;
 class nsTableRowFrame;
 class nsTableColGroupFrame;
 class nsITableLayoutStrategy;
 class nsStyleContext;
 
 struct nsTableReflowState;
 struct nsStylePosition;
@@ -98,17 +100,17 @@ private:
 /**
   * nsTableFrame maps the inner portion of a table (everything except captions.)
   * Used as a pseudo-frame within nsTableOuterFrame, it may also be used
   * stand-alone as the top-level frame.
   *
   * The principal child list contains row group frames. There is also an
   * additional child list, kColGroupList, which contains the col group frames.
   */
-class nsTableFrame : public nsContainerFrame, public nsITableLayout
+class nsTableFrame : public nsContainerFrame
 {
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   /** nsTableOuterFrame has intimate knowledge of the inner table frame */
   friend class nsTableOuterFrame;
 
@@ -456,19 +458,16 @@ public:
   void InsertColGroups(int32_t                   aStartColIndex,
                        const nsFrameList::Slice& aColgroups);
 
   virtual void RemoveCol(nsTableColGroupFrame* aColGroupFrame,
                          int32_t               aColIndex,
                          bool                  aRemoveFromCache,
                          bool                  aRemoveFromCellMap);
 
-  NS_IMETHOD GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn, int32_t *aIndex);
-  NS_IMETHOD GetRowAndColumnByIndex(int32_t aIndex, int32_t *aRow, int32_t *aColumn);
-
   bool ColumnHasCellSpacingBefore(int32_t aColIndex) const;
 
   bool HasPctCol() const;
   void SetHasPctCol(bool aValue);
 
   bool HasCellSpanningPctCol() const;
   void SetHasCellSpanningPctCol(bool aValue);
 
@@ -717,34 +716,16 @@ public: /* ----- Cell Map public methods
   }
 
   // return the last col index which isn't of type eColAnonymousCell
   int32_t GetIndexOfLastRealCol();
 
   /** returns true if table-layout:auto  */
   virtual bool IsAutoLayout();
 
-  /*---------------- nsITableLayout methods ------------------------*/
-  
-  /** Get the cell and associated data for a table cell from the frame's cellmap */
-  NS_IMETHOD GetCellDataAt(int32_t aRowIndex, int32_t aColIndex, 
-                           nsIDOMElement* &aCell,   //out params
-                           int32_t& aStartRowIndex, int32_t& aStartColIndex, 
-                           int32_t& aRowSpan, int32_t& aColSpan,
-                           int32_t& aActualRowSpan, int32_t& aActualColSpan,
-                           bool& aIsSelected);
-
-  /** Get the number of rows and column for a table from the frame's cellmap 
-    *  Some rows may not have enough cells (the number returned is the maximum possible),
-    *  which displays as a ragged-right edge table
-    */
-  NS_IMETHOD GetTableSize(int32_t& aRowCount, int32_t& aColCount);
-
-  /*------------end of nsITableLayout methods -----------------------*/
-
 public:
  
 #ifdef DEBUG
   void Dump(bool            aDumpRows,
             bool            aDumpCols, 
             bool            aDumpCellMap);
 #endif
 
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "nsTableOuterFrame.h"
 #include "nsTableFrame.h"
+#include "nsTableCellFrame.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsCSSRendering.h"
 #include "nsIContent.h"
 #include "prinrval.h"
 #include "nsGkAtoms.h"
 #include "nsHTMLParts.h"
@@ -145,17 +146,17 @@ nsTableOuterFrame::nsTableOuterFrame(nsS
 {
 }
 
 nsTableOuterFrame::~nsTableOuterFrame()
 {
 }
 
 NS_QUERYFRAME_HEAD(nsTableOuterFrame)
-  NS_QUERYFRAME_ENTRY(nsITableLayout)
+  NS_QUERYFRAME_ENTRY(nsTableOuterFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 #ifdef ACCESSIBILITY
 a11y::AccType
 nsTableOuterFrame::AccessibleType()
 {
   return a11y::eHTMLTable;
 }
@@ -1059,56 +1060,32 @@ NS_METHOD nsTableOuterFrame::Reflow(nsPr
 nsIAtom*
 nsTableOuterFrame::GetType() const
 {
   return nsGkAtoms::tableOuterFrame;
 }
 
 /* ----- global methods ----- */
 
-/*------------------ nsITableLayout methods ------------------------------*/
-NS_IMETHODIMP 
-nsTableOuterFrame::GetCellDataAt(int32_t aRowIndex, int32_t aColIndex, 
-                                 nsIDOMElement* &aCell,   //out params
-                                 int32_t& aStartRowIndex, int32_t& aStartColIndex, 
-                                 int32_t& aRowSpan, int32_t& aColSpan,
-                                 int32_t& aActualRowSpan, int32_t& aActualColSpan,
-                                 bool& aIsSelected)
+nsIContent*
+nsTableOuterFrame::GetCellAt(uint32_t aRowIdx, uint32_t aColIdx) const
 {
-  return InnerTableFrame()->GetCellDataAt(aRowIndex, aColIndex, aCell,
-                                          aStartRowIndex, aStartColIndex, 
-                                          aRowSpan, aColSpan, aActualRowSpan,
-                                          aActualColSpan, aIsSelected);
-}
+  nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap();
+  if (!cellMap) {
+    return nullptr;
+  }
 
-NS_IMETHODIMP
-nsTableOuterFrame::GetTableSize(int32_t& aRowCount, int32_t& aColCount)
-{
-  return InnerTableFrame()->GetTableSize(aRowCount, aColCount);
+  nsTableCellFrame* cell = cellMap->GetCellInfoAt(aRowIdx, aColIdx);
+  if (!cell) {
+    return nullptr;
+  }
+
+  return cell->GetContent();
 }
 
-NS_IMETHODIMP
-nsTableOuterFrame::GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn,
-                                          int32_t *aIndex)
-{
-  NS_ENSURE_ARG_POINTER(aIndex);
-  return InnerTableFrame()->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
-}
-
-NS_IMETHODIMP
-nsTableOuterFrame::GetRowAndColumnByIndex(int32_t aIndex,
-                                          int32_t *aRow, int32_t *aColumn)
-{
-  NS_ENSURE_ARG_POINTER(aRow);
-  NS_ENSURE_ARG_POINTER(aColumn);
-  return InnerTableFrame()->GetRowAndColumnByIndex(aIndex, aRow, aColumn);
-}
-
-/*---------------- end of nsITableLayout implementation ------------------*/
-
 
 nsIFrame*
 NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableOuterFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableOuterFrame)
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -3,18 +3,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsTableOuterFrame_h__
 #define nsTableOuterFrame_h__
 
 #include "mozilla/Attributes.h"
 #include "nscore.h"
 #include "nsContainerFrame.h"
+#include "nsCellMap.h"
 #include "nsBlockFrame.h"
-#include "nsITableLayout.h"
 #include "nsTableFrame.h"
 
 class nsTableCaptionFrame : public nsBlockFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsISupports
@@ -46,22 +46,24 @@ protected:
 1. decide if we'll allow subclassing.  If so, decide which methods really need to be virtual.
 */
 
 /**
  * main frame for an nsTable content object, 
  * the nsTableOuterFrame contains 0 or one caption frame, and a nsTableFrame
  * pseudo-frame (referred to as the "inner frame').
  */
-class nsTableOuterFrame : public nsContainerFrame, public nsITableLayout
+class nsTableOuterFrame : public nsContainerFrame
 {
 public:
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
+  NS_DECL_QUERYFRAME_TARGET(nsTableOuterFrame)
+
   /** instantiate a new instance of nsTableRowFrame.
     * @param aPresShell the pres shell for this frame
     *
     * @return           the frame that was created
     */
   friend nsIFrame* NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
   
   // nsIFrame overrides - see there for a description
@@ -125,31 +127,92 @@ public:
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
 
-  /*---------------- nsITableLayout methods ------------------------*/
+  /**
+   * Return the content for the cell at the given row and column.
+   */
+  nsIContent* GetCellAt(uint32_t aRowIdx, uint32_t aColIdx) const;
+
+  /**
+   * Return the number of rows in the table.
+   */
+  int32_t GetRowCount() const
+  {
+    return InnerTableFrame()->GetRowCount();
+  }
+
+  /**
+   * Return the number of columns in the table.
+   */
+  int32_t GetColCount() const
+  {
+    return InnerTableFrame()->GetColCount();
+  }
+
+  /**
+   * Return the index of the cell at the given row and column.
+   */
+  int32_t GetIndexByRowAndColumn(int32_t aRowIdx, int32_t aColIdx) const
+  {
+    nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap();
+    if (!cellMap)
+      return -1;
+
+    return cellMap->GetIndexByRowAndColumn(aRowIdx, aColIdx);
+  }
 
-  /** @see nsITableFrame::GetCellDataAt */
-  NS_IMETHOD GetCellDataAt(int32_t aRowIndex, int32_t aColIndex, 
-                           nsIDOMElement* &aCell,   //out params
-                           int32_t& aStartRowIndex, int32_t& aStartColIndex, 
-                           int32_t& aRowSpan, int32_t& aColSpan,
-                           int32_t& aActualRowSpan, int32_t& aActualColSpan,
-                           bool& aIsSelected);
+  /**
+   * Get the row and column indices for the cell at the given index.
+   */
+  void GetRowAndColumnByIndex(int32_t aCellIdx, int32_t* aRowIdx,
+                              int32_t* aColIdx) const
+  {
+    *aRowIdx = *aColIdx = 0;
+    nsTableCellMap* cellMap = InnerTableFrame()->GetCellMap();
+    if (cellMap) {
+      cellMap->GetRowAndColumnByIndex(aCellIdx, aRowIdx, aColIdx);
+    }
+  }
 
-  /** @see nsITableFrame::GetTableSize */
-  NS_IMETHOD GetTableSize(int32_t& aRowCount, int32_t& aColCount) MOZ_OVERRIDE;
+  /**
+   * return the frame for the cell at the given row and column.
+   */
+  nsTableCellFrame* GetCellFrameAt(uint32_t aRowIdx, uint32_t aColIdx) const
+  {
+    nsTableCellMap* map = InnerTableFrame()->GetCellMap();
+    if (!map) {
+      return nullptr;
+    }
+
+    return map->GetCellInfoAt(aRowIdx, aColIdx);
+  }
 
-  NS_IMETHOD GetIndexByRowAndColumn(int32_t aRow, int32_t aColumn, int32_t *aIndex) MOZ_OVERRIDE;
-  NS_IMETHOD GetRowAndColumnByIndex(int32_t aIndex, int32_t *aRow, int32_t *aColumn) MOZ_OVERRIDE;
+  /**
+   * Return the col span of the cell at the given row and column indices.
+   */
+  uint32_t GetEffectiveColSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const
+  {
+    nsTableCellMap* map = InnerTableFrame()->GetCellMap();
+    return map->GetEffectiveColSpan(aRowIdx, aColIdx);
+  }
+
+  /**
+   * Return the effective row span of the cell at the given row and column.
+   */
+  uint32_t GetEffectiveRowSpanAt(uint32_t aRowIdx, uint32_t aColIdx) const
+  {
+    nsTableCellMap* map = InnerTableFrame()->GetCellMap();
+    return map->GetEffectiveRowSpan(aRowIdx, aColIdx);
+  }
 
 protected:
 
 
   nsTableOuterFrame(nsStyleContext* aContext);
   virtual ~nsTableOuterFrame();
 
   void InitChildReflowState(nsPresContext&    aPresContext,