diff --git a/layout/html/table/public/nsITableLayout.h b/layout/html/table/public/nsITableLayout.h
index ca57a8ab83a..ff632eb40a1 100644
--- a/layout/html/table/public/nsITableLayout.h
+++ b/layout/html/table/public/nsITableLayout.h
@@ -48,14 +48,18 @@ public:
* @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 [OUT] the row in which aCell starts
- * @param aStartColIndex [OUT] the col in which aCell starts
+ * @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 number of rows aCell spans
* @param aColSpan [OUT] the number of cols aCell spans
* @param aIsSelected [OUT] PR_TRUE if the frame that maps aCell is selected
* in the presentation shell that owns this.
*/
- NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
+ NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
diff --git a/layout/html/table/src/nsTableFrame.cpp b/layout/html/table/src/nsTableFrame.cpp
index 511b56ef089..7f7640f19d9 100644
--- a/layout/html/table/src/nsTableFrame.cpp
+++ b/layout/html/table/src/nsTableFrame.cpp
@@ -5348,7 +5348,7 @@ void nsTableFrame::GetCellInfoAt(PRInt32 aRowX,
}
NS_IMETHODIMP
-nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
+nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
@@ -5370,13 +5370,67 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
// This will pass the NS_SUCCEEDED() test
// Thus we can iterate indexes to get all cells in a row or col
// and stop when aCell is returned null.
- if (aRowIndex >= cellMap->GetRowCount() ||
- aColIndex >= cellMap->GetColCount())
+ PRInt32 rowCount = cellMap->GetRowCount();
+ PRInt32 colCount = cellMap->GetColCount();
+
+ if (aRowIndex >= rowCount || aColIndex >= colCount)
{
return NS_TABLELAYOUT_CELL_NOT_FOUND;
}
nsTableCellFrame *cellFrame = cellMap->GetCellFrameAt(aRowIndex, aColIndex);
- if (!cellFrame) { return NS_ERROR_FAILURE;} // Some other error
+ if (!cellFrame)
+ {
+ PRInt32 rowSpan, colSpan;
+ PRInt32 row = aStartRowIndex;
+ PRInt32 col = aStartColIndex;
+
+ // We didn't find a cell at requested location,
+ // most probably because of ROWSPAN and/or COLSPAN > 1
+ // Find the cell that extends into the location we requested,
+ // starting at the most likely indexes supplied by the caller
+ // in aStartRowIndex and aStartColIndex;
+ cellFrame = cellMap->GetCellFrameAt(row, col);
+ if (cellFrame)
+ {
+ rowSpan = cellFrame->GetRowSpan();
+ colSpan = cellFrame->GetColSpan();
+
+ // Check if this extends into the location we want
+ if( aRowIndex >= row && aRowIndex < row+rowSpan &&
+ aColIndex >= col && aColIndex < col+colSpan)
+ {
+CELL_FOUND:
+ aStartRowIndex = row;
+ aStartColIndex = col;
+ aRowSpan = rowSpan;
+ aColSpan = colSpan;
+ // I know jumps aren't cool, but it's efficient!
+ goto TEST_IF_SELECTED;
+ } else {
+ // Suggested indexes didn't work,
+ // Scan through entire table to find the spanned cell
+ for (row = 0; row < rowCount; row++ )
+ {
+ for (col = 0; col < colCount; col++)
+ {
+ cellFrame = cellMap->GetCellFrameAt(row, col);
+ if (cellFrame)
+ {
+ rowSpan = cellFrame->GetRowSpan();
+ colSpan = cellFrame->GetColSpan();
+ if( aRowIndex >= row && aRowIndex < row+rowSpan &&
+ aColIndex >= col && aColIndex < col+colSpan)
+ {
+ goto CELL_FOUND;
+ }
+ }
+ }
+ col = 0;
+ }
+ }
+ return NS_ERROR_FAILURE; // Some other error
+ }
+ }
result = cellFrame->GetRowIndex(aStartRowIndex);
if (NS_FAILED(result)) return result;
@@ -5387,6 +5441,7 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
result = cellFrame->GetSelected(&aIsSelected);
if (NS_FAILED(result)) return result;
+TEST_IF_SELECTED:
// do this last, because it addrefs,
// and we don't want the caller leaking it on error
nsCOMPtrcontent;
diff --git a/layout/tables/nsITableLayout.h b/layout/tables/nsITableLayout.h
index ca57a8ab83a..ff632eb40a1 100644
--- a/layout/tables/nsITableLayout.h
+++ b/layout/tables/nsITableLayout.h
@@ -48,14 +48,18 @@ public:
* @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 [OUT] the row in which aCell starts
- * @param aStartColIndex [OUT] the col in which aCell starts
+ * @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 number of rows aCell spans
* @param aColSpan [OUT] the number of cols aCell spans
* @param aIsSelected [OUT] PR_TRUE if the frame that maps aCell is selected
* in the presentation shell that owns this.
*/
- NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
+ NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 511b56ef089..7f7640f19d9 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -5348,7 +5348,7 @@ void nsTableFrame::GetCellInfoAt(PRInt32 aRowX,
}
NS_IMETHODIMP
-nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
+nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
@@ -5370,13 +5370,67 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
// This will pass the NS_SUCCEEDED() test
// Thus we can iterate indexes to get all cells in a row or col
// and stop when aCell is returned null.
- if (aRowIndex >= cellMap->GetRowCount() ||
- aColIndex >= cellMap->GetColCount())
+ PRInt32 rowCount = cellMap->GetRowCount();
+ PRInt32 colCount = cellMap->GetColCount();
+
+ if (aRowIndex >= rowCount || aColIndex >= colCount)
{
return NS_TABLELAYOUT_CELL_NOT_FOUND;
}
nsTableCellFrame *cellFrame = cellMap->GetCellFrameAt(aRowIndex, aColIndex);
- if (!cellFrame) { return NS_ERROR_FAILURE;} // Some other error
+ if (!cellFrame)
+ {
+ PRInt32 rowSpan, colSpan;
+ PRInt32 row = aStartRowIndex;
+ PRInt32 col = aStartColIndex;
+
+ // We didn't find a cell at requested location,
+ // most probably because of ROWSPAN and/or COLSPAN > 1
+ // Find the cell that extends into the location we requested,
+ // starting at the most likely indexes supplied by the caller
+ // in aStartRowIndex and aStartColIndex;
+ cellFrame = cellMap->GetCellFrameAt(row, col);
+ if (cellFrame)
+ {
+ rowSpan = cellFrame->GetRowSpan();
+ colSpan = cellFrame->GetColSpan();
+
+ // Check if this extends into the location we want
+ if( aRowIndex >= row && aRowIndex < row+rowSpan &&
+ aColIndex >= col && aColIndex < col+colSpan)
+ {
+CELL_FOUND:
+ aStartRowIndex = row;
+ aStartColIndex = col;
+ aRowSpan = rowSpan;
+ aColSpan = colSpan;
+ // I know jumps aren't cool, but it's efficient!
+ goto TEST_IF_SELECTED;
+ } else {
+ // Suggested indexes didn't work,
+ // Scan through entire table to find the spanned cell
+ for (row = 0; row < rowCount; row++ )
+ {
+ for (col = 0; col < colCount; col++)
+ {
+ cellFrame = cellMap->GetCellFrameAt(row, col);
+ if (cellFrame)
+ {
+ rowSpan = cellFrame->GetRowSpan();
+ colSpan = cellFrame->GetColSpan();
+ if( aRowIndex >= row && aRowIndex < row+rowSpan &&
+ aColIndex >= col && aColIndex < col+colSpan)
+ {
+ goto CELL_FOUND;
+ }
+ }
+ }
+ col = 0;
+ }
+ }
+ return NS_ERROR_FAILURE; // Some other error
+ }
+ }
result = cellFrame->GetRowIndex(aStartRowIndex);
if (NS_FAILED(result)) return result;
@@ -5387,6 +5441,7 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
result = cellFrame->GetSelected(&aIsSelected);
if (NS_FAILED(result)) return result;
+TEST_IF_SELECTED:
// do this last, because it addrefs,
// and we don't want the caller leaking it on error
nsCOMPtrcontent;