Bug 410052 - Fix our nsHTMLAccessibleTable class so GetIndexAt and GetRowAtIndex and GetColumnAtIndex behave consistently, patch=me, marcoz, r=marcoz, me, bernd, sr=roc, blocking1.9+=dsicore
authorsurkov.alexander@gmail.com
Wed, 06 Feb 2008 23:03:26 -0800
changeset 11311 3a6c4e3c25836d4df6feab419fac7eac9b998968
parent 11310 650391fd52bd70d55ded63ede237b7260962e2d8
child 11312 0a075bac0ab3b82e3b64069300d2a9353470a7c5
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersmarcoz, me, bernd, roc, blocking1.9
bugs410052
milestone1.9b4pre
Bug 410052 - Fix our nsHTMLAccessibleTable class so GetIndexAt and GetRowAtIndex and GetColumnAtIndex behave consistently, patch=me, marcoz, r=marcoz, me, bernd, sr=roc, blocking1.9+=dsicore
accessible/src/html/nsHTMLTableAccessible.cpp
layout/tables/nsCellMap.cpp
layout/tables/nsCellMap.h
layout/tables/nsITableLayout.h
layout/tables/nsTableFrame.cpp
layout/tables/nsTableFrame.h
layout/tables/nsTableOuterFrame.cpp
layout/tables/nsTableOuterFrame.h
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -526,64 +526,47 @@ nsHTMLTableAccessible::CellRefAt(PRInt32
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
                                   PRInt32 *aIndex)
 {
   NS_ENSURE_ARG_POINTER(aIndex);
 
   NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
 
-  nsresult rv = NS_OK;
-  nsCOMPtr<nsIDOMElement> domElement;
-  rv = GetCellAt(aRow, aColumn, *getter_AddRefs(domElement));
+  nsITableLayout *tableLayout = nsnull;
+  nsresult rv = GetTableLayout(&tableLayout);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccService()->GetCachedAccessible(domElement, mWeakShell, getter_AddRefs(accessible));
-  if (accessible) {
-    rv = accessible->GetIndexInParent(aIndex);
-  } else {
-    // not found the corresponding cell
-    *aIndex = -1;
-  }
-  return rv;
+  return tableLayout->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
 {
   NS_ENSURE_ARG_POINTER(aColumn);
 
-  nsCOMPtr<nsIAccessible> child;
-  GetChildAt(aIndex, getter_AddRefs(child));
-  NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
-  nsCOMPtr<nsPIAccessNode> childNode(do_QueryInterface(child));
-  NS_ASSERTION(childNode, "childNode not valid in GetColumnAtIndex!");
-  nsIFrame* frame = childNode->GetFrame();
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
-  nsCOMPtr<nsITableCellLayout> cellLayout(do_QueryInterface(frame));
-  NS_ENSURE_TRUE(cellLayout, NS_ERROR_FAILURE);
-  return cellLayout->GetColIndex(*aColumn);
+  nsITableLayout *tableLayout = nsnull;
+  nsresult rv = GetTableLayout(&tableLayout);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 row;
+  return tableLayout->GetRowAndColumnByIndex(aIndex, &row, aColumn);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
 {
   NS_ENSURE_ARG_POINTER(aRow);
 
-  nsCOMPtr<nsIAccessible> child;
-  GetChildAt(aIndex, getter_AddRefs(child));
-  NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
-  nsCOMPtr<nsPIAccessNode> childNode(do_QueryInterface(child));
-  NS_ASSERTION(childNode, "childNode not valid in GetRowAtIndex!");
-  nsIFrame* frame = childNode->GetFrame();
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
-  nsCOMPtr<nsITableCellLayout> cellLayout(do_QueryInterface(frame));
-  NS_ENSURE_TRUE(cellLayout, NS_ERROR_FAILURE);
-  return cellLayout->GetRowIndex(*aRow);
+  nsITableLayout *tableLayout = nsnull;
+  nsresult rv = GetTableLayout(&tableLayout);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 column;
+  return tableLayout->GetRowAndColumnByIndex(aIndex, aRow, &column);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
                                          PRInt32 *_retval)
 {
   NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
 
--- a/layout/tables/nsCellMap.cpp
+++ b/layout/tables/nsCellMap.cpp
@@ -886,17 +886,93 @@ nsTableCellMap::GetCellInfoAt(PRInt32  a
     if (cellMap->GetRowCount() > rowIndex) {
       return cellMap->GetCellInfoAt(*this, rowIndex, aColIndex, aOriginates, aColSpan);
     }
     rowIndex -= cellMap->GetRowCount();
     cellMap = cellMap->GetNextSibling();
   }
   return nsnull;
 }
-  
+
+PRInt32
+nsTableCellMap::GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn) const
+{
+  PRInt32 index = 0;
+
+  PRInt32 colCount = mCols.Count();
+  PRInt32 rowIndex = aRow;
+
+  nsCellMap* cellMap = mFirstMap;
+  while (cellMap) {
+    PRInt32 rowCount = cellMap->GetRowCount();
+    if (rowCount < rowIndex) {
+      // If the rowCount is less than the rowIndex, this means that the index is
+      // not within the current map. If so, get the index of the last cell in
+      // the last row.
+      PRInt32 cellMapIdx = cellMap->GetIndexByRowAndColumn(colCount,
+                                                           rowCount - 1,
+                                                           colCount - 1);
+      if (cellMapIdx != -1) {
+        index += cellMapIdx;
+        rowIndex -= rowCount;
+      }
+    } else {
+      // Index is in valid range for this cellmap, so get the index of rowIndex
+      // and aColumn.
+      PRInt32 cellMapIdx = cellMap->GetIndexByRowAndColumn(colCount, rowIndex,
+                                                           aColumn);
+      if (cellMapIdx != -1) {
+        index += cellMapIdx;
+        return index;  // no need to look through further maps here
+      }
+    }
+
+    cellMap = cellMap->GetNextSibling();
+  }
+
+  return -1;
+}
+
+void
+nsTableCellMap::GetRowAndColumnByIndex(PRInt32 aIndex,
+                                       PRInt32 *aRow, PRInt32 *aColumn) const
+{
+  *aRow = -1;
+  *aColumn = -1;
+
+  PRInt32 colCount = mCols.Count();
+
+  PRInt32 previousRows = 0;
+  PRInt32 index = aIndex;
+
+  nsCellMap* cellMap = mFirstMap;
+  while (cellMap) {
+    PRInt32 rowCount = cellMap->GetRowCount();
+    // Determine the highest possible index in this map to see
+    // if wanted index is in here.
+    PRInt32 cellMapIdx = cellMap->GetIndexByRowAndColumn(colCount,
+                                                         rowCount - 1,
+                                                         colCount - 1);
+    if (cellMapIdx != -1) {
+      if (index > cellMapIdx) {
+        // The index is not within this map, so decrease it by the cellMapIdx
+        // determined index and increase the total row index accordingly.
+        index -= cellMapIdx;
+        previousRows += rowCount;
+      } else {
+        cellMap->GetRowAndColumnByIndex(colCount, index, aRow, aColumn);
+        // If there were previous indexes, take them into account.
+        *aRow += previousRows;
+        return; // no need to look any further.
+      }
+    }
+
+    cellMap = cellMap->GetNextSibling();
+  }
+}
 
 PRBool nsTableCellMap::RowIsSpannedInto(PRInt32 aRowIndex,
                                         PRInt32 aNumEffCols) const
 {
   PRInt32 rowIndex = aRowIndex;
   nsCellMap* cellMap = mFirstMap;
   while (cellMap) {
     if (cellMap->GetRowCount() > rowIndex) {
@@ -1245,16 +1321,67 @@ nsCellMap::GetCellFrame(PRInt32   aRowIn
   CellData* data =
     mRows.SafeElementAt(rowIndex, *sEmptyRow).SafeElementAt(colIndex);
   if (data) {
     return data->GetCellFrame();
   }
   return nsnull;
 }
 
+PRInt32
+nsCellMap::GetIndexByRowAndColumn(PRInt32 aColCount,
+                                  PRInt32 aRow, PRInt32 aColumn) const
+{
+  PRInt32 index = -1;
+
+  if (aRow >= mRows.Length())
+    return index;
+
+  PRInt32 lastColsIdx = aColCount - 1;
+  for (PRInt32 rowIdx = 0; rowIdx <= aRow; rowIdx++) {
+    const CellDataArray& row = mRows[rowIdx];
+    PRInt32 colCount = (rowIdx == aRow) ? aColumn : lastColsIdx;
+
+    for (PRInt32 colIdx = 0; colIdx <= colCount; colIdx++) {
+      CellData* data = row.SafeElementAt(colIdx);
+      if (data && data->IsOrig())
+        index++;
+    }
+  }
+
+  return index;
+}
+
+void
+nsCellMap::GetRowAndColumnByIndex(PRInt32 aColCount, PRInt32 aIndex,
+                                  PRInt32 *aRow, PRInt32 *aColumn) const
+{
+  *aRow = -1;
+  *aColumn = -1;
+
+  PRInt32 index = aIndex;
+  PRInt32 rowCount = mRows.Length();
+
+  for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    const CellDataArray& row = mRows[rowIdx];
+
+    for (PRInt32 colIdx = 0; colIdx < aColCount; colIdx++) {
+      CellData* data = row.SafeElementAt(colIdx);
+      if (data && data->IsOrig())
+        index--;
+
+      if (index < 0) {
+        *aRow = rowIdx;
+        *aColumn = colIdx;
+        return;
+      }
+    }
+  }
+}
+
 PRBool nsCellMap::Grow(nsTableCellMap& aMap,
                        PRInt32         aNumRows,
                        PRInt32         aRowIndex)
 {
   NS_ASSERTION(aNumRows >= 1, "Why are we calling this?");
 
   // Get the number of cols we want to use for preallocating the row arrays.
   PRInt32 numCols = aMap.GetColCount();
--- a/layout/tables/nsCellMap.h
+++ b/layout/tables/nsCellMap.h
@@ -168,16 +168,39 @@ public:
   /** return the actual number of rows in the table represented by this CellMap */
   PRInt32 GetRowCount() const;
 
   nsTableCellFrame* GetCellInfoAt(PRInt32  aRowX, 
                                   PRInt32  aColX, 
                                   PRBool*  aOriginates = nsnull, 
                                   PRInt32* aColSpan = nsnull) const;
 
+  /**
+   * Returns the index at the given row and column coordinates.
+   *
+   * @see  nsITableLayout::GetIndexByRowAndColumn()
+   *
+   * @param aRow     [in] the row coordinate
+   * @param aColumn  [in] the column coordinate
+   * @returns             the index for the cell
+   */
+  PRInt32 GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn) const;
+
+  /**
+   * Retrieves the row and column coordinates for the given index.
+   *
+   * @see  nsITableLayout::GetRowAndColumnByIndex()
+   *
+   * @param aIndex  [in] the index for which coordinates are to be retrieved
+   * @param aRow    [out] the row coordinate to be returned
+   * @param aColumn [out] the column coordinate to be returned
+   */
+  void GetRowAndColumnByIndex(PRInt32 aIndex,
+                              PRInt32 *aRow, PRInt32 *aColumn) const;
+
   void AddColsAtEnd(PRUint32 aNumCols);
   void RemoveColsAtEnd();
 
   PRBool RowIsSpannedInto(PRInt32 aRowIndex, PRInt32 aNumEffCols) const;
   PRBool RowHasSpanningCells(PRInt32 aRowIndex, PRInt32 aNumEffCols) const;
   void RebuildConsideringCells(nsCellMap*      aCellMap,
                                nsVoidArray*    aCellFrames,
                                PRInt32         aRowIndex,
@@ -296,16 +319,41 @@ public:
 
   nsTableRowGroupFrame* GetRowGroup() const;
 
   nsTableCellFrame* GetCellFrame(PRInt32   aRowIndex,
                                  PRInt32   aColIndex,
                                  CellData& aData,
                                  PRBool    aUseRowSpanIfOverlap) const;
 
+  /**
+   * Returns the index of the given row and column coordinates.
+   *
+   * @see  nsITableLayout::GetIndexByRowAndColumn()
+   *
+   * @param aColCount  [in] the number of columns in a row
+   * @param aRow       [in] the row coordinate
+   * @param aColumn    [in] the column coordinate
+   */
+  PRInt32 GetIndexByRowAndColumn(PRInt32 aColCount,
+                                 PRInt32 aRow, PRInt32 aColumn) const;
+
+  /**
+   * Get the row and column coordinates at the given index.
+   *
+   * @see  nsITableLayout::GetRowAndColumnByIndex()
+   *
+   * @param aColCount  [in] the number of columns in a row
+   * @param aIndex     [in] the index for which coordinates are to be retrieved
+   * @param aRow       [out] the row coordinate to be returned
+   * @param aColumn    [out] the column coordinate to be returned
+   */
+  void GetRowAndColumnByIndex(PRInt32 aColCount, PRInt32 aIndex,
+                              PRInt32 *aRow, PRInt32 *aColumn) const;
+
   /** append the cellFrame at an empty or dead cell or finally at the end of 
     * the row at aRowIndex and return a pointer to the celldata entry in the 
     * cellmap
     *
     * @param aMap               - reference to the table cell map
     * @param aCellFrame         - a pointer to the cellframe which will be appended 
     *                             to the row
     * @param aRowIndex          - to this row the celldata entry will be added
--- a/layout/tables/nsITableLayout.h
+++ b/layout/tables/nsITableLayout.h
@@ -38,17 +38,17 @@
 #define nsITableLayout_h__
 
 #include "nsISupports.h"
 class nsIDOMElement;
 
 // IID for the nsITableLayout interface 
 // A9222E6B-437E-11d3-B227-004095E27A10
 #define NS_ITABLELAYOUT_IID \
- { 0xa9222e6b, 0x437e, 0x11d3, { 0xb2, 0x27, 0x0, 0x40, 0x95, 0xe2, 0x7a, 0x10 }}
+ { 0xf8363dea, 0x11ad, 0x483a, { 0xba, 0xea, 0xf6, 0xf2, 0xc3, 0x58, 0x8d, 0xde }}
 
 /**
  * nsITableLayout
  * interface for layout objects that act like tables.
  * initially, we use this to get cell info 
  *
  * @author  sclark
  */
@@ -82,13 +82,38 @@ public:
                            PRInt32& aActualRowSpan, PRInt32& aActualColSpan,
                            PRBool& 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(PRInt32& aRowCount, PRInt32& 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(PRInt32 aRow, PRInt32 aColumn,
+                                    PRInt32 *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(PRInt32 aIndex,
+                                    PRInt32 *aRow, PRInt32 *aColumn) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsITableLayout, NS_ITABLELAYOUT_IID)
 
 #endif
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -3875,16 +3875,49 @@ NS_IMETHODIMP nsTableFrame::GetTableSize
   aColCount = 0;
   if (!cellMap) { return NS_ERROR_NOT_INITIALIZED;}
 
   aRowCount = cellMap->GetRowCount();
   aColCount = cellMap->GetColCount();
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsTableFrame::GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn,
+                                     PRInt32 *aIndex)
+{
+  NS_ENSURE_ARG_POINTER(aIndex);
+  *aIndex = -1;
+
+  nsTableCellMap* cellMap = GetCellMap();
+  if (!cellMap)
+    return NS_ERROR_NOT_INITIALIZED;
+
+  *aIndex = cellMap->GetIndexByRowAndColumn(aRow, aColumn);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTableFrame::GetRowAndColumnByIndex(PRInt32 aIndex,
+                                    PRInt32 *aRow, PRInt32 *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 ------------------*/
 
 PRInt32 nsTableFrame::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
 {
   nsTableCellMap* cellMap = GetCellMap();
   if (cellMap) 
     return cellMap->GetNumCellsOriginatingInCol(aColIndex);
   else
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -464,16 +464,18 @@ public:
                        nsIFrame*       aFirstFrame,
                        nsIFrame*       aLastFrame = nsnull);
 
   virtual void RemoveCol(nsTableColGroupFrame* aColGroupFrame,
                          PRInt32               aColIndex,
                          PRBool                aRemoveFromCache,
                          PRBool                aRemoveFromCellMap);
 
+  NS_IMETHOD GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex);
+  NS_IMETHOD GetRowAndColumnByIndex(PRInt32 aIndex, PRInt32 *aRow, PRInt32 *aColumn);
   PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
   PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
 
   PRBool HasPctCol() const;
   void SetHasPctCol(PRBool aValue);
 
   PRBool HasCellSpanningPctCol() const;
   void SetHasCellSpanningPctCol(PRBool aValue);
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -1337,35 +1337,51 @@ nsTableOuterFrame::GetType() const
 NS_IMETHODIMP 
 nsTableOuterFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex, 
                                  nsIDOMElement* &aCell,   //out params
                                  PRInt32& aStartRowIndex, PRInt32& aStartColIndex, 
                                  PRInt32& aRowSpan, PRInt32& aColSpan,
                                  PRInt32& aActualRowSpan, PRInt32& aActualColSpan,
                                  PRBool& aIsSelected)
 {
-  if (!mInnerTableFrame) { return NS_ERROR_NOT_INITIALIZED; }
-  nsITableLayout *inner;
-  if (NS_SUCCEEDED(CallQueryInterface(mInnerTableFrame, &inner))) {
-    return (inner->GetCellDataAt(aRowIndex, aColIndex, aCell,
-                                 aStartRowIndex, aStartColIndex, 
-                                 aRowSpan, aColSpan, aActualRowSpan, aActualColSpan, 
-                                 aIsSelected));
-  }
-  return NS_ERROR_NULL_POINTER;
+  NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?");
+  
+  mInnerTableFrame->GetCellDataAt(aRowIndex, aColIndex, aCell,
+                                  aStartRowIndex, aStartColIndex, 
+                                  aRowSpan, aColSpan, aActualRowSpan,
+                                  aActualColSpan, aIsSelected);
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
+{
+  NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?");
+
+  mInnerTableFrame->GetTableSize(aRowCount, aColCount);
 }
 
-NS_IMETHODIMP nsTableOuterFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
+NS_IMETHODIMP
+nsTableOuterFrame::GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn,
+                                          PRInt32 *aIndex)
 {
-  if (!mInnerTableFrame) { return NS_ERROR_NOT_INITIALIZED; }
-  nsITableLayout *inner;
-  if (NS_SUCCEEDED(CallQueryInterface(mInnerTableFrame, &inner))) {
-    return (inner->GetTableSize(aRowCount, aColCount));
-  }
-  return NS_ERROR_NULL_POINTER;
+  NS_ENSURE_ARG_POINTER(aIndex);
+
+  NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?");
+  return mInnerTableFrame->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
+}
+
+NS_IMETHODIMP
+nsTableOuterFrame::GetRowAndColumnByIndex(PRInt32 aIndex,
+                                          PRInt32 *aRow, PRInt32 *aColumn)
+{
+  NS_ENSURE_ARG_POINTER(aRow);
+  NS_ENSURE_ARG_POINTER(aColumn);
+
+  NS_ASSERTION(mInnerTableFrame, "no inner table frame yet?");
+  return mInnerTableFrame->GetRowAndColumnByIndex(aIndex, aRow, aColumn);
 }
 
 /*---------------- end of nsITableLayout implementation ------------------*/
 
 
 nsIFrame*
 NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -187,16 +187,19 @@ public:
                            PRInt32& aStartRowIndex, PRInt32& aStartColIndex, 
                            PRInt32& aRowSpan, PRInt32& aColSpan,
                            PRInt32& aActualRowSpan, PRInt32& aActualColSpan,
                            PRBool& aIsSelected);
 
   /** @see nsITableFrame::GetTableSize */
   NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount);
 
+  NS_IMETHOD GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex);
+  NS_IMETHOD GetRowAndColumnByIndex(PRInt32 aIndex, PRInt32 *aRow, PRInt32 *aColumn);
+
   PRBool IsNested(const nsHTMLReflowState& aReflowState) const;
 
 protected:
 
 
   nsTableOuterFrame(nsStyleContext* aContext);
   virtual ~nsTableOuterFrame();