mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 09:49:14 +00:00
Bug 503727 - Reorganize implementation of XUL tree accessibility, r=marcoz, ginn, sr=neil
This commit is contained in:
parent
b61d0f7850
commit
4f036876e8
@ -45,66 +45,15 @@
|
||||
// --------------------------------------------------------
|
||||
// nsXULTreeAccessibleWrap Accessible
|
||||
// --------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessibleWrap, nsXULTreeAccessible, nsIAccessibleTable)
|
||||
|
||||
nsXULTreeAccessibleWrap::nsXULTreeAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
|
||||
nsXULTreeAccessible(aDOMNode, aShell)
|
||||
nsXULTreeGridAccessibleWrap::
|
||||
nsXULTreeGridAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
|
||||
nsXULTreeGridAccessible(aDOMNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
// tree's children count is row count * col count + treecols count
|
||||
// override "children count = row count + treecols count" defined in
|
||||
// nsXULTreeAccessible
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetChildCount(PRInt32 *aAccChildCount)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
|
||||
// get treecols count, which is cached by nsAccessibleTreeWalker
|
||||
// by going through DOM structure of XUL tree
|
||||
nsAccessible::GetChildCount(aAccChildCount);
|
||||
|
||||
if (*aAccChildCount != 0 && *aAccChildCount != eChildCountUninitialized) {
|
||||
// add the count of table cell (or tree item) accessibles, which are
|
||||
// created and appended by XUL tree accessible implementation
|
||||
PRInt32 rowCount, colCount = 1;
|
||||
mTreeView->GetRowCount(&rowCount);
|
||||
GetColumns(&colCount);
|
||||
|
||||
*aAccChildCount += rowCount * colCount;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetCaption(nsIAccessible **aCaption)
|
||||
{
|
||||
*aCaption = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSummary(nsAString &aSummary)
|
||||
{
|
||||
aSummary.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumns(PRInt32 *aColumnCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aColumnCount);
|
||||
*aColumnCount = 0;
|
||||
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
column = GetFirstVisibleColumn(mTree);
|
||||
if (!column)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
do {
|
||||
(*aColumnCount)++;
|
||||
} while ((column = GetNextVisibleColumn(column)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeGridAccessibleWrap::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -121,210 +70,8 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnHeader(nsIAccessibleTable **aCol
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRows(PRInt32 *aRows)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
|
||||
return mTreeView->GetRowCount(aRows);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowHeader(nsIAccessibleTable **aRowHeader)
|
||||
{
|
||||
// Row header not supported
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::GetSelectedCellsCount(PRUint32* aCount)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::GetSelectedColumnsCount(PRUint32* aCount)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::GetSelectedRowsCount(PRUint32* aCount)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::GetSelectedCells(PRUint32 *aNumCells,
|
||||
PRInt32 **aCells)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSelectedColumns(PRUint32 *aNumColumns, PRInt32 **aColumns)
|
||||
{
|
||||
// If all the row has been selected, then all the columns are selected.
|
||||
// Because we can't select a column alone.
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_ARG_POINTER(aNumColumns);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 rows;
|
||||
rv = GetRows(&rows);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 selectedRows;
|
||||
rv = GetSelectionCount(&selectedRows);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (rows == selectedRows) {
|
||||
PRInt32 columns;
|
||||
rv = GetColumns(&columns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aNumColumns = columns;
|
||||
} else {
|
||||
*aNumColumns = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 *outArray = (PRInt32 *)nsMemory::Alloc((*aNumColumns) * sizeof(PRInt32));
|
||||
NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
for (PRUint32 index = 0; index < *aNumColumns; index++) {
|
||||
outArray[index] = index;
|
||||
}
|
||||
|
||||
*aColumns = outArray;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetSelectedRows(PRUint32 *aNumRows, PRInt32 **aRows)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_ARG_POINTER(aNumRows);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
rv = GetSelectionCount((PRInt32 *)aNumRows);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 *outArray = (PRInt32 *)nsMemory::Alloc((*aNumRows) * sizeof(PRInt32));
|
||||
NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsITreeView> view;
|
||||
rv = mTree->GetView(getter_AddRefs(view));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsITreeSelection> selection;
|
||||
rv = view->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 rowCount;
|
||||
rv = GetRows(&rowCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool isSelected;
|
||||
PRInt32 index, curr = 0;
|
||||
for (index = 0; index < rowCount; index++) {
|
||||
selection->IsSelected(index, &isSelected);
|
||||
if (isSelected) {
|
||||
outArray[curr++] = index;
|
||||
}
|
||||
}
|
||||
|
||||
*aRows = outArray;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::CellRefAt(PRInt32 aRow, PRInt32 aColumn, nsIAccessible **aAccessibleCell)
|
||||
{
|
||||
NS_ENSURE_TRUE(mDOMNode && mTree, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 index;
|
||||
rv = GetIndexAt(aRow, aColumn, &index);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return GetChildAt(index, aAccessibleCell);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex)
|
||||
{
|
||||
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_ARG_POINTER(aIndex);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 columns;
|
||||
rv = GetColumns(&columns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
*aIndex = aRow * columns + aColumn + treeCols;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aColumn);
|
||||
|
||||
*aColumn = -1;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 columns;
|
||||
rv = GetColumns(&columns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
|
||||
if (aIndex >= treeCols) {
|
||||
*aColumn = (aIndex - treeCols) % columns;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRow);
|
||||
|
||||
*aRow = -1;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 columns;
|
||||
rv = GetColumns(&columns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
|
||||
if (aIndex >= treeCols) {
|
||||
*aRow = (aIndex - treeCols) / columns;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
*_retval = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
*_retval = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsAString & _retval)
|
||||
nsXULTreeGridAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsAString & _retval)
|
||||
{
|
||||
nsCOMPtr<nsIAccessibleTable> columnHeader;
|
||||
nsresult rv = GetColumnHeader(getter_AddRefs(columnHeader));
|
||||
@ -334,112 +81,6 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsA
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowDescription(PRInt32 aRow, nsAString & _retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::IsColumnSelected(PRInt32 aColumn, PRBool *_retval)
|
||||
{
|
||||
// If all the row has been selected, then all the columns are selected.
|
||||
// Because we can't select a column alone.
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRInt32 rows;
|
||||
rv = GetRows(&rows);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 selectedRows;
|
||||
rv = GetSelectionCount(&selectedRows);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = rows == selectedRows;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::IsRowSelected(PRInt32 aRow, PRBool *_retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsITreeView> view;
|
||||
rv = mTree->GetView(getter_AddRefs(view));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsITreeSelection> selection;
|
||||
rv = view->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return selection->IsSelected(aRow, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, PRBool *_retval)
|
||||
{
|
||||
return IsRowSelected(aRow, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::SelectRow(PRInt32 aRow)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::SelectColumn(PRInt32 aColumn)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::UnselectRow(PRInt32 aRow)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeAccessibleWrap::UnselectColumn(PRInt32 aColumn)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
|
||||
{
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
|
||||
PRInt32 rowIndex;
|
||||
nsresult rv = GetRowAtIndex(aIndex, &rowIndex);
|
||||
|
||||
nsCOMPtr<nsITreeSelection> selection;
|
||||
rv = mTreeView->GetSelection(getter_AddRefs(selection));
|
||||
NS_ASSERTION(selection, "Can't get selection from mTreeView");
|
||||
|
||||
if (selection) {
|
||||
selection->IsSelected(rowIndex, aSelState);
|
||||
// XXX: Can move to nsXULTreeAccessible if this can be applied to cross-platform
|
||||
if ((!(*aSelState) && eSelection_Add == aMethod)) {
|
||||
nsresult rv = selection->Select(rowIndex);
|
||||
mTree->EnsureRowIsVisible(aIndex);
|
||||
return rv;
|
||||
}
|
||||
// XXX: Will eSelection_Remove happen for XULTree? Leave the original implementation here
|
||||
if ((*aSelState) && eSelection_Remove == aMethod) {
|
||||
return selection->ToggleSelect(rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
|
||||
{
|
||||
*aIsProbablyForLayout = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// nsXULTreeColumnsAccessibleWrap Accessible
|
||||
// --------------------------------------------------------
|
||||
|
@ -40,27 +40,16 @@
|
||||
#ifndef __nsXULTreeAccessibleWrap_h__
|
||||
#define __nsXULTreeAccessibleWrap_h__
|
||||
|
||||
#include "nsIAccessibleTable.h"
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#include "nsXULTreeGridAccessible.h"
|
||||
|
||||
typedef class nsXULTreeitemAccessible nsXULTreeitemAccessibleWrap;
|
||||
|
||||
class nsXULTreeAccessibleWrap : public nsXULTreeAccessible,
|
||||
public nsIAccessibleTable
|
||||
class nsXULTreeGridAccessibleWrap : public nsXULTreeGridAccessible
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
nsXULTreeGridAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
|
||||
nsXULTreeAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULTreeAccessibleWrap() {}
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
|
||||
protected:
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod,
|
||||
PRBool *aSelState);
|
||||
// nsIAccessibleTable
|
||||
NS_IMETHOD GetColumnHeader(nsIAccessibleTable **aColumnHeader);
|
||||
NS_IMETHOD GetColumnDescription(PRInt32 aColumn, nsAString& aDescription);
|
||||
};
|
||||
|
||||
class nsXULTreeColumnsAccessibleWrap : public nsXULTreeColumnsAccessible,
|
||||
@ -71,7 +60,6 @@ public:
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
|
||||
nsXULTreeColumnsAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULTreeColumnsAccessibleWrap() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -50,7 +50,7 @@
|
||||
#include "nsAccessibleTreeWalker.h"
|
||||
#include "nsAccessible.h"
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#include "nsXULTreeGridAccessible.h"
|
||||
|
||||
#include "nsIDOMXULContainerElement.h"
|
||||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
@ -779,16 +779,6 @@ nsAccUtils::QueryAccessibleTree(nsIAccessible *aAccessible)
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
already_AddRefed<nsXULTreeitemAccessible>
|
||||
nsAccUtils::QueryAccessibleTreeitem(nsIAccessNode *aAccessNode)
|
||||
{
|
||||
nsXULTreeitemAccessible* accessible = nsnull;
|
||||
if (aAccessNode)
|
||||
CallQueryInterface(aAccessNode, &accessible);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
|
@ -58,7 +58,6 @@ class nsHTMLTableAccessible;
|
||||
class nsDocAccessible;
|
||||
#ifdef MOZ_XUL
|
||||
class nsXULTreeAccessible;
|
||||
class nsXULTreeitemAccessible;
|
||||
#endif
|
||||
|
||||
class nsAccUtils
|
||||
@ -289,6 +288,28 @@ public:
|
||||
*/
|
||||
static void GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
|
||||
|
||||
/**
|
||||
* Query DestinationType from the given SourceType.
|
||||
*/
|
||||
template<class DestinationType, class SourceType> static inline
|
||||
already_AddRefed<DestinationType> QueryObject(SourceType *aObject)
|
||||
{
|
||||
DestinationType* object = nsnull;
|
||||
if (aObject)
|
||||
CallQueryInterface(aObject, &object);
|
||||
|
||||
return object;
|
||||
}
|
||||
template<class DestinationType, class SourceType> static inline
|
||||
already_AddRefed<DestinationType> QueryObject(nsCOMPtr<SourceType>& aObject)
|
||||
{
|
||||
DestinationType* object = nsnull;
|
||||
if (aObject)
|
||||
CallQueryInterface(aObject, &object);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query nsAccessNode from the given nsIAccessible.
|
||||
*/
|
||||
@ -364,12 +385,6 @@ public:
|
||||
*/
|
||||
static already_AddRefed<nsXULTreeAccessible>
|
||||
QueryAccessibleTree(nsIAccessible *aAccessible);
|
||||
|
||||
/**
|
||||
* Query nsXULTreeitemAccessible from the given nsIAccessNode.
|
||||
*/
|
||||
static already_AddRefed<nsXULTreeitemAccessible>
|
||||
QueryAccessibleTreeitem(nsIAccessNode *aAccessNode);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
|
@ -74,6 +74,18 @@ class nsIDocShellTreeItem;
|
||||
typedef nsInterfaceHashtable<nsVoidPtrHashKey, nsIAccessNode>
|
||||
nsAccessNodeHashtable;
|
||||
|
||||
// What we want is: NS_INTERFACE_MAP_ENTRY(self) for static IID accessors,
|
||||
// but some of our classes have an ambiguous base class of nsISupports which
|
||||
// prevents this from working (the default macro converts it to nsISupports,
|
||||
// then addrefs it, then returns it). Therefore, we expand the macro here and
|
||||
// change it so that it works. Yuck.
|
||||
#define NS_INTERFACE_MAP_STATIC_AMBIGUOUS(_class) \
|
||||
if (aIID.Equals(NS_GET_IID(_class))) { \
|
||||
NS_ADDREF(this); \
|
||||
*aInstancePtr = this; \
|
||||
return NS_OK; \
|
||||
} else
|
||||
|
||||
#define NS_OK_DEFUNCT_OBJECT \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x22)
|
||||
|
||||
|
@ -1912,8 +1912,7 @@ nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
|
||||
*aAccessible = new nsXULThumbAccessible(aNode, weakShell);
|
||||
break;
|
||||
case nsIAccessibleProvider::XULTree:
|
||||
*aAccessible = new nsXULTreeAccessibleWrap(aNode, weakShell);
|
||||
break;
|
||||
return GetAccessibleForXULTree(aNode, weakShell, aAccessible);
|
||||
case nsIAccessibleProvider::XULTreeColumns:
|
||||
*aAccessible = new nsXULTreeColumnsAccessibleWrap(aNode, weakShell);
|
||||
break;
|
||||
@ -2147,3 +2146,34 @@ nsAccessibilityService::GetAccessibleForDeckChildren(nsIDOMNode *aNode, nsIAcces
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
nsresult
|
||||
nsAccessibilityService::GetAccessibleForXULTree(nsIDOMNode *aNode,
|
||||
nsIWeakReference *aWeakShell,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
nsCOMPtr<nsITreeBoxObject> treeBoxObj;
|
||||
nsCoreUtils::GetTreeBoxObject(aNode, getter_AddRefs(treeBoxObj));
|
||||
if (!treeBoxObj)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsITreeColumns> treeColumns;
|
||||
treeBoxObj->GetColumns(getter_AddRefs(treeColumns));
|
||||
if (!treeColumns)
|
||||
return NS_OK;
|
||||
|
||||
PRInt32 count = 0;
|
||||
treeColumns->GetCount(&count);
|
||||
if (count == 1) // outline of list accessible
|
||||
*aAccessible = new nsXULTreeAccessible(aNode, aWeakShell);
|
||||
else // table or tree table accessible
|
||||
*aAccessible = new nsXULTreeGridAccessibleWrap(aNode, aWeakShell);
|
||||
|
||||
if (!*aAccessible)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aAccessible);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -136,6 +136,15 @@ private:
|
||||
nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode,
|
||||
nsIAccessible **aAccessible);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
/**
|
||||
* Create accessible for XUL tree element.
|
||||
*/
|
||||
nsresult GetAccessibleForXULTree(nsIDOMNode *aNode,
|
||||
nsIWeakReference *aWeakShell,
|
||||
nsIAccessible **aAccessible);
|
||||
#endif
|
||||
|
||||
static nsAccessibilityService *gAccessibilityService;
|
||||
|
||||
/**
|
||||
|
@ -2700,48 +2700,9 @@ NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure)
|
||||
nsresult
|
||||
nsAccessible::DoCommand(nsIContent *aContent, PRUint32 aActionIndex)
|
||||
{
|
||||
NS_ASSERTION(gDoCommandTimer,
|
||||
"How did we get here if there was no gDoCommandTimer?");
|
||||
NS_RELEASE(gDoCommandTimer);
|
||||
|
||||
nsCOMPtr<nsIContent> content =
|
||||
reinterpret_cast<nsIContent*>(aClosure);
|
||||
|
||||
nsIDocument *doc = content->GetDocument();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
|
||||
// Scroll into view.
|
||||
presShell->ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
|
||||
// Fire mouse down and mouse up events.
|
||||
PRBool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
|
||||
content);
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_UP, presShell, content);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use Timer to execute "Click" command of XUL/HTML element (e.g. menuitem, button...).
|
||||
*
|
||||
* When "Click" is to open a "modal" dialog/window, it won't return untill the
|
||||
* dialog/window is closed. If executing "Click" command directly in
|
||||
* nsXXXAccessible::DoAction, it will block AT-Tools(e.g. GOK) that invoke
|
||||
* "action" of mozilla accessibles direclty.
|
||||
*/
|
||||
nsresult nsAccessible::DoCommand(nsIContent *aContent)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = aContent;
|
||||
if (!content) {
|
||||
content = do_QueryInterface(mDOMNode);
|
||||
}
|
||||
if (gDoCommandTimer) {
|
||||
// Already have timer going for another command
|
||||
NS_WARNING("Doubling up on do command timers doesn't work. This wasn't expected.");
|
||||
@ -2749,14 +2710,55 @@ nsresult nsAccessible::DoCommand(nsIContent *aContent)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (!timer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ENSURE_TRUE(timer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIContent> content = aContent;
|
||||
if (!content)
|
||||
content = do_QueryInterface(mDOMNode);
|
||||
|
||||
// Command closure object memory will be free in DoCommandCallback().
|
||||
nsCommandClosure *closure =
|
||||
new nsCommandClosure(this, content, aActionIndex);
|
||||
NS_ENSURE_TRUE(closure, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(gDoCommandTimer = timer);
|
||||
return gDoCommandTimer->InitWithFuncCallback(DoCommandCallback,
|
||||
(void*)content, 0,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
static_cast<void*>(closure),
|
||||
0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
NS_ASSERTION(gDoCommandTimer,
|
||||
"How did we get here if there was no gDoCommandTimer?");
|
||||
NS_RELEASE(gDoCommandTimer);
|
||||
|
||||
nsCommandClosure *closure = static_cast<nsCommandClosure*>(aClosure);
|
||||
closure->accessible->DispatchClickEvent(closure->content,
|
||||
closure->actionIndex);
|
||||
delete closure;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessible::DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
|
||||
// Scroll into view.
|
||||
presShell->ScrollContentIntoView(aContent, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
|
||||
// Fire mouse down and mouse up events.
|
||||
PRBool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
|
||||
aContent);
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_UP, presShell, aContent);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIAccessible>
|
||||
|
@ -338,9 +338,52 @@ protected:
|
||||
// Hyperlink helpers
|
||||
virtual nsresult GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset);
|
||||
|
||||
// For accessibles that have actions
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Action helpers
|
||||
|
||||
/**
|
||||
* Used to describe click action target. See DoCommand() method.
|
||||
*/
|
||||
struct nsCommandClosure
|
||||
{
|
||||
nsCommandClosure(nsAccessible *aAccessible, nsIContent *aContent,
|
||||
PRUint32 aActionIndex) :
|
||||
accessible(aAccessible), content(aContent), actionIndex(aActionIndex) {}
|
||||
|
||||
nsRefPtr<nsAccessible> accessible;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
PRUint32 actionIndex;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepares click action that will be invoked in timeout.
|
||||
*
|
||||
* @note DoCommand() prepares an action in timeout because when action
|
||||
* command opens a modal dialog/window, it won't return until the
|
||||
* dialog/window is closed. If executing action command directly in
|
||||
* nsIAccessible::DoAction() method, it will block AT tools (e.g. GOK) that
|
||||
* invoke action of mozilla accessibles direclty (see bug 277888 for details).
|
||||
*
|
||||
* @param aContent [in, optional] element to click
|
||||
* @param aActionIndex [in, optional] index of accessible action
|
||||
*/
|
||||
nsresult DoCommand(nsIContent *aContent = nsnull, PRUint32 aActionIndex = 0);
|
||||
|
||||
/**
|
||||
* Dispatch click event to target by calling DispatchClickEvent() method.
|
||||
*
|
||||
* @param aTimer [in] timer object
|
||||
* @param aClosure [in] nsCommandClosure object describing a target.
|
||||
*/
|
||||
static void DoCommandCallback(nsITimer *aTimer, void *aClosure);
|
||||
nsresult DoCommand(nsIContent *aContent = nsnull);
|
||||
|
||||
/**
|
||||
* Dispatch click event.
|
||||
*/
|
||||
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
// Check the visibility across both parent content and chrome
|
||||
PRBool CheckVisibilityInParentChain(nsIDocument* aDocument, nsIView* aView);
|
||||
|
@ -266,8 +266,8 @@ nsAccEvent::GetAccessibleByNode()
|
||||
if (!accService)
|
||||
return nsnull;
|
||||
|
||||
nsIAccessible *accessible = nsnull;
|
||||
accService->GetAccessibleFor(mDOMNode, &accessible);
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
accService->GetAccessibleFor(mDOMNode, getter_AddRefs(accessible));
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
// hack for xul tree table. We need a better way for firing delayed event
|
||||
@ -283,18 +283,16 @@ nsAccEvent::GetAccessibleByNode()
|
||||
PRInt32 treeIndex = -1;
|
||||
multiSelect->GetCurrentIndex(&treeIndex);
|
||||
if (treeIndex >= 0) {
|
||||
nsRefPtr<nsXULTreeAccessible> treeCache =
|
||||
nsRefPtr<nsXULTreeAccessible> treeAcc =
|
||||
nsAccUtils::QueryAccessibleTree(accessible);
|
||||
if (treeCache) {
|
||||
treeCache->GetCachedTreeitemAccessible(treeIndex, nsnull,
|
||||
&accessible);
|
||||
}
|
||||
if (treeAcc)
|
||||
treeAcc->GetTreeItemAccessible(treeIndex, getter_AddRefs(accessible));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return accessible;
|
||||
return accessible.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -84,6 +84,69 @@ nsCoreUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
|
||||
return listenerManager && listenerManager->HasListenersFor(aEventType);
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
|
||||
PRInt32 aRowIndex, nsITreeColumn *aColumn,
|
||||
const nsCString& aPseudoElt)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> tcElm;
|
||||
aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
|
||||
if (!tcElm)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
|
||||
nsIDocument *document = tcContent->GetCurrentDoc();
|
||||
if (!document)
|
||||
return;
|
||||
|
||||
nsIPresShell *presShell = nsnull;
|
||||
presShell = document->GetPrimaryShell();
|
||||
if (!presShell)
|
||||
return;
|
||||
|
||||
// Ensure row is visible.
|
||||
aTreeBoxObj->EnsureRowIsVisible(aRowIndex);
|
||||
|
||||
// Calculate x and y coordinates.
|
||||
PRInt32 x = 0, y = 0, width = 0, height = 0;
|
||||
nsresult rv = aTreeBoxObj->GetCoordsForCellItem(aRowIndex, aColumn,
|
||||
aPseudoElt,
|
||||
&x, &y, &width, &height);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMXULElement> tcXULElm(do_QueryInterface(tcElm));
|
||||
nsCOMPtr<nsIBoxObject> tcBoxObj;
|
||||
tcXULElm->GetBoxObject(getter_AddRefs(tcBoxObj));
|
||||
|
||||
PRInt32 tcX = 0;
|
||||
tcBoxObj->GetX(&tcX);
|
||||
|
||||
PRInt32 tcY = 0;
|
||||
tcBoxObj->GetY(&tcY);
|
||||
|
||||
// Dispatch mouse events.
|
||||
nsIFrame* tcFrame = presShell->GetPrimaryFrameFor(tcContent);
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
|
||||
nsPoint offset;
|
||||
nsIWidget *rootWidget =
|
||||
rootFrame->GetViewExternal()->GetNearestWidget(&offset);
|
||||
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
|
||||
PRInt32 cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
|
||||
presContext->AppUnitsToDevPixels(offset.x);
|
||||
PRInt32 cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
|
||||
presContext->AppUnitsToDevPixels(offset.y);
|
||||
|
||||
DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, cnvdX, cnvdY,
|
||||
tcContent, tcFrame, presShell, rootWidget);
|
||||
|
||||
DispatchMouseEvent(NS_MOUSE_BUTTON_UP, cnvdX, cnvdY,
|
||||
tcContent, tcFrame, presShell, rootWidget);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCoreUtils::DispatchMouseEvent(PRUint32 aEventType,
|
||||
nsIPresShell *aPresShell,
|
||||
@ -109,21 +172,28 @@ nsCoreUtils::DispatchMouseEvent(PRUint32 aEventType,
|
||||
|
||||
PRInt32 x = presContext->AppUnitsToDevPixels(point.x + size.width / 2);
|
||||
PRInt32 y = presContext->AppUnitsToDevPixels(point.y + size.height / 2);
|
||||
|
||||
|
||||
// Fire mouse event.
|
||||
nsMouseEvent event(PR_TRUE, aEventType, rootWidget,
|
||||
DispatchMouseEvent(aEventType, x, y, aContent, frame, aPresShell, rootWidget);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::DispatchMouseEvent(PRUint32 aEventType, PRInt32 aX, PRInt32 aY,
|
||||
nsIContent *aContent, nsIFrame *aFrame,
|
||||
nsIPresShell *aPresShell, nsIWidget *aRootWidget)
|
||||
{
|
||||
nsMouseEvent event(PR_TRUE, aEventType, aRootWidget,
|
||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||
|
||||
event.refPoint = nsIntPoint(x, y);
|
||||
|
||||
event.refPoint = nsIntPoint(aX, aY);
|
||||
|
||||
event.clickCount = 1;
|
||||
event.button = nsMouseEvent::eLeftButton;
|
||||
event.time = PR_IntervalNow();
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
aPresShell->HandleEventWithTarget(&event, frame, aContent, &status);
|
||||
|
||||
return PR_TRUE;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
@ -891,3 +961,149 @@ nsCoreUtils::GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj)
|
||||
tcXULElm->GetBoxObject(&boxObj);
|
||||
return boxObj;
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::GetTreeBoxObject(nsIDOMNode *aDOMNode,
|
||||
nsITreeBoxObject **aBoxObject)
|
||||
{
|
||||
nsAutoString name;
|
||||
nsCOMPtr<nsIDOMNode> parentNode, currentNode;
|
||||
|
||||
// Find DOMNode's parents recursively until reach the <tree> tag
|
||||
currentNode = aDOMNode;
|
||||
while (currentNode) {
|
||||
currentNode->GetLocalName(name);
|
||||
if (name.EqualsLiteral("tree")) {
|
||||
// We will get the nsITreeBoxObject from the tree node
|
||||
nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(currentNode));
|
||||
if (xulElement) {
|
||||
nsCOMPtr<nsIBoxObject> box;
|
||||
xulElement->GetBoxObject(getter_AddRefs(box));
|
||||
nsCOMPtr<nsITreeBoxObject> treeBox(do_QueryInterface(box));
|
||||
if (treeBox) {
|
||||
*aBoxObject = treeBox;
|
||||
NS_ADDREF(*aBoxObject);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
currentNode->GetParentNode(getter_AddRefs(parentNode));
|
||||
currentNode = parentNode;
|
||||
}
|
||||
|
||||
*aBoxObject = nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<nsITreeColumn>
|
||||
nsCoreUtils::GetFirstSensibleColumn(nsITreeBoxObject *aTree)
|
||||
{
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
aTree->GetColumns(getter_AddRefs(cols));
|
||||
if (!cols)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
cols->GetFirstColumn(getter_AddRefs(column));
|
||||
if (column && IsColumnHidden(column))
|
||||
return GetNextSensibleColumn(column);
|
||||
|
||||
return column.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsITreeColumn>
|
||||
nsCoreUtils::GetLastSensibleColumn(nsITreeBoxObject *aTree)
|
||||
{
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
aTree->GetColumns(getter_AddRefs(cols));
|
||||
if (!cols)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
cols->GetLastColumn(getter_AddRefs(column));
|
||||
if (column && IsColumnHidden(column))
|
||||
return GetPreviousSensibleColumn(column);
|
||||
|
||||
return column.forget();
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsCoreUtils::GetSensibleColumnsCount(nsITreeBoxObject *aTree)
|
||||
{
|
||||
PRUint32 count = 0;
|
||||
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
aTree->GetColumns(getter_AddRefs(cols));
|
||||
if (!cols)
|
||||
return count;
|
||||
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
cols->GetFirstColumn(getter_AddRefs(column));
|
||||
|
||||
while (column) {
|
||||
if (!IsColumnHidden(column))
|
||||
count++;
|
||||
|
||||
nsCOMPtr<nsITreeColumn> nextColumn;
|
||||
column->GetNext(getter_AddRefs(nextColumn));
|
||||
column.swap(nextColumn);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
already_AddRefed<nsITreeColumn>
|
||||
nsCoreUtils::GetSensibleColumnAt(nsITreeBoxObject *aTree, PRUint32 aIndex)
|
||||
{
|
||||
PRUint32 idx = aIndex;
|
||||
|
||||
nsCOMPtr<nsITreeColumn> column = GetFirstSensibleColumn(aTree);
|
||||
while (column) {
|
||||
if (idx == 0)
|
||||
return column.forget();
|
||||
|
||||
idx--;
|
||||
column = GetNextSensibleColumn(column);
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<nsITreeColumn>
|
||||
nsCoreUtils::GetNextSensibleColumn(nsITreeColumn *aColumn)
|
||||
{
|
||||
nsCOMPtr<nsITreeColumn> nextColumn;
|
||||
aColumn->GetNext(getter_AddRefs(nextColumn));
|
||||
|
||||
while (nextColumn && IsColumnHidden(nextColumn)) {
|
||||
nsCOMPtr<nsITreeColumn> tempColumn;
|
||||
nextColumn->GetNext(getter_AddRefs(tempColumn));
|
||||
nextColumn.swap(tempColumn);
|
||||
}
|
||||
|
||||
return nextColumn.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsITreeColumn>
|
||||
nsCoreUtils::GetPreviousSensibleColumn(nsITreeColumn *aColumn)
|
||||
{
|
||||
nsCOMPtr<nsITreeColumn> prevColumn;
|
||||
aColumn->GetPrevious(getter_AddRefs(prevColumn));
|
||||
|
||||
while (prevColumn && IsColumnHidden(prevColumn)) {
|
||||
nsCOMPtr<nsITreeColumn> tempColumn;
|
||||
prevColumn->GetPrevious(getter_AddRefs(tempColumn));
|
||||
prevColumn.swap(tempColumn);
|
||||
}
|
||||
|
||||
return prevColumn.forget();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
aColumn->GetElement(getter_AddRefs(element));
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
|
||||
return content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::hidden,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters);
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nsIContent.h"
|
||||
#include "nsIBoxObject.h"
|
||||
#include "nsITreeBoxObject.h"
|
||||
#include "nsITreeColumns.h"
|
||||
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
@ -62,16 +63,45 @@ public:
|
||||
static PRBool HasListener(nsIContent *aContent, const nsAString& aEventType);
|
||||
|
||||
/**
|
||||
* Send mouse events to the given element.
|
||||
* Dispatch click event to XUL tree cell.
|
||||
*
|
||||
* @param aEventType an event type (see nsGUIEvent.h for constants)
|
||||
* @param aPresShell the presshell for the given element
|
||||
* @param aContent the element element
|
||||
* @param aTreeBoxObj [in] tree box object
|
||||
* @param aRowIndex [in] row index
|
||||
* @param aColumn [in] column object
|
||||
* @param aPseudoElm [in] pseudo elemenet inside the cell, see
|
||||
* nsITreeBoxObject for available values
|
||||
*/
|
||||
static void DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
|
||||
PRInt32 aRowIndex, nsITreeColumn *aColumn,
|
||||
const nsCString& aPseudoElt = EmptyCString());
|
||||
|
||||
/**
|
||||
* Send mouse event to the given element.
|
||||
*
|
||||
* @param aEventType [in] an event type (see nsGUIEvent.h for constants)
|
||||
* @param aPresShell [in] the presshell for the given element
|
||||
* @param aContent [in] the element
|
||||
*/
|
||||
static PRBool DispatchMouseEvent(PRUint32 aEventType,
|
||||
nsIPresShell *aPresShell,
|
||||
nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Send mouse event to the given element.
|
||||
*
|
||||
* @param aEventType [in] an event type (see nsGUIEvent.h for constants)
|
||||
* @param aX [in] x coordinate in dev pixels
|
||||
* @param aY [in] y coordinate in dev pixels
|
||||
* @param aContent [in] the element
|
||||
* @param aFrame [in] frame of the element
|
||||
* @param aPresShell [in] the presshell for the element
|
||||
* @param aRootWidget [in] the root widget of the element
|
||||
*/
|
||||
static void DispatchMouseEvent(PRUint32 aEventType, PRInt32 aX, PRInt32 aY,
|
||||
nsIContent *aContent, nsIFrame *aFrame,
|
||||
nsIPresShell *aPresShell,
|
||||
nsIWidget *aRootWidget);
|
||||
|
||||
/**
|
||||
* Return an accesskey registered on the given element by
|
||||
* nsIEventStateManager or 0 if there is no registered accesskey.
|
||||
@ -362,6 +392,52 @@ public:
|
||||
static already_AddRefed<nsIBoxObject>
|
||||
GetTreeBodyBoxObject(nsITreeBoxObject *aTreeBoxObj);
|
||||
|
||||
/**
|
||||
* Return tree box object from any levels DOMNode under the XUL tree.
|
||||
*/
|
||||
static void
|
||||
GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
|
||||
|
||||
/**
|
||||
* Return first sensible column for the given tree box object.
|
||||
*/
|
||||
static already_AddRefed<nsITreeColumn>
|
||||
GetFirstSensibleColumn(nsITreeBoxObject *aTree);
|
||||
|
||||
/**
|
||||
* Return last sensible column for the given tree box object.
|
||||
*/
|
||||
static already_AddRefed<nsITreeColumn>
|
||||
GetLastSensibleColumn(nsITreeBoxObject *aTree);
|
||||
|
||||
/**
|
||||
* Return sensible columns count for the given tree box object.
|
||||
*/
|
||||
static PRUint32 GetSensibleColumnsCount(nsITreeBoxObject *aTree);
|
||||
|
||||
/**
|
||||
* Return sensible column at the given index for the given tree box object.
|
||||
*/
|
||||
static already_AddRefed<nsITreeColumn>
|
||||
GetSensibleColumnAt(nsITreeBoxObject *aTree, PRUint32 aIndex);
|
||||
|
||||
/**
|
||||
* Return next sensible column for the given column.
|
||||
*/
|
||||
static already_AddRefed<nsITreeColumn>
|
||||
GetNextSensibleColumn(nsITreeColumn *aColumn);
|
||||
|
||||
/**
|
||||
* Return previous sensible column for the given column.
|
||||
*/
|
||||
static already_AddRefed<nsITreeColumn>
|
||||
GetPreviousSensibleColumn(nsITreeColumn *aColumn);
|
||||
|
||||
/**
|
||||
* Return true if the given column is hidden (i.e. not sensible).
|
||||
*/
|
||||
static PRBool IsColumnHidden(nsITreeColumn *aColumn);
|
||||
|
||||
/**
|
||||
* Return true if the given node is table header element.
|
||||
*/
|
||||
|
@ -150,18 +150,6 @@ ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// What we want is: NS_INTERFACE_MAP_ENTRY(self) for static IID accessors,
|
||||
// but some of our classes have an ambiguous base class of nsISupports which
|
||||
// prevents this from working (the default macro converts it to nsISupports,
|
||||
// then addrefs it, then returns it). Therefore, we expand the macro here and
|
||||
// change it so that it works. Yuck.
|
||||
#define NS_INTERFACE_MAP_STATIC_AMBIGUOUS(_class) \
|
||||
if (aIID.Equals(NS_GET_IID(_class))) { \
|
||||
NS_ADDREF(this); \
|
||||
*aInstancePtr = this; \
|
||||
return NS_OK; \
|
||||
} else
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
||||
@ -581,6 +569,17 @@ nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
|
||||
PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode)
|
||||
{
|
||||
if (!aAccessNode)
|
||||
return;
|
||||
|
||||
void *uniqueID = nsnull;
|
||||
aAccessNode->GetUniqueID(&uniqueID);
|
||||
mAccessNodeCache.Remove(uniqueID);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent)
|
||||
{
|
||||
// Hook up our new accessible with our parent
|
||||
|
@ -56,11 +56,11 @@ class nsIScrollableView;
|
||||
const PRUint32 kDefaultCacheSize = 256;
|
||||
|
||||
#define NS_DOCACCESSIBLE_IMPL_CID \
|
||||
{ /* 0ed1be1d-52a7-4bfd-b4f5-0de7caed4617 */ \
|
||||
0x0ed1be1d, \
|
||||
0x52a7, \
|
||||
0x4bfd, \
|
||||
{ 0xb4, 0xf5, 0x0d, 0xe7, 0xca, 0xed, 0x46, 0x17 } \
|
||||
{ /* 9735bc5f-a4b6-4668-ab73-6f8434c8e750 */ \
|
||||
0x9735bc5f, \
|
||||
0xa4b6, \
|
||||
0x4668, \
|
||||
{ 0xab, 0x73, 0x6f, 0x84, 0x34, 0xc8, 0xe7, 0x50 } \
|
||||
}
|
||||
|
||||
class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
@ -160,6 +160,11 @@ public:
|
||||
*/
|
||||
void CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Remove the given access node from document cache.
|
||||
*/
|
||||
void RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Fires pending events.
|
||||
*/
|
||||
|
@ -736,11 +736,11 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
||||
PRInt32 treeIndex = -1;
|
||||
multiSelect->GetCurrentIndex(&treeIndex);
|
||||
if (treeIndex >= 0) {
|
||||
nsRefPtr<nsXULTreeAccessible> treeCache =
|
||||
nsRefPtr<nsXULTreeAccessible> treeAcc =
|
||||
nsAccUtils::QueryAccessibleTree(accessible);
|
||||
if (treeCache) {
|
||||
treeCache->GetCachedTreeitemAccessible(treeIndex, nsnull,
|
||||
getter_AddRefs(treeItemAccessible));
|
||||
if (treeAcc) {
|
||||
treeAcc->GetTreeItemAccessible(treeIndex,
|
||||
getter_AddRefs(treeItemAccessible));
|
||||
if (treeItemAccessible)
|
||||
accessible = treeItemAccessible;
|
||||
}
|
||||
|
@ -38,9 +38,8 @@
|
||||
#ifndef __nsXULTreeAccessibleWrap_h__
|
||||
#define __nsXULTreeAccessibleWrap_h__
|
||||
|
||||
#include "nsXULTreeAccessible.h"
|
||||
typedef class nsXULTreeAccessible nsXULTreeAccessibleWrap;
|
||||
typedef class nsXULTreeitemAccessible nsXULTreeitemAccessibleWrap;
|
||||
#include "nsXULTreeGridAccessible.h"
|
||||
typedef class nsXULTreeGridAccessible nsXULTreeGridAccessibleWrap;
|
||||
typedef class nsXULTreeColumnsAccessible nsXULTreeColumnsAccessibleWrap;
|
||||
|
||||
#endif
|
||||
|
@ -1294,6 +1294,15 @@ __try {
|
||||
"MSAA role map skewed");
|
||||
|
||||
*aRole = gWindowsRoleMap[xpRole].ia2Role;
|
||||
|
||||
// Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call
|
||||
// the IA2 role a ROLE_OUTLINEITEM.
|
||||
if (xpRole == nsIAccessibleRole::ROLE_ROW) {
|
||||
nsCOMPtr<nsIAccessible> parent = GetParent();
|
||||
if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE)
|
||||
*aRole = ROLE_SYSTEM_OUTLINEITEM;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
|
@ -20,7 +20,8 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Aaron Leventhal
|
||||
* Aaron Leventhal <aaronleventhal@moonset.net> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -38,124 +39,19 @@
|
||||
|
||||
#include "nsXULTreeAccessibleWrap.h"
|
||||
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsIFrame.h"
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeGridAccessibleWrap
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------
|
||||
// nsXULTreeAccessibleWrap
|
||||
// --------------------------------------------------------
|
||||
|
||||
nsXULTreeAccessibleWrap::nsXULTreeAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
|
||||
nsXULTreeAccessible(aDOMNode, aShell)
|
||||
nsXULTreeGridAccessibleWrap::
|
||||
nsXULTreeGridAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
|
||||
nsXULTreeGridAccessible(aDOMNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULTreeAccessibleWrap::GetRoleInternal(PRUint32 *aRole)
|
||||
{
|
||||
NS_ENSURE_STATE(mTree);
|
||||
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
mTree->GetColumns(getter_AddRefs(cols));
|
||||
nsCOMPtr<nsITreeColumn> primaryCol;
|
||||
if (cols) {
|
||||
cols->GetPrimaryColumn(getter_AddRefs(primaryCol));
|
||||
}
|
||||
// No primary column means we're in a list
|
||||
// In fact, history and mail turn off the primary flag when switching to a flat view
|
||||
*aRole = primaryCol ? nsIAccessibleRole::ROLE_OUTLINE :
|
||||
nsIAccessibleRole::ROLE_LIST;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// nsXULTreeitemAccessibleWrap Accessible
|
||||
// --------------------------------------------------------
|
||||
|
||||
nsXULTreeitemAccessibleWrap::nsXULTreeitemAccessibleWrap(nsIAccessible *aParent,
|
||||
nsIDOMNode *aDOMNode,
|
||||
nsIWeakReference *aShell,
|
||||
PRInt32 aRow,
|
||||
nsITreeColumn* aColumn) :
|
||||
nsXULTreeitemAccessible(aParent, aDOMNode, aShell, aRow, aColumn)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULTreeitemAccessibleWrap::GetRoleInternal(PRUint32 *aRole)
|
||||
{
|
||||
// No primary column means we're in a list
|
||||
// In fact, history and mail turn off the primary flag when switching to a flat view
|
||||
NS_ENSURE_STATE(mColumn);
|
||||
PRBool isPrimary = PR_FALSE;
|
||||
mColumn->GetPrimary(&isPrimary);
|
||||
*aRole = isPrimary ? nsIAccessibleRole::ROLE_OUTLINEITEM :
|
||||
nsIAccessibleRole::ROLE_LISTITEM;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeitemAccessibleWrap::GetBounds(PRInt32 *aX, PRInt32 *aY,
|
||||
PRInt32 *aWidth, PRInt32 *aHeight)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aX);
|
||||
*aX = 0;
|
||||
NS_ENSURE_ARG_POINTER(aY);
|
||||
*aY = 0;
|
||||
NS_ENSURE_ARG_POINTER(aWidth);
|
||||
*aWidth = 0;
|
||||
NS_ENSURE_ARG_POINTER(aHeight);
|
||||
*aHeight = 0;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Get x coordinate and width from treechildren element, get y coordinate and
|
||||
// height from tree cell.
|
||||
|
||||
nsCOMPtr<nsIBoxObject> boxObj = nsCoreUtils::GetTreeBodyBoxObject(mTree);
|
||||
NS_ENSURE_STATE(boxObj);
|
||||
|
||||
PRInt32 cellStartX, cellWidth;
|
||||
nsresult rv = mTree->GetCoordsForCellItem(mRow, mColumn, EmptyCString(),
|
||||
&cellStartX, aY,
|
||||
&cellWidth, aHeight);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
boxObj->GetWidth(aWidth);
|
||||
|
||||
PRInt32 tcX = 0, tcY = 0;
|
||||
boxObj->GetScreenX(&tcX);
|
||||
boxObj->GetScreenY(&tcY);
|
||||
|
||||
*aX = tcX;
|
||||
*aY += tcY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeitemAccessibleWrap::GetName(nsAString& aName)
|
||||
{
|
||||
NS_ENSURE_STATE(mTree);
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
mTree->GetColumns(getter_AddRefs(cols));
|
||||
if (!cols) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
cols->GetFirstColumn(getter_AddRefs(column));
|
||||
while (column) {
|
||||
nsAutoString colText;
|
||||
mTreeView->GetCellText(mRow, column, colText);
|
||||
aName += colText + NS_LITERAL_STRING(" ");
|
||||
nsCOMPtr<nsITreeColumn> nextColumn;
|
||||
column->GetNext(getter_AddRefs(nextColumn));
|
||||
column = nextColumn;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeGridAccessibleWrap,
|
||||
nsXULTreeGridAccessible)
|
||||
|
||||
IMPL_IUNKNOWN_INHERITED1(nsXULTreeGridAccessibleWrap,
|
||||
nsAccessibleWrap,
|
||||
CAccessibleTable);
|
||||
|
@ -20,7 +20,8 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pete Zha (pete.zha@sun.com)
|
||||
* Pete Zha <pete.zha@sun.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -39,33 +40,28 @@
|
||||
#ifndef __nsXULTreeAccessibleWrap_h__
|
||||
#define __nsXULTreeAccessibleWrap_h__
|
||||
|
||||
#include "nsXULTreeAccessible.h"
|
||||
#include "nsXULTreeGridAccessible.h"
|
||||
|
||||
#include "CAccessibleTable.h"
|
||||
|
||||
typedef class nsXULTreeColumnsAccessible nsXULTreeColumnsAccessibleWrap;
|
||||
|
||||
class nsXULTreeAccessibleWrap : public nsXULTreeAccessible
|
||||
/**
|
||||
* IA2 wrapper of nsXULTreeGridAccessible class, implements IAccessibleTable
|
||||
* interface.
|
||||
*/
|
||||
class nsXULTreeGridAccessibleWrap : public nsXULTreeGridAccessible,
|
||||
public CAccessibleTable
|
||||
{
|
||||
public:
|
||||
nsXULTreeAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell);
|
||||
virtual ~nsXULTreeAccessibleWrap() {}
|
||||
nsXULTreeGridAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell);
|
||||
virtual ~nsXULTreeGridAccessibleWrap() {}
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
};
|
||||
// IUnknown
|
||||
DECL_IUNKNOWN_INHERITED
|
||||
|
||||
class nsXULTreeitemAccessibleWrap : public nsXULTreeitemAccessible
|
||||
{
|
||||
public:
|
||||
nsXULTreeitemAccessibleWrap(nsIAccessible *aParent, nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
PRInt32 aRow, nsITreeColumn* aColumn);
|
||||
virtual ~nsXULTreeitemAccessibleWrap() {}
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
NS_IMETHOD GetName(nsAString &aName);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -38,9 +38,8 @@
|
||||
#ifndef __nsXULTreeAccessibleWrap_h__
|
||||
#define __nsXULTreeAccessibleWrap_h__
|
||||
|
||||
#include "nsXULTreeAccessible.h"
|
||||
typedef class nsXULTreeAccessible nsXULTreeAccessibleWrap;
|
||||
typedef class nsXULTreeitemAccessible nsXULTreeitemAccessibleWrap;
|
||||
#include "nsXULTreeGridAccessible.h"
|
||||
typedef class nsXULTreeGridAccessible nsXULTreeGridAccessibleWrap;
|
||||
typedef class nsXULTreeColumnsAccessible nsXULTreeColumnsAccessibleWrap;
|
||||
|
||||
#endif
|
||||
|
@ -77,6 +77,7 @@ CPPSRCS = \
|
||||
nsXULTabAccessible.cpp \
|
||||
nsXULTextAccessible.cpp \
|
||||
nsXULTreeAccessible.cpp \
|
||||
nsXULTreeGridAccessible.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -65,22 +65,25 @@ class nsXULTreeAccessible : public nsXULSelectableAccessible
|
||||
{
|
||||
public:
|
||||
nsXULTreeAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULTreeAccessible() {}
|
||||
|
||||
// nsISupports
|
||||
// nsISupports and cycle collection
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeAccessible,
|
||||
nsAccessible)
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *aChildCount);
|
||||
NS_IMETHOD GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild);
|
||||
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
// nsIAccessibleSelectable
|
||||
NS_DECL_NSIACCESSIBLESELECTABLE
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *_retval);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual nsresult Shutdown();
|
||||
@ -97,16 +100,13 @@ public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Return tree item accessible at the givem row and column. If accessible
|
||||
* doesn't exist in the cache then create it.
|
||||
* Return tree item accessible at the givem row. If accessible doesn't exist
|
||||
* in the cache then create and cache it.
|
||||
*
|
||||
* @param aRow [in] the given row index
|
||||
* @param aColumn [in] the given column object. If is is nsnull then
|
||||
* primary column is used
|
||||
* @param aAccessible [out] tree item accessible
|
||||
*/
|
||||
void GetCachedTreeitemAccessible(PRInt32 aRow, nsITreeColumn *aColumn,
|
||||
nsIAccessible **aAccessible);
|
||||
void GetTreeItemAccessible(PRInt32 aRow, nsIAccessible **aAccessible);
|
||||
|
||||
/**
|
||||
* Invalidates the number of cached treeitem accessibles.
|
||||
@ -135,18 +135,16 @@ public:
|
||||
*/
|
||||
void TreeViewChanged();
|
||||
|
||||
static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
|
||||
static nsresult GetColumnCount(nsITreeBoxObject* aBoxObject, PRInt32 *aCount);
|
||||
|
||||
static PRBool IsColumnHidden(nsITreeColumn *aColumn);
|
||||
static already_AddRefed<nsITreeColumn> GetNextVisibleColumn(nsITreeColumn *aColumn);
|
||||
static already_AddRefed<nsITreeColumn> GetFirstVisibleColumn(nsITreeBoxObject *aTree);
|
||||
static already_AddRefed<nsITreeColumn> GetLastVisibleColumn(nsITreeBoxObject *aTree);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Creates tree item accessible for the given row index.
|
||||
*/
|
||||
virtual void CreateTreeItemAccessible(PRInt32 aRowIndex,
|
||||
nsAccessNode** aAccessNode);
|
||||
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeView> mTreeView;
|
||||
nsAccessNodeHashtable *mAccessNodeCache;
|
||||
nsAccessNodeHashtable mAccessNodeCache;
|
||||
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
|
||||
};
|
||||
@ -155,47 +153,112 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeAccessible,
|
||||
NS_XULTREEACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Accessible class for items for XUL tree.
|
||||
* Base class for tree item accessibles.
|
||||
*/
|
||||
|
||||
#define NS_XULTREEITEMACCESSIBLE_IMPL_CID \
|
||||
{ /* 7b1aa039-7270-4523-aeb3-61063a13ac3f */ \
|
||||
0x7b1aa039, \
|
||||
0x7270, \
|
||||
0x4523, \
|
||||
{ 0xae, 0xb3, 0x61, 0x06, 0x3a, 0x13, 0xac, 0x3f } \
|
||||
#define NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID \
|
||||
{ /* 1ab79ae7-766a-443c-940b-b1e6b0831dfc */ \
|
||||
0x1ab79ae7, \
|
||||
0x766a, \
|
||||
0x443c, \
|
||||
{ 0x94, 0x0b, 0xb1, 0xe6, 0xb0, 0x83, 0x1d, 0xfc } \
|
||||
}
|
||||
|
||||
class nsXULTreeitemAccessible : public nsLeafAccessible
|
||||
class nsXULTreeItemAccessibleBase : public nsAccessibleWrap
|
||||
{
|
||||
public:
|
||||
enum { eAction_Click = 0, eAction_Expand = 1 };
|
||||
|
||||
nsXULTreeitemAccessible(nsIAccessible *aParent, nsIDOMNode *aDOMNode, nsIWeakReference *aShell, PRInt32 aRow, nsITreeColumn* aColumn = nsnull);
|
||||
virtual ~nsXULTreeitemAccessible() {}
|
||||
nsXULTreeItemAccessibleBase(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsIAccessible *aParent, nsITreeBoxObject *aTree,
|
||||
nsITreeView *aTreeView, PRInt32 aRow);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessNode
|
||||
NS_IMETHOD GetUniqueID(void **aUniqueID);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
|
||||
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
|
||||
|
||||
NS_IMETHOD GetParent(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetNextSibling(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetPreviousSibling(nsIAccessible **_retval);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
|
||||
PRInt32 *aWidth, PRInt32 *aHeight);
|
||||
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||
NS_IMETHOD SetSelected(PRBool aSelect);
|
||||
NS_IMETHOD TakeFocus(void);
|
||||
NS_IMETHOD TakeFocus();
|
||||
|
||||
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
|
||||
nsIAccessibleRelation **aRelation);
|
||||
|
||||
// nsIAccessNode
|
||||
NS_IMETHOD GetUniqueID(void **aUniqueID);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aCount);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual nsresult Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsXULTreeItemAccessibleBase
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Return cell accessible for the given column. If XUL tree accessible is not
|
||||
* accessible table then return null.
|
||||
*/
|
||||
virtual void GetCellAccessible(nsITreeColumn *aColumn,
|
||||
nsIAccessible **aCellAcc)
|
||||
{ *aCellAcc = nsnull; }
|
||||
|
||||
/**
|
||||
* Proccess row invalidation. Used to fires name change events.
|
||||
*/
|
||||
virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx) = 0;
|
||||
|
||||
protected:
|
||||
enum { eAction_Click = 0, eAction_Expand = 1 };
|
||||
|
||||
// nsAccessible
|
||||
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
|
||||
|
||||
// nsXULTreeItemAccessibleBase
|
||||
|
||||
/**
|
||||
* Return true if the tree item accessible is expandable (contains subrows).
|
||||
*/
|
||||
PRBool IsExpandable();
|
||||
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeView> mTreeView;
|
||||
PRInt32 mRow;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeItemAccessibleBase,
|
||||
NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
|
||||
|
||||
|
||||
/**
|
||||
* Accessible class for items for XUL tree.
|
||||
*/
|
||||
class nsXULTreeItemAccessible : public nsXULTreeItemAccessibleBase
|
||||
{
|
||||
public:
|
||||
nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsIAccessible *aParent, nsITreeBoxObject *aTree,
|
||||
nsITreeView *aTreeView, PRInt32 aRow);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *aChildCount);
|
||||
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
@ -203,30 +266,16 @@ public:
|
||||
virtual nsresult Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsXULTreeitemAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Get/set cached name.
|
||||
*/
|
||||
void GetCachedName(nsAString& aName);
|
||||
void SetCachedName(const nsAString& aName);
|
||||
// nsXULTreeItemAccessibleBase
|
||||
virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
|
||||
|
||||
protected:
|
||||
PRBool IsExpandable();
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeView> mTreeView;
|
||||
PRInt32 mRow;
|
||||
nsCOMPtr<nsITreeColumn> mColumn;
|
||||
nsString mCachedName;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeitemAccessible,
|
||||
NS_XULTREEITEMACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Accessible class for columns element of XUL tree.
|
||||
|
1228
accessible/src/xul/nsXULTreeGridAccessible.cpp
Normal file
1228
accessible/src/xul/nsXULTreeGridAccessible.cpp
Normal file
File diff suppressed because it is too large
Load Diff
203
accessible/src/xul/nsXULTreeGridAccessible.h
Normal file
203
accessible/src/xul/nsXULTreeGridAccessible.h
Normal file
@ -0,0 +1,203 @@
|
||||
/* -*- 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 __nsXULTreeGridAccessible_h__
|
||||
#define __nsXULTreeGridAccessible_h__
|
||||
|
||||
#include "nsIAccessibleTable.h"
|
||||
|
||||
#include "nsXULTreeAccessible.h"
|
||||
|
||||
/**
|
||||
* Represents accessible for XUL tree in the case when it has multiple columns.
|
||||
*/
|
||||
class nsXULTreeGridAccessible : public nsXULTreeAccessible,
|
||||
public nsIAccessibleTable
|
||||
{
|
||||
public:
|
||||
nsXULTreeGridAccessible(nsIDOMNode *aDOMNode,
|
||||
nsIWeakReference *aShell);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessibleTable
|
||||
NS_DECL_NSIACCESSIBLETABLE
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
|
||||
protected:
|
||||
|
||||
// nsXULTreeAccessible
|
||||
virtual void CreateTreeItemAccessible(PRInt32 aRow,
|
||||
nsAccessNode** aAccessNode);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents accessible for XUL tree item in the case when XUL tree has
|
||||
* multiple columns.
|
||||
*/
|
||||
class nsXULTreeGridRowAccessible : public nsXULTreeItemAccessibleBase
|
||||
{
|
||||
public:
|
||||
nsXULTreeGridRowAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsIAccessible *aParent, nsITreeBoxObject *aTree,
|
||||
nsITreeView *aTreeView, PRInt32 aRow);
|
||||
|
||||
// nsISupports and cycle collection
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridRowAccessible,
|
||||
nsAccessible)
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
|
||||
NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
|
||||
NS_IMETHOD GetChildCount(PRInt32 *aChildCount);
|
||||
NS_IMETHOD GetChildAt(PRInt32 aChildIndex, nsIAccessible **aChild);
|
||||
|
||||
// nsAccessNode
|
||||
virtual nsresult Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
PRBool aDeepestChild,
|
||||
nsIAccessible **aChild);
|
||||
|
||||
// nsXULTreeItemAccessibleBase
|
||||
virtual void GetCellAccessible(nsITreeColumn *aColumn, nsIAccessible **aCell);
|
||||
virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
|
||||
|
||||
protected:
|
||||
nsAccessNodeHashtable mAccessNodeCache;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents an accessible for XUL tree cell in the case when XUL tree has
|
||||
* multiple columns.
|
||||
*/
|
||||
|
||||
#define NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID \
|
||||
{ /* 84588ad4-549c-4196-a932-4c5ca5de5dff */ \
|
||||
0x84588ad4, \
|
||||
0x549c, \
|
||||
0x4196, \
|
||||
{ 0xa9, 0x32, 0x4c, 0x5c, 0xa5, 0xde, 0x5d, 0xff } \
|
||||
}
|
||||
|
||||
class nsXULTreeGridCellAccessible : public nsLeafAccessible
|
||||
{
|
||||
public:
|
||||
nsXULTreeGridCellAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsXULTreeGridRowAccessible *aRowAcc,
|
||||
nsITreeBoxObject *aTree, nsITreeView *aTreeView,
|
||||
PRInt32 aRow, nsITreeColumn* aColumn);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIAccessNode
|
||||
NS_IMETHOD GetUniqueID(void **aUniqueID);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
|
||||
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPrevSibling);
|
||||
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
|
||||
PRInt32 *aWidth, PRInt32 *aHeight);
|
||||
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aCount);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual nsresult Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsXULTreeGridCellAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Return index of the column.
|
||||
*/
|
||||
PRInt32 GetColumnIndex() const;
|
||||
|
||||
/**
|
||||
* Fire name or state change event if the accessible text or value has been
|
||||
* changed.
|
||||
*/
|
||||
void CellInvalidated();
|
||||
|
||||
protected:
|
||||
// nsAccessible
|
||||
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
|
||||
|
||||
// nsXULTreeGridCellAccessible
|
||||
|
||||
/**
|
||||
* Return true if value of cell can be modified.
|
||||
*/
|
||||
PRBool IsEditable() const;
|
||||
|
||||
enum { eAction_Click = 0 };
|
||||
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeView> mTreeView;
|
||||
|
||||
PRInt32 mRow;
|
||||
nsCOMPtr<nsITreeColumn> mColumn;
|
||||
|
||||
nsString mCachedTextEquiv;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeGridCellAccessible,
|
||||
NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
|
||||
|
||||
#endif
|
@ -68,9 +68,11 @@ _TEST_FILES =\
|
||||
table.js \
|
||||
value.js \
|
||||
test_accessnode_invalidation.html \
|
||||
test_actions.xul \
|
||||
test_actions_aria.html \
|
||||
test_actions_inputs.html \
|
||||
test_actions.xul \
|
||||
test_actions_tree.xul \
|
||||
test_actions_treegrid.xul \
|
||||
test_aria_activedescendant.html \
|
||||
test_aria_role_article.html \
|
||||
test_aria_role_equation.html \
|
||||
@ -78,6 +80,7 @@ _TEST_FILES =\
|
||||
test_aria_roles.html \
|
||||
test_aria_roles.xul \
|
||||
test_aria_token_attrs.html \
|
||||
test_attrs_elm_tree.xul \
|
||||
test_bug420863.html \
|
||||
$(warning test_childAtPoint.html temporarily disabled) \
|
||||
$(warning test_childAtPoint.xul temporarily disabled) \
|
||||
@ -86,6 +89,7 @@ _TEST_FILES =\
|
||||
test_elm_filectrl.html \
|
||||
$(warning test_elm_media.html temporarily disabled) \
|
||||
test_elm_table.html \
|
||||
test_elm_tree.xul \
|
||||
test_elm_txtcntnr.html \
|
||||
test_events_caretmove.html \
|
||||
test_events_doc.html \
|
||||
@ -117,6 +121,7 @@ _TEST_FILES =\
|
||||
test_relations.html \
|
||||
test_relations.xul \
|
||||
test_relations_table.html \
|
||||
test_relations_tree.xul \
|
||||
test_role_nsHyperTextAcc.html \
|
||||
test_role_table_cells.html \
|
||||
test_states.html \
|
||||
@ -124,19 +129,23 @@ _TEST_FILES =\
|
||||
test_states_doc.html \
|
||||
test_states_docarticle.html \
|
||||
test_states_frames.html \
|
||||
test_states_tree.xul \
|
||||
test_table_1.html \
|
||||
test_table_2.html \
|
||||
test_table_4.html \
|
||||
test_table_indexes.html \
|
||||
test_table_indexes_ariagrid.html \
|
||||
test_table_indexes_tree.xul \
|
||||
test_table_layoutguess.html \
|
||||
test_table_sels.html \
|
||||
test_table_sels_ariagrid.html \
|
||||
test_table_sels_tree.xul \
|
||||
test_textattrs.html \
|
||||
test_textboxes.html \
|
||||
test_textboxes.xul \
|
||||
test_value.xul \
|
||||
testTextboxes.js \
|
||||
treeview.css \
|
||||
treeview.js \
|
||||
z_states_frame.html \
|
||||
z_states_framearticle.html \
|
||||
|
@ -18,14 +18,25 @@ const ALL_EVENTS = CLICK_EVENTS | COMMAND_EVENT;
|
||||
* Action tester interface is:
|
||||
*
|
||||
* var actionObj = {
|
||||
* // identifier of accessible
|
||||
* // identifier of accessible to perform an action on
|
||||
* get ID() {},
|
||||
*
|
||||
* // name of default action
|
||||
* // index of the action
|
||||
* get actionIndex() {},
|
||||
*
|
||||
* // name of the action
|
||||
* get actionName() {},
|
||||
*
|
||||
* // event constant defined above
|
||||
* get events() {}
|
||||
* // DOM events (see constants defined above)
|
||||
* get events() {},
|
||||
*
|
||||
* // [optional] identifier of target DOM events listeners are registered on,
|
||||
* // used with 'events', if missing then 'ID' is used instead.
|
||||
* get targetID() {},
|
||||
*
|
||||
* // [optional] perform checks when 'click' event is handled if 'events'
|
||||
* // is used.
|
||||
* checkOnClickEvent: function() {},
|
||||
*
|
||||
* // [optional] an array of invoker's checker objects (see eventQueue
|
||||
* // constructor events.js)
|
||||
@ -43,13 +54,15 @@ function testActions(aArray)
|
||||
|
||||
var actionObj = aArray[idx];
|
||||
var accOrElmOrID = actionObj.ID;
|
||||
var actionIndex = actionObj.actionIndex;
|
||||
var actionName = actionObj.actionName;
|
||||
var events = actionObj.events;
|
||||
var accOrElmOrIDOfTarget = actionObj.targetID ?
|
||||
actionObj.targetID : accOrElmOrID;
|
||||
|
||||
var eventSeq = new Array();
|
||||
if (events) {
|
||||
var elm = getNode(accOrElmOrID);
|
||||
//alert(elm.QueryInterface(Components.interfaces.nsIDOMNode));
|
||||
var elm = getNode(accOrElmOrIDOfTarget);
|
||||
if (events & MOUSEDOWN_EVENT)
|
||||
eventSeq.push(new checkerOfActionInvoker("mousedown", elm));
|
||||
|
||||
@ -66,7 +79,8 @@ function testActions(aArray)
|
||||
if (actionObj.eventSeq)
|
||||
eventSeq = eventSeq.concat(actionObj.eventSeq);
|
||||
|
||||
var invoker = new actionInvoker(accOrElmOrID, actionName, eventSeq);
|
||||
var invoker = new actionInvoker(accOrElmOrID, actionIndex, actionName,
|
||||
eventSeq);
|
||||
gActionsQueue.push(invoker);
|
||||
}
|
||||
|
||||
@ -78,7 +92,7 @@ function testActions(aArray)
|
||||
|
||||
var gActionsQueue = null;
|
||||
|
||||
function actionInvoker(aAccOrElmOrId, aActionName, aEventSeq)
|
||||
function actionInvoker(aAccOrElmOrId, aActionIndex, aActionName, aEventSeq)
|
||||
{
|
||||
this.invoke = function actionInvoker_invoke()
|
||||
{
|
||||
@ -93,14 +107,14 @@ function actionInvoker(aAccOrElmOrId, aActionName, aEventSeq)
|
||||
if (!isThereActions)
|
||||
return INVOKER_ACTION_FAILED;
|
||||
|
||||
is(acc.getActionName(0), aActionName,
|
||||
is(acc.getActionName(aActionIndex), aActionName,
|
||||
"Wrong action name of the accessible for " + prettyName(aAccOrElmOrId));
|
||||
|
||||
try {
|
||||
acc.doAction(0);
|
||||
acc.doAction(aActionIndex);
|
||||
}
|
||||
catch (e){
|
||||
ok(false, "doAction(0) failed with: " + e.name);
|
||||
ok(false, "doAction(" + aActionIndex + ") failed with: " + e.name);
|
||||
return INVOKER_ACTION_FAILED;
|
||||
}
|
||||
}
|
||||
@ -114,6 +128,8 @@ function checkerOfActionInvoker(aType, aTarget, aActionObj)
|
||||
|
||||
this.target = aTarget;
|
||||
|
||||
this.phase = false;
|
||||
|
||||
this.getID = function getID()
|
||||
{
|
||||
return aType + " event handling";
|
||||
@ -121,7 +137,7 @@ function checkerOfActionInvoker(aType, aTarget, aActionObj)
|
||||
|
||||
this.check = function check(aEvent)
|
||||
{
|
||||
if (aActionObj && "check" in aActionObj)
|
||||
aActionObj.check(aEvent);
|
||||
if (aActionObj && "checkOnClickEvent" in aActionObj)
|
||||
aActionObj.checkOnClickEvent(aEvent);
|
||||
}
|
||||
}
|
||||
|
@ -179,11 +179,11 @@ function testAttrsInternal(aAccOrElmOrID, aAttrs, aSkipUnexpectedAttrs,
|
||||
} catch (e) { }
|
||||
|
||||
if (!attrs) {
|
||||
ok(false, "Can't get object attributes for " + aAccOrElmOrID);
|
||||
ok(false, "Can't get object attributes for " + prettyName(aAccOrElmOrID));
|
||||
return;
|
||||
}
|
||||
|
||||
var errorMsg = " for " + aAccOrElmOrID;
|
||||
var errorMsg = " for " + prettyName(aAccOrElmOrID);
|
||||
compareAttrs(errorMsg, attrs, aAttrs, aSkipUnexpectedAttrs, aAbsentAttrs);
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ function compareAttrs(aErrorMsg, aAttrs, aExpectedAttrs, aSkipUnexpectedAttrs,
|
||||
ok(false, "Unexpected attribute '" + prop.key + "' having '" +
|
||||
prop.value + "'" + aErrorMsg);
|
||||
} else {
|
||||
var msg = "Attribute '" + prop.key + " 'has wrong value" + aErrorMsg;
|
||||
var msg = "Attribute '" + prop.key + "' has wrong value" + aErrorMsg;
|
||||
var expectedValue = aExpectedAttrs[prop.key];
|
||||
|
||||
if (typeof expectedValue == "function")
|
||||
|
@ -6,6 +6,7 @@ const EVENT_DOCUMENT_LOAD_COMPLETE =
|
||||
const EVENT_DOM_DESTROY = nsIAccessibleEvent.EVENT_DOM_DESTROY;
|
||||
const EVENT_FOCUS = nsIAccessibleEvent.EVENT_FOCUS;
|
||||
const EVENT_NAME_CHANGE = nsIAccessibleEvent.EVENT_NAME_CHANGE;
|
||||
const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
|
||||
const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -133,6 +134,7 @@ function invokerChecker(aEventType, aTarget)
|
||||
* // var checker = {
|
||||
* // type getter: function() {}, // DOM or a11y event type
|
||||
* // target getter: function() {}, // DOM node or accessible
|
||||
* // phase getter: function() {}, // DOM event phase (false - bubbling)
|
||||
* // check: function(aEvent) {},
|
||||
* // getID: function() {}
|
||||
* // };
|
||||
@ -281,26 +283,10 @@ function eventQueue(aEventType)
|
||||
// We wait for events in order specified by eventSeq variable.
|
||||
var idx = this.mEventSeqIdx + 1;
|
||||
|
||||
if (gA11yEventDumpID) { // debug stuff
|
||||
var matched = this.compareEvents(idx, aEvent);
|
||||
this.dumpEventToDOM(aEvent, idx, matched);
|
||||
|
||||
if (aEvent instanceof nsIDOMEvent) {
|
||||
var info = "Event type: " + aEvent.type;
|
||||
info += ". Target: " + prettyName(aEvent.originalTarget);
|
||||
dumpInfoToDOM(info);
|
||||
}
|
||||
|
||||
var currType = this.getEventType(idx);
|
||||
var currTarget = this.getEventTarget(idx);
|
||||
|
||||
var info = "Event queue processing. Expected event type: ";
|
||||
info += (typeof currType == "string") ?
|
||||
currType : eventTypeToString(currType);
|
||||
info += ". Target: " + prettyName(currTarget);
|
||||
|
||||
dumpInfoToDOM(info);
|
||||
}
|
||||
|
||||
if (this.compareEvents(idx, aEvent)) {
|
||||
if (matched) {
|
||||
this.checkEvent(idx, aEvent);
|
||||
invoker.wasCaught[idx] = true;
|
||||
|
||||
@ -341,7 +327,7 @@ function eventQueue(aEventType)
|
||||
for (var idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
var eventType = this.getEventType(idx);
|
||||
if (typeof eventType == "string") // DOM event
|
||||
document.addEventListener(eventType, this, true);
|
||||
document.addEventListener(eventType, this, this.getEventPhase(idx));
|
||||
else // A11y event
|
||||
addA11yEventListener(eventType, this);
|
||||
}
|
||||
@ -354,7 +340,7 @@ function eventQueue(aEventType)
|
||||
for (var idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
var eventType = this.getEventType(idx);
|
||||
if (typeof eventType == "string") // DOM event
|
||||
document.removeEventListener(eventType, this, true);
|
||||
document.removeEventListener(eventType, this, this.getEventPhase(idx));
|
||||
else // A11y event
|
||||
removeA11yEventListener(eventType, this);
|
||||
}
|
||||
@ -373,6 +359,15 @@ function eventQueue(aEventType)
|
||||
return this.mEventSeq[aIdx].target;
|
||||
}
|
||||
|
||||
this.getEventPhase = function eventQueue_getEventPhase(aIdx)
|
||||
{
|
||||
var eventItem = this.mEventSeq[aIdx];
|
||||
if ("phase" in eventItem)
|
||||
return eventItem.phase;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
this.compareEvents = function eventQueue_compareEvents(aIdx, aEvent)
|
||||
{
|
||||
var eventType1 = this.getEventType(aIdx);
|
||||
@ -419,6 +414,32 @@ function eventQueue(aEventType)
|
||||
return invoker.getID();
|
||||
}
|
||||
|
||||
this.dumpEventToDOM = function eventQueue_dumpEventToDOM(aOrigEvent,
|
||||
aExpectedEventIdx,
|
||||
aMatch)
|
||||
{
|
||||
if (!gA11yEventDumpID) // debug stuff
|
||||
return;
|
||||
|
||||
// Dump DOM event information. Skip a11y event since it is dumped by
|
||||
// gA11yEventObserver.
|
||||
if (aOrigEvent instanceof nsIDOMEvent) {
|
||||
var info = "Event type: " + aOrigEvent.type;
|
||||
info += ". Target: " + prettyName(aOrigEvent.originalTarget);
|
||||
dumpInfoToDOM(info);
|
||||
}
|
||||
|
||||
var currType = this.getEventType(aExpectedEventIdx);
|
||||
var currTarget = this.getEventTarget(aExpectedEventIdx);
|
||||
|
||||
var info = "EQ: " + (aMatch ? "matched" : "expected") + " event, type: ";
|
||||
info += (typeof currType == "string") ?
|
||||
currType : eventTypeToString(currType);
|
||||
info += ". Target: " + prettyName(currTarget);
|
||||
|
||||
dumpInfoToDOM(info);
|
||||
}
|
||||
|
||||
this.mDefEventType = aEventType;
|
||||
|
||||
this.mInvokers = new Array();
|
||||
|
@ -24,8 +24,11 @@ const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
|
||||
const ROLE_LINK = nsIAccessibleRole.ROLE_LINK;
|
||||
const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
|
||||
const ROLE_LISTBOX = nsIAccessibleRole.ROLE_LISTBOX;
|
||||
const ROLE_LISTITEM = nsIAccessibleRole.ROLE_LISTITEM;
|
||||
const ROLE_NOTHING = nsIAccessibleRole.ROLE_NOTHING;
|
||||
const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
|
||||
const ROLE_OUTLINE = nsIAccessibleRole.ROLE_OUTLINE;
|
||||
const ROLE_OUTLINEITEM = nsIAccessibleRole.ROLE_OUTLINEITEM;
|
||||
const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
|
||||
const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
|
||||
const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
|
||||
@ -37,6 +40,7 @@ const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
|
||||
const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
|
||||
const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
|
||||
const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
|
||||
const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public methods
|
||||
|
139
accessible/tests/mochitest/test_actions_tree.xul
Normal file
139
accessible/tests/mochitest/test_actions_tree.xul
Normal file
@ -0,0 +1,139 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tree actions tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/states.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/actions.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible tree testers
|
||||
|
||||
function focusChecker(aAcc, aStates)
|
||||
{
|
||||
this.type = EVENT_FOCUS;
|
||||
this.target = aAcc;
|
||||
this.getID = function focusChecker_getID()
|
||||
{
|
||||
return "focus handling";
|
||||
}
|
||||
this.check = function focusChecker_check(aEvent)
|
||||
{
|
||||
var states = aStates ? aStates : 0;
|
||||
testStates(this.target, STATE_FOCUSED | STATE_SELECTED | states);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
|
||||
function doTestActions()
|
||||
{
|
||||
var treeNode = getNode("tree");
|
||||
treeNode.removeEventListener("TreeViewChanged", doTestActions, false);
|
||||
|
||||
var treeBodyNode = treeNode.boxObject.treeBody;
|
||||
|
||||
var tree = getAccessible(treeNode);
|
||||
var expandedTreeItem = tree.getChildAt(2);
|
||||
var collapsedTreeItem = tree.getChildAt(5);
|
||||
|
||||
var actions = [
|
||||
{
|
||||
ID: expandedTreeItem,
|
||||
actionName: "activate",
|
||||
actionIndex: 0,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
eventSeq: [
|
||||
new focusChecker(expandedTreeItem, STATE_EXPANDED)
|
||||
]
|
||||
},
|
||||
{
|
||||
ID: collapsedTreeItem,
|
||||
actionName: "expand",
|
||||
actionIndex: 1,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
checkOnClickEvent: function check(aEvent)
|
||||
{
|
||||
testStates(this.ID, STATE_EXPANDED);
|
||||
}
|
||||
},
|
||||
{
|
||||
ID: collapsedTreeItem,
|
||||
actionName: "collapse",
|
||||
actionIndex: 1,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
checkOnClickEvent: function check(aEvent)
|
||||
{
|
||||
testStates(this.ID, STATE_COLLAPSED);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
testActions(actions); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var treeNode = getNode("tree");
|
||||
treeNode.addEventListener("TreeViewChanged", doTestActions, false);
|
||||
treeNode.view = new nsTreeTreeView();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tree id="tree" flex="1" minheight="100px">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<vbox id="debug"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
200
accessible/tests/mochitest/test_actions_treegrid.xul
Normal file
200
accessible/tests/mochitest/test_actions_treegrid.xul
Normal file
@ -0,0 +1,200 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/treeview.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tree actions tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/states.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/actions.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible tree testers
|
||||
|
||||
function focusChecker(aAcc, aStates)
|
||||
{
|
||||
this.type = EVENT_FOCUS;
|
||||
this.target = aAcc;
|
||||
this.getID = function focusChecker_getID()
|
||||
{
|
||||
return "focus handling";
|
||||
}
|
||||
this.check = function focusChecker_check(aEvent)
|
||||
{
|
||||
var states = aStates ? aStates : 0;
|
||||
testStates(this.target, STATE_FOCUSED | STATE_SELECTED | states);
|
||||
}
|
||||
}
|
||||
|
||||
function stateChangeChecker(aAcc, aIsEnabled)
|
||||
{
|
||||
this.type = EVENT_STATE_CHANGE;
|
||||
this.target = aAcc;
|
||||
this.getID = function stateChangeChecker_getID()
|
||||
{
|
||||
return "state change handling";
|
||||
}
|
||||
this.check = function stateChangeChecker_check(aEvent)
|
||||
{
|
||||
if (aIsEnabled)
|
||||
testStates(this.target, STATE_CHECKED);
|
||||
else
|
||||
testStates(this.target, STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTestActions()
|
||||
{
|
||||
var treeNode = getNode("tabletree");
|
||||
treeNode.removeEventListener("TreeViewChanged", doTestActions, false);
|
||||
|
||||
var treeBodyNode = treeNode.boxObject.treeBody;
|
||||
treeNode.focus();
|
||||
|
||||
var tree = getAccessible(treeNode);
|
||||
|
||||
var expandedTreeItem = tree.getChildAt(2);
|
||||
var collapsedTreeItem = tree.getChildAt(5);
|
||||
var cycleCell = expandedTreeItem.getChildAt(0);
|
||||
var checkableCell = expandedTreeItem.getChildAt(3);
|
||||
|
||||
var actions = [
|
||||
{
|
||||
ID: expandedTreeItem,
|
||||
actionName: "activate",
|
||||
actionIndex: 0,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
eventSeq: [
|
||||
new focusChecker(expandedTreeItem, STATE_EXPANDED)
|
||||
]
|
||||
},
|
||||
{
|
||||
ID: collapsedTreeItem,
|
||||
actionName: "expand",
|
||||
actionIndex: 1,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
check: function check(aEvent)
|
||||
{
|
||||
testStates(this.ID, STATE_EXPANDED);
|
||||
}
|
||||
},
|
||||
{
|
||||
ID: collapsedTreeItem,
|
||||
actionName: "collapse",
|
||||
actionIndex: 1,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
check: function check(aEvent)
|
||||
{
|
||||
testStates(this.ID, STATE_COLLAPSED);
|
||||
}
|
||||
},
|
||||
{
|
||||
ID: cycleCell,
|
||||
actionName: "cycle",
|
||||
actionIndex: 0,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode
|
||||
},
|
||||
{
|
||||
ID: checkableCell,
|
||||
actionName: "uncheck",
|
||||
actionIndex: 0,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
eventSeq: [
|
||||
new stateChangeChecker(checkableCell, false)
|
||||
]
|
||||
},
|
||||
{
|
||||
ID: checkableCell,
|
||||
actionName: "check",
|
||||
actionIndex: 0,
|
||||
events: CLICK_EVENTS,
|
||||
targetID: treeBodyNode,
|
||||
eventSeq: [
|
||||
new stateChangeChecker(checkableCell, true)
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
testActions(actions); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var treeNode = getNode("tabletree");
|
||||
treeNode.addEventListener("TreeViewChanged", doTestActions, false);
|
||||
treeNode.view = new nsTreeTreeView();
|
||||
}
|
||||
|
||||
function test1()
|
||||
{
|
||||
var boxObj = getNode("tabletree").treeBoxObject;
|
||||
boxObj.view.setCellValue(0, boxObj.columns.firstColumn, "false");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tree id="tabletree" flex="1" editable="true">
|
||||
<treecols>
|
||||
<treecol id="tabletree_col1" cycler="true" label="cycler"/>
|
||||
<treecol id="tabletree_col2" flex="1" primary="true" label="column1"/>
|
||||
<treecol id="tabletree_col3" flex="1" label="column2"/>
|
||||
<treecol id="tabletree_col4" flex="1" label="checker"
|
||||
type="checkbox" editable="true"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<vbox id="debug"/>
|
||||
<button oncommand="test1();" label="uncheck"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
93
accessible/tests/mochitest/test_attrs_elm_tree.xul
Normal file
93
accessible/tests/mochitest/test_attrs_elm_tree.xul
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tree attributes tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/attributes.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTestAttrs()
|
||||
{
|
||||
var treeNode = getNode("tree");
|
||||
treeNode.removeEventListener("TreeViewChanged", doTestAttrs, false);
|
||||
|
||||
var tree = getAccessible(treeNode);
|
||||
var treeitem1 = tree.firstChild.nextSibling;
|
||||
testGroupAttrs(treeitem1, "1", "4", "1");
|
||||
|
||||
var treeitem2 = treeitem1.nextSibling;
|
||||
testGroupAttrs(treeitem2, "2", "4", "1");
|
||||
|
||||
var treeitem3 = treeitem2.nextSibling;
|
||||
testGroupAttrs(treeitem3, "1", "2", "2");
|
||||
|
||||
var treeitem4 = treeitem3.nextSibling;
|
||||
testGroupAttrs(treeitem4, "2", "2", "2");
|
||||
|
||||
var treeitem5 = treeitem4.nextSibling;
|
||||
testGroupAttrs(treeitem5, "3", "4", "1");
|
||||
|
||||
var treeitem6 = treeitem5.nextSibling;
|
||||
testGroupAttrs(treeitem6, "4", "4", "1");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var treeNode = getNode("tree");
|
||||
treeNode.addEventListener("TreeViewChanged", doTestAttrs, false);
|
||||
treeNode.view = new nsTreeTreeView();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<vbox id="debug"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
185
accessible/tests/mochitest/test_elm_tree.xul
Normal file
185
accessible/tests/mochitest/test_elm_tree.xul
Normal file
@ -0,0 +1,185 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tree hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/role.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible tree testers
|
||||
|
||||
function getTreeItemAccTree(aTableRole, aColumnsCount)
|
||||
{
|
||||
var treeItemRole;
|
||||
switch (aTableRole) {
|
||||
case ROLE_LIST:
|
||||
treeItemRole = ROLE_LISTITEM;
|
||||
break;
|
||||
case ROLE_OUTLINE:
|
||||
treeItemRole = ROLE_OUTLINEITEM;
|
||||
break;
|
||||
case ROLE_TABLE: case ROLE_TREE_TABLE:
|
||||
treeItemRole = ROLE_ROW;
|
||||
break;
|
||||
}
|
||||
|
||||
var accTree = {
|
||||
role: treeItemRole,
|
||||
children: []
|
||||
};
|
||||
|
||||
if (aTableRole == ROLE_TABLE || aTableRole == ROLE_TREE_TABLE) {
|
||||
for (var idx = 0; idx < aColumnsCount; idx++) {
|
||||
var cellAccTree = {
|
||||
role: ROLE_GRID_CELL,
|
||||
children: []
|
||||
};
|
||||
accTree.children.push(cellAccTree);
|
||||
}
|
||||
}
|
||||
|
||||
return accTree;
|
||||
}
|
||||
|
||||
function testAccessibleTreeFor(aTree, aRole)
|
||||
{
|
||||
var accTreeForColumns = {
|
||||
role: ROLE_LIST,
|
||||
children: []
|
||||
};
|
||||
|
||||
var accTreeForTree = {
|
||||
role: aRole,
|
||||
children: [
|
||||
accTreeForColumns
|
||||
]
|
||||
};
|
||||
|
||||
var treeBoxObject = aTree.treeBoxObject;
|
||||
var view = treeBoxObject.view;
|
||||
var columnsCount = treeBoxObject.columns.count;
|
||||
|
||||
for (var idx = 0; idx < columnsCount; idx++)
|
||||
accTreeForColumns.children.push({ role: ROLE_COLUMNHEADER, children: []});
|
||||
if (!aTree.hasAttribute("hidecolumnpicker"))
|
||||
accTreeForColumns.children.push({ role: ROLE_PUSHBUTTON, children: []});
|
||||
|
||||
for (var idx = 0; idx < view.rowCount; idx++)
|
||||
accTreeForTree.children.push(getTreeItemAccTree(aRole, columnsCount));
|
||||
|
||||
testAccessibleTree(aTree, accTreeForTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event queue invoker object to test accessible tree for XUL tree element.
|
||||
*/
|
||||
function treeChecker(aID, aView, aRole)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.invoke = function invoke()
|
||||
{
|
||||
this.DOMNode.treeBoxObject.view = aView;
|
||||
}
|
||||
this.check = function check(aEvent)
|
||||
{
|
||||
testAccessibleTreeFor(this.DOMNode, aRole);
|
||||
}
|
||||
this.getID = function getID()
|
||||
{
|
||||
return "Tree testing of " + aID;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
var gQueue = null;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var gQueue = new eventQueue("TreeViewChanged");
|
||||
|
||||
gQueue.push(new treeChecker("list", new nsTableTreeView(3), ROLE_LIST));
|
||||
gQueue.push(new treeChecker("tree", new nsTreeTreeView(), ROLE_OUTLINE));
|
||||
gQueue.push(new treeChecker("table", new nsTableTreeView(3), ROLE_TABLE));
|
||||
gQueue.push(new treeChecker("treetable", new nsTreeTreeView(), ROLE_TREE_TABLE));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tree id="list" flex="1" hidecolumnpicker="true">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" hideheader="true"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="table" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" label="column"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="treetable" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" primary="true" label="column"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<vbox id="debug"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
@ -30,6 +30,24 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invoker's checkers
|
||||
|
||||
/**
|
||||
* Check TreeViewChanged event and run through accessible tree to ensure
|
||||
* it's created.
|
||||
*/
|
||||
function treeViewChangedChecker(aMsg)
|
||||
{
|
||||
this.type = "TreeViewChanged";
|
||||
this.target = gTree;
|
||||
this.check = function check(aEvent)
|
||||
{
|
||||
ensureAccessibleTree(gTree);
|
||||
}
|
||||
this.getID = function getID()
|
||||
{
|
||||
return "TreeViewChanged";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check TreeRowCountChanged event.
|
||||
*/
|
||||
@ -93,13 +111,8 @@
|
||||
{
|
||||
var acc = getAccessible(gTree);
|
||||
|
||||
var tableAcc = getAccessible(acc, [nsIAccessibleTable], null,
|
||||
DONOTFAIL_IF_NO_INTERFACE);
|
||||
|
||||
if (tableAcc)
|
||||
return tableAcc.cellRefAt(aRow, aCol);
|
||||
|
||||
return acc.getChildAt(aRow + 1);
|
||||
var tableAcc = getAccessible(acc, [nsIAccessibleTable]);
|
||||
return tableAcc.cellRefAt(aRow, aCol);
|
||||
}
|
||||
this.getID = function getID()
|
||||
{
|
||||
@ -122,7 +135,7 @@
|
||||
|
||||
this.getID = function setTreeView_getID() { return "TreeViewChanged"; }
|
||||
|
||||
this.eventSeq = [ new invokerChecker("TreeViewChanged", gTree) ];
|
||||
this.eventSeq = [ new treeViewChangedChecker() ];
|
||||
};
|
||||
|
||||
/**
|
||||
@ -133,7 +146,7 @@
|
||||
{
|
||||
this.invoke = function insertRow_invoke()
|
||||
{
|
||||
++gView.mRowCount;
|
||||
gView.appendItem("last");
|
||||
gTreeBox.rowCountChanged(0, 1);
|
||||
}
|
||||
|
||||
@ -154,18 +167,14 @@
|
||||
{
|
||||
// Make sure accessibles for the tree is created because it makes
|
||||
// sure accessible events will be fired.
|
||||
var treeAcc = getAccessible(gTree);
|
||||
|
||||
// Makes sure tree children accessibles are created otherwise they won't
|
||||
// Make sure tree children accessibles are created otherwise they won't
|
||||
// be a cause of name changed events.
|
||||
var children = treeAcc.children;
|
||||
ensureAccessibleTree(gTree);
|
||||
|
||||
// Fire 'TreeInvalidated' event by InvalidateColumn()
|
||||
var firstCol = gTree.columns.getFirstColumn();
|
||||
for (var i = 0; i < gView.mRowCount; i++) {
|
||||
var key = String(i) + firstCol.id;
|
||||
gView.mData[key] = key + "_col";
|
||||
}
|
||||
for (var i = 0; i < gView.rowCount; i++)
|
||||
gView.setCellText(i, firstCol, "hey " + String(i) + "x0");
|
||||
|
||||
gTreeBox.invalidateColumn(firstCol);
|
||||
}
|
||||
@ -193,9 +202,10 @@
|
||||
{
|
||||
// Fire 'TreeInvalidated' event by InvalidateRow()
|
||||
var colCount = gTree.columns.count;
|
||||
for (var i = 0; i < colCount; i++) {
|
||||
var key = "1" + gTree.columns.getColumnAt(i).id;
|
||||
gView.mData[key] = key + "_row";
|
||||
var column = gTree.columns.getFirstColumn();
|
||||
while (column) {
|
||||
gView.setCellText(1, column, "aloha 1x" + String(column.index));
|
||||
column = column.getNext();
|
||||
}
|
||||
|
||||
gTreeBox.invalidateRow(1);
|
||||
@ -204,6 +214,7 @@
|
||||
this.eventSeq =
|
||||
[
|
||||
new nameChangeChecker("invalidateColumn: ", 1, 0),
|
||||
new nameChangeChecker("invalidateColumn: ", 1, 1),
|
||||
new treeInvalidatedChecker("invalidateColumn", 1, 1, null, null)
|
||||
];
|
||||
}
|
||||
@ -223,9 +234,7 @@
|
||||
// Initialize the tree
|
||||
gTree = document.getElementById("tree");
|
||||
gTreeBox = gTree.treeBoxObject;
|
||||
|
||||
gView = new inTreeView();
|
||||
gView.mRowCount = 5;
|
||||
gView = new nsTableTreeView(5);
|
||||
|
||||
// Perform actions
|
||||
gQueue = new eventQueue();
|
||||
@ -265,8 +274,8 @@
|
||||
<vbox id="debug"/>
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
<treecol id="scol" flex="1" label="column 2"/>
|
||||
<treecol id="col1" flex="1" primary="true" label="column"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="treechildren"/>
|
||||
</tree>
|
||||
|
93
accessible/tests/mochitest/test_relations_tree.xul
Normal file
93
accessible/tests/mochitest/test_relations_tree.xul
Normal file
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tree relations tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/relations.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTestRelations()
|
||||
{
|
||||
var treeNode = getNode("tree");
|
||||
treeNode.removeEventListener("TreeViewChanged", doTestRelations, false);
|
||||
|
||||
var tree = getAccessible(treeNode);
|
||||
var treeitem1 = tree.firstChild.nextSibling;
|
||||
testRelation(treeitem1, RELATION_NODE_CHILD_OF, [tree]);
|
||||
|
||||
var treeitem2 = treeitem1.nextSibling;
|
||||
testRelation(treeitem2, RELATION_NODE_CHILD_OF, [tree]);
|
||||
|
||||
var treeitem3 = treeitem2.nextSibling;
|
||||
testRelation(treeitem3, RELATION_NODE_CHILD_OF, [treeitem2]);
|
||||
|
||||
var treeitem4 = treeitem3.nextSibling;
|
||||
testRelation(treeitem4, RELATION_NODE_CHILD_OF, [treeitem2]);
|
||||
|
||||
var treeitem5 = treeitem4.nextSibling;
|
||||
testRelation(treeitem5, RELATION_NODE_CHILD_OF, [tree]);
|
||||
|
||||
var treeitem6 = treeitem5.nextSibling;
|
||||
testRelation(treeitem6, RELATION_NODE_CHILD_OF, [tree]);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var treeNode = getNode("tree");
|
||||
treeNode.addEventListener("TreeViewChanged", doTestRelations, false);
|
||||
treeNode.view = new nsTreeTreeView();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<vbox id="debug"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
145
accessible/tests/mochitest/test_states_tree.xul
Normal file
145
accessible/tests/mochitest/test_states_tree.xul
Normal file
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/treeview.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tree states tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/states.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
|
||||
/**
|
||||
* Event queue invoker object to test accessible states for XUL tree
|
||||
* accessible.
|
||||
*/
|
||||
function statesChecker(aTreeID, aView)
|
||||
{
|
||||
this.DOMNode = getNode(aTreeID);
|
||||
this.invoke = function invoke()
|
||||
{
|
||||
this.DOMNode.treeBoxObject.view = aView;
|
||||
}
|
||||
this.check = function check()
|
||||
{
|
||||
var tree = getAccessible(this.DOMNode);
|
||||
|
||||
// tree states
|
||||
testStates(tree, STATE_READONLY);
|
||||
|
||||
if (this.DOMNode.getAttribute("seltype") != "single")
|
||||
testStates(tree, STATE_MULTISELECTABLE);
|
||||
else
|
||||
testStates(tree, 0, 0, STATE_MULTISELECTABLE);
|
||||
|
||||
// tree item states
|
||||
var expandedItem = tree.getChildAt(2);
|
||||
testStates(expandedItem,
|
||||
STATE_SELECTABLE | STATE_FOCUSABLE | STATE_EXPANDED);
|
||||
|
||||
var collapsedItem = tree.getChildAt(5);
|
||||
testStates(collapsedItem,
|
||||
STATE_SELECTABLE | STATE_FOCUSABLE | STATE_COLLAPSED);
|
||||
|
||||
// cells states if any
|
||||
var cells = collapsedItem.children;
|
||||
if (cells && cells.length) {
|
||||
for (var idx = 0; idx < cells.length; idx++) {
|
||||
var cell = cells.queryElementAt(idx, nsIAccessible);
|
||||
testStates(cell, STATE_SELECTABLE);
|
||||
}
|
||||
|
||||
var checkboxCell = cells.queryElementAt(3, nsIAccessible);
|
||||
testStates(checkboxCell, STATE_CHECKABLE | STATE_CHECKED);
|
||||
}
|
||||
}
|
||||
this.getID = function getID()
|
||||
{
|
||||
"tree processor for " + prettyName(aTreeID);
|
||||
}
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue("TreeViewChanged");
|
||||
gQueue.push(new statesChecker("tree", new nsTreeTreeView()));
|
||||
gQueue.push(new statesChecker("treesingle", new nsTreeTreeView()));
|
||||
gQueue.push(new statesChecker("tabletree", new nsTreeTreeView()));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="treesingle" flex="1" seltype="single">
|
||||
<treecols>
|
||||
<treecol id="col_single" flex="1" primary="true" label="column"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="tabletree" flex="1" editable="true">
|
||||
<treecols>
|
||||
<treecol id="tabletree_col1" cycler="true" label="cycler"/>
|
||||
<treecol id="tabletree_col2" flex="1" primary="true" label="column1"/>
|
||||
<treecol id="tabletree_col3" flex="1" label="column2"/>
|
||||
<treecol id="tabletree_col4" flex="1" label="checker"
|
||||
type="checkbox" editable="true"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<vbox id="debug"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
88
accessible/tests/mochitest/test_table_indexes_tree.xul
Normal file
88
accessible/tests/mochitest/test_table_indexes_tree.xul
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible Table indexes tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/table.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gTree = null;
|
||||
var gTreeBox = null;
|
||||
var gTreeView = null;
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// Initialize the tree
|
||||
gTree = document.getElementById("tree");
|
||||
gTreeBox = gTree.treeBoxObject;
|
||||
gView = new nsTableTreeView(3);
|
||||
|
||||
gTree.addEventListener("TreeViewChanged", continueTest, false);
|
||||
gTreeBox.view = gView;
|
||||
}
|
||||
|
||||
function continueTest()
|
||||
{
|
||||
gTree.removeEventListener("TreeViewChanged", continueTest, false);
|
||||
|
||||
var idxes = [
|
||||
[0, 1],
|
||||
[2, 3],
|
||||
[4, 5]
|
||||
];
|
||||
testTableIndexes(gTree, idxes);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="debug"/>
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
<treecol id="scol" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="treechildren"/>
|
||||
</tree>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
94
accessible/tests/mochitest/test_table_sels_tree.xul
Normal file
94
accessible/tests/mochitest/test_table_sels_tree.xul
Normal file
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible Table selection tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/states.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/table.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gTree = null;
|
||||
var gTreeBox = null;
|
||||
var gTreeView = null;
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// Initialize the tree
|
||||
gTree = document.getElementById("tree");
|
||||
gTreeBox = gTree.treeBoxObject;
|
||||
gView = new nsTableTreeView(3);
|
||||
|
||||
gTree.addEventListener("TreeViewChanged", continueTest, false);
|
||||
gTreeBox.view = gView;
|
||||
}
|
||||
|
||||
function continueTest()
|
||||
{
|
||||
gTree.removeEventListener("TreeViewChanged", continueTest, false);
|
||||
|
||||
var cellsArray =
|
||||
[
|
||||
[false, false],
|
||||
[false, false],
|
||||
[false, false]
|
||||
];
|
||||
|
||||
testTableSelection(gTree, cellsArray);
|
||||
testSelectTableRow(gTree, 0, cellsArray);
|
||||
testUnselectTableRow(gTree, 0, cellsArray);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
|
||||
title="Reorganize implementation of XUL tree accessibility">
|
||||
Mozilla Bug 503727
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="debug"/>
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col" flex="1" primary="true" label="column"/>
|
||||
<treecol id="scol" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="treechildren"/>
|
||||
</tree>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
15
accessible/tests/mochitest/treeview.css
Normal file
15
accessible/tests/mochitest/treeview.css
Normal file
@ -0,0 +1,15 @@
|
||||
treechildren::-moz-tree-checkbox(checked) {
|
||||
list-style-image: url("chrome://global/skin/checkbox/cbox-check.gif");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(cyclerState1) {
|
||||
list-style-image: url("chrome://global/skin/console/bullet-question.png");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(cyclerState2) {
|
||||
list-style-image: url("chrome://global/skin/console/bullet-warning.png");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(cyclerState3) {
|
||||
list-style-image: url("chrome://global/skin/console/bullet-error.png");
|
||||
}
|
@ -1,14 +1,33 @@
|
||||
function inTreeView() { }
|
||||
|
||||
inTreeView.prototype =
|
||||
function nsTableTreeView(aRowCount)
|
||||
{
|
||||
mRowCount: 0,
|
||||
mTree: null,
|
||||
mData: {},
|
||||
this.__proto__ = new nsTreeView();
|
||||
|
||||
for (var idx = 0; idx < aRowCount; idx++)
|
||||
this.mData.push(new treeItem("row" + String(idx) + "_"));
|
||||
}
|
||||
|
||||
function nsTreeTreeView()
|
||||
{
|
||||
this.__proto__ = new nsTreeView();
|
||||
|
||||
this.mData = [
|
||||
new treeItem("row1"),
|
||||
new treeItem("row2_", true, [new treeItem("row2.1_"), new treeItem("row2.2_")]),
|
||||
new treeItem("row3_", false, [new treeItem("row3.1_"), new treeItem("row3.2_")]),
|
||||
new treeItem("row4")
|
||||
];
|
||||
}
|
||||
|
||||
function nsTreeView() { }
|
||||
|
||||
nsTreeView.prototype =
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// nsITreeView implementation
|
||||
|
||||
get rowCount()
|
||||
{
|
||||
return this.mRowCount;
|
||||
return this.getRowCountIntl(this.mData);
|
||||
},
|
||||
setTree: function setTree(aTree)
|
||||
{
|
||||
@ -16,35 +35,198 @@ inTreeView.prototype =
|
||||
},
|
||||
getCellText: function getCellText(aRow, aCol)
|
||||
{
|
||||
var key = String(aRow) + aCol.id;
|
||||
if (key in this.mData)
|
||||
return this.mData[key];
|
||||
|
||||
return "hello";
|
||||
var data = this.getDataForIndex(aRow);
|
||||
if (aCol in data.colsText)
|
||||
return data.colsText[aCol];
|
||||
|
||||
return data.text + aCol.id;
|
||||
},
|
||||
getCellValue: function getCellValue(aRow, aCol)
|
||||
{
|
||||
var data = this.getDataForIndex(aRow);
|
||||
return data.value;
|
||||
},
|
||||
getRowProperties: function getRowProperties(aIndex, aProperties) {},
|
||||
getCellProperties: function getCellProperties(aIndex, aCol, aProperties) {},
|
||||
getCellProperties: function getCellProperties(aIndex, aCol, aProperties)
|
||||
{
|
||||
if (!aCol.cycler)
|
||||
return;
|
||||
|
||||
var data = this.getDataForIndex(aIndex);
|
||||
var atom = this.mCyclerStates[data.cyclerState];
|
||||
aProperties.AppendElement(atom);
|
||||
},
|
||||
getColumnProperties: function getColumnProperties(aCol, aProperties) {},
|
||||
getParentIndex: function getParentIndex(aRowIndex) { },
|
||||
getParentIndex: function getParentIndex(aRowIndex)
|
||||
{
|
||||
var info = this.getInfoByIndex(aRowIndex);
|
||||
return info.parentIndex;
|
||||
},
|
||||
hasNextSibling: function hasNextSibling(aRowIndex, aAfterIndex) { },
|
||||
getLevel: function getLevel(aIndex) {},
|
||||
getLevel: function getLevel(aIndex)
|
||||
{
|
||||
var info = this.getInfoByIndex(aIndex);
|
||||
return info.level;
|
||||
},
|
||||
getImageSrc: function getImageSrc(aRow, aCol) {},
|
||||
getProgressMode: function getProgressMode(aRow, aCol) {},
|
||||
getCellValue: function getCellValue(aRow, aCol) {},
|
||||
isContainer: function isContainer(aIndex) {},
|
||||
isContainerOpen: function isContainerOpen(aIndex) {},
|
||||
isContainerEmpty: function isContainerEmpty(aIndex) {},
|
||||
isContainer: function isContainer(aIndex)
|
||||
{
|
||||
var data = this.getDataForIndex(aIndex);
|
||||
return data.open != undefined;
|
||||
},
|
||||
isContainerOpen: function isContainerOpen(aIndex)
|
||||
{
|
||||
var data = this.getDataForIndex(aIndex);
|
||||
return data.open;
|
||||
},
|
||||
isContainerEmpty: function isContainerEmpty(aIndex)
|
||||
{
|
||||
var data = this.getDataForIndex(aIndex);
|
||||
return data.open == undefined;
|
||||
},
|
||||
isSeparator: function isSeparator(aIndex) {},
|
||||
isSorted: function isSorted() {},
|
||||
toggleOpenState: function toggleOpenState(aIndex) {},
|
||||
toggleOpenState: function toggleOpenState(aIndex)
|
||||
{
|
||||
var data = this.getDataForIndex(aIndex);
|
||||
|
||||
data.open = !data.open;
|
||||
var rowCount = this.getRowCountIntl(data.children);
|
||||
|
||||
if (data.open)
|
||||
this.mTree.rowCountChanged(aIndex + 1, rowCount);
|
||||
else
|
||||
this.mTree.rowCountChanged(aIndex + 1, -rowCount);
|
||||
},
|
||||
selectionChanged: function selectionChanged() {},
|
||||
cycleHeader: function cycleHeader(aCol) {},
|
||||
cycleCell: function cycleCell(aRow, aCol) {},
|
||||
isEditable: function isEditable(aRow, aCol) {},
|
||||
cycleCell: function cycleCell(aRow, aCol)
|
||||
{
|
||||
var data = this.getDataForIndex(aRow);
|
||||
data.cyclerState = (data.cyclerState + 1) % 3;
|
||||
|
||||
this.mTree.invalidateCell(aRow, aCol);
|
||||
},
|
||||
isEditable: function isEditable(aRow, aCol)
|
||||
{
|
||||
return true;
|
||||
},
|
||||
isSelectable: function isSelectable(aRow, aCol) {},
|
||||
setCellValue: function setCellValue(aRow, aCol, aValue) {},
|
||||
setCellText: function setCellText(aRow, aCol, aValue) { },
|
||||
setCellText: function setCellText(aRow, aCol, aValue)
|
||||
{
|
||||
var data = this.getDataForIndex(aRow);
|
||||
data.colsText[aCol] = aValue;
|
||||
},
|
||||
setCellValue: function setCellValue(aRow, aCol, aValue)
|
||||
{
|
||||
var data = this.getDataForIndex(aRow);
|
||||
data.value = aValue;
|
||||
|
||||
this.mTree.invalidateCell(aRow, aCol);
|
||||
},
|
||||
performAction: function performAction(aAction) {},
|
||||
performActionOnRow: function performActionOnRow(aAction, aRow) {},
|
||||
performActionOnCell: function performActionOnCell(aAction, aRow, aCol) {}
|
||||
performActionOnCell: function performActionOnCell(aAction, aRow, aCol) {},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// public implementation
|
||||
|
||||
appendItem: function appendItem(aText)
|
||||
{
|
||||
this.mData.push(new treeItem(aText));
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// private implementation
|
||||
|
||||
getDataForIndex: function getDataForIndex(aRowIndex)
|
||||
{
|
||||
return this.getInfoByIndex(aRowIndex).data;
|
||||
},
|
||||
|
||||
getInfoByIndex: function getInfoByIndex(aRowIndex)
|
||||
{
|
||||
var info = {
|
||||
data: null,
|
||||
parentIndex: -1,
|
||||
level: 0,
|
||||
index: -1
|
||||
};
|
||||
|
||||
this.getInfoByIndexIntl(aRowIndex, info, this.mData, 0);
|
||||
return info;
|
||||
},
|
||||
|
||||
getRowCountIntl: function getRowCountIntl(aChildren)
|
||||
{
|
||||
var rowCount = 0;
|
||||
for (var childIdx = 0; childIdx < aChildren.length; childIdx++) {
|
||||
rowCount++;
|
||||
|
||||
var data = aChildren[childIdx];
|
||||
if (data.open)
|
||||
rowCount += this.getRowCountIntl(data.children);
|
||||
}
|
||||
|
||||
return rowCount;
|
||||
},
|
||||
|
||||
getInfoByIndexIntl: function getInfoByIndexIntl(aRowIdx, aInfo,
|
||||
aChildren, aLevel)
|
||||
{
|
||||
var rowIdx = aRowIdx;
|
||||
for (var childIdx = 0; childIdx < aChildren.length; childIdx++) {
|
||||
var data = aChildren[childIdx];
|
||||
|
||||
aInfo.index++;
|
||||
|
||||
if (rowIdx == 0) {
|
||||
aInfo.data = data;
|
||||
aInfo.level = aLevel;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (data.open) {
|
||||
var parentIdx = aInfo.index;
|
||||
rowIdx = this.getInfoByIndexIntl(rowIdx - 1, aInfo, data.children,
|
||||
aLevel + 1);
|
||||
|
||||
if (rowIdx == -1) {
|
||||
if (aInfo.parentIndex == -1)
|
||||
aInfo.parentIndex = parentIdx;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
rowIdx--;
|
||||
}
|
||||
}
|
||||
|
||||
return rowIdx;
|
||||
},
|
||||
|
||||
mTree: null,
|
||||
mData: [],
|
||||
mCyclerStates: [
|
||||
createAtom("cyclerState1"),
|
||||
createAtom("cyclerState2"),
|
||||
createAtom("cyclerState3")
|
||||
]
|
||||
};
|
||||
|
||||
function treeItem(aText, aOpen, aChildren)
|
||||
{
|
||||
this.text = aText;
|
||||
this.colsText = {};
|
||||
this.open = aOpen;
|
||||
this.value = "true";
|
||||
this.cyclerState = 0;
|
||||
if (aChildren)
|
||||
this.children = aChildren;
|
||||
}
|
||||
|
||||
function createAtom(aName)
|
||||
{
|
||||
return Components.classes["@mozilla.org/atom-service;1"]
|
||||
.getService(Components.interfaces.nsIAtomService).getAtom(aName);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user