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
Родитель f5ba183f67
Коммит cd3950ff3f
7 изменённых файлов: 51 добавлений и 39 удалений

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

@ -7,11 +7,9 @@
#include "Accessible-inl.h" #include "Accessible-inl.h"
#include "AccIterator.h" #include "AccIterator.h"
#include "DocAccessible-inl.h" #include "DocAccessible-inl.h"
#include "HTMLImageMapAccessible.h"
#include "nsAccessibilityService.h" #include "nsAccessibilityService.h"
#include "nsAccUtils.h" #include "nsAccUtils.h"
#include "nsEventShell.h" #include "nsEventShell.h"
#include "nsImageFrame.h"
#include "Role.h" #include "Role.h"
#include "nsEventStateManager.h" #include "nsEventStateManager.h"
@ -39,7 +37,7 @@ FocusManager::FocusedAccessible() const
if (focusedNode) { if (focusedNode) {
DocAccessible* doc = DocAccessible* doc =
GetAccService()->GetDocAccessible(focusedNode->OwnerDoc()); GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
return doc ? GetFocusableAccessibleFor(focusedNode, doc) : nullptr; return doc ? doc->GetAccessibleEvenIfNotInMapOrContainer(focusedNode) : nullptr;
} }
return nullptr; return nullptr;
@ -63,7 +61,7 @@ FocusManager::IsFocused(const Accessible* aAccessible) const
DocAccessible* doc = DocAccessible* doc =
GetAccService()->GetDocAccessible(focusedNode->OwnerDoc()); GetAccService()->GetDocAccessible(focusedNode->OwnerDoc());
return aAccessible == return aAccessible ==
(doc ? GetFocusableAccessibleFor(focusedNode, doc) : nullptr); (doc ? doc->GetAccessibleEvenIfNotInMapOrContainer(focusedNode) : nullptr);
} }
} }
return false; return false;
@ -243,7 +241,7 @@ FocusManager::ProcessDOMFocus(nsINode* aTarget)
DocAccessible* document = DocAccessible* document =
GetAccService()->GetDocAccessible(aTarget->OwnerDoc()); GetAccService()->GetDocAccessible(aTarget->OwnerDoc());
Accessible* target = GetFocusableAccessibleFor(aTarget, document); Accessible* target = document->GetAccessibleEvenIfNotInMapOrContainer(aTarget);
if (target && document) { if (target && document) {
// Check if still focused. Otherwise we can end up with storing the active // Check if still focused. Otherwise we can end up with storing the active
// item for control that isn't focused anymore. // item for control that isn't focused anymore.
@ -251,7 +249,8 @@ FocusManager::ProcessDOMFocus(nsINode* aTarget)
if (!focusedNode) if (!focusedNode)
return; return;
Accessible* DOMFocus = GetFocusableAccessibleFor(focusedNode, document); Accessible* DOMFocus =
document->GetAccessibleEvenIfNotInMapOrContainer(focusedNode);
if (target != DOMFocus) if (target != DOMFocus)
return; return;
@ -283,7 +282,8 @@ FocusManager::ProcessFocusEvent(AccEvent* aEvent)
if (!focusedNode) if (!focusedNode)
return; return;
Accessible* DOMFocus = GetFocusableAccessibleFor(focusedNode, document); Accessible* DOMFocus =
document->GetAccessibleEvenIfNotInMapOrContainer(focusedNode);
if (target != DOMFocus) if (target != DOMFocus)
return; return;
@ -408,28 +408,3 @@ FocusManager::FocusedDOMDocument() const
nsINode* focusedNode = FocusedDOMNode(); nsINode* focusedNode = FocusedDOMNode();
return focusedNode ? focusedNode->OwnerDoc() : nullptr; 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);
}

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

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

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

@ -116,6 +116,13 @@ DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
FireDelayedEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, 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 a11y
} // namespace mozilla } // namespace mozilla

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

@ -6,6 +6,7 @@
#include "Accessible-inl.h" #include "Accessible-inl.h"
#include "AccIterator.h" #include "AccIterator.h"
#include "DocAccessible-inl.h" #include "DocAccessible-inl.h"
#include "HTMLImageMapAccessible.h"
#include "nsAccCache.h" #include "nsAccCache.h"
#include "nsAccessiblePivot.h" #include "nsAccessiblePivot.h"
#include "nsAccUtils.h" #include "nsAccUtils.h"
@ -30,6 +31,7 @@
#include "nsEventStateManager.h" #include "nsEventStateManager.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
#include "nsImageFrame.h"
#include "nsIPersistentProperties2.h" #include "nsIPersistentProperties2.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
@ -1435,6 +1437,30 @@ DocAccessible::ProcessInvalidationList()
mInvalidationList.Clear(); 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 // Accessible protected

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

@ -211,6 +211,15 @@ public:
*/ */
Accessible* GetAccessible(nsINode* aNode) const; 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. * Return whether the given DOM node has an accessible or not.
*/ */

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

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

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

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