mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 359924. Crash when entering characters in XUL textfields, such as find field. r=nian.liu, r=surkov
This commit is contained in:
parent
196aba5515
commit
076279d46f
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user