Bug 1613634 - Reduce calls to CoalesceMutationEvents r=Jamie,eeejay

When adding a new accessibility event to NotificationController, we
check to see if the event should be suppressed. This is a time-memory
tradeoff; since we check every event before dispatching them, the
correctness should not be impacted regardless of whether we always
append events. This change takes the time required from O(mn^2) where m
is the average depth of an event's parent tree and n is the number of
events, to O(mn).

Differential Revision: https://phabricator.services.mozilla.com/D135159
This commit is contained in:
Neia Finch 2022-01-07 18:48:37 +00:00
parent 8ce2b9a19e
commit b4dbcf262c
2 changed files with 33 additions and 25 deletions

View File

@ -116,6 +116,31 @@ EventTree* NotificationController::QueueMutation(LocalAccessible* aContainer) {
return tree;
}
void NotificationController::CoalesceHideEvent(AccHideEvent* aHideEvent) {
LocalAccessible* parent = aHideEvent->LocalParent();
while (parent) {
if (parent->IsDoc()) {
break;
}
if (parent->HideEventTarget()) {
DropMutationEvent(aHideEvent);
break;
}
if (parent->ShowEventTarget()) {
AccShowEvent* showEvent =
downcast_accEvent(mMutationMap.GetEvent(parent, EventMap::ShowEvent));
if (showEvent->EventGeneration() < aHideEvent->EventGeneration()) {
DropMutationEvent(aHideEvent);
break;
}
}
parent = parent->LocalParent();
}
}
bool NotificationController::QueueMutationEvent(AccTreeMutationEvent* aEvent) {
if (aEvent->GetEventType() == nsIAccessibleEvent::EVENT_HIDE) {
// We have to allow there to be a hide and then a show event for a target
@ -157,10 +182,9 @@ bool NotificationController::QueueMutationEvent(AccTreeMutationEvent* aEvent) {
mMutationMap.PutEvent(aEvent);
// Because we could be hiding the target of a show event we need to get rid
// of any such events. It may be possible to do less than coallesce all
// events, however that is easiest.
// of any such events.
if (aEvent->GetEventType() == nsIAccessibleEvent::EVENT_HIDE) {
CoalesceMutationEvents();
CoalesceHideEvent(downcast_accEvent(aEvent));
// mLastMutationEvent will point to something other than aEvent if and only
// if aEvent was just coalesced away. In that case a parent accessible
@ -402,28 +426,7 @@ void NotificationController::CoalesceMutationEvents() {
"mutation event list has an invalid event");
AccHideEvent* hideEvent = downcast_accEvent(event);
LocalAccessible* parent = hideEvent->LocalParent();
while (parent) {
if (parent->IsDoc()) {
break;
}
if (parent->HideEventTarget()) {
DropMutationEvent(event);
break;
}
if (parent->ShowEventTarget()) {
AccShowEvent* showEvent = downcast_accEvent(
mMutationMap.GetEvent(parent, EventMap::ShowEvent));
if (showEvent->EventGeneration() < hideEvent->EventGeneration()) {
DropMutationEvent(hideEvent);
break;
}
}
parent = parent->LocalParent();
}
CoalesceHideEvent(hideEvent);
}
event = nextEvent;

View File

@ -317,6 +317,11 @@ class NotificationController final : public EventQueue,
}
private:
/**
* Remove a specific hide event if it should not be propagated.
*/
void CoalesceHideEvent(AccHideEvent* aHideEvent);
/**
* get rid of a mutation event that is no longer necessary.
*/