зеркало из https://github.com/mozilla/gecko-dev.git
Bug 405414. nsDocAccessible is not destroyed when closing a tab. Patch by Ginn Chen. r=aaronlev, a=dsicore
This commit is contained in:
Родитель
a9e0d87a65
Коммит
912dbcb392
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче