Bug 891338 - Popup accessibility broken, r=tbsaunde, roc, f=marcoz, jamie

This commit is contained in:
Alexander Surkov 2013-07-22 11:58:19 -04:00
Родитель b4587ffa38
Коммит 9f0f0b2d59
4 изменённых файлов: 64 добавлений и 33 удалений

Просмотреть файл

@ -1265,7 +1265,7 @@ DocAccessible::GetAccessibleByUniqueIDInSubtree(void* aUniqueID)
}
Accessible*
DocAccessible::GetAccessibleOrContainer(nsINode* aNode)
DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const
{
if (!aNode || !aNode->IsInDoc())
return nullptr;
@ -1278,6 +1278,30 @@ DocAccessible::GetAccessibleOrContainer(nsINode* aNode)
return accessible;
}
Accessible*
DocAccessible::GetAccessibleOrDescendant(nsINode* aNode) const
{
Accessible* acc = GetAccessible(aNode);
if (acc)
return acc;
acc = GetContainerAccessible(aNode);
if (acc) {
uint32_t childCnt = acc->ChildCount();
for (uint32_t idx = 0; idx < childCnt; idx++) {
Accessible* child = acc->GetChildAt(idx);
for (nsIContent* elm = child->GetContent();
elm && elm != acc->GetContent();
elm = elm->GetFlattenedTreeParent()) {
if (elm == aNode)
return child;
}
}
}
return nullptr;
}
bool
DocAccessible::BindToDocument(Accessible* aAccessible,
nsRoleMapEntry* aRoleMapEntry)

Просмотреть файл

@ -242,16 +242,21 @@ public:
* Return an accessible for the given DOM node or container accessible if
* the node is not accessible.
*/
Accessible* GetAccessibleOrContainer(nsINode* aNode);
Accessible* GetAccessibleOrContainer(nsINode* aNode) const;
/**
* Return a container accessible for the given DOM node.
*/
Accessible* GetContainerAccessible(nsINode* aNode)
Accessible* GetContainerAccessible(nsINode* aNode) const
{
return aNode ? GetAccessibleOrContainer(aNode->GetParentNode()) : nullptr;
}
/**
* Return an accessible for the given node or its first accessible descendant.
*/
Accessible* GetAccessibleOrDescendant(nsINode* aNode) const;
/**
* Return true if the given ID is referred by relation attribute.
*

Просмотреть файл

@ -1826,25 +1826,23 @@ AccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild)
// Convert child ID to unique ID.
void* uniqueID = reinterpret_cast<void*>(-aVarChild.lVal);
// Document.
if (IsDoc())
return AsDoc()->GetAccessibleByUniqueIDInSubtree(uniqueID);
// ARIA document and menu popups.
if (ARIARole() == roles::DOCUMENT || IsMenuPopup()) {
DocAccessible* document = Document();
Accessible* child =
document->GetAccessibleByUniqueIDInSubtree(uniqueID);
// Check whether the accessible for the given ID is a child.
Accessible* parent = child ? child->Parent() : nullptr;
// If it is a document then just return an accessible.
if (IsDoc())
return child;
// Otherwise check whether the accessible is a child (this path works for
// ARIA documents and popups).
Accessible* parent = child;
while (parent && parent != document) {
if (parent == this)
return child;
parent = parent->Parent();
}
}
return nullptr;
}

Просмотреть файл

@ -141,6 +141,11 @@
#include <richedit.h>
#if defined(ACCESSIBILITY)
#ifdef DEBUG
#include "mozilla/a11y/Logging.h"
#endif
#include "oleidl.h"
#include <winuser.h>
#include "nsAccessibilityService.h"
@ -6639,20 +6644,19 @@ nsWindow::GetIMEUpdatePreference()
}
#ifdef ACCESSIBILITY
#ifdef DEBUG_WMGETOBJECT
#ifdef DEBUG
#define NS_LOG_WMGETOBJECT(aWnd, aHwnd, aAcc) \
PR_LOG(gWindowsLog, PR_LOG_ALWAYS, \
("Get the window:\n {\n HWND: %d, parent HWND: %d, wndobj: %p,\n",\
aHwnd, ::GetParent(aHwnd), aWnd)); \
PR_LOG(gWindowsLog, PR_LOG_ALWAYS, (" acc: %p", aAcc)); \
if (a11y::logging::IsEnabled(a11y::logging::ePlatforms)) { \
printf("Get the window:\n {\n HWND: %d, parent HWND: %d, wndobj: %p,\n",\
aHwnd, ::GetParent(aHwnd), aWnd); \
printf(" acc: %p", aAcc); \
if (aAcc) { \
nsAutoString name; \
aAcc->Name(name); \
PR_LOG(gWindowsLog, PR_LOG_ALWAYS, \
(", accname: %s", NS_ConvertUTF16toUTF8(name).get())); \
printf(", accname: %s", NS_ConvertUTF16toUTF8(name).get()); \
} \
PR_LOG(gWindowsLog, PR_LOG_ALWAYS, ("\n }\n"));
printf("\n }\n"); \
}
#else
#define NS_LOG_WMGETOBJECT(aWnd, aHwnd, aAcc)
@ -6681,8 +6685,8 @@ nsWindow::GetAccessible()
GetAccService()->GetDocAccessible(frame->PresContext()->PresShell());
if (docAcc) {
NS_LOG_WMGETOBJECT(this, mWnd,
docAcc->GetAccessible(frame->GetContent()));
return docAcc->GetAccessible(frame->GetContent());
docAcc->GetAccessibleOrDescendant(frame->GetContent()));
return docAcc->GetAccessibleOrDescendant(frame->GetContent());
}
}
}