mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1262420 - split updateTreeInternal for removals and insertions, part 2, r=yzen
This commit is contained in:
parent
e3f1739729
commit
446c271cb6
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user