Bug 405414. nsDocAccessible is not destroyed when closing a tab. Patch by Ginn Chen. r=aaronlev, a=dsicore

This commit is contained in:
aaronleventhal@moonset.net 2007-11-30 11:47:16 -08:00
Родитель a9e0d87a65
Коммит 912dbcb392
6 изменённых файлов: 51 добавлений и 38 удалений

Просмотреть файл

@ -41,7 +41,7 @@
interface nsIAccessNode;
interface nsIContent;
[uuid(08811f23-1298-4882-9a68-6f1466c28007)]
[uuid(fa9cafac-9562-49ad-afcf-911ab1e4e4fb)]
interface nsPIAccessibleDocument : nsISupports
{
@ -61,7 +61,6 @@ interface nsPIAccessibleDocument : nsISupports
void invalidateCacheSubtree(in nsIContent aChangeContent,
in PRUint32 aChangeEvent);
void cacheAccessNode(in voidPtr aUniqueID, in nsIAccessNode aAccessNode);
void destroy();
void flushPendingEvents();
void fireDocLoadEvents(in PRUint32 aEventType);
void fireAnchorJumpEvent();

Просмотреть файл

@ -655,11 +655,16 @@ void nsAccessNode::GetComputedStyleDeclaration(const nsAString& aPseudoElt,
/***************** Hashtable of nsIAccessNode's *****************/
already_AddRefed<nsIAccessibleDocument>
nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aPresShell)
nsAccessNode::GetDocAccessibleFor(nsIDocument *aDocument)
{
if (!aDocument) {
return nsnull;
}
nsIAccessibleDocument *docAccessible = nsnull;
nsCOMPtr<nsIAccessNode> accessNode;
gGlobalDocAccessibleCache.Get(static_cast<void*>(aPresShell), getter_AddRefs(accessNode));
gGlobalDocAccessibleCache.Get(static_cast<void*>(aDocument),
getter_AddRefs(accessNode));
if (accessNode) {
CallQueryInterface(accessNode, &docAccessible);
}
@ -667,15 +672,26 @@ nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aPresShell)
}
already_AddRefed<nsIAccessibleDocument>
nsAccessNode::GetDocAccessibleFor(nsISupports *aContainer, PRBool aCanCreate)
nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aWeakShell)
{
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
if (!presShell) {
return nsnull;
}
return nsAccessNode::GetDocAccessibleFor(presShell->GetDocument());
}
already_AddRefed<nsIAccessibleDocument>
nsAccessNode::GetDocAccessibleFor(nsIDocShellTreeItem *aContainer,
PRBool aCanCreate)
{
if (!aCanCreate) {
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
NS_ASSERTION(docShell, "This method currently only supports docshells");
nsCOMPtr<nsIPresShell> presShell;
docShell->GetPresShell(getter_AddRefs(presShell));
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
return weakShell ? GetDocAccessibleFor(weakShell) : nsnull;
return presShell ? GetDocAccessibleFor(presShell->GetDocument()) : nsnull;
}
nsCOMPtr<nsIDOMNode> node = GetDOMNodeForContainer(aContainer);
@ -696,8 +712,16 @@ already_AddRefed<nsIAccessibleDocument>
nsAccessNode::GetDocAccessibleFor(nsIDOMNode *aNode)
{
nsCOMPtr<nsIPresShell> eventShell = GetPresShellFor(aNode);
nsCOMPtr<nsIWeakReference> weakEventShell(do_GetWeakReference(eventShell));
return weakEventShell? GetDocAccessibleFor(weakEventShell) : nsnull;
if (eventShell) {
return GetDocAccessibleFor(eventShell->GetDocument());
}
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
if (doc) {
return GetDocAccessibleFor(doc);
}
return nsnull;
}
already_AddRefed<nsIPresShell>

Просмотреть файл

@ -64,6 +64,7 @@ class nsIDOMNodeList;
class nsITimer;
class nsRootAccessible;
class nsApplicationAccessibleWrap;
class nsIDocShellTreeItem;
#define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
#define PLATFORM_KEYS_BUNDLE_URL "chrome://global-platform/locale/platformKeys.properties"
@ -109,8 +110,9 @@ class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
static PLDHashOperator PR_CALLBACK ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg);
// Static cache methods for global document cache
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIWeakReference *aPresShell);
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsISupports *aContainer, PRBool aCanCreate = PR_FALSE);
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocument *aDocument);
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIWeakReference *aWeakShell);
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocShellTreeItem *aContainer, PRBool aCanCreate = PR_FALSE);
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDOMNode *aNode);
static already_AddRefed<nsIDOMNode> GetDOMNodeForContainer(nsISupports *aContainer);

Просмотреть файл

@ -1865,9 +1865,8 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
"Incorrect aEvent passed in");
NS_ENSURE_ARG_POINTER(aShell);
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aShell));
nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
nsAccessNode::GetDocAccessibleFor(weakShell);
nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
do_QueryInterface(accessibleDoc);
if (!privateAccessibleDoc) {

Просмотреть файл

@ -521,7 +521,7 @@ nsDocAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
NS_IMETHODIMP nsDocAccessible::Init()
{
PutCacheEntry(gGlobalDocAccessibleCache, mWeakShell, this);
PutCacheEntry(gGlobalDocAccessibleCache, mDocument, this);
AddEventListeners();
@ -539,19 +539,6 @@ NS_IMETHODIMP nsDocAccessible::Init()
return rv;
}
NS_IMETHODIMP nsDocAccessible::Destroy()
{
nsresult rv = Shutdown();
if (mWeakShell) {
// Remove from the cache after Shutdown(), so that Shutdown() procedures
// can find the doc or root accessible in the cache if they need it
gGlobalDocAccessibleCache.Remove(static_cast<void*>(mWeakShell));
}
return rv;
}
NS_IMETHODIMP nsDocAccessible::Shutdown()
{
if (!mWeakShell) {

Просмотреть файл

@ -600,11 +600,6 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
}
#endif
nsCOMPtr<nsIPresShell> eventShell = GetPresShellFor(aTargetNode);
if (!eventShell) {
return NS_OK;
}
nsIAccessibilityService *accService = GetAccService();
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
@ -615,16 +610,23 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
// so that we don't destroy something still in use, like wizard page.
// And we only get cached document accessible to destroy, so that we don't
// create it just to destroy it.
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(eventShell));
nsCOMPtr<nsIAccessible> accessible;
accService->GetCachedAccessible(aTargetNode, weakShell, getter_AddRefs(accessible));
nsCOMPtr<nsPIAccessibleDocument> privateAccDoc = do_QueryInterface(accessible);
if (privateAccDoc) {
privateAccDoc->Destroy();
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aTargetNode));
nsCOMPtr<nsIAccessibleDocument> accDoc = GetDocAccessibleFor(doc);
nsCOMPtr<nsPIAccessNode> privateAcc = do_QueryInterface(accDoc);
if (privateAcc) {
privateAcc->Shutdown();
// Remove from the cache after Shutdown(), so that Shutdown() procedures
// can find the doc or root accessible in the cache if they need it.
gGlobalDocAccessibleCache.Remove(static_cast<void*>(doc));
}
return NS_OK;
}
nsCOMPtr<nsIPresShell> eventShell = GetPresShellFor(aTargetNode);
if (!eventShell) {
return NS_OK;
}
if (eventType.EqualsLiteral("DOMContentLoaded")) {
// Don't create the doc accessible until load scripts have a chance to set
// role attribute for <body> or <html> element, because the value of