From 0a304aba4a7aa2c53fc91c70f4df284d6ed180c4 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Wed, 31 Jul 2013 10:47:39 -0400 Subject: [PATCH] Bug 889512 - no focus event for google's moving textbox, r=tbsaunde --- accessible/src/generic/DocAccessible.cpp | 34 +++++++++++++++--------- accessible/src/generic/DocAccessible.h | 7 ++++- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/accessible/src/generic/DocAccessible.cpp b/accessible/src/generic/DocAccessible.cpp index afbb27d21cc0..d358e86daf0e 100644 --- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -1830,10 +1830,16 @@ DocAccessible::UpdateTreeInternal(Accessible* aChild, bool aIsInsert, { uint32_t updateFlags = eAccessible; + // If a focused node has been shown then it could mean its frame was recreated + // while the node stays focused and we need to fire focus event on + // the accessible we just created. If the queue contains a focus event for + // this node already then it will be suppressed by this one. + Accessible* focusedAcc = nullptr; + nsINode* node = aChild->GetNode(); if (aIsInsert) { // Create accessible tree for shown accessible. - CacheChildrenInSubtree(aChild); + CacheChildrenInSubtree(aChild, &focusedAcc); } else { // Fire menupopup end event before hide event if a menu goes away. @@ -1870,16 +1876,6 @@ DocAccessible::UpdateTreeInternal(Accessible* aChild, bool aIsInsert, updateFlags = eAlertAccessible; FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aChild); } - - // If focused node has been shown then it means its frame was recreated - // while it's focused. Fire focus event on new focused accessible. If - // the queue contains focus event for this node then it's suppressed by - // this one. - // XXX: do we really want to send focus to focused DOM node not taking into - // account active item? - if (FocusMgr()->IsFocused(aChild)) - FocusMgr()->DispatchFocusEvent(this, aChild); - } else { // Update the tree for content removal. // The accessible parent may differ from container accessible if @@ -1893,12 +1889,24 @@ DocAccessible::UpdateTreeInternal(Accessible* aChild, bool aIsInsert, UncacheChildrenInSubtree(aChild); } + // XXX: do we really want to send focus to focused DOM node not taking into + // account active item? + if (focusedAcc) + FocusMgr()->DispatchFocusEvent(this, focusedAcc); + return updateFlags; } void -DocAccessible::CacheChildrenInSubtree(Accessible* aRoot) +DocAccessible::CacheChildrenInSubtree(Accessible* aRoot, + Accessible** aFocusedAcc) { + // If the accessible is focused then report a focus event after all related + // mutation events. + if (aFocusedAcc && !*aFocusedAcc && + FocusMgr()->HasDOMFocus(aRoot->GetContent())) + *aFocusedAcc = aRoot; + aRoot->EnsureChildren(); // Make sure we create accessible tree defined in DOM only, i.e. if accessible @@ -1910,7 +1918,7 @@ DocAccessible::CacheChildrenInSubtree(Accessible* aRoot) NS_ASSERTION(child, "Illicit tree change while tree is created!"); // Don't cross document boundaries. if (child && child->IsContent()) - CacheChildrenInSubtree(child); + CacheChildrenInSubtree(child, aFocusedAcc); } // Fire document load complete on ARIA documents. diff --git a/accessible/src/generic/DocAccessible.h b/accessible/src/generic/DocAccessible.h index a4443b21ea1b..73446d2f5388 100644 --- a/accessible/src/generic/DocAccessible.h +++ b/accessible/src/generic/DocAccessible.h @@ -449,8 +449,13 @@ protected: /** * Create accessible tree. + * + * @param aRoot [in] a root of subtree to create + * @param aFocusedAcc [in, optional] a focused accessible under created + * subtree if any */ - void CacheChildrenInSubtree(Accessible* aRoot); + void CacheChildrenInSubtree(Accessible* aRoot, + Accessible** aFocusedAcc = nullptr); /** * Remove accessibles in subtree from node to accessible map.