mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 419416. Follow useful rules for handling ARIA properties on a frame, iframe and body elements. r=ginn.chen, a=dsicore
This commit is contained in:
parent
7b83e29004
commit
8b18471351
@ -117,5 +117,13 @@ interface nsPIAccessible : nsISupports
|
||||
* nsnull if none.
|
||||
*/
|
||||
void setRoleMapEntry(in nsRoleMapEntryPtr aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Maps ARIA state attributes to state of accessible. Note the given state
|
||||
* argument should hold states for accessible before you pass it into this
|
||||
* method.
|
||||
* @param in/out where to fill the states into.
|
||||
*/
|
||||
void getARIAState(out unsigned long aState);
|
||||
};
|
||||
|
||||
|
@ -234,3 +234,8 @@ ACCESSIBILITY_ATOM(level, "level")
|
||||
ACCESSIBILITY_ATOM(posinset, "posinset")
|
||||
ACCESSIBILITY_ATOM(setsize, "setsize")
|
||||
ACCESSIBILITY_ATOM(lineNumber, "line-number")
|
||||
ACCESSIBILITY_ATOM(containerRelevant, "container-relevant")
|
||||
ACCESSIBILITY_ATOM(containerLive, "container-live")
|
||||
ACCESSIBILITY_ATOM(containerChannel, "container-channel")
|
||||
ACCESSIBILITY_ATOM(containerAtomic, "container-atomic")
|
||||
ACCESSIBILITY_ATOM(containerBusy, "container-busy")
|
||||
|
@ -453,6 +453,10 @@ nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell,
|
||||
|
||||
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(*aRootAcc));
|
||||
privateAccessNode->Init();
|
||||
nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(rootNode);
|
||||
nsCOMPtr<nsPIAccessible> privateAccessible =
|
||||
do_QueryInterface(privateAccessNode);
|
||||
privateAccessible->SetRoleMapEntry(roleMapEntry);
|
||||
|
||||
NS_ADDREF(*aRootAcc);
|
||||
|
||||
|
@ -933,3 +933,33 @@ nsAccUtils::IsARIAPropForObjectAttr(nsIAtom *aAtom)
|
||||
aAtom != nsAccessibilityAtoms::aria_valuenow &&
|
||||
aAtom != nsAccessibilityAtoms::aria_valuetext;
|
||||
}
|
||||
|
||||
void nsAccUtils::GetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
|
||||
nsIContent *aStartContent, nsIContent *aTopContent)
|
||||
{
|
||||
nsAutoString atomic, live, relevant, channel, busy;
|
||||
nsIContent *ancestor = aStartContent;
|
||||
while (ancestor) {
|
||||
if (relevant.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerRelevant, relevant);
|
||||
if (live.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live, live))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerLive, live);
|
||||
if (channel.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel, channel))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerChannel, channel);
|
||||
if (atomic.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerAtomic, atomic);
|
||||
if (busy.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy, busy))
|
||||
SetAccAttr(aAttributes, nsAccessibilityAtoms::containerBusy, busy);
|
||||
if (ancestor == aTopContent)
|
||||
break;
|
||||
ancestor = ancestor->GetParent();
|
||||
if (!ancestor) {
|
||||
ancestor = aTopContent; // Use <body>/<frameset>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -366,6 +366,16 @@ public:
|
||||
|
||||
// Return PR_TRUE if the ARIA property should always be exposed as an object attribute
|
||||
static PRBool IsARIAPropForObjectAttr(nsIAtom *aAtom);
|
||||
|
||||
|
||||
/**
|
||||
* Get container-foo live region attributes for the given node
|
||||
* @param aAttributes Where to store the attributes
|
||||
* @param aStartContent Node to start from
|
||||
* @param aTopContent Node to end at
|
||||
*/
|
||||
static void GetLiveContainerAttributes(nsIPersistentProperties *aAttributes,
|
||||
nsIContent *aStartContent, nsIContent *aTopContent);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -489,10 +489,9 @@ NS_IMETHODIMP nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
|
||||
nsIContent *nsAccessible::GetRoleContent(nsIDOMNode *aDOMNode)
|
||||
{
|
||||
// Given the DOM node for an acessible, return content node that
|
||||
// we should look at role string from
|
||||
// we should look for ARIA properties on.
|
||||
// For non-document accessibles, this is the associated content node.
|
||||
// For doc accessibles, first try the <body> if it's HTML and there is
|
||||
// a role attribute used there.
|
||||
// For doc accessibles, use the <body>/<frameset> if it's HTML.
|
||||
// For any other doc accessible , this is the document element.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
|
||||
if (!content) {
|
||||
@ -504,7 +503,7 @@ nsIContent *nsAccessible::GetRoleContent(nsIDOMNode *aDOMNode)
|
||||
htmlDoc->GetBody(getter_AddRefs(bodyElement));
|
||||
content = do_QueryInterface(bodyElement);
|
||||
}
|
||||
if (!content) {
|
||||
else {
|
||||
nsCOMPtr<nsIDOMElement> docElement;
|
||||
domDoc->GetDocumentElement(getter_AddRefs(docElement));
|
||||
content = do_QueryInterface(docElement);
|
||||
@ -2003,19 +2002,20 @@ NS_IMETHODIMP nsAccessible::GetFinalRole(PRUint32 *aRole)
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAttributes);
|
||||
*aAttributes = nsnull;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aAttributes); // In/out param. Created if necessary.
|
||||
|
||||
nsCOMPtr<nsIContent> content = GetRoleContent(mDOMNode);
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPersistentProperties> attributes =
|
||||
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
|
||||
NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsAccEvent::GetLastEventAttributes(mDOMNode, attributes);
|
||||
nsCOMPtr<nsIPersistentProperties> attributes = *aAttributes;
|
||||
if (!attributes) {
|
||||
// Create only if an array wasn't already passed in
|
||||
attributes = do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
|
||||
NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ADDREF(*aAttributes = attributes);
|
||||
}
|
||||
|
||||
nsresult rv = GetAttributesInternal(attributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -2023,13 +2023,11 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
nsAutoString id;
|
||||
nsAutoString oldValueUnused;
|
||||
if (nsAccUtils::GetID(content, id)) {
|
||||
// Expose ID. If an <iframe id> exists override the one on the <body> of the source doc,
|
||||
// because the specific instance is what makes the ID useful for scripts
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
|
||||
}
|
||||
|
||||
nsAutoString _class;
|
||||
if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::_class, _class))
|
||||
nsAccUtils::SetAccAttr(attributes, nsAccessibilityAtoms::_class, _class);
|
||||
|
||||
nsAutoString xmlRoles;
|
||||
if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, xmlRoles)) {
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"), xmlRoles, oldValueUnused);
|
||||
@ -2046,29 +2044,6 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
}
|
||||
|
||||
|
||||
// Get container-foo computed live region properties based on the closest container with
|
||||
// the live region attribute
|
||||
nsAutoString atomic, live, relevant, channel, busy;
|
||||
nsIContent *ancestor = content;
|
||||
while (ancestor) {
|
||||
if (relevant.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-relevant"), relevant, oldValueUnused);
|
||||
if (live.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live, live))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-live"), live, oldValueUnused);
|
||||
if (channel.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_channel, channel))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-channel"), channel, oldValueUnused);
|
||||
if (atomic.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-atomic"), atomic, oldValueUnused);
|
||||
if (busy.IsEmpty() &&
|
||||
ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_busy, busy))
|
||||
attributes->SetStringProperty(NS_LITERAL_CSTRING("container-busy"), busy, oldValueUnused);
|
||||
ancestor = ancestor->GetParent();
|
||||
}
|
||||
|
||||
PRUint32 role = Role(this);
|
||||
if (role == nsIAccessibleRole::ROLE_CHECKBUTTON ||
|
||||
role == nsIAccessibleRole::ROLE_PUSHBUTTON ||
|
||||
@ -2168,15 +2143,16 @@ nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
attributes.swap(*aAttributes);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(GetRoleContent(mDOMNode)));
|
||||
// Attributes set by this method will not be used to override attributes on a sub-document accessible
|
||||
// when there is a <frame>/<iframe> element that spawned the sub-document
|
||||
nsIContent *content = GetRoleContent(mDOMNode);
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(content));
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoString tagName;
|
||||
@ -2187,6 +2163,43 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
oldValueUnused);
|
||||
}
|
||||
|
||||
nsAccEvent::GetLastEventAttributes(mDOMNode, aAttributes);
|
||||
|
||||
// Expose class because it may have useful microformat information
|
||||
// Let the class from an iframe's document be exposed, don't override from <iframe class>
|
||||
nsAutoString _class;
|
||||
if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::_class, _class))
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::_class, _class);
|
||||
|
||||
// Get container-foo computed live region properties based on the closest container with
|
||||
// the live region attribute.
|
||||
// Inner nodes override outer nodes within the same document --
|
||||
// The inner nodes can be used to override live region behavior on more general outer nodes
|
||||
// However, nodes in outer documents override nodes in inner documents:
|
||||
// Outer doc author may want to override properties on a widget they used in an iframe
|
||||
nsCOMPtr<nsIDOMNode> startNode = mDOMNode;
|
||||
nsIContent *startContent = content;
|
||||
while (PR_TRUE) {
|
||||
NS_ENSURE_STATE(startContent);
|
||||
nsIDocument *doc = startContent->GetDocument();
|
||||
nsCOMPtr<nsIDOMNode> docNode = do_QueryInterface(doc);
|
||||
NS_ENSURE_STATE(docNode);
|
||||
nsIContent *topContent = GetRoleContent(docNode);
|
||||
NS_ENSURE_STATE(topContent);
|
||||
nsAccUtils::GetLiveContainerAttributes(aAttributes, startContent, topContent);
|
||||
// Allow ARIA live region markup from outer documents to override
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
nsIDocShellTreeItem *docShellTreeItem = nsnull;
|
||||
if (container)
|
||||
CallQueryInterface(container, &docShellTreeItem);
|
||||
nsIDocShellTreeItem *sameTypeParent = nsnull;
|
||||
docShellTreeItem->GetSameTypeParent(&sameTypeParent);
|
||||
if (!sameTypeParent || sameTypeParent == docShellTreeItem)
|
||||
break;
|
||||
nsIDocument *parentDoc = doc->GetParentDocument();
|
||||
startContent = parentDoc->FindContentForSubDocument(doc);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2266,7 +2279,7 @@ nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Apply ARIA states to be sure accessible states will be overriden.
|
||||
*aState |= GetARIAState();
|
||||
GetARIAState(aState);
|
||||
|
||||
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) {
|
||||
if (*aState & nsIAccessibleStates::STATE_FOCUSED) {
|
||||
@ -2391,39 +2404,39 @@ nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsAccessible::GetARIAState()
|
||||
nsresult
|
||||
nsAccessible::GetARIAState(PRUint32 *aState)
|
||||
{
|
||||
// Test for universal states first
|
||||
nsIContent *content = GetRoleContent(mDOMNode);
|
||||
if (!content) {
|
||||
return 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 ariaState = 0;
|
||||
PRUint32 index = 0;
|
||||
while (MappedAttrState(content, &ariaState, &nsARIAMap::gWAIUnivStateMap[index])) {
|
||||
while (MappedAttrState(content, aState, &nsARIAMap::gWAIUnivStateMap[index])) {
|
||||
++ index;
|
||||
}
|
||||
|
||||
if (!mRoleMapEntry)
|
||||
return ariaState;
|
||||
return NS_OK;
|
||||
|
||||
// Once DHTML role is used, we're only readonly if DHTML readonly used
|
||||
ariaState &= ~nsIAccessibleStates::STATE_READONLY;
|
||||
|
||||
ariaState |= mRoleMapEntry->state;
|
||||
if (MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap1) &&
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap2) &&
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap3) &&
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap4) &&
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap5) &&
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap6) &&
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap7)) {
|
||||
MappedAttrState(content, &ariaState, &mRoleMapEntry->attributeMap8);
|
||||
if (MappedAttrState(content, aState, &mRoleMapEntry->attributeMap1) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap2) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap3) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap4) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap5) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap6) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap7)) {
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap8);
|
||||
}
|
||||
|
||||
return ariaState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Not implemented by this class
|
||||
|
@ -130,13 +130,6 @@ public:
|
||||
*/
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
|
||||
/**
|
||||
* Maps ARIA state attributes to state of accessible. Note the given state
|
||||
* argument should hold states for accessible before you pass it into this
|
||||
* method.
|
||||
*/
|
||||
PRUint32 GetARIAState();
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
static PRBool IsTextInterfaceSupportCorrect(nsIAccessible *aAccessible);
|
||||
#endif
|
||||
|
@ -152,14 +152,14 @@ NS_IMETHODIMP nsDocAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
aName.Truncate();
|
||||
if (mRoleMapEntry) {
|
||||
rv = nsAccessible::GetName(aName);
|
||||
if (mParent) {
|
||||
rv = mParent->GetName(aName); // Allow owning iframe to override the name
|
||||
}
|
||||
if (aName.IsEmpty()) {
|
||||
rv = GetTitle(aName);
|
||||
rv = nsAccessible::GetName(aName); // Allow name via aria-labelledby or title attribute
|
||||
}
|
||||
if (aName.IsEmpty() && mParent) {
|
||||
rv = mParent->GetName(aName);
|
||||
if (aName.IsEmpty()) {
|
||||
rv = GetTitle(aName); // Finally try title element
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -202,17 +202,38 @@ NS_IMETHODIMP nsDocAccessible::GetRole(PRUint32 *aRole)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetValue(nsAString& aValue)
|
||||
NS_IMETHODIMP nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||
{
|
||||
return GetURL(aValue);
|
||||
NS_ENSURE_STATE(mDocument);
|
||||
|
||||
mRoleMapEntry = aRoleMapEntry;
|
||||
|
||||
// Allow use of ARIA role from outer to override
|
||||
nsIDocument *parentDoc = mDocument->GetParentDocument();
|
||||
NS_ENSURE_TRUE(parentDoc, NS_ERROR_FAILURE);
|
||||
nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument);
|
||||
nsCOMPtr<nsIDOMNode> ownerNode(do_QueryInterface(ownerContent));
|
||||
if (ownerNode) {
|
||||
nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(ownerNode);
|
||||
if (roleMapEntry)
|
||||
mRoleMapEntry = roleMapEntry; // Override
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocAccessible::GetDescription(nsAString& aDescription)
|
||||
{
|
||||
nsAutoString description;
|
||||
GetTextFromRelationID(nsAccessibilityAtoms::aria_describedby, description);
|
||||
aDescription = description;
|
||||
if (mParent)
|
||||
mParent->GetDescription(aDescription);
|
||||
|
||||
if (aDescription.IsEmpty()) {
|
||||
nsAutoString description;
|
||||
GetTextFromRelationID(nsAccessibilityAtoms::aria_describedby, description);
|
||||
aDescription = description;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -265,6 +286,31 @@ nsDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocAccessible::GetARIAState(PRUint32 *aState)
|
||||
{
|
||||
// Combine with states from outer doc
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsresult rv = nsAccessible::GetARIAState(aState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsPIAccessible> privateParentAccessible = do_QueryInterface(mParent);
|
||||
if (privateParentAccessible) // Allow iframe/frame etc. to have final state override via ARIA
|
||||
return privateParentAccessible->GetARIAState(aState);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
|
||||
{
|
||||
nsAccessible::GetAttributes(aAttributes);
|
||||
if (mParent) {
|
||||
mParent->GetAttributes(aAttributes); // Add parent attributes (override inner)
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
|
||||
{
|
||||
if (!gLastFocusedNode) {
|
||||
@ -502,18 +548,10 @@ NS_IMETHODIMP nsDocAccessible::Init()
|
||||
|
||||
AddEventListeners();
|
||||
|
||||
nsresult rv = nsHyperTextAccessibleWrap::Init();
|
||||
nsCOMPtr<nsIAccessible> parentAccessible; // Ensure outer doc mParent accessible
|
||||
GetParent(getter_AddRefs(parentAccessible));
|
||||
|
||||
if (mRoleMapEntry && mRoleMapEntry->role != nsIAccessibleRole::ROLE_DIALOG &&
|
||||
mRoleMapEntry->role != nsIAccessibleRole::ROLE_APPLICATION &&
|
||||
mRoleMapEntry->role != nsIAccessibleRole::ROLE_ALERT &&
|
||||
mRoleMapEntry->role != nsIAccessibleRole::ROLE_DOCUMENT) {
|
||||
// Document accessible can only have certain roles
|
||||
// This was set in nsAccessible::Init() based on dynamic role attribute
|
||||
mRoleMapEntry = nsnull; // role attribute is not valid for a document
|
||||
}
|
||||
|
||||
return rv;
|
||||
return nsHyperTextAccessibleWrap::Init();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::Shutdown()
|
||||
|
@ -74,10 +74,12 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
virtual ~nsDocAccessible();
|
||||
|
||||
NS_IMETHOD GetRole(PRUint32 *aRole);
|
||||
NS_IMETHOD SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetValue(nsAString& aValue);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetARIAState(PRUint32 *aState);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
NS_IMETHOD TakeFocus(void);
|
||||
|
@ -155,3 +155,15 @@ void nsOuterDocAccessible::CacheChildren()
|
||||
privateInnerAccessible->SetNextSibling(nsnull);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOuterDocAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
nsAutoString tag;
|
||||
aAttributes->GetStringProperty(NS_LITERAL_CSTRING("tag"), tag);
|
||||
if (!tag.IsEmpty()) {
|
||||
// We're overriding the ARIA attributes on an sub document, but we don't want to
|
||||
// override the other attributes
|
||||
return NS_OK;
|
||||
}
|
||||
return nsAccessible::GetAttributesInternal(aAttributes);
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ class nsOuterDocAccessible : public nsAccessibleWrap
|
||||
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsIAccessible **aAccessible);
|
||||
void CacheChildren();
|
||||
nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -448,12 +448,15 @@ PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
|
||||
// Check for aria-activedescendant, which changes which element has focus
|
||||
nsCOMPtr<nsIDOMNode> finalFocusNode = aNode;
|
||||
nsCOMPtr<nsIAccessible> finalFocusAccessible = aAccessible;
|
||||
nsCOMPtr<nsIContent> finalFocusContent = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsIContent> finalFocusContent = GetRoleContent(finalFocusNode);
|
||||
if (finalFocusContent) {
|
||||
nsAutoString id;
|
||||
if (finalFocusContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant, id)) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aNode->GetOwnerDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc) { // Maybe the passed-in node actually is a doc
|
||||
domDoc = do_QueryInterface(aNode);
|
||||
}
|
||||
if (!domDoc) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ __try {
|
||||
GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
|
||||
if (xpAccessible) {
|
||||
nsAutoString value;
|
||||
if (NS_FAILED(xpAccessible->GetValue(value)))
|
||||
if (NS_FAILED(xpAccessible->GetValue(value)) || value.IsEmpty())
|
||||
return S_FALSE;
|
||||
|
||||
*pszValue = ::SysAllocString(value.get());
|
||||
|
@ -272,3 +272,23 @@ STDMETHODIMP nsDocAccessibleWrap::put_alternateViewMediaTypes( /* [in] */ BSTR _
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsDocAccessibleWrap::get_accValue(
|
||||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszValue)
|
||||
{
|
||||
// For backwards-compat, we still support old MSAA hack to provide URL in accValue
|
||||
*pszValue = NULL;
|
||||
// Check for real value first
|
||||
HRESULT hr = nsAccessibleWrap::get_accValue(varChild, pszValue);
|
||||
if (FAILED(hr) || *pszValue || varChild.lVal != CHILDID_SELF)
|
||||
return hr;
|
||||
// If document is being used to create a widget, don't use the URL hack
|
||||
PRUint32 role = Role(this);
|
||||
if (role != nsIAccessibleRole::ROLE_DOCUMENT &&
|
||||
role != nsIAccessibleRole::ROLE_APPLICATION &&
|
||||
role != nsIAccessibleRole::ROLE_DIALOG &&
|
||||
role != nsIAccessibleRole::ROLE_ALERT)
|
||||
return hr;
|
||||
|
||||
return get_URL(pszValue);
|
||||
}
|
||||
|
@ -87,6 +87,11 @@ public:
|
||||
/* [in] */ VARIANT varChild,
|
||||
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild);
|
||||
|
||||
// Override get_accValue to provide URL when no other value is available
|
||||
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accValue(
|
||||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszValue);
|
||||
|
||||
NS_IMETHOD FireAnchorJumpEvent();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user