mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-24 19:37:15 +00:00
bug 201922 Make XUL tree accessibles keep track of their own tree item accessibles
r = aaronleventhal sr= Henry.Jia
This commit is contained in:
parent
26ee61eb3e
commit
69c97f7259
@ -64,6 +64,7 @@ XPIDLSRCS = \
|
||||
nsPIAccessibleDocument.idl \
|
||||
nsIAccessibleProvider.idl \
|
||||
nsIAccessibleSelectable.idl \
|
||||
nsIAccessibleTreeCache.idl \
|
||||
nsIAccessNode.idl \
|
||||
nsPIAccessNode.idl \
|
||||
nsIAccessibleEvent.idl \
|
||||
|
53
accessible/public/nsIAccessibleTreeCache.idl
Normal file
53
accessible/public/nsIAccessibleTreeCache.idl
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- 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
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsITreeColumns.idl"
|
||||
|
||||
interface nsIAccessible;
|
||||
/**
|
||||
* A cross-platform interface that supports cache for tree item
|
||||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(CC742DA2-9C25-4D04-96CD-DA407D676C6D)]
|
||||
interface nsIAccessibleTreeCache : nsISupports
|
||||
{
|
||||
/**
|
||||
* Get tree item from cache according to row and column, create if doesn't exist in cache
|
||||
* "aColumn" can be nsnull
|
||||
*/
|
||||
[noscript] nsIAccessible getCachedTreeitemAccessible(in PRInt32 aRow, in nsITreeColumn aColumn);
|
||||
};
|
@ -869,7 +869,7 @@ getIndexInParentCB(AtkObject *aAtkObj)
|
||||
|
||||
nsCOMPtr<nsIAccessible> accChild;
|
||||
nsCOMPtr<nsIAccessible> accTmpChild;
|
||||
accWrap->GetFirstChild(getter_AddRefs(accChild));
|
||||
accParent->GetFirstChild(getter_AddRefs(accChild));
|
||||
|
||||
PRInt32 currentIndex = -1;
|
||||
void *currentAccId = nsnull;
|
||||
|
@ -225,12 +225,7 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
|
||||
rv = treeColumns->GetColumnFor(columnElement, getter_AddRefs(treeColumn));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = new nsXULTreeitemAccessible(this, mDOMNode, mWeakShell, aRow, treeColumn);
|
||||
NS_ENSURE_TRUE(*_retval, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_IF_ADDREF(*_retval);
|
||||
|
||||
return NS_OK;
|
||||
return GetCachedTreeitemAccessible(aRow, treeColumn, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessibleWrap::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
|
||||
@ -257,7 +252,11 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32
|
||||
rv = GetColumns(&columns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = aIndex % columns;
|
||||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
|
||||
*_retval = (aIndex - treeCols) % columns;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -271,7 +270,11 @@ NS_IMETHODIMP nsXULTreeAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *_r
|
||||
rv = GetColumns(&columns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = aIndex / columns;
|
||||
PRInt32 treeCols;
|
||||
nsAccessible::GetChildCount(&treeCols);
|
||||
|
||||
*_retval = (aIndex - treeCols) / columns;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -384,15 +384,14 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
|
||||
PRInt32 treeIndex = -1;
|
||||
multiSelect->GetCurrentIndex(&treeIndex);
|
||||
if (treeIndex >= 0) {
|
||||
// XXX todo Kyle - fix bug 201922 so that tree is responsible for keeping track
|
||||
// of it's own accessibles. Then we'll ask the tree so we can reuse
|
||||
// the accessibles already created.
|
||||
nsCOMPtr<nsIWeakReference> weakEventShell(do_GetWeakReference(eventShell));
|
||||
treeItemAccessible = new nsXULTreeitemAccessible(accessible, targetNode,
|
||||
weakEventShell, treeIndex);
|
||||
if (!treeItemAccessible) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(accessible));
|
||||
if (!treeCache ||
|
||||
NS_FAILED(treeCache->GetCachedTreeitemAccessible(
|
||||
treeIndex,
|
||||
nsnull,
|
||||
getter_AddRefs(treeItemAccessible))) ||
|
||||
!treeItemAccessible)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,18 +47,33 @@
|
||||
#include "nsIAccessibleTable.h"
|
||||
#endif
|
||||
|
||||
#define kMaxTreeColumns 100
|
||||
// ---------- nsXULTreeAccessible ----------
|
||||
|
||||
nsXULTreeAccessible::nsXULTreeAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
|
||||
nsXULSelectableAccessible(aDOMNode, aShell)
|
||||
nsXULSelectableAccessible(aDOMNode, aShell),
|
||||
mAccessNodeCache(nsnull)
|
||||
|
||||
{
|
||||
GetTreeBoxObject(aDOMNode, getter_AddRefs(mTree));
|
||||
if (mTree)
|
||||
mTree->GetView(getter_AddRefs(mTreeView));
|
||||
NS_ASSERTION(mTree && mTreeView, "Can't get mTree or mTreeView!\n");
|
||||
mAccessNodeCache = new nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode>;
|
||||
mAccessNodeCache->Init(kDefaultTreeCacheSize);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeAccessible, nsXULSelectableAccessible)
|
||||
nsXULTreeAccessible::~nsXULTreeAccessible()
|
||||
{
|
||||
if (mAccessNodeCache) {
|
||||
ClearCache(*mAccessNodeCache);
|
||||
mAccessNodeCache = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeAccessible, nsXULSelectableAccessible, nsIAccessibleTreeCache)
|
||||
|
||||
|
||||
|
||||
// Get the nsITreeBoxObject interface from any levels DOMNode under the <tree>
|
||||
void nsXULTreeAccessible::GetTreeBoxObject(nsIDOMNode *aDOMNode, nsITreeBoxObject **aBoxObject)
|
||||
@ -158,10 +173,7 @@ NS_IMETHODIMP nsXULTreeAccessible::GetFirstChild(nsIAccessible **aFirstChild)
|
||||
PRInt32 rowCount;
|
||||
mTreeView->GetRowCount(&rowCount);
|
||||
if (rowCount > 0) {
|
||||
*aFirstChild = new nsXULTreeitemAccessible(this, mDOMNode, mWeakShell, 0);
|
||||
if (! *aFirstChild)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aFirstChild);
|
||||
return GetCachedTreeitemAccessible(0, nsnull, aFirstChild);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,10 +187,7 @@ NS_IMETHODIMP nsXULTreeAccessible::GetLastChild(nsIAccessible **aLastChild)
|
||||
PRInt32 rowCount;
|
||||
mTreeView->GetRowCount(&rowCount);
|
||||
if (rowCount > 0) {
|
||||
*aLastChild = new nsXULTreeitemAccessible(this, mDOMNode, mWeakShell, rowCount - 1);
|
||||
if (! *aLastChild)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aLastChild);
|
||||
return GetCachedTreeitemAccessible(rowCount - 1, nsnull, aLastChild);
|
||||
}
|
||||
else // if there is not any rows, use treecols as tree's last child
|
||||
nsAccessible::GetLastChild(aLastChild);
|
||||
@ -223,8 +232,8 @@ NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
|
||||
selection->IsSelected(rowIndex, &isSelected);
|
||||
if (isSelected) {
|
||||
nsCOMPtr<nsIAccessible> tempAccess;
|
||||
tempAccess = new nsXULTreeitemAccessible(this, mDOMNode, mWeakShell, rowIndex);
|
||||
if (!tempAccess)
|
||||
if (NS_FAILED(GetCachedTreeitemAccessible(rowIndex, nsnull, getter_AddRefs(tempAccess))) || !tempAccess)
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
selectedAccessibles->AppendElement(tempAccess, PR_FALSE);
|
||||
}
|
||||
@ -318,12 +327,7 @@ NS_IMETHODIMP nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **
|
||||
selection->IsSelected(rowIndex, &isSelected);
|
||||
if (isSelected) {
|
||||
if (selCount == aIndex) {
|
||||
nsCOMPtr<nsIAccessible> tempAccess;
|
||||
tempAccess = new nsXULTreeitemAccessible(this, mDOMNode, mWeakShell, rowIndex);
|
||||
if (!tempAccess)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*_retval = tempAccess;
|
||||
NS_ADDREF(*_retval);
|
||||
return GetCachedTreeitemAccessible(rowIndex, nsnull, _retval);
|
||||
}
|
||||
selCount++;
|
||||
}
|
||||
@ -355,6 +359,39 @@ NS_IMETHODIMP nsXULTreeAccessible::SelectAllSelection(PRBool *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeAccessible::GetCachedTreeitemAccessible(PRInt32 aRow, nsITreeColumn* aColumn, nsIAccessible** aAccessible)
|
||||
{
|
||||
NS_ASSERTION(mAccessNodeCache, "No accessibility cache for tree");
|
||||
|
||||
NS_ASSERTION(mTree && mTreeView, "Can't get mTree or mTreeView!\n");
|
||||
|
||||
nsCOMPtr<nsITreeColumn> col = aColumn;
|
||||
PRInt32 columnIndex = -1;
|
||||
|
||||
if (!col && mTree) {
|
||||
nsCOMPtr<nsITreeColumns> cols;
|
||||
mTree->GetColumns(getter_AddRefs(cols));
|
||||
if (cols)
|
||||
cols->GetKeyColumn(getter_AddRefs(col));
|
||||
}
|
||||
|
||||
if (col)
|
||||
col->GetIndex(&columnIndex);
|
||||
|
||||
nsCOMPtr<nsIAccessNode> accessNode;
|
||||
GetCacheEntry(*mAccessNodeCache, (void*)(aRow * kMaxTreeColumns + columnIndex), getter_AddRefs(accessNode));
|
||||
if (!accessNode)
|
||||
{
|
||||
accessNode = new nsXULTreeitemAccessible(this, mDOMNode, mWeakShell, aRow, col);
|
||||
if (! accessNode)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
PutCacheEntry(*mAccessNodeCache, (void*)(aRow * kMaxTreeColumns + columnIndex), accessNode);
|
||||
}
|
||||
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode));
|
||||
NS_IF_ADDREF(*aAccessible = accessible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// ---------- nsXULTreeitemAccessible ----------
|
||||
|
||||
nsXULTreeitemAccessible::nsXULTreeitemAccessible(nsIAccessible *aParent, nsIDOMNode *aDOMNode, nsIWeakReference *aShell, PRInt32 aRow, nsITreeColumn* aColumn)
|
||||
@ -513,18 +550,17 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetNextSibling(nsIAccessible **aNextSibli
|
||||
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(mParent));
|
||||
NS_ENSURE_TRUE(treeCache, NS_ERROR_FAILURE);
|
||||
|
||||
PRInt32 rowCount;
|
||||
mTreeView->GetRowCount(&rowCount);
|
||||
|
||||
if (!mColumn) {
|
||||
if (mRow < rowCount - 1) {
|
||||
*aNextSibling = new nsXULTreeitemAccessible(mParent, mDOMNode, mWeakShell, mRow + 1);
|
||||
if (! *aNextSibling)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aNextSibling);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
if (mRow < rowCount - 1)
|
||||
return treeCache->GetCachedTreeitemAccessible(mRow + 1, nsnull, aNextSibling);
|
||||
else
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
@ -542,10 +578,7 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetNextSibling(nsIAccessible **aNextSibli
|
||||
cols->GetFirstColumn(getter_AddRefs(column));
|
||||
}
|
||||
|
||||
*aNextSibling = new nsXULTreeitemAccessible(mParent, mDOMNode, mWeakShell, row, column);
|
||||
NS_ENSURE_TRUE(*aNextSibling, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
NS_ADDREF(*aNextSibling);
|
||||
rv = treeCache->GetCachedTreeitemAccessible(row, column, aNextSibling);
|
||||
#endif //MOZ_ACCESSIBILITY_ATK
|
||||
|
||||
return rv;
|
||||
@ -559,16 +592,15 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetPreviousSibling(nsIAccessible **aPrevi
|
||||
|
||||
NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
|
||||
|
||||
if (!mColumn && mRow > 0) {
|
||||
*aPreviousSibling = new nsXULTreeitemAccessible(mParent, mDOMNode, mWeakShell, mRow - 1);
|
||||
if (! *aPreviousSibling)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aPreviousSibling);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(mParent));
|
||||
NS_ENSURE_TRUE(treeCache, NS_ERROR_FAILURE);
|
||||
|
||||
if (!mColumn && mRow > 0)
|
||||
return treeCache->GetCachedTreeitemAccessible(mRow - 1, nsnull, aPreviousSibling);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
||||
#ifdef MOZ_ACCESSIBILITY_ATK
|
||||
PRInt32 row = mRow;
|
||||
nsCOMPtr<nsITreeColumn> column;
|
||||
@ -583,10 +615,8 @@ NS_IMETHODIMP nsXULTreeitemAccessible::GetPreviousSibling(nsIAccessible **aPrevi
|
||||
cols->GetLastColumn(getter_AddRefs(column));
|
||||
}
|
||||
|
||||
*aPreviousSibling = new nsXULTreeitemAccessible(mParent, mDOMNode, mWeakShell, row, column);
|
||||
NS_ENSURE_TRUE(*aPreviousSibling, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = treeCache->GetCachedTreeitemAccessible(row, column, aPreviousSibling);
|
||||
|
||||
NS_ADDREF(*aPreviousSibling);
|
||||
#endif //MOZ_ACCESSIBILITY_ATK
|
||||
|
||||
return rv;
|
||||
@ -750,11 +780,9 @@ NS_IMETHODIMP nsXULTreeColumnsAccessible::GetNextSibling(nsIAccessible **aNextSi
|
||||
PRInt32 rowCount;
|
||||
treeView->GetRowCount(&rowCount);
|
||||
if (rowCount > 0) {
|
||||
*aNextSibling = new nsXULTreeitemAccessible(mParent, mDOMNode, mWeakShell, 0);
|
||||
if (! *aNextSibling)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aNextSibling);
|
||||
ret = NS_OK;
|
||||
nsCOMPtr<nsIAccessibleTreeCache> treeCache(do_QueryInterface(mParent));
|
||||
NS_ENSURE_TRUE(treeCache, NS_ERROR_FAILURE);
|
||||
ret = treeCache->GetCachedTreeitemAccessible(0, nsnull, aNextSibling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,18 +43,24 @@
|
||||
#include "nsITreeView.h"
|
||||
#include "nsITreeColumns.h"
|
||||
#include "nsXULSelectAccessible.h"
|
||||
#include "nsIAccessibleTreeCache.h"
|
||||
|
||||
|
||||
/*
|
||||
* A class the represents the XUL Tree widget.
|
||||
*/
|
||||
class nsXULTreeAccessible : public nsXULSelectableAccessible
|
||||
const PRUint32 kDefaultTreeCacheSize = 256;
|
||||
|
||||
class nsXULTreeAccessible : public nsXULSelectableAccessible,
|
||||
public nsIAccessibleTreeCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIACCESSIBLESELECTABLE
|
||||
NS_DECL_NSIACCESSIBLETREECACHE
|
||||
|
||||
nsXULTreeAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsXULTreeAccessible() {}
|
||||
virtual ~nsXULTreeAccessible();
|
||||
|
||||
/* ----- nsIAccessible ----- */
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
@ -70,6 +76,7 @@ public:
|
||||
protected:
|
||||
nsCOMPtr<nsITreeBoxObject> mTree;
|
||||
nsCOMPtr<nsITreeView> mTreeView;
|
||||
nsInterfaceHashtable<nsVoidHashKey, nsIAccessNode> *mAccessNodeCache;
|
||||
|
||||
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user