mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
575576 - cache position in set and set size, r=davidb, marcoz, sr=neil
This commit is contained in:
parent
7dc26b1584
commit
db76e79301
169
accessible/src/base/AccGroupInfo.cpp
Normal file
169
accessible/src/base/AccGroupInfo.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/* ***** 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 "AccGroupInfo.h"
|
||||
|
||||
AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
|
||||
mPosInSet(0), mSetSize(0), mParent(nsnull)
|
||||
{
|
||||
nsAccessible* parent = aItem->GetParent();
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
PRInt32 indexInParent = aItem->GetIndexInParent();
|
||||
PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(aItem);
|
||||
|
||||
// Compute position in set.
|
||||
mPosInSet = 1;
|
||||
for (PRInt32 idx = indexInParent - 1; idx >=0 ; idx--) {
|
||||
nsAccessible* sibling = parent->GetChildAt(idx);
|
||||
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
||||
|
||||
// If the sibling is separator then the group is ended.
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
||||
break;
|
||||
|
||||
// If sibling is not visible and hasn't the same base role.
|
||||
if (BaseRole(siblingRole) != aRole ||
|
||||
nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)
|
||||
continue;
|
||||
|
||||
// Check if it's hierarchical flatten structure, i.e. if the sibling
|
||||
// level is lesser than this one then group is ended, if the sibling level
|
||||
// is greater than this one then the group is split by some child elements
|
||||
// (group will be continued).
|
||||
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
||||
if (siblingLevel < level) {
|
||||
mParent = sibling;
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip subset.
|
||||
if (siblingLevel > level)
|
||||
continue;
|
||||
|
||||
// If the previous item in the group has calculated group information then
|
||||
// build group information for this item based on found one.
|
||||
if (sibling->mGroupInfo) {
|
||||
mPosInSet += sibling->mGroupInfo->mPosInSet;
|
||||
mParent = sibling->mGroupInfo->mParent;
|
||||
mSetSize = sibling->mGroupInfo->mSetSize;
|
||||
return;
|
||||
}
|
||||
|
||||
mPosInSet++;
|
||||
}
|
||||
|
||||
// Compute set size.
|
||||
mSetSize = mPosInSet;
|
||||
|
||||
PRInt32 siblingCount = parent->GetChildCount();
|
||||
for (PRInt32 idx = indexInParent + 1; idx < siblingCount; idx++) {
|
||||
nsAccessible* sibling = parent->GetChildAt(idx);
|
||||
|
||||
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
||||
|
||||
// If the sibling is separator then the group is ended.
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
||||
break;
|
||||
|
||||
// If sibling is visible and has the same base role
|
||||
if (BaseRole(siblingRole) != aRole ||
|
||||
nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)
|
||||
continue;
|
||||
|
||||
// and check if it's hierarchical flatten structure.
|
||||
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
||||
if (siblingLevel < level)
|
||||
break;
|
||||
|
||||
// Skip subset.
|
||||
if (siblingLevel > level)
|
||||
continue;
|
||||
|
||||
// If the next item in the group has calculated group information then
|
||||
// build group information for this item based on found one.
|
||||
if (sibling->mGroupInfo) {
|
||||
mParent = sibling->mGroupInfo->mParent;
|
||||
mSetSize = sibling->mGroupInfo->mSetSize;
|
||||
return;
|
||||
}
|
||||
|
||||
mSetSize++;
|
||||
}
|
||||
|
||||
if (mParent)
|
||||
return;
|
||||
|
||||
// Compute parent.
|
||||
PRUint32 parentRole = nsAccUtils::Role(parent);
|
||||
|
||||
// In the case of ARIA row in treegrid, return treegrid since ARIA
|
||||
// groups aren't used to organize levels in ARIA treegrids.
|
||||
if (aRole == nsIAccessibleRole::ROLE_ROW &&
|
||||
parentRole == nsIAccessibleRole::ROLE_TREE_TABLE) {
|
||||
mParent = parent;
|
||||
return;
|
||||
}
|
||||
|
||||
// In the case of ARIA tree, a tree can be arranged by using ARIA groups
|
||||
// to organize levels. In this case the parent of the tree item will be
|
||||
// a group and the previous treeitem of that should be the tree item
|
||||
// parent. Or, if the parent is something other than a tree we will
|
||||
// return that.
|
||||
|
||||
if (parentRole != nsIAccessibleRole::ROLE_GROUPING) {
|
||||
mParent = parent;
|
||||
return;
|
||||
}
|
||||
|
||||
nsAccessible* parentPrevSibling = parent->GetSiblingAtOffset(-1);
|
||||
PRUint32 parentPrevSiblingRole = nsAccUtils::Role(parentPrevSibling);
|
||||
if (parentPrevSiblingRole == nsIAccessibleRole::ROLE_TEXT_LEAF) {
|
||||
// XXX Sometimes an empty text accessible is in the hierarchy here,
|
||||
// although the text does not appear to be rendered, GetRenderedText()
|
||||
// says that it is so we need to skip past it to find the true
|
||||
// previous sibling.
|
||||
parentPrevSibling = parentPrevSibling->GetSiblingAtOffset(-1);
|
||||
parentPrevSiblingRole = nsAccUtils::Role(parentPrevSibling);
|
||||
}
|
||||
|
||||
// Previous sibling of parent group is a tree item, this is the
|
||||
// conceptual tree item parent.
|
||||
if (parentPrevSiblingRole == nsIAccessibleRole::ROLE_OUTLINEITEM)
|
||||
mParent = parentPrevSibling;
|
||||
}
|
96
accessible/src/base/AccGroupInfo.h
Normal file
96
accessible/src/base/AccGroupInfo.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* ***** 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 AccGroupInfo_h_
|
||||
#define AccGroupInfo_h_
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
||||
/**
|
||||
* Calculate and store group information.
|
||||
*/
|
||||
class AccGroupInfo
|
||||
{
|
||||
public:
|
||||
AccGroupInfo(nsAccessible* aItem, PRUint32 aRole);
|
||||
~AccGroupInfo() { }
|
||||
|
||||
PRInt32 PosInSet() const { return mPosInSet; }
|
||||
PRUint32 SetSize() const { return mSetSize; }
|
||||
nsAccessible* GetConceptualParent() const { return mParent; }
|
||||
|
||||
/**
|
||||
* Create group info.
|
||||
*/
|
||||
static AccGroupInfo* CreateGroupInfo(nsAccessible* aAccessible)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(aAccessible);
|
||||
if (role != nsIAccessibleRole::ROLE_ROW &&
|
||||
role != nsIAccessibleRole::ROLE_GRID_CELL &&
|
||||
role != nsIAccessibleRole::ROLE_OUTLINEITEM &&
|
||||
role != nsIAccessibleRole::ROLE_OPTION &&
|
||||
role != nsIAccessibleRole::ROLE_LISTITEM &&
|
||||
role != nsIAccessibleRole::ROLE_MENUITEM &&
|
||||
role != nsIAccessibleRole::ROLE_CHECK_MENU_ITEM &&
|
||||
role != nsIAccessibleRole::ROLE_RADIO_MENU_ITEM &&
|
||||
role != nsIAccessibleRole::ROLE_RADIOBUTTON &&
|
||||
role != nsIAccessibleRole::ROLE_PAGETAB)
|
||||
return nsnull;
|
||||
|
||||
AccGroupInfo* info = new AccGroupInfo(aAccessible, BaseRole(role));
|
||||
return info;
|
||||
}
|
||||
|
||||
private:
|
||||
AccGroupInfo(const AccGroupInfo&);
|
||||
AccGroupInfo& operator =(const AccGroupInfo&);
|
||||
|
||||
static PRUint32 BaseRole(PRUint32 aRole)
|
||||
{
|
||||
if (aRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||
aRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||
return nsIAccessibleRole::ROLE_MENUITEM;
|
||||
return aRole;
|
||||
}
|
||||
|
||||
PRUint32 mPosInSet;
|
||||
PRUint32 mSetSize;
|
||||
nsAccessible* mParent;
|
||||
};
|
||||
|
||||
#endif
|
@ -49,6 +49,7 @@ LIBXUL_LIBRARY = 1
|
||||
|
||||
CPPSRCS = \
|
||||
AccCollector.cpp \
|
||||
AccGroupInfo.cpp \
|
||||
AccIterator.cpp \
|
||||
filters.cpp \
|
||||
nsAccDocManager.cpp \
|
||||
|
@ -367,106 +367,6 @@ nsAccUtils::GetAncestorWithRole(nsAccessible *aDescendant, PRUint32 aRole)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
|
||||
nsIContent *aStartContent,
|
||||
nsIAccessible **aTreeItemParentResult)
|
||||
{
|
||||
*aTreeItemParentResult = nsnull;
|
||||
|
||||
nsCOMPtr<nsIAccessible> parentAccessible;
|
||||
aStartTreeItem->GetParent(getter_AddRefs(parentAccessible));
|
||||
if (!parentAccessible)
|
||||
return;
|
||||
|
||||
PRUint32 startTreeItemRole = nsAccUtils::Role(aStartTreeItem);
|
||||
|
||||
// Calculate tree grid row parent only if the row inside of ARIA treegrid.
|
||||
if (startTreeItemRole == nsIAccessibleRole::ROLE_ROW) {
|
||||
PRUint32 role = nsAccUtils::Role(parentAccessible);
|
||||
if (role != nsIAccessibleRole::ROLE_TREE_TABLE)
|
||||
return;
|
||||
}
|
||||
|
||||
// This is a tree or treegrid that uses aria-level to define levels, so find
|
||||
// the first previous sibling accessible where level is defined to be less
|
||||
// than the current level.
|
||||
nsAutoString levelStr;
|
||||
if (nsAccUtils::HasDefinedARIAToken(aStartContent, nsAccessibilityAtoms::aria_level) &&
|
||||
aStartContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, levelStr)) {
|
||||
|
||||
PRInt32 success;
|
||||
PRInt32 level = levelStr.ToInteger(&success);
|
||||
if (level > 1 && NS_SUCCEEDED(success)) {
|
||||
nsCOMPtr<nsIAccessible> currentAccessible = aStartTreeItem, prevAccessible;
|
||||
while (PR_TRUE) {
|
||||
currentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
||||
currentAccessible.swap(prevAccessible);
|
||||
nsCOMPtr<nsIAccessNode> accessNode = do_QueryInterface(currentAccessible);
|
||||
if (!accessNode) {
|
||||
break; // Reached top of tree, no higher level found
|
||||
}
|
||||
PRUint32 role = nsAccUtils::Role(currentAccessible);
|
||||
if (role != startTreeItemRole)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> treeItemNode;
|
||||
accessNode->GetDOMNode(getter_AddRefs(treeItemNode));
|
||||
nsCOMPtr<nsIContent> treeItemContent = do_QueryInterface(treeItemNode);
|
||||
if (treeItemContent &&
|
||||
nsAccUtils::HasDefinedARIAToken(treeItemContent,
|
||||
nsAccessibilityAtoms::aria_level) &&
|
||||
treeItemContent->GetAttr(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_level, levelStr)) {
|
||||
if (levelStr.ToInteger(&success) < level && NS_SUCCEEDED(success)) {
|
||||
NS_ADDREF(*aTreeItemParentResult = currentAccessible);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In the case of ARIA treegrid, return its parent since ARIA group isn't
|
||||
// used to organize levels in ARIA treegrids.
|
||||
|
||||
if (startTreeItemRole == nsIAccessibleRole::ROLE_ROW) {
|
||||
NS_ADDREF(*aTreeItemParentResult = parentAccessible);
|
||||
return; // The container for the tree grid rows
|
||||
}
|
||||
|
||||
// In the case of ARIA tree, a tree can be arranged by using role="group" to
|
||||
// organize levels. In this case the parent of the tree item will be a group
|
||||
// and the previous sibling of that should be the tree item parent. Or, if
|
||||
// the parent is something other than a tree we will return that.
|
||||
|
||||
PRUint32 role = nsAccUtils::Role(parentAccessible);
|
||||
if (role != nsIAccessibleRole::ROLE_GROUPING) {
|
||||
NS_ADDREF(*aTreeItemParentResult = parentAccessible);
|
||||
return; // The container for the tree items
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> prevAccessible;
|
||||
parentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
||||
if (!prevAccessible)
|
||||
return;
|
||||
role = nsAccUtils::Role(prevAccessible);
|
||||
if (role == nsIAccessibleRole::ROLE_TEXT_LEAF) {
|
||||
// XXX Sometimes an empty text accessible is in the hierarchy here,
|
||||
// although the text does not appear to be rendered, GetRenderedText() says that it is
|
||||
// so we need to skip past it to find the true previous sibling
|
||||
nsCOMPtr<nsIAccessible> tempAccessible = prevAccessible;
|
||||
tempAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
|
||||
if (!prevAccessible)
|
||||
return;
|
||||
role = nsAccUtils::Role(prevAccessible);
|
||||
}
|
||||
if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
|
||||
// Previous sibling of parent group is a tree item -- this is the conceptual tree item parent
|
||||
NS_ADDREF(*aTreeItemParentResult = prevAccessible);
|
||||
}
|
||||
}
|
||||
|
||||
nsAccessible *
|
||||
nsAccUtils::GetSelectableContainer(nsAccessible *aAccessible, PRUint32 aState)
|
||||
{
|
||||
|
@ -198,19 +198,6 @@ public:
|
||||
static nsAccessible * GetAncestorWithRole(nsAccessible *aDescendant,
|
||||
PRUint32 aRole);
|
||||
|
||||
/**
|
||||
* For an ARIA tree item , get the accessible that represents its conceptual parent.
|
||||
* This method will use the correct method for the given way the tree is constructed.
|
||||
* The conceptual parent is what the user sees as the parent, not the DOM or accessible parent.
|
||||
* @param aStartTreeItem The tree item to get the parent for
|
||||
* @param aStartTreeItemContent The content node for the tree item
|
||||
* @param The tree item's parent, or null if none
|
||||
*/
|
||||
static void
|
||||
GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
|
||||
nsIContent *aStartTreeItemContent,
|
||||
nsIAccessible **aTreeItemParent);
|
||||
|
||||
/**
|
||||
* Return single or multi selectable container for the given item.
|
||||
*
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "nsIXBLAccessible.h"
|
||||
|
||||
#include "AccGroupInfo.h"
|
||||
#include "AccIterator.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsARIAMap.h"
|
||||
@ -2125,11 +2126,12 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||
(mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM ||
|
||||
mRoleMapEntry->role == nsIAccessibleRole::ROLE_ROW)) {
|
||||
|
||||
nsCOMPtr<nsIAccessible> accTarget;
|
||||
nsAccUtils::GetARIATreeItemParent(this, mContent,
|
||||
getter_AddRefs(accTarget));
|
||||
AccGroupInfo* groupInfo = GetGroupInfo();
|
||||
if (!groupInfo)
|
||||
return NS_OK_NO_RELATION_TARGET;
|
||||
|
||||
return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget);
|
||||
return nsRelUtils::AddTarget(aRelationType, aRelation,
|
||||
groupInfo->GetConceptualParent());
|
||||
}
|
||||
|
||||
// If accessible is in its own Window, or is the root of a document,
|
||||
@ -3091,98 +3093,24 @@ nsAccessible::GetActionRule(PRUint32 aStates)
|
||||
return eNoAction;
|
||||
}
|
||||
|
||||
AccGroupInfo*
|
||||
nsAccessible::GetGroupInfo()
|
||||
{
|
||||
if (mGroupInfo)
|
||||
return mGroupInfo;
|
||||
|
||||
mGroupInfo = AccGroupInfo::CreateGroupInfo(this);
|
||||
return mGroupInfo;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, PRInt32 *aSetSize)
|
||||
{
|
||||
PRUint32 role = nsAccUtils::Role(this);
|
||||
if (role != nsIAccessibleRole::ROLE_LISTITEM &&
|
||||
role != nsIAccessibleRole::ROLE_MENUITEM &&
|
||||
role != nsIAccessibleRole::ROLE_CHECK_MENU_ITEM &&
|
||||
role != nsIAccessibleRole::ROLE_RADIO_MENU_ITEM &&
|
||||
role != nsIAccessibleRole::ROLE_RADIOBUTTON &&
|
||||
role != nsIAccessibleRole::ROLE_PAGETAB &&
|
||||
role != nsIAccessibleRole::ROLE_OPTION &&
|
||||
role != nsIAccessibleRole::ROLE_OUTLINEITEM &&
|
||||
role != nsIAccessibleRole::ROLE_ROW &&
|
||||
role != nsIAccessibleRole::ROLE_GRID_CELL)
|
||||
return;
|
||||
|
||||
PRUint32 baseRole = role;
|
||||
if (role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||
baseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
||||
|
||||
nsAccessible* parent = GetParent();
|
||||
NS_ENSURE_TRUE(parent,);
|
||||
|
||||
PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(this);
|
||||
|
||||
// Compute 'posinset'.
|
||||
PRInt32 positionInGroup = 1;
|
||||
for (PRInt32 idx = mIndexInParent - 1; idx >= 0; idx--) {
|
||||
nsAccessible* sibling = parent->GetChildAt(idx);
|
||||
|
||||
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
||||
|
||||
// If the sibling is separator then the group is ended.
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
||||
break;
|
||||
|
||||
PRUint32 siblingBaseRole = siblingRole;
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
||||
|
||||
// If sibling is visible and has the same base role
|
||||
if (siblingBaseRole == baseRole &&
|
||||
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
||||
|
||||
// and check if it's hierarchical flatten structure, i.e. if the sibling
|
||||
// level is lesser than this one then group is ended, if the sibling level
|
||||
// is greater than this one then the group is splited by some child
|
||||
// elements (group will be continued).
|
||||
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
||||
if (siblingLevel < level)
|
||||
break;
|
||||
else if (level == siblingLevel)
|
||||
++ positionInGroup;
|
||||
}
|
||||
AccGroupInfo* groupInfo = GetGroupInfo();
|
||||
if (groupInfo) {
|
||||
*aPosInSet = groupInfo->PosInSet();
|
||||
*aSetSize = groupInfo->SetSize();
|
||||
}
|
||||
|
||||
// Compute 'setsize'.
|
||||
PRInt32 setSize = positionInGroup;
|
||||
|
||||
PRInt32 siblingCount = parent->GetChildCount();
|
||||
for (PRInt32 idx = mIndexInParent + 1; idx < siblingCount; idx++) {
|
||||
nsAccessible* sibling = parent->GetChildAt(idx);
|
||||
NS_ENSURE_TRUE(sibling,);
|
||||
|
||||
PRUint32 siblingRole = nsAccUtils::Role(sibling);
|
||||
|
||||
// If the sibling is separator then the group is ended.
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
|
||||
break;
|
||||
|
||||
PRUint32 siblingBaseRole = siblingRole;
|
||||
if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
|
||||
siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
|
||||
siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
|
||||
|
||||
// If sibling is visible and has the same base role
|
||||
if (siblingBaseRole == baseRole &&
|
||||
!(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
|
||||
|
||||
// and check if it's hierarchical flatten structure.
|
||||
PRInt32 siblingLevel = nsAccUtils::GetARIAOrDefaultLevel(sibling);
|
||||
if (siblingLevel < level)
|
||||
break;
|
||||
else if (level == siblingLevel)
|
||||
++ setSize;
|
||||
}
|
||||
}
|
||||
|
||||
*aPosInSet = positionInGroup;
|
||||
*aSetSize = setSize;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
class AccGroupInfo;
|
||||
class nsAccessible;
|
||||
class nsAccEvent;
|
||||
struct nsRoleMapEntry;
|
||||
@ -324,7 +325,12 @@ protected:
|
||||
* Set accessible parent and index in parent.
|
||||
*/
|
||||
void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
|
||||
void UnbindFromParent() { mParent = nsnull; mIndexInParent = -1; }
|
||||
void UnbindFromParent()
|
||||
{
|
||||
mParent = nsnull;
|
||||
mIndexInParent = -1;
|
||||
mGroupInfo = nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return sibling accessible at the given offset.
|
||||
@ -424,6 +430,11 @@ protected:
|
||||
*/
|
||||
PRUint32 GetActionRule(PRUint32 aStates);
|
||||
|
||||
/**
|
||||
* Return group info.
|
||||
*/
|
||||
AccGroupInfo* GetGroupInfo();
|
||||
|
||||
/**
|
||||
* Fires platform accessible event. It's notification method only. It does
|
||||
* change nothing on Gecko side. Don't use it until you're sure what you do
|
||||
@ -440,6 +451,9 @@ protected:
|
||||
PRBool mAreChildrenInitialized;
|
||||
PRInt32 mIndexInParent;
|
||||
|
||||
nsAutoPtr<AccGroupInfo> mGroupInfo;
|
||||
friend class AccGroupInfo;
|
||||
|
||||
nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user