Bug 359924. Crash when entering characters in XUL textfields, such as find field. r=nian.liu, r=surkov

This commit is contained in:
aaronleventhal%moonset.net 2006-12-12 19:04:25 +00:00
parent 196aba5515
commit 076279d46f
5 changed files with 34 additions and 78 deletions

View File

@ -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<nsIAccessibleDocument> docAccessible(GetDocAccessible());
NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
return NS_OK;
return docAccessible->GetAccessibleInParentChain(mDOMNode, aParent);
}
NS_IMETHODIMP nsAccessible::GetCachedParent(nsIAccessible ** aParent)

View File

@ -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 <children/> 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<nsIContent> childContent(do_QueryInterface(aChildNode));
nsCOMPtr<nsIContent> bindingParentContent;
nsCOMPtr<nsIDOMNode> 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<nsIContent> 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<nsIDOMNode> 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;

View File

@ -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();

View File

@ -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<nsIAccessible> accessible;
nsCOMPtr<nsIAccessibilityService> 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<nsIDOMNode> focusNode;
domSel->GetFocusNode(getter_AddRefs(focusNode));
@ -188,9 +189,14 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns
}
nsCOMPtr<nsIAccessibleText> textAcc;
while (focusNode) {
// Make sure to get the correct starting node for selection events inside XBL content trees
nsCOMPtr<nsIDOMNode> relevantNode;
if (NS_SUCCEEDED(accService->GetRelevantContentNodeFor(focusNode, getter_AddRefs(relevantNode))) && relevantNode) {
focusNode = relevantNode;
}
nsCOMPtr<nsIContent> 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) {

View File

@ -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<nsIAccessible> accessible = do_QueryInterface(*aAccessNode);
if (accessible) {
nsCOMPtr<nsPIAccessible> privateAccessible = do_QueryInterface(accessible);
if (privateAccessible) {
nsCOMPtr<nsIAccessible> parent;
accessible->GetParent(getter_AddRefs(parent));
privateAccessible->GetCachedParent(getter_AddRefs(parent));
nsCOMPtr<nsPIAccessible> 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<nsPIAccessible> 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<nsIDOMNode> currentNode(aNode), parentNode;
nsCOMPtr<nsIAccessNode> accessNode;
do {
GetCachedAccessNode(currentNode, getter_AddRefs(accessNode));
nsCOMPtr<nsIAccessible> 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<nsIDOMNode> relevantNode;
if (NS_SUCCEEDED(accService->GetRelevantContentNodeFor(currentNode, getter_AddRefs(relevantNode))) && relevantNode) {
currentNode = relevantNode;
}
accService->GetAccessibleInWeakShell(currentNode, mWeakShell, aAccessible);
} while (!*aAccessible);
return NS_OK;
}