From 66b4c351aa51da180e5b1288d5b8ed39bed1752f Mon Sep 17 00:00:00 2001 From: "aaronleventhal@moonset.net" Date: Fri, 8 Feb 2008 05:03:14 -0800 Subject: [PATCH] Bug 412878. Crashes when doc load finished. Possibly specific to framed pages. r=surkov, a=schrep. --- .../src/base/nsAccessibilityService.cpp | 54 +++++++++++-------- accessible/src/base/nsRootAccessible.cpp | 13 +++-- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 14cfb82f9ea..313e5437f92 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -180,25 +180,37 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress nsCOMPtr domDoc; domWindow->GetDocument(getter_AddRefs(domDoc)); - nsCOMPtr domDocRootNode(do_QueryInterface(domDoc)); - NS_ENSURE_TRUE(domDocRootNode, NS_ERROR_FAILURE); - - // Get the accessible for the new document. - // If it not created yet this will create it & cache it, as well as - // set up event listeners so that MSAA/ATK toolkit and internal - // accessibility events will get fired. - nsCOMPtr accessible; - GetAccessibleFor(domDocRootNode, getter_AddRefs(accessible)); - nsCOMPtr docAccessible = - do_QueryInterface(accessible); - NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE); + nsCOMPtr domDocNode(do_QueryInterface(domDoc)); + NS_ENSURE_TRUE(domDocNode, NS_ERROR_FAILURE); + nsCOMPtr docAccessible; PRUint32 eventType = 0; - if ((aStateFlags & STATE_STOP) && NS_SUCCEEDED(aStatus)) { - eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE; - } else if ((aStateFlags & STATE_STOP) && (aStatus & NS_BINDING_ABORTED)) { - eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED; - } else if (aStateFlags & STATE_START) { + if (aStateFlags & STATE_STOP) { + // Do not create accessible for page load end events + // in case it was already shut down before page finished loading + docAccessible = nsAccessNode::GetDocAccessibleFor(domDocNode); // Cached doc accessibles only + if (!docAccessible) + return NS_OK; + nsCOMPtr domDocTest; + docAccessible->GetDocument(getter_AddRefs(domDocTest)); + if (domDocTest != domDoc) { + // Doc from accessible is not the doc we started from + // We must be shutdown, and domDocTest should be null + NS_ASSERTION(!domDocTest, "Doc not shut down but reports incorrect DOM document"); + return NS_OK; + } + + eventType = NS_FAILED(aStatus) ? nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED : + nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE; + } + else { + // Get the accessible for the new document. + // If it not created yet this will create it & cache it, as well as + // set up event listeners so that MSAA/ATK toolkit and internal + // accessibility events will get fired. + nsCOMPtr accessible; + GetAccessibleFor(domDocNode, getter_AddRefs(accessible)); // Create if necessary + docAccessible = do_QueryInterface(accessible); eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START; nsCOMPtr webNav(do_GetInterface(domWindow)); nsCOMPtr docShell(do_QueryInterface(webNav)); @@ -213,11 +225,9 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress } } - if (eventType == 0) - return NS_OK; //no actural event need to be fired - - if (docAccessible) { - docAccessible->FireDocLoadEvents(eventType); + nsCOMPtr privDocAccessible = do_QueryInterface(docAccessible); + if (eventType && privDocAccessible) { + privDocAccessible->FireDocLoadEvents(eventType); } return NS_OK; diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index dbeea4444d2..02948f98b06 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -393,11 +393,8 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode) return; } - // At minimum, create doc accessible so that events are listened to, - // allowing us to see any mutations from a page load handler - nsCOMPtr docAccessible; - GetAccService()->GetAccessibleFor(aDocNode, getter_AddRefs(docAccessible)); - + // The doc accessible should already be created as a result of the + // OnStateChange() for the initiation of page loading nsCOMPtr treeNode(do_QueryInterface(treeItem)); if (treeNode) { PRInt32 subDocuments; @@ -420,8 +417,10 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode) if (!rootContentAccessible) { return; } - PRUint32 state = State(rootContentAccessible); - if (state & nsIAccessibleStates::STATE_BUSY) { + PRUint32 state, extState; + rootContentAccessible->GetFinalState(&state, &extState); + if ((state & nsIAccessibleStates::STATE_BUSY) || + (extState & nsIAccessibleStates::EXT_STATE_DEFUNCT)) { // Don't fire page load events on subdocuments for initial page load of entire page return; }