Implement basic accessible relations. r=louie.zhao, sr=jst, a=mkaply

This commit is contained in:
aaronleventhal%moonset.net 2005-06-24 16:29:15 +00:00
parent b42edae703
commit cc014c3df1
7 changed files with 365 additions and 35 deletions

View File

@ -188,6 +188,11 @@ interface nsIAccessible : nsISupports
*/
nsIAccessible getAccessibleBelow();
/**
* Accessible node related to this one
*/
nsIAccessible getAccessibleRelated(in unsigned long aRelationType);
void getBounds(out long x,
out long y,
out long width,
@ -301,10 +306,57 @@ interface nsIAccessible : nsISupports
const unsigned long EXT_STATE_TRANSIENT = 0x40000000; // Tells accessibility aid "Don't add event listener - this object doesn't generate any". For example, could be used with higher level containers.
const unsigned long EXT_STATE_VERTICAL = 0x80000000; // Especially used for sliders and scrollbars
/**
* Relation Types -- most of these come from ATK's atkrelationtype.h
* RELATION_NULL:
* RELATION_CONTROLLED_BY: Controlled by one or more target objects.
* RELATION_CONTROLLER_FOR: Controller for one or more target objects.
* RELATION_LABEL_FOR: Label for one or more target objects.
* RELATION_LABELLED_BY: Labelled by one or more target objects.
* RELATION_MEMBER_OF: Member of a group of one or more target objects.
* RELATION_NODE_CHILD_OF: Cell in a treetable which is displayed because a
* cell in the same col is expanded & identifies it.
* RELATION_FLOWS_TO: Has content that flows logically to another
* object in a sequential way, e.g. text flow.
* RELATION_FLOWS_FROM: Has content that flows logically from another
* object in a sequential way, e.g. text flow.
* RELATION_SUBWINDOW_OF: Subwindow attached to a component but otherwise
* not connected in the UI hierarchy to that component.
* RELATION_EMBEDS: Visually embeds another object's content, i.e.
* this object's content flows around another's content.
* RELATION_EMBEDDED_BY: Inverse of RELATION_EMBEDS; this object's content
* is visually embedded in another object.
* RELATION_POPUP_FOR: Popup for another object.
* RELATION_PARENT_WINDOW_OF: Parent window of another object.
* RELATION_DEFAULT_BUTTON: Part of a form/dialog with a related default button.
* RELATION_DESCRIBED_BY: Described by one or more target objects.
* RELATION_DESCRIPTION_FOR: Description for one or more target objects.
* RELATION_LAST_DEFINED:
*/
const unsigned long RELATION_NUL = 0x00; // ATK_RELATION_NUL
const unsigned long RELATION_CONTROLLED_BY = 0x01; // ATK_RELATION_CONTROLLED_BY
const unsigned long RELATION_CONTROLLER_FOR = 0x02; // ATK_RELATION_CONTROLLER_FOR
const unsigned long RELATION_LABEL_FOR = 0x03; // ATK_RELATION_LABEL_FOR
const unsigned long RELATION_LABELLED_BY = 0x04; // ATK_RELATION_LABELLED_BY
const unsigned long RELATION_MEMBER_OF = 0x05; // ATK_RELATION_MEMBER_OF
const unsigned long RELATION_NODE_CHILD_OF = 0x06; // ATK_RELATION_NODE_CHILD_OF
const unsigned long RELATION_FLOWS_TO = 0x07; // ATK_RELATION_FLOWS_TO
const unsigned long RELATION_FLOWS_FROM = 0x08; // ATK_RELATION_FLOWS_FROM
const unsigned long RELATION_SUBWINDOW_OF = 0x09; // ATK_RELATION_SUBWINDOW_OF
const unsigned long RELATION_EMBEDS = 0x0a; // ATK_RELATION_EMBEDS
const unsigned long RELATION_EMBEDDED_BY = 0x0b; // ATK_RELATION_EMBEDDED_BY
const unsigned long RELATION_POPUP_FOR = 0x0c; // ATK_RELATION_POPUP_FOR
const unsigned long RELATION_PARENT_WINDOW_OF = 0x0d; // ATK_RELATION_PARENT_WINDOW_OF
const unsigned long RELATION_DEFAULT_BUTTON = 0x4000; // MSAA only, no ATK relation
const unsigned long RELATION_DESCRIBED_BY = 0x4001; // MSAA only, no ATK relation
const unsigned long RELATION_DESCRIPTION_FOR = 0x4002; // MSAA only, no ATK relation
%{C++
#ifdef MOZ_ACCESSIBILITY_ATK
enum { RELATION_LAST_DEFINED = 14U };
/**
* The following nsIAccessible roles are translated to ATK_ROLE_UNKNOWN
*
@ -545,6 +597,25 @@ interface nsIAccessible : nsISupports
// When in doubt map them to ROLE_NOTHING so that the role string is exposed
enum { ROLE_ICON = ROLE_NOTHING };
enum { ROLE_PASSWORD_TEXT = ROLE_TEXT };
// MSAA relationship extensions to accNavigate
enum { NAVRELATION_CONTROLLED_BY = 0x1000 };
enum { NAVRELATION_CONTROLLER_FOR = 0x1001 };
enum { NAVRELATION_LABEL_FOR = 0x1002 };
enum { NAVRELATION_LABELLED_BY = 0x1003 };
enum { NAVRELATION_MEMBER_OF = 0x1004 };
enum { NAVRELATION_NODE_CHILD_OF = 0x1005 };
enum { NAVRELATION_FLOWS_TO = 0x1006 };
enum { NAVRELATION_FLOWS_FROM = 0x1007 };
enum { NAVRELATION_SUBWINDOW_OF = 0x1008 };
enum { NAVRELATION_EMBEDS = 0x1009 };
enum { NAVRELATION_EMBEDDED_BY = 0x100a };
enum { NAVRELATION_POPUP_FOR = 0x100b };
enum { NAVRELATION_PARENT_WINDOW_OF = 0x100c };
enum { NAVRELATION_DEFAULT_BUTTON = 0x100d };
enum { NAVRELATION_DESCRIBED_BY = 0x100e };
enum { NAVRELATION_DESCRIPTION_FOR = 0x100f };
#endif
%}
};

View File

@ -107,10 +107,10 @@ static gint getChildCountCB(AtkObject *aAtkObj);
static AtkObject* refChildCB(AtkObject *aAtkObj, gint aChildIndex);
static gint getIndexInParentCB(AtkObject *aAtkObj);
static AtkStateSet* refStateSetCB(AtkObject *aAtkObj);
static AtkRelationSet* refRelationSetCB(AtkObject *aAtkObj);
/* the missing atkobject virtual functions */
/*
static AtkRelationSet* refRelationSetCB(AtkObject *aAtkObj);
static AtkLayer getLayerCB(AtkObject *aAtkObj);
static gint getMdiZorderCB(AtkObject *aAtkObj);
static void SetNameCB(AtkObject *aAtkObj,
@ -455,7 +455,6 @@ The following nsIAccessible states aren't translated, just ignored.
STATE_READONLY: The object is designated read-only.
STATE_HOTTRACKED: Means its appearance has changed to indicate mouse
over it.
STATE_DEFAULT: Represents the default button in a window.
STATE_FLOATING: Not supported yet.
STATE_MARQUEED: Indicate scrolling or moving text or graphics.
STATE_ANIMATED:
@ -535,6 +534,11 @@ nsAccessibleWrap::TranslateStates(PRUint32 aState, PRUint32 aExtState, void *aAt
if (aState & nsIAccessible::STATE_INVALID)
atk_state_set_add_state (state_set, ATK_STATE_INVALID);
#ifdef MAI_HAS_ATK_STATE_DEFAULT
if (aState & nsIAccessible::STATE_DEFAULT)
atk_state_set_add_state (state_set, ATK_STATE_DEFAULT);
#endif
#ifdef MAI_HAS_ATK_STATE_REQUIRED
if (aState & nsIAccessible::STATE_REQUIRED)
atk_state_set_add_state (state_set, ATK_STATE_REQUIRED);
@ -595,6 +599,7 @@ classInitCB(AtkObjectClass *aClass)
aClass->get_index_in_parent = getIndexInParentCB;
aClass->get_role = getRoleCB;
aClass->ref_state_set = refStateSetCB;
aClass->ref_relation_set = refRelationSetCB;
aClass->initialize = initializeCB;
@ -898,6 +903,38 @@ refStateSetCB(AtkObject *aAtkObj)
return state_set;
}
AtkRelationSet *
refRelationSetCB(AtkObject *aAtkObj)
{
AtkRelationSet *relation_set = nsnull;
relation_set = ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj);
NS_ENSURE_SUCCESS(CheckMaiAtkObject(aAtkObj), relation_set);
nsAccessibleWrap *accWrap =
NS_REINTERPRET_CAST(MaiAtkObject*, aAtkObj)->accWrap;
AtkObject *accessible_array[1];
AtkRelation* relation;
PRUint32 relationType[2] = {nsIAccessible::RELATION_LABELLED_BY,
nsIAccessible::RELATION_LABEL_FOR};
for (PRUint32 i = 0; i <= 1; i++) {
if (!atk_relation_set_contains(relation_set, NS_STATIC_CAST(AtkRelationType, relationType[i]))) {
nsIAccessible* accRelated;
nsresult rv = accWrap->GetAccessibleRelated(relationType[i], &accRelated);
if (NS_SUCCEEDED(rv) && accRelated) {
accessible_array[0] = NS_STATIC_CAST(nsAccessibleWrap*, accRelated)->GetAtkObject();
relation = atk_relation_new(accessible_array, 1,
NS_STATIC_CAST(AtkRelationType, relationType[i]));
atk_relation_set_add(relation_set, relation);
}
}
}
return relation_set;
}
// Check if aAtkObj is a valid MaiAtkObject
nsresult
CheckMaiAtkObject(AtkObject *aAtkObj)

View File

@ -69,6 +69,7 @@ ACCESSIBILITY_ATOM(area, "area")
ACCESSIBILITY_ATOM(blockquote, "blockquote")
ACCESSIBILITY_ATOM(br, "br")
ACCESSIBILITY_ATOM(body, "body")
ACCESSIBILITY_ATOM(description, "description") // XUL
ACCESSIBILITY_ATOM(form, "form")
ACCESSIBILITY_ATOM(h1, "h1")
ACCESSIBILITY_ATOM(h2, "h2")
@ -88,7 +89,7 @@ ACCESSIBILITY_ATOM(select, "select")
ACCESSIBILITY_ATOM(tbody, "tbody")
ACCESSIBILITY_ATOM(tfoot, "tfoot")
ACCESSIBILITY_ATOM(thead, "thead")
ACCESSIBILITY_ATOM(toolbaritem, "toolbaritem")
ACCESSIBILITY_ATOM(toolbaritem, "toolbaritem") // XUL
ACCESSIBILITY_ATOM(ul, "ul")
// DHTML accessibility relationship attributes

View File

@ -67,7 +67,6 @@
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLBRElement.h"
#include "nsIAtom.h"
#include "nsAccessibilityAtoms.h"
#include "nsGUIEvent.h"
#include "nsIDOMHTMLInputElement.h"
@ -77,8 +76,13 @@
#include "nsIDOMXULButtonElement.h"
#include "nsIDOMXULCheckboxElement.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentXBL.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULElement.h"
#include "nsIDOMXULLabelElement.h"
#include "nsIForm.h"
#include "nsIFormControl.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIScriptGlobalObject.h"
@ -86,7 +90,6 @@
#include "nsAccessibleTreeWalker.h"
#include "nsIURI.h"
#include "nsIImageLoadingContent.h"
#include "nsINameSpaceManager.h"
#include "nsITimer.h"
#include "nsIDOMHTMLDocument.h"
@ -197,10 +200,7 @@ NS_IMETHODIMP nsAccessible::GetKeyboardShortcut(nsAString& _retval)
elt->GetAttribute(NS_LITERAL_STRING("accesskey"), accesskey);
if (accesskey.IsEmpty()) {
nsCOMPtr<nsIContent> content = do_QueryInterface(elt);
nsIContent *labelContent =
content->IsContentOfType(nsIContent::eXUL) ? GetXULLabelContent(content) :
GetHTMLLabelContent(content);
nsIContent *labelContent = GetLabelContent(content);
if (labelContent) {
labelContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey, accesskey);
}
@ -1209,10 +1209,17 @@ nsresult nsAccessible::AppendFlatStringFromSubtreeRecurse(nsIContent *aContent,
return NS_OK;
}
nsIContent* nsAccessible::GetXULLabelContent(nsIContent *aForNode)
nsIContent *nsAccessible::GetLabelContent(nsIContent *aForNode)
{
return aForNode->IsContentOfType(nsIContent::eXUL) ? GetXULLabelContent(aForNode) :
GetHTMLLabelContent(aForNode);
}
nsIContent* nsAccessible::GetXULLabelContent(nsIContent *aForNode, nsIAtom *aLabelType)
{
nsAutoString controlID;
nsIContent *labelContent = GetLabelForId(aForNode, nsnull, &controlID);
nsIContent *labelContent = GetContentPointingTo(&controlID, aForNode, nsnull,
kNameSpaceID_None, aLabelType);
if (labelContent) {
return labelContent;
}
@ -1232,12 +1239,14 @@ nsIContent* nsAccessible::GetXULLabelContent(nsIContent *aForNode)
}
}
// Look for child label of control
// Look for label in subtrees of nearby ancestors
static const PRUint32 kAncestorLevelsToSearch = 3;
PRUint32 count = 0;
while (!labelContent && ++count <= kAncestorLevelsToSearch &&
(aForNode = aForNode->GetParent()) != nsnull) {
labelContent = GetLabelForId(aForNode, nsAccessibilityAtoms::control, &controlID);
labelContent = GetContentPointingTo(&controlID, aForNode,
nsAccessibilityAtoms::control,
kNameSpaceID_None, aLabelType);
}
return labelContent;
@ -1264,7 +1273,7 @@ nsIContent* nsAccessible::GetHTMLLabelContent(nsIContent *aForNode)
if (forId.IsEmpty()) {
break;
}
return GetLabelForId(walkUpContent, nsAccessibilityAtoms::_for, &forId);
return GetContentPointingTo(&forId, walkUpContent, nsAccessibilityAtoms::_for);
}
}
@ -1303,20 +1312,24 @@ nsresult nsAccessible::GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName
return rv;
}
// Pass in forAttrib == nsnull if any <label> will do
nsIContent *nsAccessible::GetLabelForId(nsIContent *aLookContent,
nsIAtom *forAttrib,
const nsAString *aId)
// Pass in aForAttrib == nsnull if any <label> will do
nsIContent *nsAccessible::GetContentPointingTo(const nsAString *aId,
nsIContent *aLookContent,
nsIAtom *aForAttrib,
PRUint32 aForAttribNameSpace,
nsIAtom *aTagType)
{
if (aLookContent->Tag() == nsAccessibilityAtoms::label) {
if (forAttrib) {
if (!aTagType || aLookContent->Tag() == aTagType) {
if (aForAttrib) {
nsAutoString labelIsFor;
aLookContent->GetAttr(kNameSpaceID_None, forAttrib, labelIsFor);
aLookContent->GetAttr(aForAttribNameSpace, aForAttrib, labelIsFor);
if (labelIsFor.Equals(*aId)) {
return aLookContent;
}
}
return nsnull;
if (aTagType) {
return nsnull;
}
}
// Recursively search descendents for labels
@ -1324,7 +1337,8 @@ nsIContent *nsAccessible::GetLabelForId(nsIContent *aLookContent,
nsIContent *child;
while ((child = aLookContent->GetChildAt(count++)) != nsnull) {
nsIContent *labelContent = GetLabelForId(child, forAttrib, aId);
nsIContent *labelContent = GetContentPointingTo(aId, child, aForAttrib,
aForAttribNameSpace, aTagType);
if (labelContent) {
return labelContent;
}
@ -1794,6 +1808,176 @@ NS_IMETHODIMP nsAccessible::GetAccessibleBelow(nsIAccessible **_retval)
return NS_ERROR_NOT_IMPLEMENTED;
}
/* nsIAccessible getAccessibleRelated(); */
NS_IMETHODIMP nsAccessible::GetAccessibleRelated(PRUint32 aRelationType, nsIAccessible **aRelated)
{
*aRelated = nsnull;
// Relationships are defined on the same content node
// that the role would be defined on
nsIContent *content = GetRoleContent(mDOMNode);
if (!content) {
return NS_ERROR_FAILURE; // Node already shut down
}
nsCOMPtr<nsIDOMNode> relatedNode;
nsAutoString relatedID;
// Search for the related DOM node according to the specified "relation type"
switch (aRelationType)
{
case RELATION_LABEL_FOR:
{
if (content->Tag() == nsAccessibilityAtoms::label) {
nsIAtom *relatedIDAttr = content->IsContentOfType(nsIContent::eHTML) ?
nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
content->GetAttr(kNameSpaceID_None, relatedIDAttr, relatedID);
if (relatedID.IsEmpty()) {
// Check first child for form control
}
}
break;
}
case RELATION_LABELLED_BY:
{
relatedNode = do_QueryInterface(GetLabelContent(content));
break;
}
case RELATION_DESCRIBED_BY:
{
content->GetAttr(kNameSpaceID_StatesWAI_Unofficial,
nsAccessibilityAtoms::describedby, relatedID);
if (relatedID.IsEmpty()) {
nsIContent *description =
GetXULLabelContent(content, nsAccessibilityAtoms::description);
relatedNode = do_QueryInterface(description);
}
break;
}
case RELATION_DESCRIPTION_FOR:
{
nsAutoString controlID;
content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::id, controlID);
if (!controlID.IsEmpty()) {
// Something might be pointing to us
PRUint32 count = 0;
nsIContent *start = content;
static const PRUint32 kAncestorLevelsToSearch = 3;
while (!relatedNode && ++count <= kAncestorLevelsToSearch &&
(start = start->GetParent()) != nsnull) {
nsIContent *description = GetContentPointingTo(&controlID, start,
nsAccessibilityAtoms::describedby,
kNameSpaceID_StatesWAI_Unofficial,
nsnull);
relatedNode = do_QueryInterface(description);
}
}
nsIContent *description =
GetXULLabelContent(content, nsAccessibilityAtoms::description);
if (!relatedNode && content->Tag() == nsAccessibilityAtoms::description &&
content->IsContentOfType(nsIContent::eXUL)) {
// This affectively adds an optional control attribute to xul:description,
// which only affects accessibility, by allowing the description to be
// tied to a control.
content->GetAttr(kNameSpaceID_None,
nsAccessibilityAtoms::control, relatedID);
}
break;
}
case RELATION_DEFAULT_BUTTON:
{
if (content->IsContentOfType(nsIContent::eHTML)) {
nsCOMPtr<nsIForm> form;
while ((form = do_QueryInterface(content)) == nsnull &&
(content = content->GetParent()) != nsnull) /* nothing */ ;
if (form) {
// We have a <form> element, so iterate through and try to find a submit button
nsCOMPtr<nsISimpleEnumerator> formControls;
form->GetControlEnumerator(getter_AddRefs(formControls));
nsCOMPtr<nsISupports> controlSupports;
PRBool hasMoreElements;
while (NS_SUCCEEDED(formControls->HasMoreElements(&hasMoreElements)) &&
hasMoreElements) {
nsresult rv = formControls->GetNext(getter_AddRefs(controlSupports));
nsCOMPtr<nsIFormControl> control = do_QueryInterface(controlSupports);
if (control) {
PRInt32 type = control->GetType();
if (type == NS_FORM_INPUT_SUBMIT || type == NS_FORM_BUTTON_SUBMIT ||
type == NS_FORM_INPUT_IMAGE) {
relatedNode = do_QueryInterface(control);
break;
}
}
}
}
}
else {
// In XUL, use first <button default="true" .../> in the document
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(content->GetDocument());
nsCOMPtr<nsIDOMXULButtonElement> buttonEl;
if (xulDoc) {
nsCOMPtr<nsIDOMNodeList> possibleDefaultButtons;
xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("default"),
NS_LITERAL_STRING("true"),
getter_AddRefs(possibleDefaultButtons));
if (possibleDefaultButtons) {
PRUint32 length;
possibleDefaultButtons->GetLength(&length);
nsCOMPtr<nsIDOMNode> possibleButton;
// Check for button in list of default="true" elements
for (PRUint32 count = 0; count < length && !buttonEl; count ++) {
possibleDefaultButtons->Item(count, getter_AddRefs(possibleButton));
buttonEl = do_QueryInterface(possibleButton);
}
}
if (!buttonEl) { // Check for anonymous accept button in <dialog>
nsCOMPtr<nsIDOMDocumentXBL> xblDoc(do_QueryInterface(xulDoc));
if (xblDoc) {
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(xulDoc);
NS_ASSERTION(domDoc, "No DOM document");
nsCOMPtr<nsIDOMElement> rootEl;
domDoc->GetDocumentElement(getter_AddRefs(rootEl));
if (rootEl) {
nsCOMPtr<nsIDOMElement> possibleButtonEl;
xblDoc->GetAnonymousElementByAttribute(rootEl,
NS_LITERAL_STRING("default"),
NS_LITERAL_STRING("true"),
getter_AddRefs(possibleButtonEl));
buttonEl = do_QueryInterface(possibleButtonEl);
}
}
}
relatedNode = do_QueryInterface(buttonEl);
}
}
break;
}
default:
return NS_ERROR_NOT_IMPLEMENTED;
}
if (!relatedID.IsEmpty()) {
// In some cases we need to get the relatedNode from an ID-style attribute
nsCOMPtr<nsIDOMDocument> domDoc;
mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMElement> relatedEl;
domDoc->GetElementById(relatedID, getter_AddRefs(relatedEl));
relatedNode = do_QueryInterface(relatedEl);
}
// Return the corresponding accessible if the related DOM node is found
if (relatedNode) {
nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
return accService->GetAccessibleInWeakShell(relatedNode, mWeakShell, aRelated);
}
return NS_ERROR_FAILURE;
}
/* void addSelection (); */
NS_IMETHODIMP nsAccessible::AddSelection()
{

View File

@ -40,10 +40,12 @@
#define _nsAccessible_H_
#include "nsAccessNodeWrap.h"
#include "nsAccessibilityAtoms.h"
#include "nsIAccessible.h"
#include "nsPIAccessible.h"
#include "nsWeakReference.h"
#include "nsIDOMNodeList.h"
#include "nsINameSpaceManager.h"
#include "nsWeakReference.h"
#include "nsString.h"
struct nsRect;
@ -142,12 +144,18 @@ protected:
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
PRBool IsPartiallyVisible(PRBool *aIsOffscreen);
nsresult GetTextFromRelationID(nsIAtom *aIDAttrib, nsString &aName);
static nsIContent *GetLabelForId(nsIContent *aLookContent,
nsIAtom *forAttrib,
const nsAString *aId);
static nsIContent *GetXULLabelContent(nsIContent *aForNode);
static nsIContent *GetContentPointingTo(const nsAString *aId,
nsIContent *aLookContent,
nsIAtom *forAttrib,
PRUint32 aForAttribNamespace = kNameSpaceID_None,
nsIAtom *aTagType = nsAccessibilityAtoms::label);
static nsIContent *GetXULLabelContent(nsIContent *aForNode,
nsIAtom *aLabelType = nsAccessibilityAtoms::label);
static nsIContent *GetHTMLLabelContent(nsIContent *aForNode);
static nsIContent *GetLabelContent(nsIContent *aForNode);
static nsIContent *GetRoleContent(nsIDOMNode *aDOMNode);
nsresult GetHTMLName(nsAString& _retval, PRBool aCanAggregateSubtree = PR_TRUE);
nsresult GetXULName(nsAString& aName, PRBool aCanAggregateSubtree = PR_TRUE);
// For accessibles that are not lists of choices, the name of the subtree should be the

View File

@ -698,6 +698,7 @@ STDMETHODIMP nsAccessibleWrap::accNavigate(
return E_FAIL;
VariantInit(pvarEndUpAt);
PRUint32 xpRelation = 0;
switch(navDir) {
case NAVDIR_DOWN:
@ -724,6 +725,33 @@ STDMETHODIMP nsAccessibleWrap::accNavigate(
case NAVDIR_UP:
xpAccessibleStart->GetAccessibleAbove(getter_AddRefs(xpAccessibleResult));
break;
// MSAA relationship extensions to accNavigate
case NAVRELATION_CONTROLLED_BY: xpRelation = RELATION_CONTROLLED_BY; break;
case NAVRELATION_CONTROLLER_FOR: xpRelation = RELATION_CONTROLLER_FOR; break;
case NAVRELATION_LABEL_FOR: xpRelation = RELATION_LABEL_FOR; break;
case NAVRELATION_LABELLED_BY: xpRelation = RELATION_LABELLED_BY; break;
case NAVRELATION_MEMBER_OF: xpRelation = RELATION_MEMBER_OF; break;
case NAVRELATION_NODE_CHILD_OF: xpRelation = RELATION_NODE_CHILD_OF; break;
case NAVRELATION_FLOWS_TO: xpRelation = RELATION_FLOWS_TO; break;
case NAVRELATION_FLOWS_FROM: xpRelation = RELATION_FLOWS_FROM; break;
case NAVRELATION_SUBWINDOW_OF: xpRelation = RELATION_SUBWINDOW_OF; break;
case NAVRELATION_EMBEDS: xpRelation = RELATION_EMBEDS; break;
case NAVRELATION_EMBEDDED_BY: xpRelation = RELATION_EMBEDDED_BY; break;
case NAVRELATION_POPUP_FOR: xpRelation = RELATION_POPUP_FOR; break;
case NAVRELATION_PARENT_WINDOW_OF: xpRelation = RELATION_PARENT_WINDOW_OF; break;
case NAVRELATION_DEFAULT_BUTTON: xpRelation = RELATION_DEFAULT_BUTTON; break;
case NAVRELATION_DESCRIBED_BY: xpRelation = RELATION_DESCRIBED_BY; break;
case NAVRELATION_DESCRIPTION_FOR: xpRelation = RELATION_DESCRIPTION_FOR; break;
}
pvarEndUpAt->vt = VT_EMPTY;
if (xpRelation) {
nsresult rv = GetAccessibleRelated(xpRelation,
getter_AddRefs(xpAccessibleResult));
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
return E_NOTIMPL;
}
}
if (xpAccessibleResult) {
@ -731,7 +759,6 @@ STDMETHODIMP nsAccessibleWrap::accNavigate(
pvarEndUpAt->vt = VT_DISPATCH;
return NS_OK;
}
pvarEndUpAt->vt = VT_EMPTY;
return E_FAIL;
}

View File

@ -50,14 +50,16 @@ nsTextAccessibleWrap(aDomNode, aShell)
}
/* wstring getName (); */
NS_IMETHODIMP nsXULTextAccessible::GetName(nsAString& _retval)
NS_IMETHODIMP nsXULTextAccessible::GetName(nsAString& aName)
{
nsCOMPtr<nsIDOMXULDescriptionElement> descriptionElement(do_QueryInterface(mDOMNode));
if (descriptionElement) {
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
return AppendFlatStringFromSubtree(content, &_retval);
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
if (!content) {
return NS_ERROR_FAILURE; // Node shut down
}
return NS_ERROR_FAILURE;
if (content->Tag() == nsAccessibilityAtoms::label) {
return content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::value, aName);
}
return nsTextAccessibleWrap::GetName(aName);
}
NS_IMETHODIMP nsXULTextAccessible::GetState(PRUint32 *_retval)