зеркало из https://github.com/mozilla/gecko-dev.git
Bug 571459 - shutdown document accessible when presshell goes away, patch=bz, surkov, r=surkov, davidb, sr=roc, bz, f=marcoz
This commit is contained in:
Родитель
88ddfb5dd3
Коммит
1b0c05dd76
|
@ -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
|
||||
{
|
||||
|
@ -166,6 +166,12 @@ public:
|
|||
*/
|
||||
virtual void NotifyOfAnchorJumpTo(nsIContent *aTarget) = 0;
|
||||
|
||||
/**
|
||||
* Notify the accessibility service that the given presshell is
|
||||
* being destroyed.
|
||||
*/
|
||||
virtual void PresShellDestroyed(nsIPresShell *aPresShell) = 0;
|
||||
|
||||
/**
|
||||
* Fire accessible event of the given type for the given target.
|
||||
*
|
||||
|
|
|
@ -96,6 +96,7 @@ nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocument *aDocument)
|
|||
ShutdownDocAccessiblesInTree(treeItem, aDocument);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager protected
|
||||
|
||||
|
@ -128,6 +129,22 @@ nsAccDocManager::Shutdown()
|
|||
ClearDocCache();
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::ShutdownDocAccessible(nsIDocument *aDocument)
|
||||
{
|
||||
nsDocAccessible* docAccessible =
|
||||
mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
|
||||
if (!docAccessible)
|
||||
return;
|
||||
|
||||
// We're allowed to not remove listeners when accessible document is shutdown
|
||||
// since we don't keep strong reference on chrome event target and listeners
|
||||
// are removed automatically when chrome event target goes away.
|
||||
|
||||
docAccessible->Shutdown();
|
||||
mDocAccessibleCache.Remove(static_cast<void*>(aDocument));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
|
@ -413,30 +430,6 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::RemoveListeners(nsIDocument *aDocument)
|
||||
{
|
||||
// Document has no window when application shuts down. The document can still
|
||||
// exist because we didn't receive a "pagehide" event.
|
||||
nsPIDOMWindow *window = aDocument->GetWindow();
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
nsPIDOMEventTarget *target = window->GetChromeEventHandler();
|
||||
nsIEventListenerManager* elm = target->GetListenerManager(PR_TRUE);
|
||||
elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
|
||||
NS_EVENT_FLAG_CAPTURE, nsnull);
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("removed 'pagehide' listener", aDocument)
|
||||
|
||||
if (nsCoreUtils::IsRootDocument(aDocument)) {
|
||||
elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
|
||||
NS_EVENT_FLAG_CAPTURE, nsnull);
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("removed 'DOMContentLoaded' listener", aDocument)
|
||||
}
|
||||
}
|
||||
|
||||
nsDocAccessible*
|
||||
nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
|
||||
{
|
||||
|
@ -502,7 +495,6 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
|
|||
if (outerDocAcc) {
|
||||
// Root document accessible doesn't have associated outerdoc accessible, it
|
||||
// adds itself to application accessible instead.
|
||||
NS_LOG_ACCDOCCREATE("append document to outerdoc", aDocument)
|
||||
outerDocAcc->AppendChild(docAcc);
|
||||
}
|
||||
|
||||
|
@ -512,7 +504,7 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
NS_LOG_ACCDOCCREATE("document created", aDocument)
|
||||
NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
|
||||
|
||||
AddListeners(aDocument, isRootDoc);
|
||||
return docAcc;
|
||||
|
@ -547,19 +539,6 @@ nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
|
|||
ShutdownDocAccessible(aDocument);
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::ShutdownDocAccessible(nsIDocument *aDocument)
|
||||
{
|
||||
RemoveListeners(aDocument);
|
||||
|
||||
nsDocAccessible *docAccessible =
|
||||
mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
|
||||
if (docAccessible)
|
||||
docAccessible->Shutdown();
|
||||
|
||||
mDocAccessibleCache.Remove(static_cast<void*>(aDocument));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager static
|
||||
|
||||
|
@ -573,14 +552,8 @@ nsAccDocManager::ClearDocCacheEntry(const void* aKey,
|
|||
NS_ASSERTION(aDocAccessible,
|
||||
"Calling ClearDocCacheEntry with a NULL pointer!");
|
||||
|
||||
if (aDocAccessible) {
|
||||
nsCOMPtr<nsIDocument> document = aDocAccessible->GetDOMDocument();
|
||||
NS_ASSERTION(document, "Document accessible was shutdown already!");
|
||||
if (document)
|
||||
accDocMgr->RemoveListeners(document);
|
||||
|
||||
if (aDocAccessible)
|
||||
aDocAccessible->Shutdown();
|
||||
}
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
|
||||
class nsDocAccessible;
|
||||
|
||||
//#define DEBUG_ACCDOCMGR
|
||||
|
||||
/**
|
||||
* Manage the document accessible life cycle.
|
||||
*/
|
||||
|
@ -80,6 +82,14 @@ public:
|
|||
*/
|
||||
void ShutdownDocAccessiblesInTree(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Return document accessible from the cache. Convenient method for testing.
|
||||
*/
|
||||
inline nsDocAccessible* GetDocAccessibleFromCache(nsIDocument* aDocument) const
|
||||
{
|
||||
return mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
|
||||
}
|
||||
|
||||
protected:
|
||||
nsAccDocManager() { };
|
||||
|
||||
|
@ -93,10 +103,10 @@ protected:
|
|||
*/
|
||||
void Shutdown();
|
||||
|
||||
inline nsDocAccessible* GetDocAccessibleFromCache(nsIDocument* aDocument) const
|
||||
{
|
||||
return mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
|
||||
}
|
||||
/**
|
||||
* Shutdown the document accessible.
|
||||
*/
|
||||
void ShutdownDocAccessible(nsIDocument* aDocument);
|
||||
|
||||
private:
|
||||
nsAccDocManager(const nsAccDocManager&);
|
||||
|
@ -137,10 +147,9 @@ private:
|
|||
PRBool IsEventTargetDocument(nsIDocument *aDocument) const;
|
||||
|
||||
/**
|
||||
* Add/remove 'pagehide' and 'DOMContentLoaded' event listeners.
|
||||
* Add 'pagehide' and 'DOMContentLoaded' event listeners.
|
||||
*/
|
||||
void AddListeners(nsIDocument *aDocument, PRBool aAddPageShowListener);
|
||||
void RemoveListeners(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Create document or root accessible.
|
||||
|
@ -153,11 +162,6 @@ private:
|
|||
void ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
|
||||
nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Shutdown the document accessible.
|
||||
*/
|
||||
void ShutdownDocAccessible(nsIDocument *aDocument);
|
||||
|
||||
typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
|
||||
nsDocAccessibleHashtable;
|
||||
|
||||
|
@ -194,8 +198,6 @@ private:
|
|||
/**
|
||||
* nsAccDocManager debugging macros.
|
||||
*/
|
||||
//#define DEBUG_ACCDOCMGR
|
||||
|
||||
#ifdef DEBUG_ACCDOCMGR
|
||||
|
||||
// Enable these to log accessible document loading, creation or destruction.
|
||||
|
@ -205,9 +207,7 @@ private:
|
|||
|
||||
// Common macros, do not use directly.
|
||||
#define NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc) \
|
||||
printf("DOM id: 0x%x, acc id: 0x%x", \
|
||||
reinterpret_cast<PRInt32>(static_cast<void*>(aDocument)), \
|
||||
reinterpret_cast<PRInt32>(aDocAcc));
|
||||
printf("DOM id: %p, acc id: %p", aDocument, aDocAcc);
|
||||
|
||||
#define NS_LOG_ACCDOC_URI(aDocument) \
|
||||
nsIURI *uri = aDocument->GetDocumentURI(); \
|
||||
|
@ -260,19 +260,18 @@ private:
|
|||
|
||||
#define NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
|
||||
nsIPresShell *ps = aDocument->GetPrimaryShell(); \
|
||||
printf("presshell: 0x%x", reinterpret_cast<PRInt32>(ps)); \
|
||||
printf("presshell: %p", ps); \
|
||||
nsIScrollableFrame *sf = ps ? \
|
||||
ps->GetRootScrollFrameAsScrollableExternal() : nsnull; \
|
||||
printf(", root scroll frame: 0x%x", reinterpret_cast<PRInt32>(sf));
|
||||
printf(", root scroll frame: %p", sf);
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = aDocument->GetDocumentLoadGroup(); \
|
||||
printf("load group: 0x%x", reinterpret_cast<PRInt32>(loadGroup.get()));
|
||||
printf("load group: %p", loadGroup);
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCPARENT(aDocument) \
|
||||
nsIDocument *parentDoc = aDocument->GetParentDocument(); \
|
||||
printf("parent id: 0x%x", \
|
||||
reinterpret_cast<PRInt32>(parentDoc)); \
|
||||
printf("parent id: %p", parentDoc); \
|
||||
if (parentDoc) { \
|
||||
printf("\n parent "); \
|
||||
NS_LOG_ACCDOC_URI(parentDoc) \
|
||||
|
@ -397,6 +396,21 @@ private:
|
|||
} \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc) \
|
||||
{ \
|
||||
nsINode* node = aAcc->GetNode(); \
|
||||
nsIDocument* doc = aAcc->GetDocumentNode(); \
|
||||
nsDocAccessible *docacc = GetAccService()->GetDocAccessibleFromCache(doc); \
|
||||
printf(" " aName " accessible: %p, node: %p\n", aAcc, node); \
|
||||
printf(" docacc for " aName " accessible: %p, node: %p\n", docacc, doc); \
|
||||
printf(" "); \
|
||||
NS_LOG_ACCDOC_URI(doc) \
|
||||
printf("\n"); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_MSG(aMsg) \
|
||||
printf("\n" aMsg "\n"); \
|
||||
|
||||
#define NS_LOG_ACCDOC_TEXT(aMsg) \
|
||||
printf(" " aMsg "\n");
|
||||
|
||||
|
@ -431,7 +445,7 @@ private:
|
|||
|
||||
#define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags) \
|
||||
{ \
|
||||
printf("\nA11Y DOCLOAD: " aMsg "\n"); \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg); \
|
||||
\
|
||||
nsCOMPtr<nsIDOMWindow> DOMWindow; \
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow)); \
|
||||
|
@ -441,7 +455,7 @@ private:
|
|||
if (DOMDocument) { \
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument)); \
|
||||
nsDocAccessible *docAcc = \
|
||||
mDocAccessibleCache.GetWeak(static_cast<void*>(document)); \
|
||||
GetAccService()->GetDocAccessibleFromCache(document); \
|
||||
NS_LOG_ACCDOC_DOCINFO(document, docAcc) \
|
||||
\
|
||||
printf(" {\n"); \
|
||||
|
@ -463,9 +477,9 @@ private:
|
|||
|
||||
#define NS_LOG_ACCDOCLOAD2(aMsg, aDocument) \
|
||||
{ \
|
||||
printf("\nA11Y DOCLOAD: " aMsg "\n"); \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg); \
|
||||
nsDocAccessible *docAcc = \
|
||||
mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument)); \
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocument); \
|
||||
NS_LOG_ACCDOC_DOCINFO(aDocument, docAcc) \
|
||||
}
|
||||
|
||||
|
@ -496,16 +510,19 @@ private:
|
|||
// Accessible document creation macros.
|
||||
#ifdef DEBUG_ACCDOCMGR_DOCCREATE
|
||||
#define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc) \
|
||||
printf("\nA11Y DOCCREATE: " aMsg "\n"); \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCCREATE: " aMsg); \
|
||||
NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE(aMsg, aDocument) \
|
||||
{ \
|
||||
nsDocAccessible *docAcc = \
|
||||
mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument)); \
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocument); \
|
||||
NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, docAcc) \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc) \
|
||||
NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE_TEXT(aMsg) \
|
||||
NS_LOG_ACCDOC_TEXT(aMsg)
|
||||
|
||||
|
@ -514,16 +531,24 @@ private:
|
|||
// Accessible document destruction macros.
|
||||
#ifdef DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
#define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc) \
|
||||
printf("\nA11Y DOCDESTROY: " aMsg "\n"); \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCDESTROY: " aMsg); \
|
||||
NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY(aMsg, aDocument) \
|
||||
nsDocAccessible *docAcc = \
|
||||
mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument)); \
|
||||
NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc)
|
||||
{ \
|
||||
nsDocAccessible* docAcc = \
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocument); \
|
||||
NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc) \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg) \
|
||||
NS_LOG_ACCDOC_TEXT(aMsg)
|
||||
#define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc) \
|
||||
NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY_MSG(aMsg) \
|
||||
NS_LOG_ACCDOC_MSG(aMsg)
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg) \
|
||||
NS_LOG_ACCDOC_TEXT(aMsg)
|
||||
|
||||
#endif // DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
|
||||
|
@ -541,12 +566,15 @@ private:
|
|||
#ifndef DEBUG_ACCDOCMGR_DOCCREATE
|
||||
#define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc)
|
||||
#define NS_LOG_ACCDOCCREATE(aMsg, aDocument)
|
||||
#define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc)
|
||||
#define NS_LOG_ACCDOCCREATE_TEXT(aMsg)
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
#define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc)
|
||||
#define NS_LOG_ACCDOCDESTROY(aMsg, aDocument)
|
||||
#define NS_LOG_ACCDOCDESTROY_MSG(aMsg)
|
||||
#define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc)
|
||||
#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -157,6 +157,8 @@ public:
|
|||
*/
|
||||
virtual nsINode* GetNode() const { return mContent; }
|
||||
nsIContent* GetContent() const { return mContent; }
|
||||
nsIDocument* GetDocumentNode() const
|
||||
{ return mContent ? mContent->GetOwnerDoc() : nsnull; }
|
||||
|
||||
/**
|
||||
* Return node type information of DOM node associated with the accessible.
|
||||
|
|
|
@ -780,6 +780,25 @@ nsAccessibilityService::CreateHTMLCaptionAccessible(nsIFrame *aFrame,
|
|||
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.
|
||||
// When document subtree containing iframe is hidden then we don't get
|
||||
// pagehide event for the iframe's underlying document and its presshell is
|
||||
// destroyed before we're notified styles were changed. Shutdown the document
|
||||
// accessible early.
|
||||
nsIDocument* doc = aPresShell->GetDocument();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
|
||||
ShutdownDocAccessible(doc);
|
||||
}
|
||||
|
||||
// nsAccessibilityService protected
|
||||
nsAccessible *
|
||||
nsAccessibilityService::GetCachedAccessible(nsINode *aNode,
|
||||
|
|
|
@ -124,6 +124,8 @@ public:
|
|||
|
||||
virtual void NotifyOfAnchorJumpTo(nsIContent *aTarget);
|
||||
|
||||
virtual void PresShellDestroyed(nsIPresShell* aPresShell);
|
||||
|
||||
virtual nsresult FireAccessibleEvent(PRUint32 aEvent, nsIAccessible *aTarget);
|
||||
|
||||
// nsAccessibiltiyService
|
||||
|
|
|
@ -596,6 +596,8 @@ nsDocAccessible::RemoveAccessNodeFromCache(nsAccessible *aAccessible)
|
|||
PRBool
|
||||
nsDocAccessible::Init()
|
||||
{
|
||||
NS_LOG_ACCDOCCREATE_FOR("document initialize", mDocument, this)
|
||||
|
||||
// Initialize event queue.
|
||||
mEventQueue = new nsAccEventQueue(this);
|
||||
if (!mEventQueue)
|
||||
|
@ -630,8 +632,8 @@ nsDocAccessible::Shutdown()
|
|||
RemoveEventListeners();
|
||||
|
||||
if (mParent) {
|
||||
NS_LOG_ACCDOCDESTROY_FOR("remove document from outer doc", mDocument, this);
|
||||
mParent->RemoveChild(this);
|
||||
mParent = nsnull;
|
||||
}
|
||||
|
||||
mWeakShell = nsnull; // Avoid reentrancy
|
||||
|
|
|
@ -124,8 +124,6 @@ public:
|
|||
|
||||
// nsDocAccessible
|
||||
|
||||
nsIDocument *GetDOMDocument() const { return mDocument; }
|
||||
|
||||
/**
|
||||
* Return true if associated DOM document was loaded and isn't unloading.
|
||||
*/
|
||||
|
|
|
@ -159,17 +159,20 @@ nsOuterDocAccessible::DoAction(PRUint8 aIndex)
|
|||
void
|
||||
nsOuterDocAccessible::Shutdown()
|
||||
{
|
||||
// Shutdown child document if any.
|
||||
// XXX: sometimes outerdoc accessible is shutdown because of layout style
|
||||
// change however the presshell of underlying document isn't destroyed and
|
||||
// the document doesn't get pagehide events. Shutdown underlying document if
|
||||
// any to avoid hanging document accessible.
|
||||
NS_LOG_ACCDOCDESTROY_MSG("A11y outerdoc shutdown")
|
||||
NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
|
||||
|
||||
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());
|
||||
NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown",
|
||||
childAcc->GetDocumentNode())
|
||||
GetAccService()->ShutdownDocAccessiblesInTree(childAcc->GetDocumentNode());
|
||||
}
|
||||
|
||||
nsAccessible::InvalidateChildren();
|
||||
|
||||
nsAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
|
@ -201,6 +204,11 @@ nsOuterDocAccessible::AppendChild(nsAccessible *aAccessible)
|
|||
return PR_FALSE;
|
||||
|
||||
aAccessible->SetParent(this);
|
||||
|
||||
NS_LOG_ACCDOCCREATE("append document to outerdoc",
|
||||
aAccessible->GetDocumentNode())
|
||||
NS_LOG_ACCDOCCREATE_ACCADDRESS("outerdoc", this)
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
@ -213,13 +221,19 @@ nsOuterDocAccessible::RemoveChild(nsAccessible *aAccessible)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("remove document from outerdoc",
|
||||
child->GetDocumentNode())
|
||||
NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
|
||||
|
||||
mChildren.RemoveElement(child);
|
||||
|
||||
NS_ASSERTION(!mChildren.Length(),
|
||||
"This child document of outerdoc accessible wasn't removed!");
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible protected
|
||||
|
||||
|
|
|
@ -25,6 +25,11 @@ const EVENT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_VALUE_CHANGE;
|
|||
*/
|
||||
var gA11yEventDumpID = "";
|
||||
|
||||
/**
|
||||
* Set up this variable to dump event processing into console.
|
||||
*/
|
||||
var gA11yEventDumpToConsole = false;
|
||||
|
||||
/**
|
||||
* Executes the function when requested event is handled.
|
||||
*
|
||||
|
@ -262,6 +267,9 @@ function eventQueue(aEventType)
|
|||
|
||||
this.setEventHandler(invoker);
|
||||
|
||||
if (gA11yEventDumpToConsole)
|
||||
dump("\nEvent queue: \n invoke: " + invoker.getID() + "\n");
|
||||
|
||||
if (invoker.invoke() == INVOKER_ACTION_FAILED) {
|
||||
// Invoker failed to prepare action, fail and finish tests.
|
||||
this.processNextInvoker();
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче