From 5e9863adb914777f5ba89e2b7361e492dfdca387 Mon Sep 17 00:00:00 2001 From: "aaronleventhal%moonset.net" Date: Tue, 12 Dec 2006 19:04:25 +0000 Subject: [PATCH] Bug 359924. Crash when entering characters in XUL textfields, such as find field. r=nian.liu, r=surkov --- accessible/src/base/nsAccessible.cpp | 11 ++--- .../src/base/nsAccessibleTreeWalker.cpp | 47 ------------------- accessible/src/base/nsAccessibleTreeWalker.h | 2 - accessible/src/base/nsCaretAccessible.cpp | 12 +++-- accessible/src/base/nsDocAccessible.cpp | 40 +++++++++------- 5 files changed, 34 insertions(+), 78 deletions(-) diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 8e9cf7ae98d..abe0994787b 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -534,15 +534,10 @@ NS_IMETHODIMP nsAccessible::GetParent(nsIAccessible ** aParent) return rv; } - // Last argument of PR_TRUE indicates to walk anonymous content - nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE); - if (NS_SUCCEEDED(walker.GetParent())) { - *aParent = walker.mState.accessible; - SetParent(*aParent); // Cache it, unless perhaps accessible class overrides SetParent - NS_ADDREF(*aParent); - } + nsCOMPtr docAccessible(GetDocAccessible()); + NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE); - return NS_OK; + return docAccessible->GetAccessibleInParentChain(mDOMNode, aParent); } NS_IMETHODIMP nsAccessible::GetCachedParent(nsIAccessible ** aParent) diff --git a/accessible/src/base/nsAccessibleTreeWalker.cpp b/accessible/src/base/nsAccessibleTreeWalker.cpp index 560d74beaf7..1856bc0b289 100755 --- a/accessible/src/base/nsAccessibleTreeWalker.cpp +++ b/accessible/src/base/nsAccessibleTreeWalker.cpp @@ -73,37 +73,6 @@ nsAccessibleTreeWalker::~nsAccessibleTreeWalker() MOZ_COUNT_DTOR(nsAccessibleTreeWalker); } -// GetFullParentNode gets the parent node in the deep tree -// This might not be the DOM parent in cases where was used in an XBL binding. -// In that case, this returns the parent in the XBL'ized tree. - -NS_IMETHODIMP nsAccessibleTreeWalker::GetFullTreeParentNode(nsIDOMNode *aChildNode, nsIDOMNode **aParentNodeOut) -{ - nsCOMPtr childContent(do_QueryInterface(aChildNode)); - nsCOMPtr bindingParentContent; - nsCOMPtr parentNode; - - if (mState.prevState) - parentNode = mState.prevState->domNode; - else { - if (mBindingManager) { - mBindingManager->GetInsertionParent(childContent, getter_AddRefs(bindingParentContent)); - if (bindingParentContent) - parentNode = do_QueryInterface(bindingParentContent); - } - - if (!parentNode) - aChildNode->GetParentNode(getter_AddRefs(parentNode)); - } - - if (parentNode) { - *aParentNodeOut = parentNode; - NS_ADDREF(*aParentNodeOut); - return NS_OK; - } - return NS_ERROR_FAILURE; -} - void nsAccessibleTreeWalker::GetKids(nsIDOMNode *aParentNode) { nsCOMPtr parentContent(do_QueryInterface(aParentNode)); @@ -147,22 +116,6 @@ void nsAccessibleTreeWalker::GetKids(nsIDOMNode *aParentNode) mState.siblingList->Item(0 /* 0 == mState.siblingIndex */, getter_AddRefs(mState.domNode)); } -NS_IMETHODIMP nsAccessibleTreeWalker::GetParent() -{ - nsCOMPtr parent; - - while (NS_SUCCEEDED(GetFullTreeParentNode(mState.domNode, getter_AddRefs(parent)))) { - if (NS_FAILED(PopState())) { - mState.domNode = parent; - GetAccessible(); - } - if (mState.accessible) - return NS_OK; - } - - return NS_ERROR_FAILURE; -} - NS_IMETHODIMP nsAccessibleTreeWalker::PopState() { nsIFrame *frameParent = mState.frame? mState.frame->GetParent(): nsnull; diff --git a/accessible/src/base/nsAccessibleTreeWalker.h b/accessible/src/base/nsAccessibleTreeWalker.h index 79836edc724..fdc45041ac8 100755 --- a/accessible/src/base/nsAccessibleTreeWalker.h +++ b/accessible/src/base/nsAccessibleTreeWalker.h @@ -75,14 +75,12 @@ public: virtual ~nsAccessibleTreeWalker(); NS_IMETHOD GetNextSibling(); - NS_IMETHOD GetParent(); NS_IMETHOD GetFirstChild(); WalkState mState; protected: PRBool GetAccessible(); - NS_IMETHOD GetFullTreeParentNode(nsIDOMNode *aChildNode, nsIDOMNode **aParentNodeOut); void GetKids(nsIDOMNode *aParent); void ClearState(); diff --git a/accessible/src/base/nsCaretAccessible.cpp b/accessible/src/base/nsCaretAccessible.cpp index 4eb8c9c87e1..6a4830df5b0 100644 --- a/accessible/src/base/nsCaretAccessible.cpp +++ b/accessible/src/base/nsCaretAccessible.cpp @@ -179,7 +179,8 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns // Get first nnsIAccessibleText in parent chain and fire caret-move, selection-change event for it nsCOMPtr accessible; - nsCOMPtr accService(do_GetService("@mozilla.org/accessibilityService;1")); + nsIAccessibilityService *accService = GetAccService(); + NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE); // Get accessible from selection's focus node or its parent nsCOMPtr focusNode; domSel->GetFocusNode(getter_AddRefs(focusNode)); @@ -188,9 +189,14 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns } nsCOMPtr textAcc; while (focusNode) { + // Make sure to get the correct starting node for selection events inside XBL content trees + nsCOMPtr relevantNode; + if (NS_SUCCEEDED(accService->GetRelevantContentNodeFor(focusNode, getter_AddRefs(relevantNode))) && relevantNode) { + focusNode = relevantNode; + } + nsCOMPtr content = do_QueryInterface(focusNode); - if (!content || (PR_FALSE == content->IsNodeOfType(nsINode::eTEXT) && - PR_FALSE == content->IsNativeAnonymous())) { // Don't want anonymous nodes inside a form control + if (!content || !content->IsNodeOfType(nsINode::eTEXT)) { accService->GetAccessibleInShell(focusNode, presShell, getter_AddRefs(accessible)); textAcc = do_QueryInterface(accessible); if (textAcc) { diff --git a/accessible/src/base/nsDocAccessible.cpp b/accessible/src/base/nsDocAccessible.cpp index bd4b9ba1783..fdf7af23a85 100644 --- a/accessible/src/base/nsDocAccessible.cpp +++ b/accessible/src/base/nsDocAccessible.cpp @@ -401,9 +401,10 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod // when they were first cached, and no invalidation // ever corrected parent accessible's child cache. nsCOMPtr accessible = do_QueryInterface(*aAccessNode); - if (accessible) { + nsCOMPtr privateAccessible = do_QueryInterface(accessible); + if (privateAccessible) { nsCOMPtr parent; - accessible->GetParent(getter_AddRefs(parent)); + privateAccessible->GetCachedParent(getter_AddRefs(parent)); nsCOMPtr privateParent(do_QueryInterface(parent)); if (privateParent) { privateParent->TestChildCache(accessible); @@ -1236,7 +1237,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, containerAccessible = this; // At the root of UI or content } } - if (!containerAccessible && childAccessible) { + if (!containerAccessible && privateChildAccessible) { GetAccessibleInParentChain(childNode, getter_AddRefs(containerAccessible)); } nsCOMPtr privateContainerAccessible = @@ -1300,27 +1301,30 @@ NS_IMETHODIMP nsDocAccessible::GetAccessibleInParentChain(nsIDOMNode *aNode, nsIAccessible **aAccessible) { - // Find a pre-existing accessible in parent chain of DOM nodes, or return null + // Find accessible in parent chain of DOM nodes, or return null *aAccessible = nsnull; nsCOMPtr currentNode(aNode), parentNode; nsCOMPtr accessNode; - do { - GetCachedAccessNode(currentNode, getter_AddRefs(accessNode)); - nsCOMPtr accessible(do_QueryInterface(accessNode)); - if (accessible) { - if (currentNode == aNode) { - // We don't want an accessible for the passed-innode -- - // it must be from an ancestor - return accessible->GetParent(aAccessible); - } - NS_ADDREF(*aAccessible = accessible); - break; - } + nsIAccessibilityService *accService = GetAccService(); + NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE); + + do { currentNode->GetParentNode(getter_AddRefs(parentNode)); currentNode = parentNode; - } - while (currentNode); + if (!currentNode) { + NS_ADDREF_THIS(); + *aAccessible = this; + break; + } + + nsCOMPtr relevantNode; + if (NS_SUCCEEDED(accService->GetRelevantContentNodeFor(currentNode, getter_AddRefs(relevantNode))) && relevantNode) { + currentNode = relevantNode; + } + + accService->GetAccessibleInWeakShell(currentNode, mWeakShell, aAccessible); + } while (!*aAccessible); return NS_OK; }