Bug 571459. Shutdown the doc accessible if its presshell dies. r=surkov,roc

This commit is contained in:
Boris Zbarsky 2010-06-14 16:06:48 -04:00
parent 524cd98ad3
commit b81a48a4a5
6 changed files with 48 additions and 32 deletions

View File

@ -51,10 +51,10 @@ class nsIFrame;
class nsIPresShell;
class nsObjectFrame;
// 9f43b315-53c6-4d46-9818-9c8593e91984
// 10ff6dca-b219-4b64-9a4c-67a62b86edce
#define NS_IACCESSIBILITYSERVICE_IID \
{0x9f43b315, 0x53c6, 0x4d46, \
{0x98, 0x18, 0x9c, 0x85, 0x93, 0xe9, 0x19, 0x84} }
{ 0x10ff6dca, 0xb219, 0x4b64, \
{ 0x9a, 0x4c, 0x67, 0xa6, 0x2b, 0x86, 0xed, 0xce } }
class nsIAccessibilityService : public nsIAccessibleRetrieval
{
@ -174,6 +174,12 @@ public:
*/
virtual nsresult FireAccessibleEvent(PRUint32 aEvent,
nsIAccessible *aTarget) = 0;
/**
* Notify the accessibility service that the given presshell is
* being destroyed.
*/
virtual void PresShellDestroyed(nsIPresShell* aPresShell) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIAccessibilityService,

View File

@ -73,13 +73,6 @@ public:
*/
nsAccessible *FindAccessibleInCache(void *aUniqueID) const;
/**
* Shutdown document accessibles in the tree starting from the given one.
*
* @param aDocument [in] the DOM document of start document accessible
*/
void ShutdownDocAccessiblesInTree(nsIDocument *aDocument);
protected:
nsAccDocManager() { };
@ -93,6 +86,18 @@ protected:
*/
void Shutdown();
/**
* Shutdown the document accessible.
*/
void ShutdownDocAccessible(nsIDocument *aDocument);
/**
* Shutdown document accessibles in the tree starting from the given one.
*
* @param aDocument [in] the DOM document of start document accessible
*/
void ShutdownDocAccessiblesInTree(nsIDocument *aDocument);
private:
nsAccDocManager(const nsAccDocManager&);
nsAccDocManager& operator =(const nsAccDocManager&);
@ -148,11 +153,6 @@ private:
void ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
nsIDocument *aDocument);
/**
* Shutdown the document accessible.
*/
void ShutdownDocAccessible(nsIDocument *aDocument);
typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
nsDocAccessibleHashtable;

View File

@ -186,6 +186,18 @@ nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
return NS_OK;
}
void
nsAccessibilityService::PresShellDestroyed(nsIPresShell* aPresShell)
{
// Presshell destruction will automatically destroy shells for
// descendant documents, so no need to worry about those. Just
// shut down the accessible for this one document. That keeps us
// from having bad behavior in case of deep bushy subtrees.
nsIDocument* doc = aPresShell->GetDocument();
if (doc)
ShutdownDocAccessible(doc);
}
// nsAccessibilityService private
nsresult
nsAccessibilityService::GetInfo(nsIFrame *aFrame, nsIWeakReference **aShell,

View File

@ -126,6 +126,8 @@ public:
virtual nsresult FireAccessibleEvent(PRUint32 aEvent, nsIAccessible *aTarget);
virtual void PresShellDestroyed(nsIPresShell* aPresShell);
// nsAccessibiltiyService
/**

View File

@ -159,15 +159,6 @@ nsOuterDocAccessible::DoAction(PRUint8 aIndex)
void
nsOuterDocAccessible::Shutdown()
{
// Shutdown child document if any.
nsAccessible *childAcc = mChildren.SafeElementAt(0, nsnull);
if (childAcc) {
nsRefPtr<nsDocAccessible> docAcc(do_QueryObject(childAcc));
NS_LOG_ACCDOCDESTROY_FOR("outerdoc document shutdown",
docAcc->GetDOMDocument(), docAcc.get())
GetAccService()->ShutdownDocAccessiblesInTree(docAcc->GetDOMDocument());
}
nsAccessible::InvalidateChildren();
nsAccessibleWrap::Shutdown();
@ -179,14 +170,9 @@ nsOuterDocAccessible::Shutdown()
void
nsOuterDocAccessible::InvalidateChildren()
{
// Do not invalidate children because nsAccDocManager is responsible for
// document accessible lifetime when DOM document is created or destroyed. If
// DOM document isn't destroyed but its presshell is destroyed (for example,
// when DOM node of outerdoc accessible is hidden), then outerdoc accessible
// notifies nsAccDocManager about this. If presshell is created for existing
// DOM document (for example when DOM node of outerdoc accessible is shown)
// then allow nsAccDocManager to handle this case since the document
// accessible is created and appended as a child when it's requested.
// Do not invalidate children because nsAccDocManager is responsible
// for document accessible lifetime when DOM document or its
// presshell is created or destroyed.
mAreChildrenInitialized = PR_FALSE;
}

View File

@ -1816,6 +1816,16 @@ PresShell::Destroy()
if (mHaveShutDown)
return;
#ifdef ACCESSIBILITY
if (gIsAccessibilityActive) {
nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
if (accService) {
accService->PresShellDestroyed(this);
}
}
#endif // ACCESSIBILITY
MaybeReleaseCapturingContent();
mContentToScrollTo = nsnull;