mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-07 18:04:46 +00:00
Bug 1834718: Don't process a duplicate DocAccessible::ContentRemoved call for a DOM node we've already processed. r=morgan
ContentRemoved recursively walks both AllChildrenIterator and direct DOM children. In addition, we might get duplicate notifications from DOM and layout, plus PruneOrInsertSubtree might do a recursive walk and it too calls ContentRemoved. To avoid this duplicate processing, keep a set of removed DOM nodes on the DocAccessible which we clear after mutation events are processed. Differential Revision: https://phabricator.services.mozilla.com/D196707
This commit is contained in:
parent
6014a16340
commit
06eb0ca294
@ -995,7 +995,7 @@ void NotificationController::WillRefresh(mozilla::TimeStamp aTime) {
|
||||
}
|
||||
|
||||
if (mDocument) {
|
||||
mDocument->ClearMovedAccessibles();
|
||||
mDocument->ClearMutationData();
|
||||
}
|
||||
|
||||
if (ipc::ProcessChild::ExpectingShutdown()) {
|
||||
|
@ -1016,9 +1016,6 @@ void DocAccessible::ContentRemoved(nsIContent* aChildNode,
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
// This one and content removal notification from layout may result in
|
||||
// double processing of same subtrees. If it pops up in profiling, then
|
||||
// consider reusing a document node cache to reject these notifications early.
|
||||
ContentRemoved(aChildNode);
|
||||
}
|
||||
|
||||
@ -2176,6 +2173,10 @@ void DocAccessible::ContentRemoved(LocalAccessible* aChild) {
|
||||
}
|
||||
|
||||
void DocAccessible::ContentRemoved(nsIContent* aContentNode) {
|
||||
if (!mRemovedNodes.EnsureInserted(aContentNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If child node is not accessible then look for its accessible children.
|
||||
LocalAccessible* acc = GetAccessible(aContentNode);
|
||||
if (acc) {
|
||||
|
@ -538,12 +538,12 @@ class DocAccessible : public HyperTextAccessible,
|
||||
|
||||
/**
|
||||
* Called from NotificationController after all mutation events have been
|
||||
* processed to clear our data about Accessibles that were moved during this
|
||||
* tick.
|
||||
* processed to clear our data about mutations during this tick.
|
||||
*/
|
||||
void ClearMovedAccessibles() {
|
||||
void ClearMutationData() {
|
||||
mMovedAccessibles.Clear();
|
||||
mInsertedAccessibles.Clear();
|
||||
mRemovedNodes.Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -808,6 +808,9 @@ class DocAccessible : public HyperTextAccessible,
|
||||
// processes. This is needed to prevent insertions + moves of the same
|
||||
// Accessible in the same tick from being tracked as moves.
|
||||
nsTHashSet<RefPtr<LocalAccessible>> mInsertedAccessibles;
|
||||
// A set of DOM nodes removed during this tick. This avoids a lot of pointless
|
||||
// recursive DOM traversals.
|
||||
nsTHashSet<nsIContent*> mRemovedNodes;
|
||||
};
|
||||
|
||||
inline DocAccessible* LocalAccessible::AsDoc() {
|
||||
|
Loading…
Reference in New Issue
Block a user