author | Alexander Surkov <surkov.alexander@gmail.com> |
Wed, 31 Jul 2013 10:47:39 -0400 | |
changeset 140755 | 2e7ae68148a6c5fa6a5bc40be4f47479419e0ae2 |
parent 140754 | e27bd873b413e11e3c197b3b07f79d79899d4d22 |
child 140756 | e926c98528ffc3c7be844119bd5ddf9de72084ff |
push id | 31853 |
push user | surkov.alexander@gmail.com |
push date | Wed, 31 Jul 2013 14:48:03 +0000 |
treeherder | mozilla-inbound@2e7ae68148a6 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tbsaunde |
bugs | 889512 |
milestone | 25.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
accessible/src/generic/DocAccessible.cpp | file | annotate | diff | comparison | revisions | |
accessible/src/generic/DocAccessible.h | file | annotate | diff | comparison | revisions |
--- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -1825,20 +1825,26 @@ DocAccessible::UpdateTree(Accessible* aC } uint32_t DocAccessible::UpdateTreeInternal(Accessible* aChild, bool aIsInsert, AccReorderEvent* aReorderEvent) { 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. // XXX: We don't look into children of hidden subtree to find hiding // menupopup (as we did prior bug 570275) because we don't do that when // menu is showing (and that's impossible until bug 606924 is fixed). // Nevertheless we should do this at least because layout coalesces @@ -1865,57 +1871,59 @@ DocAccessible::UpdateTreeInternal(Access // Fire EVENT_MENUPOPUP_START if ARIA menu appears. FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild); } else if (ariaRole == roles::ALERT) { // Fire EVENT_ALERT if ARIA alert appears. 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 // the parent doesn't have own DOM node like list accessible for HTML // selects. Accessible* parent = aChild->Parent(); NS_ASSERTION(parent, "No accessible parent?!"); if (parent) parent->RemoveChild(aChild); 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 // provides specific tree (like XUL trees) then tree creation is handled by // this accessible. uint32_t count = aRoot->ContentChildCount(); for (uint32_t idx = 0; idx < count; idx++) { Accessible* child = aRoot->ContentChildAt(idx); 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. // XXX: we should delay an event if the ARIA document has aria-busy. if (aRoot->HasARIARole() && !aRoot->IsDoc()) { a11y::role role = aRoot->ARIARole(); if (role == roles::DIALOG || role == roles::DOCUMENT) FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot);
--- a/accessible/src/generic/DocAccessible.h +++ b/accessible/src/generic/DocAccessible.h @@ -444,18 +444,23 @@ protected: eAlertAccessible = 2 }; uint32_t UpdateTreeInternal(Accessible* aChild, bool aIsInsert, AccReorderEvent* aReorderEvent); /** * 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. */ void UncacheChildrenInSubtree(Accessible* aRoot); /** * Shutdown any cached accessible in the subtree.