Bug 977170 - can't query IAccessible from HTML area element having ISimpleDOMNode pointer, r=tbsaunde

This commit is contained in:
Alexander Surkov 2014-03-05 19:36:56 -05:00
parent e2d1db00e0
commit f5aef9e395
7 changed files with 51 additions and 39 deletions

View File

@ -7,11 +7,9 @@
#include "Accessible-inl.h"
#include "AccIterator.h"
#include "DocAccessible-inl.h"
#include "HTMLImageMapAccessible.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsEventShell.h"
#include "nsImageFrame.h"
#include "Role.h"
#include "nsEventStateManager.h"
@ -39,7 +37,7 @@ FocusManager::FocusedAccessible() const
if (focusedNode) {
DocAccessible* doc =
GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
return doc ? GetFocusableAccessibleFor(focusedNode, doc) : nullptr;
return doc ? doc->GetAccessibleEvenIfNotInMapOrContainer(focusedNode) : nullptr;
}
return nullptr;
@ -63,7 +61,7 @@ FocusManager::IsFocused(const Accessible* aAccessible) const
DocAccessible* doc =
GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
return aAccessible ==
(doc ? GetFocusableAccessibleFor(focusedNode, doc) : nullptr);
(doc ? doc->GetAccessibleEvenIfNotInMapOrContainer(focusedNode) : nullptr);
}
}
return false;
@ -243,7 +241,7 @@ FocusManager::ProcessDOMFocus(nsINode* aTarget)
DocAccessible* document =
GetAccService()->GetDocAccessible(aTarget->OwnerDoc());
Accessible* target = GetFocusableAccessibleFor(aTarget, document);
Accessible* target = document->GetAccessibleEvenIfNotInMapOrContainer(aTarget);
if (target && document) {
// Check if still focused. Otherwise we can end up with storing the active
// item for control that isn't focused anymore.
@ -251,7 +249,8 @@ FocusManager::ProcessDOMFocus(nsINode* aTarget)
if (!focusedNode)
return;
Accessible* DOMFocus = GetFocusableAccessibleFor(focusedNode, document);
Accessible* DOMFocus =
document->GetAccessibleEvenIfNotInMapOrContainer(focusedNode);
if (target != DOMFocus)
return;
@ -283,7 +282,8 @@ FocusManager::ProcessFocusEvent(AccEvent* aEvent)
if (!focusedNode)
return;
Accessible* DOMFocus = GetFocusableAccessibleFor(focusedNode, document);
Accessible* DOMFocus =
document->GetAccessibleEvenIfNotInMapOrContainer(focusedNode);
if (target != DOMFocus)
return;
@ -408,28 +408,3 @@ FocusManager::FocusedDOMDocument() const
nsINode* focusedNode = FocusedDOMNode();
return focusedNode ? focusedNode->OwnerDoc() : nullptr;
}
Accessible*
FocusManager::GetFocusableAccessibleFor(nsINode* aNode,
DocAccessible* aDoc) const
{
if (!aNode->IsContent() || !aNode->AsContent()->IsHTML(nsGkAtoms::area))
return aDoc->GetAccessibleOrContainer(aNode);
// XXX Bug 135040, incorrect when multiple images use the same map.
nsIFrame* frame = aNode->AsContent()->GetPrimaryFrame();
nsImageFrame* imageFrame = do_QueryFrame(frame);
if (imageFrame) {
Accessible* parent = aDoc->GetAccessible(imageFrame->GetContent());
if (parent) {
Accessible* area =
parent->AsImageMap()->GetChildAccessibleFor(aNode);
if (area)
return area;
return nullptr;
}
}
return aDoc->GetAccessibleOrContainer(aNode);
}

View File

@ -123,12 +123,6 @@ private:
*/
nsIDocument* FocusedDOMDocument() const;
/**
* Return accessible for a focusable node.
*/
Accessible* GetFocusableAccessibleFor(nsINode* aNode,
DocAccessible* aDoc) const;
private:
nsRefPtr<Accessible> mActiveItem;
nsRefPtr<Accessible> mActiveARIAMenubar;

View File

@ -116,6 +116,13 @@ DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible);
}
inline Accessible*
DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const
{
Accessible* acc = GetAccessibleEvenIfNotInMap(aNode);
return acc ? acc : GetContainerAccessible(aNode);
}
} // namespace a11y
} // namespace mozilla

View File

@ -6,6 +6,7 @@
#include "Accessible-inl.h"
#include "AccIterator.h"
#include "DocAccessible-inl.h"
#include "HTMLImageMapAccessible.h"
#include "nsAccCache.h"
#include "nsAccessiblePivot.h"
#include "nsAccUtils.h"
@ -30,6 +31,7 @@
#include "nsEventStateManager.h"
#include "nsIFrame.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsImageFrame.h"
#include "nsIPersistentProperties2.h"
#include "nsIPresShell.h"
#include "nsIServiceManager.h"
@ -1435,6 +1437,30 @@ DocAccessible::ProcessInvalidationList()
mInvalidationList.Clear();
}
Accessible*
DocAccessible::GetAccessibleEvenIfNotInMap(nsINode* aNode) const
{
if (!aNode->IsContent() || !aNode->AsContent()->IsHTML(nsGkAtoms::area))
return GetAccessible(aNode);
// XXX Bug 135040, incorrect when multiple images use the same map.
nsIFrame* frame = aNode->AsContent()->GetPrimaryFrame();
nsImageFrame* imageFrame = do_QueryFrame(frame);
if (imageFrame) {
Accessible* parent = GetAccessible(imageFrame->GetContent());
if (parent) {
Accessible* area =
parent->AsImageMap()->GetChildAccessibleFor(aNode);
if (area)
return area;
return nullptr;
}
}
return GetAccessible(aNode);
}
////////////////////////////////////////////////////////////////////////////////
// Accessible protected

View File

@ -211,6 +211,15 @@ public:
*/
Accessible* GetAccessible(nsINode* aNode) const;
/**
* Return an accessible for the given node even if the node is not in
* document's node map cache (like HTML area element).
*
* XXX: it should be really merged with GetAccessible().
*/
Accessible* GetAccessibleEvenIfNotInMap(nsINode* aNode) const;
Accessible* GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const;
/**
* Return whether the given DOM node has an accessible or not.
*/

View File

@ -40,6 +40,7 @@ if CONFIG['MOZ_ENABLE_GTK']:
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
LOCAL_INCLUDES += [
'../windows/ia2',
'../windows/msaa',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':

View File

@ -25,7 +25,7 @@ inline Accessible*
sdnAccessible::GetAccessible() const
{
DocAccessible* document = GetDocument();
return document ? document->GetAccessible(mNode) : nullptr;
return document ? document->GetAccessibleEvenIfNotInMap(mNode) : nullptr;
}
} // namespace a11y