From 66873ec71c81755c596563d972d2a90ceed9c424 Mon Sep 17 00:00:00 2001 From: "aaronleventhal%moonset.net" Date: Thu, 15 Nov 2007 15:33:52 +0000 Subject: [PATCH] Bug 398021. Crash [@ nsAccessible::GetFinalRole] with moving options and using visibility: hidden. r=surkov, a=schrep git-svn-id: svn://10.0.0.236/trunk@239458 18797224-902f-48f8-a5cc-f745e15eee43 --- .../accessible/src/base/nsDocAccessible.cpp | 28 ++++++++++++++----- mozilla/accessible/src/base/nsDocAccessible.h | 8 ++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/mozilla/accessible/src/base/nsDocAccessible.cpp b/mozilla/accessible/src/base/nsDocAccessible.cpp index 208c7de8dbf..5f1b0825c36 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.cpp +++ b/mozilla/accessible/src/base/nsDocAccessible.cpp @@ -1806,6 +1806,10 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, // event for it GetAccService()->GetAttachedAccessibleFor(childNode, getter_AddRefs(childAccessible)); + if (childAccessible) { + // New accessible created -- to make sure to adopt the children from the old parent. + AdoptChildren(childAccessible); + } } #ifdef DEBUG_A11Y @@ -1933,6 +1937,13 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, return NS_OK; } +void nsDocAccessible::AdoptChildren(nsIAccessible *aAccessible) +{ + PRInt32 childCountUnused; + // Force CacheChildren() + aAccessible->GetChildCount(&childCountUnused); +} + NS_IMETHODIMP nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode, PRBool aCanCreate, @@ -1959,14 +1970,17 @@ nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode, if (NS_SUCCEEDED(accService->GetRelevantContentNodeFor(currentNode, getter_AddRefs(relevantNode))) && relevantNode) { currentNode = relevantNode; } - if (aCanCreate) { - accService->GetAccessibleInWeakShell(currentNode, mWeakShell, aAccessible); + // Try cached accessible + nsCOMPtr accessNode; + GetCachedAccessNode(currentNode, getter_AddRefs(accessNode)); // AddRefs + if (accessNode) { + CallQueryInterface(accessNode, aAccessible); // AddRefs } - else { // Only return cached accessibles, don't create anything - nsCOMPtr accessNode; - GetCachedAccessNode(currentNode, getter_AddRefs(accessNode)); // AddRefs - if (accessNode) { - CallQueryInterface(accessNode, aAccessible); // AddRefs + if (!*aAccessible && aCanCreate) { + accService->GetAccessibleInWeakShell(currentNode, mWeakShell, aAccessible); + if (*aAccessible) { + // New accessible created -- to make sure to adopt the children from the old parent. + AdoptChildren(*aAccessible); } } } while (!*aAccessible); diff --git a/mozilla/accessible/src/base/nsDocAccessible.h b/mozilla/accessible/src/base/nsDocAccessible.h index 20d30252e51..812cc8f8c74 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.h +++ b/mozilla/accessible/src/base/nsDocAccessible.h @@ -204,6 +204,14 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap, nsresult FireShowHideEvents(nsIDOMNode *aDOMNode, PRUint32 aEventType, PRBool aDelay, PRBool aForceIsFromUserInput); + /** + * For a new accessible that is created because of a DOM mutation, + * make sure that any children it has, which were already children + * of the parent should be assigned to it + * @param aAccessible The new accessible + */ + void AdoptChildren(nsIAccessible *aAccessible); + nsAccessNodeHashtable mAccessNodeCache; void *mWnd; nsCOMPtr mDocument;