diff --git a/accessible/ipc/DocAccessibleParent.h b/accessible/ipc/DocAccessibleParent.h index d28e0aa85963..ef1e9937d905 100644 --- a/accessible/ipc/DocAccessibleParent.h +++ b/accessible/ipc/DocAccessibleParent.h @@ -111,7 +111,7 @@ public: */ void RemoveChildDoc(DocAccessibleParent* aChildDoc) { - aChildDoc->Parent()->SetChildDoc(nullptr); + aChildDoc->Parent()->ClearChildDoc(aChildDoc); mChildDocs.RemoveElement(aChildDoc); aChildDoc->mParentDoc = nullptr; MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0); diff --git a/accessible/ipc/ProxyAccessibleBase.cpp b/accessible/ipc/ProxyAccessibleBase.cpp index 67b76b0b45ec..8f1a2b7eda2e 100644 --- a/accessible/ipc/ProxyAccessibleBase.cpp +++ b/accessible/ipc/ProxyAccessibleBase.cpp @@ -52,15 +52,31 @@ ProxyAccessibleBase::Shutdown() template void -ProxyAccessibleBase::SetChildDoc(DocAccessibleParent* aParent) +ProxyAccessibleBase::SetChildDoc(DocAccessibleParent* aChildDoc) { - if (aParent) { - MOZ_ASSERT(mChildren.IsEmpty()); - mChildren.AppendElement(aParent); - mOuterDoc = true; + // DocAccessibleParent::AddChildDoc tolerates replacing one document with + // another. We must reflect that here. + MOZ_ASSERT(aChildDoc); + MOZ_ASSERT(mChildren.Length() <= 1); + if (mChildren.IsEmpty()) { + mChildren.AppendElement(aChildDoc); } else { - MOZ_ASSERT(mChildren.Length() == 1); - mChildren.Clear(); + mChildren.ReplaceElementAt(0, aChildDoc); + } + mOuterDoc = true; +} + +template +void +ProxyAccessibleBase::ClearChildDoc(DocAccessibleParent* aChildDoc) +{ + MOZ_ASSERT(aChildDoc); + // This is possible if we're replacing one document with another: Doc 1 + // has not had a chance to remove itself, but was already replaced by Doc 2 + // in SetChildDoc(). This could result in two subsequent calls to + // ClearChildDoc() even though mChildren.Length() == 1. + MOZ_ASSERT(mChildren.Length() <= 1); + if (mChildren.RemoveElement(aChildDoc)) { mOuterDoc = false; } } diff --git a/accessible/ipc/ProxyAccessibleBase.h b/accessible/ipc/ProxyAccessibleBase.h index 62d6287b68a4..bea669ffac53 100644 --- a/accessible/ipc/ProxyAccessibleBase.h +++ b/accessible/ipc/ProxyAccessibleBase.h @@ -78,7 +78,8 @@ public: void Shutdown(); - void SetChildDoc(DocAccessibleParent*); + void SetChildDoc(DocAccessibleParent* aChildDoc); + void ClearChildDoc(DocAccessibleParent* aChildDoc); /** * Remove The given child.