Bug 386813 - Support table interfaces for grid/treegrid when no HTML table undeneath, r=davdib, marcoz, sr=neil

This commit is contained in:
Alexander Surkov 2009-05-18 16:35:21 +08:00
Родитель 2167ad2503
Коммит f777a3304f
9 изменённых файлов: 981 добавлений и 78 удалений

Просмотреть файл

@ -46,11 +46,38 @@ interface nsIAccessible;
[scriptable, uuid(dcc1e5c3-966e-45b2-b30a-839d35432b24)]
interface nsIAccessibleTable : nsISupports
{
/**
* Returns the caption accessible for the table. For example, html:caption
* element of html:table element.
*/
readonly attribute nsIAccessible caption;
/**
* Returns summary description for the table. For example, @summary attribute
* on html:element.
*/
readonly attribute AString summary;
/**
* Returns columns count in the table.
* XXX: not very well named property.
*/
readonly attribute long columns;
/**
* Returns table accessible containing column headers.
*/
readonly attribute nsIAccessibleTable columnHeader;
/**
* Returns rows count in the table.
* XXX: not very well named property.
*/
readonly attribute long rows;
/**
* Returns table accessible containing row headers.
*/
readonly attribute nsIAccessibleTable rowHeader;
/**

Просмотреть файл

@ -75,6 +75,7 @@ REQUIRES = appshell \
CPPSRCS = \
nsAccessNode.cpp \
nsAccessibleEventData.cpp \
nsARIAGridAccessible.cpp \
nsARIAMap.cpp \
nsDocAccessible.cpp \
nsOuterDocAccessible.cpp \

Просмотреть файл

@ -0,0 +1,663 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsARIAGridAccessible.h"
////////////////////////////////////////////////////////////////////////////////
// nsARIAGridAccessible
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Constructor
nsARIAGridAccessible::nsARIAGridAccessible(nsIDOMNode* aDomNode,
nsIWeakReference* aShell) :
nsAccessibleWrap(aDomNode, aShell)
{
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridAccessible,
nsAccessible,
nsIAccessibleTable)
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleTable
NS_IMETHODIMP
nsARIAGridAccessible::GetCaption(nsIAccessible **aCaption)
{
NS_ENSURE_ARG_POINTER(aCaption);
*aCaption = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should be pointed by aria-labelledby on grid?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSummary(nsAString &aSummary)
{
aSummary.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should be pointed by aria-describedby on grid?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetColumns(PRInt32 *aColumns)
{
NS_ENSURE_ARG_POINTER(aColumns);
*aColumns = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessible> row, nextChild;
GetFirstChild(getter_AddRefs(row));
while (row && nsAccUtils::Role(row) != nsIAccessibleRole::ROLE_ROW) {
row->GetNextSibling(getter_AddRefs(nextChild));
row.swap(nextChild);
}
if (!row)
return NS_OK;
nsCOMPtr<nsIAccessible> cell;
row->GetFirstChild(getter_AddRefs(cell));
while (cell) {
PRUint32 role = nsAccUtils::Role(cell);
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
role == nsIAccessibleRole::ROLE_COLUMNHEADER)
(*aColumns)++;
cell->GetNextSibling(getter_AddRefs(nextChild));
cell.swap(nextChild);
}
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
{
NS_ENSURE_ARG_POINTER(aColumnHeader);
*aColumnHeader = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: what should we return here?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetRows(PRInt32 *aRows)
{
NS_ENSURE_ARG_POINTER(aRows);
*aRows = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIAccessible> row, nextRow;
GetFirstChild(getter_AddRefs(row));
while (row) {
if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW)
(*aRows)++;
row->GetNextSibling(getter_AddRefs(nextRow));
row.swap(nextRow);
}
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetRowHeader(nsIAccessibleTable **aRowHeader)
{
NS_ENSURE_ARG_POINTER(aRowHeader);
*aRowHeader = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: what should we return here?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
nsIAccessible **aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
PRInt32 rowIdx = aRow + 1;
nsCOMPtr<nsIAccessible> row, nextChild;
GetFirstChild(getter_AddRefs(row));
while (row) {
if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW)
rowIdx--;
if (rowIdx == 0)
break;
row->GetNextSibling(getter_AddRefs(nextChild));
row.swap(nextChild);
}
NS_ENSURE_ARG(row && rowIdx == 0);
PRInt32 colIdx = aColumn + 1;
nsCOMPtr<nsIAccessible> cell;
row->GetFirstChild(getter_AddRefs(cell));
while (cell) {
PRUint32 role = nsAccUtils::Role(cell);
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
role == nsIAccessibleRole::ROLE_COLUMNHEADER)
colIdx--;
if (colIdx == 0)
break;
cell->GetNextSibling(getter_AddRefs(nextChild));
cell.swap(nextChild);
}
NS_ENSURE_ARG(cell && colIdx == 0);
NS_ADDREF(*aAccessible = cell);
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex)
{
NS_ENSURE_ARG_POINTER(aIndex);
*aIndex = -1;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(aRow >= 0 && aColumn >= 0);
PRInt32 rowCount = 0;
GetRows(&rowCount);
NS_ENSURE_ARG(aRow < rowCount);
PRInt32 colCount = 0;
GetColumns(&colCount);
NS_ENSURE_ARG(aColumn < colCount);
*aIndex = colCount * aRow + aColumn;
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
{
NS_ENSURE_ARG_POINTER(aColumn);
*aColumn = -1;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(aIndex >= 0);
PRInt32 rowCount = 0;
GetRows(&rowCount);
PRInt32 colCount = 0;
GetColumns(&colCount);
NS_ENSURE_ARG(aIndex < rowCount * colCount);
*aColumn = aIndex % colCount;
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
{
NS_ENSURE_ARG_POINTER(aRow);
*aRow = -1;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(aIndex >= 0);
PRInt32 rowCount = 0;
GetRows(&rowCount);
PRInt32 colCount = 0;
GetColumns(&colCount);
NS_ENSURE_ARG(aIndex < rowCount * colCount);
*aRow = aIndex / colCount;
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
PRInt32 *aExtentCount)
{
NS_ENSURE_ARG_POINTER(aExtentCount);
*aExtentCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidRowNColumn(aRow, aColumn));
*aExtentCount = 1;
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn,
PRInt32 *aExtentCount)
{
NS_ENSURE_ARG_POINTER(aExtentCount);
*aExtentCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidRowNColumn(aRow, aColumn));
*aExtentCount = 1;
return NS_OK;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetColumnDescription(PRInt32 aColumn,
nsAString& aDescription)
{
aDescription.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidColumn(aColumn));
// XXX: not implemented
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
{
aDescription.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidRow(aRow));
// XXX: not implemented
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = PR_FALSE;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidColumn(aColumn));
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = PR_FALSE;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidRow(aRow));
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
PRBool *aIsSelected)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = PR_FALSE;
if (IsDefunct())
return NS_ERROR_FAILURE;
NS_ENSURE_ARG(IsValidRowNColumn(aRow, aColumn));
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSelectedCellsCount(PRUint32* aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSelectedColumnsCount(PRUint32* aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSelectedRowsCount(PRUint32* aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSelectedCells(PRUint32 *aCellsCount, PRInt32 **aCells)
{
NS_ENSURE_ARG_POINTER(aCellsCount);
*aCellsCount = 0;
NS_ENSURE_ARG_POINTER(aCells);
*aCells = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSelectedColumns(PRUint32 *aColumnsCount,
PRInt32 **aColumns)
{
NS_ENSURE_ARG_POINTER(aColumnsCount);
*aColumnsCount = 0;
NS_ENSURE_ARG_POINTER(aColumns);
*aColumns = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::GetSelectedRows(PRUint32 *aRowsCount, PRInt32 **aRows)
{
NS_ENSURE_ARG_POINTER(aRowsCount);
*aRowsCount = 0;
NS_ENSURE_ARG_POINTER(aRows);
*aRows = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::SelectRow(PRInt32 aRow)
{
NS_ENSURE_ARG(IsValidRow(aRow));
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::SelectColumn(PRInt32 aColumn)
{
NS_ENSURE_ARG(IsValidColumn(aColumn));
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::UnselectRow(PRInt32 aRow)
{
NS_ENSURE_ARG(IsValidRow(aRow));
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::UnselectColumn(PRInt32 aColumn)
{
NS_ENSURE_ARG(IsValidColumn(aColumn));
if (IsDefunct())
return NS_ERROR_FAILURE;
// XXX: should we rely on aria-selected or DOM selection?
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsARIAGridAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
{
NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
*aIsProbablyForLayout = PR_FALSE;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// Protected
PRBool
nsARIAGridAccessible::IsValidRow(PRInt32 aRow)
{
if (aRow < 0)
return PR_FALSE;
PRInt32 rowCount = 0;
GetRows(&rowCount);
return aRow < rowCount;
}
PRBool
nsARIAGridAccessible::IsValidColumn(PRInt32 aColumn)
{
if (aColumn < 0)
return PR_FALSE;
PRInt32 colCount = 0;
GetColumns(&colCount);
return aColumn < colCount;
}
PRBool
nsARIAGridAccessible::IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn)
{
if (aRow < 0 || aColumn < 0)
return PR_FALSE;
PRInt32 rowCount = 0;
GetRows(&rowCount);
if (aRow >= rowCount)
return PR_FALSE;
PRInt32 colCount = 0;
GetColumns(&colCount);
return aColumn < colCount;
}
////////////////////////////////////////////////////////////////////////////////
// nsARIAGridCellAccessible
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Constructor
nsARIAGridCellAccessible::nsARIAGridCellAccessible(nsIDOMNode* aDomNode,
nsIWeakReference* aShell) :
nsHyperTextAccessibleWrap(aDomNode, aShell)
{
}
////////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS_INHERITED0(nsARIAGridCellAccessible,
nsHyperTextAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
nsresult
nsARIAGridCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsresult rv = nsHyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
NS_ENSURE_SUCCESS(rv, rv);
// Expose "table-cell-index" attribute.
nsCOMPtr<nsIAccessible> thisRow;
GetParent(getter_AddRefs(thisRow));
if (nsAccUtils::Role(thisRow) != nsIAccessibleRole::ROLE_ROW)
return NS_OK;
PRInt32 colIdx = 0, colCount = 0;
nsCOMPtr<nsIAccessible> child, nextChild;
thisRow->GetFirstChild(getter_AddRefs(child));
while (child) {
if (child == this)
colIdx = colCount;
PRUint32 role = nsAccUtils::Role(child);
if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
role == nsIAccessibleRole::ROLE_COLUMNHEADER)
colCount++;
child->GetNextSibling(getter_AddRefs(nextChild));
child.swap(nextChild);
}
nsCOMPtr<nsIAccessible> table;
thisRow->GetParent(getter_AddRefs(table));
if (nsAccUtils::Role(table) != nsIAccessibleRole::ROLE_TABLE &&
nsAccUtils::Role(table) != nsIAccessibleRole::ROLE_TREE_TABLE)
return NS_OK;
PRInt32 rowIdx = 0;
table->GetFirstChild(getter_AddRefs(child));
while (child && child != thisRow) {
if (nsAccUtils::Role(child) == nsIAccessibleRole::ROLE_ROW)
rowIdx++;
child->GetNextSibling(getter_AddRefs(nextChild));
child.swap(nextChild);
}
PRInt32 idx = rowIdx * colCount + colIdx;
nsAutoString stringIdx;
stringIdx.AppendInt(idx);
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::tableCellIndex,
stringIdx);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsARIAGridAccessible_h_
#define nsARIAGridAccessible_h_
#include "nsIAccessibleTable.h"
#include "nsHyperTextAccessibleWrap.h"
/**
* Accessible for ARIA grid and treegrid.
*/
class nsARIAGridAccessible : public nsAccessibleWrap,
public nsIAccessibleTable
{
public:
nsARIAGridAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessibleTable
NS_DECL_NSIACCESSIBLETABLE
protected:
PRBool IsValidRow(PRInt32 aRow);
PRBool IsValidColumn(PRInt32 aColumn);
PRBool IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn);
};
/**
* Accessible for ARIA gridcell and rowheader/columnheader.
*/
class nsARIAGridCellAccessible : public nsHyperTextAccessibleWrap
{
public:
nsARIAGridCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsAccessible
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
};
#endif

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsAccessibilityService.h"
#include "nsCoreUtils.h"
#include "nsAccUtils.h"
#include "nsARIAGridAccessible.h"
#include "nsARIAMap.h"
#include "nsIContentViewer.h"
#include "nsCURILoader.h"
@ -1493,31 +1494,18 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
return NS_OK;
}
// Elements may implement nsIAccessibleProvider via XBL. This allows them to
// say what kind of accessible to create.
nsresult rv = GetAccessibleByType(aNode, getter_AddRefs(newAcc));
NS_ENSURE_SUCCESS(rv, rv);
if (!newAcc && !isHTML) {
if (content->GetNameSpaceID() == kNameSpaceID_SVG &&
content->Tag() == nsAccessibilityAtoms::svg) {
newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
nsIAccessibleRole::ROLE_DIAGRAM);
}
else if (content->GetNameSpaceID() == kNameSpaceID_MathML &&
content->Tag() == nsAccessibilityAtoms::math) {
newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
nsIAccessibleRole::ROLE_EQUATION);
}
} else if (!newAcc) { // HTML accessibles
if (!newAcc && isHTML) { // HTML accessibles
PRBool tryTagNameOrFrame = PR_TRUE;
nsIAtom *frameType = frame->GetType();
if (!roleMapEntry &&
(frameType == nsAccessibilityAtoms::tableCaptionFrame ||
frameType == nsAccessibilityAtoms::tableCellFrame ||
frameType == nsAccessibilityAtoms::tableRowGroupFrame ||
frameType == nsAccessibilityAtoms::tableRowFrame)) {
PRBool partOfHTMLTable =
frameType == nsAccessibilityAtoms::tableCaptionFrame ||
frameType == nsAccessibilityAtoms::tableCellFrame ||
frameType == nsAccessibilityAtoms::tableRowGroupFrame ||
frameType == nsAccessibilityAtoms::tableRowFrame;
if (!roleMapEntry && partOfHTMLTable) {
// Table-related frames don't get table-related roles
// unless they are inside a table, but they may still get generic
// accessibles
@ -1562,14 +1550,27 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
tryTagNameOrFrame = PR_FALSE;
}
if (tryTagNameOrFrame) {
if (roleMapEntry && (!partOfHTMLTable || !tryTagNameOrFrame ||
frameType != nsAccessibilityAtoms::tableOuterFrame)) {
// Try to create ARIA grid/treegrid accessibles.
if (roleMapEntry->role == nsIAccessibleRole::ROLE_TABLE ||
roleMapEntry->role == nsIAccessibleRole::ROLE_TREE_TABLE) {
newAcc = new nsARIAGridAccessible(aNode, aWeakShell);
} else if (roleMapEntry->role == nsIAccessibleRole::ROLE_GRID_CELL ||
roleMapEntry->role == nsIAccessibleRole::ROLE_ROWHEADER ||
roleMapEntry->role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
newAcc = new nsARIAGridCellAccessible(aNode, aWeakShell);
}
}
if (!newAcc && tryTagNameOrFrame) {
// Prefer to use markup (mostly tag name, perhaps attributes) to
// decide if and what kind of accessible to create.
// The method creates accessibles for table related content too therefore
// we do not call it if accessibles for table related content are
// prevented above.
rv = CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode,
getter_AddRefs(newAcc));
nsresult rv = CreateHTMLAccessibleByMarkup(frame, aWeakShell, aNode,
getter_AddRefs(newAcc));
NS_ENSURE_SUCCESS(rv, rv);
if (!newAcc) {
@ -1591,6 +1592,27 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
}
}
if (!newAcc) {
// Elements may implement nsIAccessibleProvider via XBL. This allows them to
// say what kind of accessible to create.
nsresult rv = GetAccessibleByType(aNode, getter_AddRefs(newAcc));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!newAcc) {
// Create generic accessibles for SVG and MathML nodes.
if (content->GetNameSpaceID() == kNameSpaceID_SVG &&
content->Tag() == nsAccessibilityAtoms::svg) {
newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
nsIAccessibleRole::ROLE_DIAGRAM);
}
else if (content->GetNameSpaceID() == kNameSpaceID_MathML &&
content->Tag() == nsAccessibilityAtoms::math) {
newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
nsIAccessibleRole::ROLE_EQUATION);
}
}
if (!newAcc) {
GetAccessibleForDeckChildren(aNode, getter_AddRefs(newAcc));
}

Просмотреть файл

@ -65,6 +65,7 @@ _TEST_FILES =\
nsIAccessibleEditableText.js \
relations.js \
role.js \
table.js \
value.js \
test_accessnode_invalidation.html \
test_actions_aria.html \
@ -94,7 +95,6 @@ _TEST_FILES =\
test_name_button.html \
test_name_link.html \
test_name_markup.html \
$(warning test_table_indexes.html temporarily disabled) \
test_nsIAccessible_applicationAccessible.html \
$(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \
test_nsIAccessible_selects.html \
@ -123,6 +123,8 @@ _TEST_FILES =\
test_table_2.html \
test_table_3.html \
test_table_4.html \
$(warning test_table_indexes.html temporarily disabled) \
test_table_indexes_ariagrid.html \
test_textattrs.html \
test_textboxes.html \
test_textboxes.xul \

Просмотреть файл

@ -0,0 +1,71 @@
/**
* Test table indexes.
*
* @param aIdentifier [in] table accessible identifier
* @param aLen [in] cells count
* @param aRowIdxes [in] array of row indexes for each cell index
* @param aColIdxes [in] array of column indexes for each cell index
*/
function testTableIndexes(aIdentifier, aLen, aRowIdxes, aColIdxes)
{
var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]);
if (!tableAcc)
return;
var row, column, index;
var cellAcc;
var id = prettyName(aIdentifier);
for (var i = 0; i < aLen; i++) {
try {
row = tableAcc.getRowAtIndex(i);
} catch (e) {
ok(false, id + ": can't get row index for cell index " + i + ".");
}
try {
column = tableAcc.getColumnAtIndex(i);
} catch (e) {
ok(false, id + ": can't get column index for cell index " + i + ".");
}
try {
index = tableAcc.getIndexAt(aRowIdxes[i], aColIdxes[i]);
} catch (e) {
ok(false,
id + ": can't get cell index by row index " + aRowIdxes[i] +
" and column index: " + aColIdxes[i] + ".");
}
is(row, aRowIdxes[i], id + ": row for index " + i +" is nor correct");
is(column, aColIdxes[i],
id + ": column for index " + i +" is not correct");
is(index, i,
id + ": row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
try {
cellAcc = null;
cellAcc = tableAcc.cellRefAt(row, column);
} catch (e) { }
ok(cellAcc,
id + ": Can't get cell accessible at row = " + row + ", column = " + column);
if (cellAcc) {
var attrs = cellAcc.attributes;
var strIdx = "";
try {
strIdx = attrs.getStringProperty("table-cell-index");
} catch (e) {
ok(false,
id + ": no cell index from object attributes on the cell accessible at index " + index + ".");
}
if (strIdx) {
is (parseInt(strIdx), index,
id + ": cell index from object attributes of cell accessible isn't corrent.");
}
}
}
}

Просмотреть файл

@ -5,96 +5,60 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
-->
<head>
<title>Table indexes chrome tests</title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/table.js"></script>
<script type="application/javascript">
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
const nsIAccessibleTable = Components.interfaces.nsIAccessibleTable;
var gAccService = null;
function doTest()
{
gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(nsIAccessibleRetrieval);
//////////////////////////////////////////////////////////////////////////
// table
var tRow = new Array(0,0,0,1,1,1,2,2,3,3);
var tCol = new Array(0,1,2,0,1,2,0,1,1,2);
testTable("table", 10, tRow, tCol);
testTableIndexes("table", 10, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableinsane1
tRow = [0,0,0,1,1,1,2,2,3,3];
tCol = [0,1,2,0,1,2,0,1,1,2];
testTable("tableinsane1", 10, tRow, tCol);
testTableIndexes("tableinsane1", 10, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableinsane2
tRow = [0,0,0,1,1,1,2,2,3,3,4,4,4];
tCol = [0,1,2,0,1,2,0,1,1,2,1,3,4];
testTable("tableinsane2", 13, tRow, tCol);
testTableIndexes("tableinsane2", 13, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableinsane4
tRow = [0,0,0,1,1,1,2,2,3,4];
tCol = [0,1,2,0,1,2,0,2,0,0];
testTable("tableinsane4", 10, tRow, tCol);
testTableIndexes("tableinsane4", 10, tRow, tCol);
//////////////////////////////////////////////////////////////////////////
// tableborder
tRow = [0,0,0,1,1,1,2,2,3,3];
tCol = [0,1,2,0,1,2,0,1,1,2];
testTable("tableborder", 10, tRow, tCol);
testTableIndexes("tableborder", 10, tRow, tCol);
SimpleTest.finish();
}
function testTable(aId, aLen, aRowIdxes, aColIdxes)
{
var table = document.getElementById(aId);
var tableAcc = gAccService.getAccessibleFor(table).
QueryInterface(nsIAccessibleTable);
var row, column, index;
var cellAcc;
for (var i = 0; i < aLen; i++) {
row = tableAcc.getRowAtIndex(i);
column = tableAcc.getColumnAtIndex(i);
index = tableAcc.getIndexAt(aRowIdxes[i], aColIdxes[i]);
is(row, aRowIdxes[i], aId + ": row for index " + i +" is nor correct");
is(column, aColIdxes[i],
aId + ": column for index " + i +"is nor correct");
is(index, i,
aId + ": row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
try {
cellAcc = null;
cellAcc = tableAcc.cellRefAt(row, column);
} catch (e) { }
ok(cellAcc,
aId + ": Can't get cell accessible at row = " + row + ", column = " + column);
if (cellAcc) {
var attrs = cellAcc.attributes;
is (parseInt(attrs.getStringProperty("table-cell-index")), index,
aId + ": cell index from object attributes of cell accessible isn't corrent.");
}
}
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>

Просмотреть файл

@ -0,0 +1,71 @@
<!DOCTYPE html>
<html>
<head>
<title>Table indexes for ARIA grid tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/attributes.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/table.js"></script>
<script type="application/javascript">
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// ARIA grid
var tRow = new Array(0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3);
var tCol = new Array(0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2);
testTableIndexes("grid", 12, tRow, tCol);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=386813"
title="support nsIAccessibleTable on ARIA grid/treegrid">Mozilla Bug 386813</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div role="grid" id="grid">
<div role="row">
<span role="columnheader">column1</span>
<span id="a" role="columnheader">column2</span>
<span role="columnheader">column3</span>
</div>
<div role="row">
<span role="rowheader">row1</span>
<span role="gridcell">cell1</span>
<span role="gridcell">cell2</span>
</div>
<div role="row">
<span role="rowheader">row2</span>
<span role="gridcell">cell3</span>
<span role="gridcell">cell4</span>
</div>
<div role="row">
<span role="rowheader">row3</span>
<span role="gridcell">cell5</span>
<span role="gridcell">cell6</span>
</div>
</div>
</body>
</html>