mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-05 16:22:53 +00:00
Bug 572394 - cache links within hypertext accessible, r=davidb, marcoz, sr=neil
--HG-- rename : accessible/src/base/nsAccIterator.cpp => accessible/src/base/AccIterator.cpp rename : accessible/src/base/nsAccIterator.h => accessible/src/base/AccIterator.h
This commit is contained in:
parent
85ccd4574e
commit
add7533996
@ -44,36 +44,46 @@
|
||||
|
||||
/**
|
||||
* A cross-platform interface that deals with text which contains hyperlinks.
|
||||
* Each link is an embedded object representing exactly 1 character within
|
||||
* the hypertext.
|
||||
*
|
||||
* Current implementation assumes every embedded object is a link.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(d56bd454-8ff3-4edc-b266-baeada00267b)]
|
||||
[scriptable, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
|
||||
interface nsIAccessibleHyperText : nsISupports
|
||||
{
|
||||
/**
|
||||
* Returns the number of links contained within this hypertext object.
|
||||
* Return the number of links contained within this hypertext object.
|
||||
*/
|
||||
readonly attribute long linkCount;
|
||||
|
||||
/*
|
||||
* Returns the link index at the given character index.
|
||||
* Each link is an embedded object representing exactly 1 character within
|
||||
* the hypertext.
|
||||
/**
|
||||
* Return link accessible at the given index.
|
||||
*
|
||||
* @param charIndex the 0-based character index.
|
||||
* @param index [in] 0-based index of the link that is to be retrieved
|
||||
*
|
||||
* @returns long 0-based link's index.
|
||||
* A return value of -1 indicates no link is present at that index.
|
||||
* @return link accessible or null if there is no link at that index
|
||||
*/
|
||||
long getLinkIndex(in long charIndex);
|
||||
nsIAccessibleHyperLink getLinkAt(in long index);
|
||||
|
||||
/**
|
||||
* Retrieves the nsIAccessibleHyperLink object at the given link index.
|
||||
* Return index of the given link.
|
||||
*
|
||||
* @param linkIndex 0-based index of the link that is to be retrieved.
|
||||
* This can be retrieved via getLinkIndex (see above).
|
||||
* @param link [in] link accessible the index is requested for
|
||||
*
|
||||
* @returns nsIAccessibleHyperLink Object representing the link properties
|
||||
* or NS_ERROR_INVALID_ARG if there is no link at that index.
|
||||
* @return index of the given link or null if there's no link within
|
||||
* hypertext accessible
|
||||
*/
|
||||
nsIAccessibleHyperLink getLink(in long linkIndex);
|
||||
long getLinkIndex(in nsIAccessibleHyperLink link);
|
||||
|
||||
/*
|
||||
* Return link index at the given offset within hypertext accessible.
|
||||
*
|
||||
* @param offset [in] the 0-based character index
|
||||
*
|
||||
* @return 0-based link's index or -1 if no link is present at that
|
||||
* offset
|
||||
*/
|
||||
long getLinkIndexAtOffset(in long offset);
|
||||
};
|
||||
|
@ -868,21 +868,11 @@ getChildCountCB(AtkObject *aAtkObj)
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRInt32 count = 0;
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
|
||||
if (hyperText) {
|
||||
// If HyperText, then number of links matches number of children
|
||||
hyperText->GetLinkCount(&count);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAccessibleText> accText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText), getter_AddRefs(accText));
|
||||
if (!accText) { // Accessible text that is not a HyperText has no children
|
||||
accWrap->GetChildCount(&count);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
// Links within hypertext accessible play role of accessible children in
|
||||
// ATK since every embedded object is a link and text accessibles are
|
||||
// ignored.
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
|
||||
return hyperText ? hyperText->GetLinkCount() : accWrap->GetChildCount();
|
||||
}
|
||||
|
||||
AtkObject *
|
||||
@ -898,25 +888,12 @@ refChildCB(AtkObject *aAtkObj, gint aChildIndex)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> accChild;
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
|
||||
if (hyperText) {
|
||||
// If HyperText, then number of links matches number of children.
|
||||
// XXX Fix this so it is not O(n^2) to walk through the children
|
||||
// (bug 566328).
|
||||
nsCOMPtr<nsIAccessibleHyperLink> hyperLink;
|
||||
hyperText->GetLink(aChildIndex, getter_AddRefs(hyperLink));
|
||||
accChild = do_QueryInterface(hyperLink);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAccessibleText> accText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText), getter_AddRefs(accText));
|
||||
if (!accText) { // Accessible Text that is not HyperText has no children
|
||||
accWrap->GetChildAt(aChildIndex, getter_AddRefs(accChild));
|
||||
}
|
||||
}
|
||||
|
||||
// Links within hypertext accessible play role of accessible children in
|
||||
// ATK since every embedded object is a link and text accessibles are
|
||||
// ignored.
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
|
||||
nsAccessible* accChild = hyperText ? hyperText->GetLinkAt(aChildIndex) :
|
||||
accWrap->GetChildAt(aChildIndex);
|
||||
if (!accChild)
|
||||
return nsnull;
|
||||
|
||||
@ -947,21 +924,12 @@ getIndexInParentCB(AtkObject *aAtkObj)
|
||||
return -1; // No parent
|
||||
}
|
||||
|
||||
PRInt32 currentIndex = 0;
|
||||
|
||||
PRInt32 childCount = parent->GetChildCount();
|
||||
for (PRInt32 idx = 0; idx < childCount; idx++) {
|
||||
nsAccessible *sibling = parent->GetChildAt(idx);
|
||||
if (sibling == accWrap) {
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
if (nsAccUtils::IsEmbeddedObject(sibling)) {
|
||||
++ currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
// Links within hypertext accessible play role of accessible children in
|
||||
// ATK since every embedded object is a link and text accessibles are
|
||||
// ignored.
|
||||
nsRefPtr<nsHyperTextAccessible> hyperTextParent(do_QueryObject(parent));
|
||||
return hyperTextParent ?
|
||||
hyperTextParent->GetLinkIndex(accWrap) : parent->GetIndexOf(accWrap);
|
||||
}
|
||||
|
||||
static void TranslateStates(PRUint32 aState, const AtkStateMap *aStateMap,
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
#include "nsMaiInterfaceHypertext.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsAccessNode.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
|
||||
void
|
||||
hypertextInterfaceInitCB(AtkHypertextIface *aIface)
|
||||
@ -59,18 +59,14 @@ getLinkCB(AtkHypertext *aText, gint aLinkIndex)
|
||||
if (!accWrap)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(hyperText));
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
|
||||
NS_ENSURE_TRUE(hyperText, nsnull);
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperLink> hyperLink;
|
||||
nsresult rv = hyperText->GetLink(aLinkIndex, getter_AddRefs(hyperLink));
|
||||
if (NS_FAILED(rv) || !hyperLink)
|
||||
nsAccessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
|
||||
if (!hyperLink)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessible> hyperLinkAcc(do_QueryInterface(hyperLink));
|
||||
AtkObject *hyperLinkAtkObj = nsAccessibleWrap::GetAtkObject(hyperLinkAcc);
|
||||
AtkObject* hyperLinkAtkObj = nsAccessibleWrap::GetAtkObject(hyperLink);
|
||||
nsAccessibleWrap *accChild = GetAccessibleWrap(hyperLinkAtkObj);
|
||||
NS_ENSURE_TRUE(accChild, nsnull);
|
||||
|
||||
@ -86,16 +82,10 @@ getLinkCountCB(AtkHypertext *aText)
|
||||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(hyperText));
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
|
||||
NS_ENSURE_TRUE(hyperText, -1);
|
||||
|
||||
PRInt32 count = -1;
|
||||
nsresult rv = hyperText->GetLinkCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return count;
|
||||
return hyperText->GetLinkCount();
|
||||
}
|
||||
|
||||
gint
|
||||
@ -105,13 +95,11 @@ getLinkIndexCB(AtkHypertext *aText, gint aCharIndex)
|
||||
if (!accWrap)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperText;
|
||||
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
|
||||
getter_AddRefs(hyperText));
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
|
||||
NS_ENSURE_TRUE(hyperText, -1);
|
||||
|
||||
PRInt32 index = -1;
|
||||
nsresult rv = hyperText->GetLinkIndex(aCharIndex, &index);
|
||||
nsresult rv = hyperText->GetLinkIndexAtOffset(aCharIndex, &index);
|
||||
NS_ENSURE_SUCCESS(rv, -1);
|
||||
|
||||
return index;
|
||||
|
118
accessible/src/base/AccCollector.cpp
Normal file
118
accessible/src/base/AccCollector.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/* ***** 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 Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* 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 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 "AccCollector.h"
|
||||
|
||||
#include "nsAccessible.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccCollector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccCollector::
|
||||
AccCollector(nsAccessible* aRoot, filters::FilterFuncPtr aFilterFunc) :
|
||||
mFilterFunc(aFilterFunc), mRoot(aRoot), mRootChildIdx(0)
|
||||
{
|
||||
}
|
||||
|
||||
AccCollector::~AccCollector()
|
||||
{
|
||||
}
|
||||
|
||||
PRUint32
|
||||
AccCollector::Count()
|
||||
{
|
||||
EnsureNGetIndex(nsnull);
|
||||
return mObjects.Length();
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
AccCollector::GetAccessibleAt(PRUint32 aIndex)
|
||||
{
|
||||
nsAccessible *accessible = mObjects.SafeElementAt(aIndex, nsnull);
|
||||
if (accessible)
|
||||
return accessible;
|
||||
|
||||
return EnsureNGetObject(aIndex);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
AccCollector::GetIndexAt(nsAccessible *aAccessible)
|
||||
{
|
||||
PRInt32 index = mObjects.IndexOf(aAccessible);
|
||||
if (index != -1)
|
||||
return index;
|
||||
|
||||
return EnsureNGetIndex(aAccessible);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccCollector protected
|
||||
|
||||
nsAccessible*
|
||||
AccCollector::EnsureNGetObject(PRUint32 aIndex)
|
||||
{
|
||||
PRInt32 childCount = mRoot->GetChildCount();
|
||||
while (mRootChildIdx < childCount) {
|
||||
nsAccessible* child = mRoot->GetChildAt(mRootChildIdx++);
|
||||
if (!mFilterFunc(child))
|
||||
continue;
|
||||
|
||||
mObjects.AppendElement(child);
|
||||
if (mObjects.Length() - 1 == aIndex)
|
||||
return mObjects[aIndex];
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
AccCollector::EnsureNGetIndex(nsAccessible* aAccessible)
|
||||
{
|
||||
PRInt32 childCount = mRoot->GetChildCount();
|
||||
while (mRootChildIdx < childCount) {
|
||||
nsAccessible* child = mRoot->GetChildAt(mRootChildIdx++);
|
||||
if (!mFilterFunc(child))
|
||||
continue;
|
||||
|
||||
mObjects.AppendElement(child);
|
||||
if (child == aAccessible)
|
||||
return mObjects.Length() - 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
94
accessible/src/base/AccCollector.h
Normal file
94
accessible/src/base/AccCollector.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* ***** 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 Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* 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 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 AccCollector_h_
|
||||
#define AccCollector_h_
|
||||
|
||||
#include "filters.h"
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
/**
|
||||
* Collect accessible children complying with filter function. Provides quick
|
||||
* access to accessible by index.
|
||||
*/
|
||||
class AccCollector
|
||||
{
|
||||
public:
|
||||
AccCollector(nsAccessible* aRoot, filters::FilterFuncPtr aFilterFunc);
|
||||
virtual ~AccCollector();
|
||||
|
||||
/**
|
||||
* Return accessible count within the collection.
|
||||
*/
|
||||
PRUint32 Count();
|
||||
|
||||
/**
|
||||
* Return an accessible from the collection at the given index.
|
||||
*/
|
||||
nsAccessible* GetAccessibleAt(PRUint32 aIndex);
|
||||
|
||||
/**
|
||||
* Return index of the given accessible within the collection.
|
||||
*/
|
||||
PRInt32 GetIndexAt(nsAccessible* aAccessible);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Ensure accessible at the given index is stored and return it.
|
||||
*/
|
||||
nsAccessible* EnsureNGetObject(PRUint32 aIndex);
|
||||
|
||||
/**
|
||||
* Ensure index for the given accessible is stored and return it.
|
||||
*/
|
||||
PRInt32 EnsureNGetIndex(nsAccessible* aAccessible);
|
||||
|
||||
filters::FilterFuncPtr mFilterFunc;
|
||||
nsAccessible* mRoot;
|
||||
PRInt32 mRootChildIdx;
|
||||
|
||||
nsTArray<nsAccessible*> mObjects;
|
||||
|
||||
private:
|
||||
AccCollector();
|
||||
AccCollector(const AccCollector&);
|
||||
AccCollector& operator =(const AccCollector&);
|
||||
};
|
||||
|
||||
#endif
|
@ -35,20 +35,22 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAccIterator.h"
|
||||
#include "AccIterator.h"
|
||||
|
||||
#include "nsAccessible.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccIterator
|
||||
|
||||
nsAccIterator::nsAccIterator(nsAccessible *aAccessible,
|
||||
AccIteratorFilterFuncPtr aFilterFunc,
|
||||
IterationType aIterationType) :
|
||||
AccIterator::AccIterator(nsAccessible *aAccessible,
|
||||
filters::FilterFuncPtr aFilterFunc,
|
||||
IterationType aIterationType) :
|
||||
mFilterFunc(aFilterFunc), mIsDeep(aIterationType != eFlatNav)
|
||||
{
|
||||
mState = new IteratorState(aAccessible);
|
||||
}
|
||||
|
||||
nsAccIterator::~nsAccIterator()
|
||||
AccIterator::~AccIterator()
|
||||
{
|
||||
while (mState) {
|
||||
IteratorState *tmp = mState;
|
||||
@ -58,7 +60,7 @@ nsAccIterator::~nsAccIterator()
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsAccIterator::GetNext()
|
||||
AccIterator::GetNext()
|
||||
{
|
||||
while (mState) {
|
||||
nsAccessible *child = mState->mParent->GetChildAt(mState->mIndex++);
|
||||
@ -86,8 +88,8 @@ nsAccIterator::GetNext()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccIterator::IteratorState
|
||||
|
||||
nsAccIterator::IteratorState::IteratorState(nsAccessible *aParent,
|
||||
IteratorState *mParentState) :
|
||||
AccIterator::IteratorState::IteratorState(nsAccessible *aParent,
|
||||
IteratorState *mParentState) :
|
||||
mParent(aParent), mIndex(0), mParentState(mParentState)
|
||||
{
|
||||
}
|
@ -38,19 +38,14 @@
|
||||
#ifndef nsAccIterator_h_
|
||||
#define nsAccIterator_h_
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
||||
/**
|
||||
* Return true if the traversed accessible complies with filter.
|
||||
*/
|
||||
typedef PRBool (*AccIteratorFilterFuncPtr) (nsAccessible *);
|
||||
#include "filters.h"
|
||||
#include "nscore.h"
|
||||
|
||||
/**
|
||||
* Allows to iterate through accessible children or subtree complying with
|
||||
* filter function.
|
||||
*/
|
||||
class nsAccIterator
|
||||
class AccIterator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -69,9 +64,9 @@ public:
|
||||
eTreeNav
|
||||
};
|
||||
|
||||
nsAccIterator(nsAccessible *aRoot, AccIteratorFilterFuncPtr aFilterFunc,
|
||||
IterationType aIterationType = eFlatNav);
|
||||
~nsAccIterator();
|
||||
AccIterator(nsAccessible* aRoot, filters::FilterFuncPtr aFilterFunc,
|
||||
IterationType aIterationType = eFlatNav);
|
||||
~AccIterator();
|
||||
|
||||
/**
|
||||
* Return next accessible complying with filter function. Return the first
|
||||
@ -79,33 +74,10 @@ public:
|
||||
*/
|
||||
nsAccessible *GetNext();
|
||||
|
||||
/**
|
||||
* Predefined filters.
|
||||
*/
|
||||
static PRBool GetSelected(nsAccessible *aAccessible)
|
||||
{
|
||||
return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTED;
|
||||
}
|
||||
static PRBool GetSelectable(nsAccessible *aAccessible)
|
||||
{
|
||||
return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTABLE;
|
||||
}
|
||||
static PRBool GetRow(nsAccessible *aAccessible)
|
||||
{
|
||||
return nsAccUtils::Role(aAccessible) == nsIAccessibleRole::ROLE_ROW;
|
||||
}
|
||||
static PRBool GetCell(nsAccessible *aAccessible)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
return role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
role == nsIAccessibleRole::ROLE_COLUMNHEADER;
|
||||
}
|
||||
|
||||
private:
|
||||
nsAccIterator();
|
||||
nsAccIterator(const nsAccIterator&);
|
||||
nsAccIterator& operator =(const nsAccIterator&);
|
||||
AccIterator();
|
||||
AccIterator(const AccIterator&);
|
||||
AccIterator& operator =(const AccIterator&);
|
||||
|
||||
struct IteratorState
|
||||
{
|
||||
@ -116,7 +88,7 @@ private:
|
||||
IteratorState *mParentState;
|
||||
};
|
||||
|
||||
AccIteratorFilterFuncPtr mFilterFunc;
|
||||
filters::FilterFuncPtr mFilterFunc;
|
||||
PRBool mIsDeep;
|
||||
IteratorState *mState;
|
||||
};
|
@ -48,10 +48,12 @@ LIBXUL_LIBRARY = 1
|
||||
|
||||
|
||||
CPPSRCS = \
|
||||
AccCollector.cpp \
|
||||
AccIterator.cpp \
|
||||
filters.cpp \
|
||||
nsAccDocManager.cpp \
|
||||
nsAccessNode.cpp \
|
||||
nsAccEvent.cpp \
|
||||
nsAccIterator.cpp \
|
||||
nsARIAGridAccessible.cpp \
|
||||
nsARIAMap.cpp \
|
||||
nsDocAccessible.cpp \
|
||||
|
74
accessible/src/base/filters.cpp
Normal file
74
accessible/src/base/filters.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/* ***** 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 Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* 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 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 "filters.h"
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
||||
bool
|
||||
filters::GetSelected(nsAccessible* aAccessible)
|
||||
{
|
||||
return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTED;
|
||||
}
|
||||
|
||||
bool
|
||||
filters::GetSelectable(nsAccessible* aAccessible)
|
||||
{
|
||||
return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTABLE;
|
||||
}
|
||||
|
||||
bool
|
||||
filters::GetRow(nsAccessible* aAccessible)
|
||||
{
|
||||
return nsAccUtils::Role(aAccessible) == nsIAccessibleRole::ROLE_ROW;
|
||||
}
|
||||
|
||||
bool
|
||||
filters::GetCell(nsAccessible* aAccessible)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
return role == nsIAccessibleRole::ROLE_GRID_CELL ||
|
||||
role == nsIAccessibleRole::ROLE_ROWHEADER ||
|
||||
role == nsIAccessibleRole::ROLE_COLUMNHEADER;
|
||||
}
|
||||
|
||||
bool
|
||||
filters::GetEmbeddedObject(nsAccessible* aAccessible)
|
||||
{
|
||||
return nsAccUtils::IsEmbeddedObject(aAccessible);
|
||||
}
|
60
accessible/src/base/filters.h
Normal file
60
accessible/src/base/filters.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* ***** 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 Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* 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 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 a11yFilters_h_
|
||||
#define a11yFilters_h_
|
||||
|
||||
class nsAccessible;
|
||||
|
||||
/**
|
||||
* Predefined filters used for nsAccIterator and nsAccCollector.
|
||||
*/
|
||||
namespace filters {
|
||||
|
||||
/**
|
||||
* Return true if the traversed accessible complies with filter.
|
||||
*/
|
||||
typedef bool (*FilterFuncPtr) (nsAccessible*);
|
||||
|
||||
bool GetSelected(nsAccessible* aAccessible);
|
||||
bool GetSelectable(nsAccessible* aAccessible);
|
||||
bool GetRow(nsAccessible* aAccessible);
|
||||
bool GetCell(nsAccessible* aAccessible);
|
||||
bool GetEmbeddedObject(nsAccessible* aAccessible);
|
||||
}
|
||||
|
||||
#endif
|
@ -38,7 +38,8 @@
|
||||
|
||||
#include "nsARIAGridAccessible.h"
|
||||
|
||||
#include "nsAccIterator.h"
|
||||
#include "AccIterator.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
@ -101,10 +102,10 @@ nsARIAGridAccessible::GetColumnCount(PRInt32 *acolumnCount)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
nsAccessible *row = rowIter.GetNext();
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
|
||||
while ((cell = cellIter.GetNext()))
|
||||
@ -122,7 +123,7 @@ nsARIAGridAccessible::GetRowCount(PRInt32 *arowCount)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
while (rowIter.GetNext())
|
||||
(*arowCount)++;
|
||||
|
||||
@ -292,7 +293,7 @@ nsARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected)
|
||||
|
||||
NS_ENSURE_ARG(IsValidColumn(aColumn));
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
nsAccessible *row = rowIter.GetNext();
|
||||
if (!row)
|
||||
return NS_OK;
|
||||
@ -325,7 +326,7 @@ nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
|
||||
NS_ENSURE_ARG(row);
|
||||
|
||||
if (!nsAccUtils::IsARIASelected(row)) {
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
while ((cell = cellIter.GetNext())) {
|
||||
if (!nsAccUtils::IsARIASelected(cell))
|
||||
@ -374,7 +375,7 @@ nsARIAGridAccessible::GetSelectedCellCount(PRUint32* aCount)
|
||||
PRInt32 colCount = 0;
|
||||
GetColumnCount(&colCount);
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
while ((row = rowIter.GetNext())) {
|
||||
@ -383,7 +384,7 @@ nsARIAGridAccessible::GetSelectedCellCount(PRUint32* aCount)
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
|
||||
while ((cell = cellIter.GetNext())) {
|
||||
@ -410,7 +411,7 @@ nsARIAGridAccessible::GetSelectedRowCount(PRUint32* aCount)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
while ((row = rowIter.GetNext())) {
|
||||
@ -419,7 +420,7 @@ nsARIAGridAccessible::GetSelectedRowCount(PRUint32* aCount)
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = cellIter.GetNext();
|
||||
if (!cell)
|
||||
continue;
|
||||
@ -453,11 +454,11 @@ nsARIAGridAccessible::GetSelectedCells(nsIArray **aCells)
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
while (row = rowIter.GetNext()) {
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
|
||||
if (nsAccUtils::IsARIASelected(row)) {
|
||||
@ -497,7 +498,7 @@ nsARIAGridAccessible::GetSelectedCellIndices(PRUint32 *aCellsCount,
|
||||
|
||||
nsTArray<PRInt32> selCells(rowCount * colCount);
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
for (PRInt32 rowIdx = 0; row = rowIter.GetNext(); rowIdx++) {
|
||||
@ -508,7 +509,7 @@ nsARIAGridAccessible::GetSelectedCellIndices(PRUint32 *aCellsCount,
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
|
||||
for (PRInt32 colIdx = 0; cell = cellIter.GetNext(); colIdx++) {
|
||||
@ -557,7 +558,7 @@ nsARIAGridAccessible::GetSelectedRowIndices(PRUint32 *arowCount,
|
||||
|
||||
nsTArray<PRInt32> selRows(rowCount);
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
for (PRInt32 rowIdx = 0; row = rowIter.GetNext(); rowIdx++) {
|
||||
@ -566,7 +567,7 @@ nsARIAGridAccessible::GetSelectedRowIndices(PRUint32 *arowCount,
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = cellIter.GetNext();
|
||||
if (!cell)
|
||||
continue;
|
||||
@ -603,7 +604,7 @@ nsARIAGridAccessible::SelectRow(PRInt32 aRow)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
for (PRInt32 rowIdx = 0; row = rowIter.GetNext(); rowIdx++) {
|
||||
@ -622,7 +623,7 @@ nsARIAGridAccessible::SelectColumn(PRInt32 aColumn)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
while ((row = rowIter.GetNext())) {
|
||||
@ -661,7 +662,7 @@ nsARIAGridAccessible::UnselectColumn(PRInt32 aColumn)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = nsnull;
|
||||
while ((row = rowIter.GetNext())) {
|
||||
@ -730,7 +731,7 @@ nsARIAGridAccessible::GetRowAt(PRInt32 aRow)
|
||||
{
|
||||
PRInt32 rowIdx = aRow;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
|
||||
nsAccessible *row = rowIter.GetNext();
|
||||
while (rowIdx != 0 && (row = rowIter.GetNext()))
|
||||
@ -744,7 +745,7 @@ nsARIAGridAccessible::GetCellInRowAt(nsAccessible *aRow, PRInt32 aColumn)
|
||||
{
|
||||
PRInt32 colIdx = aColumn;
|
||||
|
||||
nsAccIterator cellIter(aRow, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(aRow, filters::GetCell);
|
||||
nsAccessible *cell = cellIter.GetNext();
|
||||
while (colIdx != 0 && (cell = cellIter.GetNext()))
|
||||
colIdx--;
|
||||
@ -784,7 +785,7 @@ nsARIAGridAccessible::SetARIASelected(nsAccessible *aAccessible,
|
||||
// If the given accessible is row that was unselected then remove
|
||||
// aria-selected from cell accessible.
|
||||
if (role == nsIAccessibleRole::ROLE_ROW) {
|
||||
nsAccIterator cellIter(aAccessible, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(aAccessible, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
|
||||
while ((cell = cellIter.GetNext())) {
|
||||
@ -807,7 +808,7 @@ nsARIAGridAccessible::SetARIASelected(nsAccessible *aAccessible,
|
||||
rv = SetARIASelected(row, PR_FALSE, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
while ((cell = cellIter.GetNext())) {
|
||||
if (cell != aAccessible) {
|
||||
@ -833,7 +834,7 @@ nsARIAGridAccessible::GetSelectedColumnsArray(PRUint32 *acolumnCount,
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAccIterator rowIter(this, nsAccIterator::GetRow);
|
||||
AccIterator rowIter(this, filters::GetRow);
|
||||
nsAccessible *row = rowIter.GetNext();
|
||||
if (!row)
|
||||
return NS_OK;
|
||||
@ -856,7 +857,7 @@ nsARIAGridAccessible::GetSelectedColumnsArray(PRUint32 *acolumnCount,
|
||||
|
||||
PRInt32 colIdx = 0;
|
||||
|
||||
nsAccIterator cellIter(row, nsAccIterator::GetCell);
|
||||
AccIterator cellIter(row, filters::GetCell);
|
||||
nsAccessible *cell = nsnull;
|
||||
for (colIdx = 0; cell = cellIter.GetNext(); colIdx++) {
|
||||
if (isColSelArray.SafeElementAt(colIdx, PR_FALSE) &&
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsAccessNode;
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
#include "nsIXBLAccessible.h"
|
||||
|
||||
#include "nsAccIterator.h"
|
||||
#include "AccIterator.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsDocAccessible.h"
|
||||
@ -2378,7 +2378,7 @@ NS_IMETHODIMP nsAccessible::GetSelectedChildren(nsIArray **aSelectedAccessibles)
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
NS_ENSURE_STATE(selectedAccessibles);
|
||||
|
||||
nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
|
||||
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
|
||||
nsIAccessible *selected = nsnull;
|
||||
while ((selected = iter.GetNext()))
|
||||
selectedAccessibles->AppendElement(selected, PR_FALSE);
|
||||
@ -2403,7 +2403,7 @@ NS_IMETHODIMP nsAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **aSelect
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
|
||||
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
|
||||
nsAccessible *selected = nsnull;
|
||||
|
||||
PRInt32 count = 0;
|
||||
@ -2423,7 +2423,7 @@ NS_IMETHODIMP nsAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
|
||||
NS_ENSURE_ARG_POINTER(aSelectionCount);
|
||||
*aSelectionCount = 0;
|
||||
|
||||
nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
|
||||
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
|
||||
nsAccessible *selected = nsnull;
|
||||
while ((selected = iter.GetNext()))
|
||||
++(*aSelectionCount);
|
||||
@ -2485,7 +2485,7 @@ NS_IMETHODIMP nsAccessible::IsChildSelected(PRInt32 aIndex, PRBool *aIsSelected)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::ClearSelection()
|
||||
{
|
||||
nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
|
||||
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
|
||||
nsAccessible *selected = nsnull;
|
||||
while ((selected = iter.GetNext()))
|
||||
selected->SetSelected(PR_FALSE);
|
||||
@ -2495,7 +2495,7 @@ nsAccessible::ClearSelection()
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SelectAllSelection(PRBool *_retval)
|
||||
{
|
||||
nsAccIterator iter(this, nsAccIterator::GetSelectable, nsAccIterator::eTreeNav);
|
||||
AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
|
||||
nsAccessible *selectable = nsnull;
|
||||
while((selectable = iter.GetNext()))
|
||||
selectable->SetSelected(PR_TRUE);
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
class nsAccessible;
|
||||
class nsAccEvent;
|
||||
|
@ -1321,27 +1321,25 @@ nsHyperTextAccessible::GetOffsetAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
return NS_OK; // Not found, will return -1
|
||||
}
|
||||
|
||||
// ------- nsIAccessibleHyperText ---------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessibleHyperText
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::GetLinkCount(PRInt32 *aLinkCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLinkCount);
|
||||
*aLinkCount = 0;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 childCount = GetChildCount();
|
||||
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
|
||||
nsAccessible *childAcc = mChildren[childIdx];
|
||||
if (nsAccUtils::IsEmbeddedObject(childAcc))
|
||||
++*aLinkCount;
|
||||
}
|
||||
*aLinkCount = GetLinkCount();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::GetLink(PRInt32 aLinkIndex, nsIAccessibleHyperLink **aLink)
|
||||
nsHyperTextAccessible::GetLinkAt(PRInt32 aIndex, nsIAccessibleHyperLink** aLink)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLink);
|
||||
*aLink = nsnull;
|
||||
@ -1349,20 +1347,30 @@ nsHyperTextAccessible::GetLink(PRInt32 aLinkIndex, nsIAccessibleHyperLink **aLin
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 linkIndex = aLinkIndex;
|
||||
nsAccessible* link = GetLinkAt(aIndex);
|
||||
if (link)
|
||||
CallQueryInterface(link, aLink);
|
||||
|
||||
PRInt32 childCount = GetChildCount();
|
||||
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
|
||||
nsAccessible *childAcc = mChildren[childIdx];
|
||||
if (nsAccUtils::IsEmbeddedObject(childAcc) && linkIndex-- == 0)
|
||||
return CallQueryInterface(childAcc, aLink);
|
||||
}
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::GetLinkIndex(PRInt32 aCharIndex, PRInt32 *aLinkIndex)
|
||||
nsHyperTextAccessible::GetLinkIndex(nsIAccessibleHyperLink* aLink,
|
||||
PRInt32* aIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLink);
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRefPtr<nsAccessible> link(do_QueryObject(aLink));
|
||||
*aIndex = GetLinkIndex(link);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::GetLinkIndexAtOffset(PRInt32 aCharIndex,
|
||||
PRInt32* aLinkIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aLinkIndex);
|
||||
*aLinkIndex = -1; // API says this magic value means 'not found'
|
||||
@ -2029,6 +2037,19 @@ nsHyperTextAccessible::ScrollSubstringToPoint(PRInt32 aStartIndex,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible public
|
||||
|
||||
void
|
||||
nsHyperTextAccessible::InvalidateChildren()
|
||||
{
|
||||
mLinks = nsnull;
|
||||
nsAccessibleWrap::InvalidateChildren();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHyperTextAccessible public static
|
||||
|
||||
nsresult nsHyperTextAccessible::ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
|
||||
PRUint32 *aRenderedOffset)
|
||||
{
|
||||
@ -2086,6 +2107,17 @@ nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHyperTextAccessible protected
|
||||
|
||||
AccCollector*
|
||||
nsHyperTextAccessible::GetLinkCollector()
|
||||
{
|
||||
if (IsDefunct())
|
||||
return nsnull;
|
||||
|
||||
if (!mLinks)
|
||||
mLinks = new AccCollector(this, filters::GetEmbeddedObject);
|
||||
return mLinks;
|
||||
}
|
||||
|
||||
nsAccessible *
|
||||
nsHyperTextAccessible::GetAccessibleAtOffset(PRInt32 aOffset, PRInt32 *aAccIdx,
|
||||
PRInt32 *aStartOffset,
|
||||
|
@ -40,10 +40,12 @@
|
||||
#ifndef _nsHyperTextAccessible_H_
|
||||
#define _nsHyperTextAccessible_H_
|
||||
|
||||
#include "nsAccessibleWrap.h"
|
||||
#include "nsIAccessibleText.h"
|
||||
#include "nsIAccessibleHyperText.h"
|
||||
#include "nsIAccessibleEditableText.h"
|
||||
|
||||
#include "AccCollector.h"
|
||||
#include "nsAccessibleWrap.h"
|
||||
#include "nsTextAttrs.h"
|
||||
|
||||
#include "nsFrameSelection.h"
|
||||
@ -87,6 +89,10 @@ public:
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
virtual void InvalidateChildren();
|
||||
|
||||
// nsHyperTextAccessible
|
||||
|
||||
// Convert content offset to rendered text offset
|
||||
static nsresult ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
|
||||
PRUint32 *aRenderedOffset);
|
||||
@ -95,6 +101,33 @@ public:
|
||||
static nsresult RenderedToContentOffset(nsIFrame *aFrame, PRUint32 aRenderedOffset,
|
||||
PRInt32 *aContentOffset);
|
||||
|
||||
/**
|
||||
* Return link count within this hypertext accessible.
|
||||
*/
|
||||
inline PRUint32 GetLinkCount()
|
||||
{
|
||||
AccCollector* links = GetLinkCollector();
|
||||
return links ? links->Count() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return link accessible at the given index.
|
||||
*/
|
||||
inline nsAccessible* GetLinkAt(PRUint32 aIndex)
|
||||
{
|
||||
AccCollector* links = GetLinkCollector();
|
||||
return links ? links->GetAccessibleAt(aIndex) : nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return index for the given link accessible.
|
||||
*/
|
||||
inline PRInt32 GetLinkIndex(nsAccessible* aLink)
|
||||
{
|
||||
AccCollector* links = GetLinkCollector();
|
||||
return links ? links->GetIndexAt(aLink) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a DOM Node and offset into a character offset into this hypertext.
|
||||
* Will look for closest match when the DOM node does not have an accessible
|
||||
@ -154,9 +187,13 @@ public:
|
||||
PRInt32 *aEndOffset);
|
||||
|
||||
protected:
|
||||
|
||||
// nsHyperTextAccessible
|
||||
|
||||
/**
|
||||
* Return link collection, create it if necessary.
|
||||
*/
|
||||
AccCollector* GetLinkCollector();
|
||||
|
||||
/*
|
||||
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
|
||||
* @param aType, eGetBefore, eGetAt, eGetAfter
|
||||
@ -305,6 +342,9 @@ protected:
|
||||
PRInt32 *aStartOffset,
|
||||
PRInt32 *aEndOffset,
|
||||
nsIPersistentProperties *aAttributes);
|
||||
|
||||
private:
|
||||
nsAutoPtr<AccCollector> mLinks;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsHyperTextAccessible,
|
||||
|
@ -42,11 +42,7 @@
|
||||
|
||||
#include "AccessibleHypertext_i.c"
|
||||
|
||||
#include "nsIAccessibleHypertext.h"
|
||||
#include "nsIWinAccessNode.h"
|
||||
#include "nsAccessNodeWrap.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
|
||||
// IUnknown
|
||||
|
||||
@ -75,16 +71,11 @@ CAccessibleHypertext::get_nHyperlinks(long *aHyperlinkCount)
|
||||
__try {
|
||||
*aHyperlinkCount = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperAcc(do_QueryInterface(this));
|
||||
if (!hyperAcc)
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(this);
|
||||
if (!hyperText)
|
||||
return E_FAIL;
|
||||
|
||||
PRInt32 count = 0;
|
||||
nsresult rv = hyperAcc->GetLinkCount(&count);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
*aHyperlinkCount = count;
|
||||
*aHyperlinkCount = hyperText->GetLinkCount();
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
@ -98,22 +89,18 @@ CAccessibleHypertext::get_hyperlink(long aLinkIndex,
|
||||
__try {
|
||||
*aHyperlink = NULL;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperText> hyperAcc(do_QueryInterface(this));
|
||||
if (!hyperAcc)
|
||||
nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(this);
|
||||
if (!hyperText)
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIAccessibleHyperLink> hyperLink;
|
||||
nsresult rv = hyperAcc->GetLink(aLinkIndex, getter_AddRefs(hyperLink));
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(hyperLink));
|
||||
nsAccessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
|
||||
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(hyperLink));
|
||||
if (!winAccessNode)
|
||||
return E_FAIL;
|
||||
|
||||
void *instancePtr = NULL;
|
||||
rv = winAccessNode->QueryNativeInterface(IID_IAccessibleHyperlink,
|
||||
&instancePtr);
|
||||
nsresult rv = winAccessNode->QueryNativeInterface(IID_IAccessibleHyperlink,
|
||||
&instancePtr);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
|
||||
@ -135,7 +122,7 @@ __try {
|
||||
return E_FAIL;
|
||||
|
||||
PRInt32 index = 0;
|
||||
nsresult rv = hyperAcc->GetLinkIndex(aCharIndex, &index);
|
||||
nsresult rv = hyperAcc->GetLinkIndexAtOffset(aCharIndex, &index);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_hyperlinkIndex(
|
||||
/* [in] */ long charIndex,
|
||||
/* [retval][out] */ long *hyperlinkIndex);
|
||||
|
||||
// nsISupports
|
||||
NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -20,23 +20,41 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
|
||||
function testThis(aID, aCharIndex, aExpectedLinkIndex, aName)
|
||||
{
|
||||
is(gParagraphAcc.getLinkIndex(aCharIndex), aExpectedLinkIndex,
|
||||
"Wrong link index for ID " + aID + "!");
|
||||
var linkAcc = null;
|
||||
try {
|
||||
linkAcc = gParagraphAcc.getLink(aExpectedLinkIndex);
|
||||
} catch(e) { }
|
||||
is(gParagraphAcc.getLinkIndexAtOffset(aCharIndex), aExpectedLinkIndex,
|
||||
"Wrong link index at offset " + aCharIndex + " for ID " + aID + "!");
|
||||
|
||||
var linkAcc = gParagraphAcc.getLinkAt(aExpectedLinkIndex);
|
||||
ok(linkAcc, "No accessible for link " + aID + "!");
|
||||
|
||||
var linkIndex = gParagraphAcc.getLinkIndex(linkAcc);
|
||||
is(linkIndex, aExpectedLinkIndex, "Wrong link index for " + aID + "!");
|
||||
|
||||
// Just test the link's name to make sure we get the right one.
|
||||
is(linkAcc.getAnchor(0).name, aName, "Wrong name for " + aID + "!");
|
||||
}
|
||||
|
||||
const kLinksCount = 128;
|
||||
function prepareTest()
|
||||
{
|
||||
var container = document.getElementById("p3");
|
||||
for (var jdx = 0; jdx < kLinksCount; jdx++) {
|
||||
var a = document.createElement("a");
|
||||
a.setAttribute("href", "mozilla.org");
|
||||
a.textContent = "mozilla";
|
||||
container.appendChild(a);
|
||||
|
||||
var span = document.createElement("span");
|
||||
span.textContent = " text ";
|
||||
container.appendChild(span);
|
||||
}
|
||||
|
||||
window.setTimeout(doTest, 0);
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gParagraphAcc = getAccessible("testParagraph", [nsIAccessibleHyperText]);
|
||||
|
||||
// Test link count
|
||||
gParagraphAcc = getAccessible("testParagraph", [nsIAccessibleHyperText]);
|
||||
is(gParagraphAcc.linkCount, 7, "Wrong link count for paragraph!");
|
||||
|
||||
// normal hyperlink
|
||||
@ -60,16 +78,42 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
// Named anchor
|
||||
testThis("namedAnchor", 193, 6, "This should never be of state_linked");
|
||||
|
||||
// Paragraph with link
|
||||
var p2 = getAccessible("p2", [nsIAccessibleHyperText]);
|
||||
var link = p2.getLinkAt(0);
|
||||
is(link, p2.getChildAt(0), "Wrong link for p2");
|
||||
is(p2.linkCount, 1, "Wrong link count for p2");
|
||||
|
||||
// getLinkAt and getLinkIndex.
|
||||
var container = document.getElementById("p3");
|
||||
var htAcc = getAccessible(container, [nsIAccessibleHyperText]);
|
||||
for (var jdx = 0; jdx < kLinksCount; jdx++) {
|
||||
var link = htAcc.getLinkAt(jdx);
|
||||
ok(link, "No link at index " + jdx + " for 'p3'");
|
||||
|
||||
var linkIdx = htAcc.getLinkIndex(link);
|
||||
is(linkIdx, jdx, "Wrong link index for 'p3'!");
|
||||
};
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
addA11yLoadEvent(prepareTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a>
|
||||
<a target="_blank"
|
||||
title="Create tests for NSIAccessibleHyperlink interface"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">
|
||||
Mozilla Bug 418368
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
title="Cache links within hypertext accessible"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=572394">
|
||||
Mozilla Bug 572394
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -104,5 +148,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
||||
>Named anchor, must not have "linked" state for it to be exposed correctly:<br
|
||||
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
</p>
|
||||
<p id="p2"><a href="http://mozilla.org">mozilla.org</a></p>
|
||||
<p id="p3"></p>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user