mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
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
This commit is contained in:
parent
26c047f2bc
commit
d8aebfb510
@ -531,20 +531,11 @@ nsHTMLTableAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
|
||||
|
||||
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
|
||||
@ -552,16 +543,12 @@ 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
|
||||
@ -569,16 +556,12 @@ 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
|
||||
|
@ -891,7 +891,83 @@ nsTableCellMap::GetCellInfoAt(PRInt32 aRowIndex,
|
||||
}
|
||||
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
|
||||
@ -1250,6 +1326,57 @@ nsCellMap::GetCellFrame(PRInt32 aRowIndexIn,
|
||||
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)
|
||||
|
@ -173,6 +173,29 @@ public:
|
||||
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();
|
||||
|
||||
@ -301,6 +324,31 @@ public:
|
||||
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
|
||||
|
@ -43,7 +43,7 @@ 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
|
||||
@ -87,6 +87,31 @@ public:
|
||||
* 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)
|
||||
|
@ -3880,6 +3880,39 @@ NS_IMETHODIMP nsTableFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
|
||||
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
|
||||
|
@ -469,6 +469,8 @@ public:
|
||||
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;
|
||||
|
||||
|
@ -1342,25 +1342,41 @@ nsTableOuterFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
|
||||
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_IMETHODIMP
|
||||
nsTableOuterFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
|
||||
{
|
||||
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_ASSERTION(mInnerTableFrame, "no inner table frame yet?");
|
||||
|
||||
mInnerTableFrame->GetTableSize(aRowCount, aColCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTableOuterFrame::GetIndexByRowAndColumn(PRInt32 aRow, PRInt32 aColumn,
|
||||
PRInt32 *aIndex)
|
||||
{
|
||||
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 ------------------*/
|
||||
|
@ -192,6 +192,9 @@ public:
|
||||
/** @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:
|
||||
|
Loading…
Reference in New Issue
Block a user