From 33d406ae8a410fc39386a40246b485488c2c7ef3 Mon Sep 17 00:00:00 2001 From: "Evan.Yan%Sun.COM" Date: Fri, 16 Nov 2007 09:12:59 +0000 Subject: [PATCH] back out patch of bug 385070 which broke accessible tree, to make nightly build safe git-svn-id: svn://10.0.0.236/trunk@239531 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/accessible/src/base/nsAccessNode.cpp | 17 --- .../accessible/src/base/nsDocAccessible.cpp | 112 +++++++++--------- mozilla/layout/forms/nsFileControlFrame.cpp | 9 +- 3 files changed, 56 insertions(+), 82 deletions(-) diff --git a/mozilla/accessible/src/base/nsAccessNode.cpp b/mozilla/accessible/src/base/nsAccessNode.cpp index 6dcb0aa1ccd..a9361e317bc 100755 --- a/mozilla/accessible/src/base/nsAccessNode.cpp +++ b/mozilla/accessible/src/base/nsAccessNode.cpp @@ -175,29 +175,12 @@ NS_IMETHODIMP nsAccessNode::Init() return NS_ERROR_FAILURE; } } - void* uniqueID; GetUniqueID(&uniqueID); nsCOMPtr privateDocAccessible = do_QueryInterface(docAccessible); NS_ASSERTION(privateDocAccessible, "No private docaccessible for docaccessible"); privateDocAccessible->CacheAccessNode(uniqueID, this); - - // Make sure an ancestor in real content is cached - // so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when - // the root node goes away - nsCOMPtr content = do_QueryInterface(mDOMNode); - if (content && (content->IsNativeAnonymous() || - content->GetBindingParent())) { - // Specific examples of where this is used: and - nsCOMPtr parentAccessible; - docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE, getter_AddRefs(parentAccessible)); - if (parentAccessible) { - PRInt32 childCountUnused; - parentAccessible->GetChildCount(&childCountUnused); - } - } - #ifdef DEBUG_A11Y mIsInitialized = PR_TRUE; #endif diff --git a/mozilla/accessible/src/base/nsDocAccessible.cpp b/mozilla/accessible/src/base/nsDocAccessible.cpp index 7567ed5b172..6f4bf7e3de6 100644 --- a/mozilla/accessible/src/base/nsDocAccessible.cpp +++ b/mozilla/accessible/src/base/nsDocAccessible.cpp @@ -1666,75 +1666,71 @@ void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure) void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode) { + nsCOMPtr iterNode(aStartNode), nextNode; nsCOMPtr accessNode; - GetCachedAccessNode(aStartNode, getter_AddRefs(accessNode)); - nsCOMPtr nextNode, iterNode; - // Shut down accessible subtree, which may have been created for - // anonymous content subtree - nsCOMPtr accessible(do_QueryInterface(accessNode)); - if (accessible) { - nsCOMPtr privateAccessible = do_QueryInterface(accessible); - NS_ASSERTION(privateAccessible, "No nsPIAccessible for nsIAccessible"); - nsCOMPtr childAccessible; - privateAccessible->GetCachedFirstChild(getter_AddRefs(childAccessible)); - if (childAccessible) { // Has cached children that need to be shut down - nsCOMPtr children; - // use GetChildren() to fetch children at one time, instead of using - // GetNextSibling(), because after we shutdown the first child, - // mNextSibling will be set null. - accessible->GetChildren(getter_AddRefs(children)); + do { + GetCachedAccessNode(iterNode, getter_AddRefs(accessNode)); + if (accessNode) { + // Accessibles that implement their own subtrees, + // like html combo boxes and xul trees must shutdown all of their own + // children when they override Shutdown() - PRUint32 childCount; - children->GetLength(&childCount); - for (PRUint32 index = 0; index < childCount; index++) { - nsCOMPtr childAccessNode; - children->QueryElementAt(index, NS_GET_IID(nsIAccessNode), - getter_AddRefs(childAccessNode)); - childAccessNode->GetDOMNode(getter_AddRefs(iterNode)); - nsCOMPtr iterContent = do_QueryInterface(iterNode); - if (iterContent && (iterContent->IsNativeAnonymous() || - iterContent->GetBindingParent())) { - // GetBindingParent() check is a perf win -- make sure we don't - // shut down the same subtree twice since we'll reach non-anon content via - // DOM traversal later in this method - RefreshNodes(iterNode); + // Don't shutdown our doc object! + if (accessNode != static_cast(this)) { + + nsCOMPtr accessible(do_QueryInterface(accessNode)); + if (accessible) { + // Fire menupopupend events for menu popups that go away + PRUint32 role = Role(accessible); + if (role == nsIAccessibleRole::ROLE_MENUPOPUP) { + nsCOMPtr domNode; + accessNode->GetDOMNode(getter_AddRefs(domNode)); + nsCOMPtr popup(do_QueryInterface(domNode)); + if (!popup) { + // Popup elements already fire these via DOMMenuInactive + // handling in nsRootAccessible::HandleEvent + nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, + accessible); + } + } } + + void *uniqueID; + accessNode->GetUniqueID(&uniqueID); + nsCOMPtr privateAccessNode(do_QueryInterface(accessNode)); + privateAccessNode->Shutdown(); + // Remove from hash table as well + mAccessNodeCache.Remove(uniqueID); } } - // Shutdown ordinary content subtree as well -- there may be - // access node children which are not full accessible objects - aStartNode->GetFirstChild(getter_AddRefs(nextNode)); - while (nextNode) { - nextNode.swap(iterNode); - RefreshNodes(iterNode); - iterNode->GetNextSibling(getter_AddRefs(nextNode)); + iterNode->GetFirstChild(getter_AddRefs(nextNode)); + if (nextNode) { + iterNode = nextNode; + continue; } - if (accessNode && accessNode != static_cast(this)) { - // Fire menupopup end if a menu goes away - PRUint32 role = Role(accessible); - if (role == nsIAccessibleRole::ROLE_MENUPOPUP) { - nsCOMPtr domNode; - accessNode->GetDOMNode(getter_AddRefs(domNode)); - nsCOMPtr popup(do_QueryInterface(domNode)); - if (!popup) { - // Popup elements already fire these via DOMMenuInactive - // handling in nsRootAccessible::HandleEvent - nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, - accessible); - } - } + if (iterNode == aStartNode) + break; + iterNode->GetNextSibling(getter_AddRefs(nextNode)); + if (nextNode) { + iterNode = nextNode; + continue; } - // Shut down the actual accessible or access node - void *uniqueID; - accessNode->GetUniqueID(&uniqueID); - nsCOMPtr privateAccessNode(do_QueryInterface(accessNode)); - privateAccessNode->Shutdown(); - // Remove from hash table as well - mAccessNodeCache.Remove(uniqueID); + + do { + iterNode->GetParentNode(getter_AddRefs(nextNode)); + if (!nextNode || nextNode == aStartNode) { + return; + } + nextNode->GetNextSibling(getter_AddRefs(iterNode)); + if (iterNode) + break; + iterNode = nextNode; + } while (PR_TRUE); } + while (iterNode && iterNode != aStartNode); } NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index 545db00e39a..f54926eba91 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -603,13 +603,8 @@ nsFileControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, #ifdef ACCESSIBILITY NS_IMETHODIMP nsFileControlFrame::GetAccessible(nsIAccessible** aAccessible) { - // Accessible object exists just to hold onto its children, for later shutdown - nsCOMPtr accService = do_GetService("@mozilla.org/accessibilityService;1"); - - if (accService) { - return accService->CreateHTMLGenericAccessible(static_cast(this), aAccessible); - } - + // No accessible object for file control, only for child text frame and button + *aAccessible = nsnull; return NS_ERROR_FAILURE; } #endif