From 446c271cb683e58db03dd1c6b2e4fb941f0dc577 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Mon, 25 Apr 2016 09:10:41 -0400 Subject: [PATCH] Bug 1262420 - split updateTreeInternal for removals and insertions, part 2, r=yzen --- accessible/generic/DocAccessible-inl.h | 19 ++++++ accessible/generic/DocAccessible.cpp | 89 ++++++++------------------ accessible/generic/DocAccessible.h | 14 +--- 3 files changed, 49 insertions(+), 73 deletions(-) diff --git a/accessible/generic/DocAccessible-inl.h b/accessible/generic/DocAccessible-inl.h index 44a4953d049e..cf7e0758de16 100644 --- a/accessible/generic/DocAccessible-inl.h +++ b/accessible/generic/DocAccessible-inl.h @@ -160,6 +160,25 @@ DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const return acc ? acc : GetContainerAccessible(aNode); } +inline void +DocAccessible::CreateSubtree(Accessible* aChild) +{ + // 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; + CacheChildrenInSubtree(aChild, &focusedAcc); + + // XXX: do we really want to send focus to focused DOM node not taking into + // account active item? + if (focusedAcc) { + FocusMgr()->DispatchFocusEvent(this, focusedAcc); + SelectionMgr()-> + SetControlSelectionListener(focusedAcc->GetNode()->AsElement()); + } +} + } // namespace a11y } // namespace mozilla diff --git a/accessible/generic/DocAccessible.cpp b/accessible/generic/DocAccessible.cpp index 397a15865013..131a0b532e87 100644 --- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -1762,7 +1762,6 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer, aContainer); #endif - uint32_t updateFlags = 0; TreeMutation mt(aContainer); do { Accessible* parent = iter.Child()->Parent(); @@ -1791,7 +1790,7 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer, #endif mt.AfterInsertion(iter.Child()); - updateFlags |= UpdateTreeInternal(iter.Child(), true); + CreateSubtree(iter.Child()); continue; } @@ -1805,7 +1804,7 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer, aContainer); #endif - FireEventsOnInsertion(aContainer, updateFlags); + FireEventsOnInsertion(aContainer); } void @@ -1828,25 +1827,18 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer, nsIContent* aNode) mt.AfterInsertion(child); mt.Done(); - uint32_t flags = UpdateTreeInternal(child, true); - FireEventsOnInsertion(aContainer, flags); + CreateSubtree(child); + FireEventsOnInsertion(aContainer); } } } void -DocAccessible::FireEventsOnInsertion(Accessible* aContainer, - uint32_t aUpdateFlags) +DocAccessible::FireEventsOnInsertion(Accessible* aContainer) { - // Content insertion did not cause an accessible tree change. - if (aUpdateFlags == eNoAccessible) { - return; - } - // Check to see if change occurred inside an alert, and fire an EVENT_ALERT // if it did. - if (!(aUpdateFlags & eAlertAccessible) && - (aContainer->IsAlert() || aContainer->IsInsideAlert())) { + if (aContainer->IsAlert() || aContainer->IsInsideAlert()) { Accessible* ancestor = aContainer; do { if (ancestor->IsAlert()) { @@ -1897,45 +1889,6 @@ DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNod mt.Done(); } -uint32_t -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; - - if (aIsInsert) { - // Create accessible tree for shown accessible. - CacheChildrenInSubtree(aChild, &focusedAcc); - } - - if (aIsInsert) { - roles::Role ariaRole = aChild->ARIARole(); - if (ariaRole == roles::MENUPOPUP) { - // 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); - } - } - - // XXX: do we really want to send focus to focused DOM node not taking into - // account active item? - if (focusedAcc) { - FocusMgr()->DispatchFocusEvent(this, focusedAcc); - SelectionMgr()->SetControlSelectionListener(focusedAcc->GetNode()->AsElement()); - } - - return updateFlags; -} - bool DocAccessible::RelocateARIAOwnedIfNeeded(nsIContent* aElement) { @@ -2035,8 +1988,8 @@ DocAccessible::DoARIAOwnsRelocation(Accessible* aOwner) insertIdx = child->IndexInParent() + 1; arrayIdx++; - uint32_t flags = UpdateTreeInternal(child, true); - FireEventsOnInsertion(aOwner, flags); + CreateSubtree(child); + FireEventsOnInsertion(aOwner); } } continue; @@ -2223,12 +2176,26 @@ DocAccessible::CacheChildrenInSubtree(Accessible* aRoot, mt.Done(); } - // 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); + // Fire events for ARIA elements. + if (!aRoot->HasARIARole()) { + return; + } + + roles::Role role = aRoot->ARIARole(); + if (role == roles::MENUPOPUP) { + FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aRoot); + return; + } + + if (role == roles::ALERT) { + FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aRoot); + return; + } + + // XXX: we should delay document load complete event if the ARIA document + // has aria-busy. + if (!aRoot->IsDoc() && (role == roles::DIALOG || role == roles::DOCUMENT)) { + FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot); } } diff --git a/accessible/generic/DocAccessible.h b/accessible/generic/DocAccessible.h index 5f03bb208311..1f08dde7ad82 100644 --- a/accessible/generic/DocAccessible.h +++ b/accessible/generic/DocAccessible.h @@ -187,7 +187,7 @@ public: */ void FireDelayedEvent(AccEvent* aEvent); void FireDelayedEvent(uint32_t aEventType, Accessible* aTarget); - void FireEventsOnInsertion(Accessible* aContainer, uint32_t aUpdateFlags); + void FireEventsOnInsertion(Accessible* aContainer); /** * Fire value change event on the given accessible if applicable. @@ -516,17 +516,6 @@ protected: */ void UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNode); - /** - * Helper for UpdateTreeOn methods. Go down to DOM subtree and updates - * accessible tree. Return one of these flags. - */ - enum EUpdateTreeFlags { - eNoAccessible = 0, - eAccessible = 1, - eAlertAccessible = 2 - }; - uint32_t UpdateTreeInternal(Accessible* aChild, bool aIsInsert); - /** * Validates all aria-owns connections and updates the tree accordingly. */ @@ -555,6 +544,7 @@ protected: */ void CacheChildrenInSubtree(Accessible* aRoot, Accessible** aFocusedAcc = nullptr); + void CreateSubtree(Accessible* aRoot); /** * Remove accessibles in subtree from node to accessible map.