Bug 746084 - provide extended logging for a11y module, r=tbsaunde

This commit is contained in:
Alexander Surkov 2012-05-23 18:21:40 +09:00
Родитель 7343dce6df
Коммит d23f317a93
10 изменённых файлов: 720 добавлений и 453 удалений

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

@ -18,7 +18,7 @@ interface nsIAccessiblePivot;
* nsIAccessible for a given DOM node. More documentation at:
* http://www.mozilla.org/projects/ui/accessibility
*/
[scriptable, uuid(310ce77d-c92b-4761-82e8-77e1a728e8d4)]
[scriptable, uuid(aed712cb-708b-4caa-981d-767be0fba984)]
interface nsIAccessibleRetrieval : nsISupports
{
/**
@ -84,6 +84,16 @@ interface nsIAccessibleRetrieval : nsISupports
* @return a new pivot
*/
nsIAccessiblePivot createAccessiblePivot(in nsIAccessible aRoot);
/**
* Enable logging for the given modules, all other modules aren't logged.
*
* @param aModules [in] list of modules, format is comma separated list
* like 'docload,doccreate'.
* @note Works on debug build only.
* @see Logging.cpp for list of possible values.
*/
void setLogging(in ACString aModules);
};

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

@ -0,0 +1,487 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Logging.h"
#include "AccEvent.h"
#include "nsAccessibilityService.h"
#include "nsCoreUtils.h"
#include "nsDocAccessible.h"
#include "nsDocShellLoadTypes.h"
#include "nsIChannel.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsTraceRefcntImpl.h"
#include "nsIWebProgress.h"
#include "prenv.h"
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// Logging helpers
static PRUint32 sModules = 0;
struct ModuleRep {
const char* mStr;
logging::EModules mModule;
};
static void
EnableLogging(const char* aModulesStr)
{
sModules = 0;
if (!aModulesStr)
return;
static ModuleRep modules[] = {
{ "docload", logging::eDocLoad },
{ "doccreate", logging::eDocCreate },
{ "docdestroy", logging::eDocDestroy },
{ "doclifecycle", logging::eDocLifeCycle }
};
const char* token = aModulesStr;
while (*token != '\0') {
size_t tokenLen = strcspn(token, ",");
for (unsigned int idx = 0; idx < ArrayLength(modules); idx++) {
if (strncmp(token, modules[idx].mStr, tokenLen) == 0) {
sModules |= modules[idx].mModule;
printf("\n\nmodule enabled: %s\n", modules[idx].mStr);
break;
}
}
token += tokenLen;
if (*token == ',')
token++; // skip ',' char
}
}
static void
LogDocURI(nsIDocument* aDocumentNode)
{
nsIURI* uri = aDocumentNode->GetDocumentURI();
nsCAutoString spec;
uri->GetSpec(spec);
printf("uri: %s", spec.get());
}
static void
LogDocShellState(nsIDocument* aDocumentNode)
{
printf("docshell busy: ");
nsCAutoString docShellBusy;
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
if (container) {
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
docShell->GetBusyFlags(&busyFlags);
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE)
printf("'none'");
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY)
printf("'busy'");
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD)
printf(", 'before page load'");
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)
printf(", 'page loading'");
} else {
printf("[failed]");
}
}
static void
LogDocType(nsIDocument* aDocumentNode)
{
if (aDocumentNode->IsActive()) {
bool isContent = nsCoreUtils::IsContentDocument(aDocumentNode);
printf("%s document", (isContent ? "content" : "chrome"));
} else {
printf("document type: [failed]");\
}
}
static void
LogDocShellTree(nsIDocument* aDocumentNode)
{
if (aDocumentNode->IsActive()) {
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
treeItem->GetParent(getter_AddRefs(parentTreeItem));
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;",
static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem),
(nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no"));
}
}
static void
LogDocState(nsIDocument* aDocumentNode)
{
const char* docState = nsnull;
nsIDocument::ReadyState docStateFlag = aDocumentNode->GetReadyStateEnum();
switch (docStateFlag) {
case nsIDocument::READYSTATE_UNINITIALIZED:
docState = "uninitialized";
break;
case nsIDocument::READYSTATE_LOADING:
docState = "loading";
break;
case nsIDocument::READYSTATE_INTERACTIVE:
docState = "interactive";
break;
case nsIDocument::READYSTATE_COMPLETE:
docState = "complete";
break;
}
printf("doc state: %s", docState);
printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not ");
printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not ");
printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not ");
printf(", %sactive", aDocumentNode->IsActive() ? "" : "not ");
}
static void
LogPresShell(nsIDocument* aDocumentNode)
{
nsIPresShell* ps = aDocumentNode->GetShell();
printf("presshell: %p", static_cast<void*>(ps));
nsIScrollableFrame *sf = ps ?
ps->GetRootScrollFrameAsScrollableExternal() : nsnull;
printf(", root scroll frame: %p", static_cast<void*>(sf));
}
static void
LogDocLoadGroup(nsIDocument* aDocumentNode)
{
nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup();
printf("load group: %p", static_cast<void*>(loadGroup));
}
static void
LogDocParent(nsIDocument* aDocumentNode)
{
nsIDocument* parentDoc = aDocumentNode->GetParentDocument();
printf("parent id: %p", static_cast<void*>(parentDoc));
if (parentDoc) {
printf("\n parent ");
LogDocURI(parentDoc);
printf("\n");
}
}
static void
LogDocInfo(nsIDocument* aDocumentNode, nsDocAccessible* aDocument)
{
printf(" {\n");
printf(" DOM id: %p, acc id: %p\n ",
static_cast<void*>(aDocumentNode), static_cast<void*>(aDocument));
// log document info
if (aDocumentNode) {
LogDocURI(aDocumentNode);
printf("\n ");
LogDocShellState(aDocumentNode);
printf("; ");
LogDocType(aDocumentNode);
printf("\n ");
LogDocShellTree(aDocumentNode);
printf("\n ");
LogDocState(aDocumentNode);
printf("\n ");
LogPresShell(aDocumentNode);
printf("\n ");
LogDocLoadGroup(aDocumentNode);
printf(", ");
LogDocParent(aDocumentNode);
printf("\n");
}
printf(" }\n");
}
static void
LogShellLoadType(nsIDocShell* aDocShell)
{
printf("load type: ");
PRUint32 loadType = 0;
aDocShell->GetLoadType(&loadType);
switch (loadType) {
case LOAD_NORMAL:
printf("normal; ");
break;
case LOAD_NORMAL_REPLACE:
printf("normal replace; ");
break;
case LOAD_NORMAL_EXTERNAL:
printf("normal external; ");
break;
case LOAD_HISTORY:
printf("history; ");
break;
case LOAD_NORMAL_BYPASS_CACHE:
printf("normal bypass cache; ");
break;
case LOAD_NORMAL_BYPASS_PROXY:
printf("normal bypass proxy; ");
break;
case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:
printf("normal bypass proxy and cache; ");
break;
case LOAD_RELOAD_NORMAL:
printf("reload normal; ");
break;
case LOAD_RELOAD_BYPASS_CACHE:
printf("reload bypass cache; ");
break;
case LOAD_RELOAD_BYPASS_PROXY:
printf("reload bypass proxy; ");
break;
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
printf("reload bypass proxy and cache; ");
break;
case LOAD_LINK:
printf("link; ");
break;
case LOAD_REFRESH:
printf("refresh; ");
break;
case LOAD_RELOAD_CHARSET_CHANGE:
printf("reload charset change; ");
break;
case LOAD_BYPASS_HISTORY:
printf("bypass history; ");
break;
case LOAD_STOP_CONTENT:
printf("stop content; ");
break;
case LOAD_STOP_CONTENT_AND_REPLACE:
printf("stop content and replace; ");
break;
case LOAD_PUSHSTATE:
printf("load pushstate; ");
break;
case LOAD_ERROR_PAGE:
printf("error page;");
break;
default:
printf("unknown");
}
}
static void
LogRequest(nsIRequest* aRequest)
{
if (aRequest) {
nsCAutoString name;
aRequest->GetName(name);
printf(" request spec: %s\n", name.get());
PRUint32 loadFlags = 0;
aRequest->GetLoadFlags(&loadFlags);
printf(" request load flags: %x; ", loadFlags);
if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI)
printf("document uri; ");
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
printf("retargeted document uri; ");
if (loadFlags & nsIChannel::LOAD_REPLACE)
printf("replace; ");
if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI)
printf("initial document uri; ");
if (loadFlags & nsIChannel::LOAD_TARGETED)
printf("targeted; ");
if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS)
printf("call content sniffers; ");
if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI)
printf("classify uri; ");
} else {
printf(" no request");
}
}
static void
GetDocLoadEventType(AccEvent* aEvent, nsACString& aEventType)
{
PRUint32 type = aEvent->GetEventType();
if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) {
aEventType.AssignLiteral("load stopped");
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) {
aEventType.AssignLiteral("load complete");
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) {
aEventType.AssignLiteral("reload");
} else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) {
AccStateChangeEvent* event = downcast_accEvent(aEvent);
if (event->GetState() == states::BUSY) {
aEventType.AssignLiteral("busy ");
if (event->IsStateEnabled())
aEventType.AppendLiteral("true");
else
aEventType.AppendLiteral("false");
}
}
}
////////////////////////////////////////////////////////////////////////////////
// namespace logging:: document life cycle logging methods
void
logging::DocLoad(const char* aMsg, nsIWebProgress* aWebProgress,
nsIRequest* aRequest, PRUint32 aStateFlags)
{
printf("\nA11Y DOCLOAD: %s\n", aMsg);
nsCOMPtr<nsIDOMWindow> DOMWindow;
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));
if (!DOMWindow)
return;
nsCOMPtr<nsIDOMDocument> DOMDocument;
DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
if (!DOMDocument)
return;
nsCOMPtr<nsIDocument> documentNode(do_QueryInterface(DOMDocument));
nsDocAccessible* document =
GetAccService()->GetDocAccessibleFromCache(documentNode);
LogDocInfo(documentNode, document);
printf(" {\n");
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
printf(" ");
LogShellLoadType(docShell);
printf("\n");
LogRequest(aRequest);
printf("\n");
printf(" state flags: %x", aStateFlags);
bool isDocLoading;
aWebProgress->GetIsLoadingDocument(&isDocLoading);
printf(", document is %sloading\n", (isDocLoading ? "" : "not "));
printf(" }\n");
}
void
logging::DocLoad(const char* aMsg, nsIDocument* aDocumentNode)
{
printf("\nA11Y DOCLOAD: %s\n", aMsg);
nsDocAccessible* document =
GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
LogDocInfo(aDocumentNode, document);
}
void
logging::DocLoadEventFired(AccEvent* aEvent)
{
nsCAutoString strEventType;
GetDocLoadEventType(aEvent, strEventType);
if (!strEventType.IsEmpty())
printf(" fire: %s\n", strEventType.get());
}
void
logging::DocLoadEventHandled(AccEvent* aEvent)
{
nsCAutoString strEventType;
GetDocLoadEventType(aEvent, strEventType);
if (!strEventType.IsEmpty()) {
printf("\nA11Y DOCEVENT: handled '%s' event ", strEventType.get());
nsINode* node = aEvent->GetNode();
if (node->IsNodeOfType(nsINode::eDOCUMENT)) {
nsIDocument* documentNode = static_cast<nsIDocument*>(node);
nsDocAccessible* document = aEvent->GetDocAccessible();
LogDocInfo(documentNode, document);
}
printf("\n");
}
}
void
logging::DocCreate(const char* aMsg, nsIDocument* aDocumentNode,
nsDocAccessible* aDocument)
{
nsDocAccessible* document = aDocument ?
aDocument : GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
printf("\nA11Y DOCCREATE: %s\n", aMsg);
LogDocInfo(aDocumentNode, document);
}
void
logging::DocDestroy(const char* aMsg, nsIDocument* aDocumentNode,
nsDocAccessible* aDocument)
{
nsDocAccessible* document = aDocument ?
aDocument : GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
printf("\nA11Y DOCDESTROY: %s\n", aMsg);
LogDocInfo(aDocumentNode, document);
}
void
logging::Address(const char* aDescr, nsAccessible* aAcc)
{
nsINode* node = aAcc->GetNode();
nsIDocument* docNode = aAcc->GetDocumentNode();
nsDocAccessible* doc = GetAccService()->GetDocAccessibleFromCache(docNode);
printf(" %s accessible: %p, node: %p\n", aDescr,
static_cast<void*>(aAcc), static_cast<void*>(node));
printf(" docacc for %s accessible: %p, node: %p\n", aDescr,
static_cast<void*>(doc), static_cast<void*>(docNode));
printf(" ");
LogDocURI(docNode);
printf("\n");
}
void
logging::Msg(const char* aMsg)
{
printf("\n%s\n", aMsg);
}
void
logging::Text(const char* aText)
{
printf(" %s\n", aText);
}
void
logging::Stack()
{
printf(" stack: \n");
nsTraceRefcntImpl::WalkTheStack(stdout);
}
////////////////////////////////////////////////////////////////////////////////
// namespace logging:: initialization
bool
logging::IsEnabled(PRUint32 aModules)
{
return sModules & aModules;
}
void
logging::Enable(const nsAFlatCString& aModules)
{
EnableLogging(aModules.get());
}
void
logging::CheckEnv()
{
EnableLogging(PR_GetEnv("A11YLOG"));
}

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

@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_a11y_logs_h__
#define mozilla_a11y_logs_h__
#include "nscore.h"
#include "nsAString.h"
class AccEvent;
class nsAccessible;
class nsDocAccessible;
class nsIDocument;
class nsIRequest;
class nsIWebProgress;
namespace mozilla {
namespace a11y {
namespace logging {
enum EModules {
eDocLoad = 1 << 0,
eDocCreate = 1 << 1,
eDocDestroy = 1 << 2,
eDocLifeCycle = eDocLoad | eDocCreate | eDocDestroy
};
/**
* Return true if the given module is logged.
*/
bool IsEnabled(PRUint32 aModule);
/**
* Log the document loading progress.
*/
void DocLoad(const char* aMsg, nsIWebProgress* aWebProgress,
nsIRequest* aRequest, PRUint32 aStateFlags);
void DocLoad(const char* aMsg, nsIDocument* aDocumentNode);
/**
* Log that document load event was fired.
*/
void DocLoadEventFired(AccEvent* aEvent);
/**
* Log that document laod event was handled.
*/
void DocLoadEventHandled(AccEvent* aEvent);
/**
* Log the document was created.
*/
void DocCreate(const char* aMsg, nsIDocument* aDocumentNode,
nsDocAccessible* aDocument = nsnull);
/**
* Log the document was destroyed.
*/
void DocDestroy(const char* aMsg, nsIDocument* aDocumentNode,
nsDocAccessible* aDocument = nsnull);
/**
* Log the message, a piece of text on own line, no offset.
*/
void Msg(const char* aMsg);
/**
* Log the text, two spaces offset is used.
*/
void Text(const char* aText);
/**
* Log the accesisble object address, two spaces offset is used.
*/
void Address(const char* aDescr, nsAccessible* aAcc);
/**
* Log the call stack, two spaces offset is used.
*/
void Stack();
/**
* Enable logging of the specified modules, all other modules aren't logged.
*/
void Enable(const nsAFlatCString& aModules);
/**
* Enable logging of modules specified by A11YLOG environment variable,
* all other modules aren't logged.
*/
void CheckEnv();
} // namespace logs
} // namespace a11y
} // namespace mozilla
#endif

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

@ -44,6 +44,12 @@ CPPSRCS = \
TextUpdater.cpp \
$(NULL)
ifdef MOZ_DEBUG
CPPSRCS += \
Logging.cpp \
$(NULL)
endif
EXPORTS = \
a11yGeneric.h \
nsAccDocManager.h \

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

@ -12,6 +12,10 @@
#include "RootAccessibleWrap.h"
#include "States.h"
#ifdef DEBUG
#include "Logging.h"
#endif
#include "nsCURILoader.h"
#include "nsDocShellLoadTypes.h"
#include "nsIChannel.h"
@ -140,7 +144,10 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
// Document was loaded.
if (aStateFlags & STATE_STOP) {
NS_LOG_ACCDOCLOAD("document loaded", aWebProgress, aRequest, aStateFlags)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoad("document loaded", aWebProgress, aRequest, aStateFlags);
#endif
// Figure out an event type to notify the document has been loaded.
PRUint32 eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED;
@ -166,8 +173,10 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
}
// Document loading was started.
NS_LOG_ACCDOCLOAD("start document loading", aWebProgress, aRequest,
aStateFlags)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoad("start document loading", aWebProgress, aRequest, aStateFlags);
#endif
nsDocAccessible* docAcc = mDocAccessibleCache.GetWeak(document);
if (!docAcc)
@ -253,7 +262,10 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
// accessible and all its sub document accessible are shutdown as result of
// processing.
NS_LOG_ACCDOCDESTROY("received 'pagehide' event", document)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocDestroy))
logging::DocDestroy("received 'pagehide' event", document);
#endif
// Ignore 'pagehide' on temporary documents since we ignore them entirely in
// accessibility.
@ -276,7 +288,11 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
// webprogress notifications nor 'pageshow' event.
if (type.EqualsLiteral("DOMContentLoaded") &&
nsCoreUtils::IsErrorPage(document)) {
NS_LOG_ACCDOCLOAD2("handled 'DOMContentLoaded' event", document)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoad("handled 'DOMContentLoaded' event", document);
#endif
HandleDOMDocumentLoad(document,
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
@ -313,12 +329,18 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument,
elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
NS_EVENT_FLAG_CAPTURE);
NS_LOG_ACCDOCCREATE_TEXT(" added 'pagehide' listener")
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocCreate))
logging::Text("added 'pagehide' listener");
#endif
if (aAddDOMContentLoadedListener) {
elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
NS_EVENT_FLAG_CAPTURE);
NS_LOG_ACCDOCCREATE_TEXT(" added 'DOMContentLoaded' listener")
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocCreate))
logging::Text("added 'DOMContentLoaded' listener");
#endif
}
}
@ -392,8 +414,12 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
parentDocAcc->BindChildDocument(docAcc);
}
NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
NS_LOG_ACCDOCCREATE_STACK
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocCreate)) {
logging::DocCreate("document creation finished", aDocument);
logging::Stack();
}
#endif
AddListeners(aDocument, isRootDoc);
return docAcc;

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

@ -16,8 +16,6 @@
class nsAccessible;
class nsDocAccessible;
//#define DEBUG_ACCDOCMGR
/**
* Manage the document accessible life cycle.
*/
@ -146,423 +144,4 @@ private:
nsDocAccessibleHashtable mDocAccessibleCache;
};
/**
* nsAccDocManager debugging macros.
*/
#ifdef DEBUG_ACCDOCMGR
#include "nsTraceRefcntImpl.h"
// Enable these to log accessible document loading, creation or destruction.
#define DEBUG_ACCDOCMGR_DOCLOAD
#define DEBUG_ACCDOCMGR_DOCCREATE
#define DEBUG_ACCDOCMGR_DOCDESTROY
// Common macros, do not use directly.
#define NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc) \
printf("DOM id: %p, acc id: %p", aDocument, aDocAcc);
#define NS_LOG_ACCDOC_URI(aDocument) \
nsIURI *uri = aDocument->GetDocumentURI(); \
nsCAutoString spec; \
uri->GetSpec(spec); \
printf("uri: %s", spec);
#define NS_LOG_ACCDOC_TYPE(aDocument) \
if (aDocument->IsActive()) { \
bool isContent = nsCoreUtils::IsContentDocument(aDocument); \
printf("%s document", (isContent ? "content" : "chrome")); \
} else { \
printf("document type: [failed]"); \
}
#define NS_LOG_ACCDOC_DOCSHELLTREE(aDocument) \
if (aDocument->IsActive()) { \
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container)); \
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; \
treeItem->GetParent(getter_AddRefs(parentTreeItem)); \
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; \
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); \
printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;", \
parentTreeItem, rootTreeItem, \
(nsCoreUtils::IsTabDocument(aDocument) ? "yes" : "no")); \
}
#define NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
nsCAutoString docShellBusy; \
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
if (container) { \
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container); \
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE; \
docShell->GetBusyFlags(&busyFlags); \
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) \
docShellBusy.AppendLiteral("'none'"); \
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) \
docShellBusy.AppendLiteral("'busy'"); \
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) \
docShellBusy.AppendLiteral(", 'before page load'"); \
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) \
docShellBusy.AppendLiteral(", 'page loading'"); \
} \
else { \
docShellBusy.AppendLiteral("[failed]"); \
} \
printf("docshell busy: %s", docShellBusy.get());
#define NS_LOG_ACCDOC_DOCSTATES(aDocument) \
const char *docState = 0; \
nsIDocument::ReadyState docStateFlag = aDocument->GetReadyStateEnum(); \
switch (docStateFlag) { \
case nsIDocument::READYSTATE_UNINITIALIZED: \
docState = "uninitialized"; \
break; \
case nsIDocument::READYSTATE_LOADING: \
docState = "loading"; \
break; \
case nsIDocument::READYSTATE_INTERACTIVE: \
docState = "interactive"; \
break; \
case nsIDocument::READYSTATE_COMPLETE: \
docState = "complete"; \
break; \
} \
printf("doc state: %s", docState); \
printf(", %sinitial", aDocument->IsInitialDocument() ? "" : "not "); \
printf(", %sshowing", aDocument->IsShowing() ? "" : "not "); \
printf(", %svisible", aDocument->IsVisible() ? "" : "not "); \
printf(", %sactive", aDocument->IsActive() ? "" : "not ");
#define NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
nsIPresShell *ps = aDocument->GetShell(); \
printf("presshell: %p", ps); \
nsIScrollableFrame *sf = ps ? \
ps->GetRootScrollFrameAsScrollableExternal() : nsnull; \
printf(", root scroll frame: %p", sf);
#define NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
nsCOMPtr<nsILoadGroup> loadGroup = aDocument->GetDocumentLoadGroup(); \
printf("load group: %p", loadGroup);
#define NS_LOG_ACCDOC_DOCPARENT(aDocument) \
nsIDocument *parentDoc = aDocument->GetParentDocument(); \
printf("parent id: %p", parentDoc); \
if (parentDoc) { \
printf("\n parent "); \
NS_LOG_ACCDOC_URI(parentDoc) \
printf("\n"); \
}
#define NS_LOG_ACCDOC_SHELLLOADTYPE(aDocShell) \
{ \
printf("load type: "); \
PRUint32 loadType; \
docShell->GetLoadType(&loadType); \
switch (loadType) { \
case LOAD_NORMAL: \
printf("normal; "); \
break; \
case LOAD_NORMAL_REPLACE: \
printf("normal replace; "); \
break; \
case LOAD_NORMAL_EXTERNAL: \
printf("normal external; "); \
break; \
case LOAD_HISTORY: \
printf("history; "); \
break; \
case LOAD_NORMAL_BYPASS_CACHE: \
printf("normal bypass cache; "); \
break; \
case LOAD_NORMAL_BYPASS_PROXY: \
printf("normal bypass proxy; "); \
break; \
case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE: \
printf("normal bypass proxy and cache; "); \
break; \
case LOAD_RELOAD_NORMAL: \
printf("reload normal; "); \
break; \
case LOAD_RELOAD_BYPASS_CACHE: \
printf("reload bypass cache; "); \
break; \
case LOAD_RELOAD_BYPASS_PROXY: \
printf("reload bypass proxy; "); \
break; \
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: \
printf("reload bypass proxy and cache; "); \
break; \
case LOAD_LINK: \
printf("link; "); \
break; \
case LOAD_REFRESH: \
printf("refresh; "); \
break; \
case LOAD_RELOAD_CHARSET_CHANGE: \
printf("reload charset change; "); \
break; \
case LOAD_BYPASS_HISTORY: \
printf("bypass history; "); \
break; \
case LOAD_STOP_CONTENT: \
printf("stop content; "); \
break; \
case LOAD_STOP_CONTENT_AND_REPLACE: \
printf("stop content and replace; "); \
break; \
case LOAD_PUSHSTATE: \
printf("load pushstate; "); \
break; \
case LOAD_ERROR_PAGE: \
printf("error page;"); \
break; \
default: \
printf("unknown"); \
} \
}
#define NS_LOG_ACCDOC_DOCINFO_BEGIN \
printf(" {\n");
#define NS_LOG_ACCDOC_DOCINFO_BODY(aDocument, aDocAcc) \
{ \
printf(" "); \
NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc) \
printf("\n "); \
if (aDocument) { \
NS_LOG_ACCDOC_URI(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
printf("; "); \
NS_LOG_ACCDOC_TYPE(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCSHELLTREE(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCSTATES(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
printf("\n "); \
NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
printf(", "); \
NS_LOG_ACCDOC_DOCPARENT(aDocument) \
printf("\n"); \
} \
}
#define NS_LOG_ACCDOC_DOCINFO_END \
printf(" }\n");
#define NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc) \
NS_LOG_ACCDOC_DOCINFO_BEGIN \
NS_LOG_ACCDOC_DOCINFO_BODY(aDocument, aDocAcc) \
NS_LOG_ACCDOC_DOCINFO_END
#define NS_GET_ACCDOC_EVENTTYPE(aEvent) \
nsCAutoString strEventType; \
PRUint32 type = aEvent->GetEventType(); \
if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) { \
strEventType.AssignLiteral("load stopped"); \
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) { \
strEventType.AssignLiteral("load complete"); \
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) { \
strEventType.AssignLiteral("reload"); \
} else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) { \
AccStateChangeEvent* event = downcast_accEvent(aEvent); \
if (event->GetState() == states::BUSY) { \
strEventType.AssignLiteral("busy "); \
if (event->IsStateEnabled()) \
strEventType.AppendLiteral("true"); \
else \
strEventType.AppendLiteral("false"); \
} \
}
#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");
#define NS_LOG_ACCDOC_STACK \
printf(" stack: \n"); \
nsTraceRefcntImpl::WalkTheStack(stdout);
// Accessible document loading macros.
#ifdef DEBUG_ACCDOCMGR_DOCLOAD
#define NS_LOG_ACCDOCLOAD_REQUEST(aRequest) \
if (aRequest) { \
nsCAutoString name; \
aRequest->GetName(name); \
printf(" request spec: %s\n", name.get()); \
PRUint32 loadFlags = 0; \
aRequest->GetLoadFlags(&loadFlags); \
printf(" request load flags: %x; ", loadFlags); \
if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI) \
printf("document uri; "); \
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) \
printf("retargeted document uri; "); \
if (loadFlags & nsIChannel::LOAD_REPLACE) \
printf("replace; "); \
if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI) \
printf("initial document uri; "); \
if (loadFlags & nsIChannel::LOAD_TARGETED) \
printf("targeted; "); \
if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) \
printf("call content sniffers; "); \
if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI) \
printf("classify uri; "); \
} else { \
printf(" no request"); \
}
#define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags) \
{ \
NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg); \
\
nsCOMPtr<nsIDOMWindow> DOMWindow; \
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow)); \
if (DOMWindow) { \
nsCOMPtr<nsIDOMDocument> DOMDocument; \
DOMWindow->GetDocument(getter_AddRefs(DOMDocument)); \
if (DOMDocument) { \
nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument)); \
nsDocAccessible *docAcc = \
GetAccService()->GetDocAccessibleFromCache(document); \
NS_LOG_ACCDOC_DOCINFO(document, docAcc) \
\
printf(" {\n"); \
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow)); \
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav)); \
printf(" "); \
NS_LOG_ACCDOC_SHELLLOADTYPE(docShell) \
printf("\n"); \
NS_LOG_ACCDOCLOAD_REQUEST(aRequest) \
printf("\n"); \
printf(" state flags: %x", aStateFlags); \
bool isDocLoading; \
aWebProgress->GetIsLoadingDocument(&isDocLoading); \
printf(", document is %sloading\n", (isDocLoading ? "" : "not ")); \
printf(" }\n"); \
} \
} \
}
#define NS_LOG_ACCDOCLOAD2(aMsg, aDocument) \
{ \
NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg); \
nsDocAccessible *docAcc = \
GetAccService()->GetDocAccessibleFromCache(aDocument); \
NS_LOG_ACCDOC_DOCINFO(aDocument, docAcc) \
}
#define NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent) \
{ \
NS_GET_ACCDOC_EVENTTYPE(aEvent) \
if (!strEventType.IsEmpty()) \
printf(" fire: %s\n", strEventType.get()); \
}
#define NS_LOG_ACCDOCLOAD_HANDLEEVENT(aEvent) \
{ \
NS_GET_ACCDOC_EVENTTYPE(aEvent) \
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aEvent->GetNode())); \
if (doc && !strEventType.IsEmpty()) { \
printf("\nA11Y DOCEVENT: handled '%s' event ", strEventType.get()); \
nsDocAccessible *docAcc = aEvent->GetDocAccessible(); \
NS_LOG_ACCDOC_DOCINFO(doc, docAcc) \
printf("\n"); \
} \
}
#define NS_LOG_ACCDOCLOAD_TEXT(aMsg) \
NS_LOG_ACCDOC_TEXT(aMsg)
#endif // DEBUG_ACCDOCMGR_DOCLOAD
// Accessible document creation macros.
#ifdef DEBUG_ACCDOCMGR_DOCCREATE
#define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc) \
NS_LOG_ACCDOC_MSG("A11Y DOCCREATE: " aMsg); \
NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
#define NS_LOG_ACCDOCCREATE(aMsg, aDocument) \
{ \
nsDocAccessible *docAcc = \
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)
#define NS_LOG_ACCDOCCREATE_STACK \
NS_LOG_ACCDOC_STACK
#endif // DEBUG_ACCDOCMGR_DOCCREATE
// Accessible document destruction macros.
#ifdef DEBUG_ACCDOCMGR_DOCDESTROY
#define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc) \
NS_LOG_ACCDOC_MSG("A11Y DOCDESTROY: " aMsg); \
NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
#define NS_LOG_ACCDOCDESTROY(aMsg, aDocument) \
{ \
nsDocAccessible* docAcc = \
GetAccService()->GetDocAccessibleFromCache(aDocument); \
NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc) \
}
#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
#endif // DEBUG_ACCDOCMGR
#ifndef DEBUG_ACCDOCMGR_DOCLOAD
#define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags)
#define NS_LOG_ACCDOCLOAD2(aMsg, aDocument)
#define NS_LOG_ACCDOCLOAD_EVENT(aMsg, aEvent)
#define NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)
#define NS_LOG_ACCDOCLOAD_HANDLEEVENT(aEvent)
#define NS_LOG_ACCDOCLOAD_TEXT(aMsg)
#endif
#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)
#define NS_LOG_ACCDOCCREATE_STACK
#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
#endif // nsAccDocManager_h_

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

@ -36,6 +36,10 @@
#include "nsHTMLWin32ObjectAccessible.h"
#endif
#ifdef DEBUG
#include "Logging.h"
#endif
#include "nsCURILoader.h"
#include "nsEventStates.h"
#include "nsIContentViewer.h"
@ -611,7 +615,10 @@ nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
if (!doc)
return;
NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocDestroy))
logging::DocDestroy("presshell destroyed", doc);
#endif
nsDocAccessible* docAccessible = GetDocAccessibleFromCache(doc);
if (docAccessible)
@ -884,6 +891,15 @@ nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::SetLogging(const nsACString& aModules)
{
#ifdef DEBUG
logging::Enable(PromiseFlatCString(aModules));
#endif
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessibilityService public
@ -1242,6 +1258,10 @@ nsAccessibilityService::Init()
static const PRUnichar kInitIndicator[] = { '1', 0 };
observerService->NotifyObservers(nsnull, "a11y-init-or-shutdown", kInitIndicator);
#ifdef DEBUG
logging::CheckEnv();
#endif
// Initialize accessibility.
nsAccessNodeWrap::InitAccessibility();

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

@ -43,6 +43,11 @@
#include "nsIWebNavigation.h"
#include "nsFocusManager.h"
#include "mozilla/dom/Element.h"
#ifdef DEBUG
#include "Logging.h"
#endif
#ifdef MOZ_XUL
#include "nsIXULDocument.h"
#endif
@ -581,7 +586,10 @@ nsDocAccessible::GetAccessible(nsINode* aNode) const
bool
nsDocAccessible::Init()
{
NS_LOG_ACCDOCCREATE_FOR("document initialize", mDocument, this)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocCreate))
logging::DocCreate("document initialize", mDocument, this);
#endif
// Initialize notification controller.
mNotificationController = new NotificationController(this, mPresShell);
@ -604,7 +612,10 @@ nsDocAccessible::Shutdown()
if (!mPresShell) // already shutdown
return;
NS_LOG_ACCDOCDESTROY_FOR("document shutdown", mDocument, this)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocDestroy))
logging::DocDestroy("document shutdown", mDocument, this);
#endif
if (mNotificationController) {
mNotificationController->Shutdown();
@ -818,7 +829,10 @@ void nsDocAccessible::AddScrollListener()
nsIScrollableFrame* sf = mPresShell->GetRootScrollFrameAsScrollableExternal();
if (sf) {
sf->AddScrollPositionListener(this);
NS_LOG_ACCDOCCREATE_TEXT("add scroll listener")
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocCreate))
logging::Text("add scroll listener");
#endif
}
}
@ -1264,14 +1278,14 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent)
////////////////////////////////////////////////////////////////////////////////
// nsAccessible
#ifdef DEBUG_ACCDOCMGR
#ifdef DEBUG
nsresult
nsDocAccessible::HandleAccEvent(AccEvent* aAccEvent)
nsDocAccessible::HandleAccEvent(AccEvent* aEvent)
{
NS_LOG_ACCDOCLOAD_HANDLEEVENT(aAccEvent)
return nsHyperTextAccessible::HandleAccEvent(aAccEvent);
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoadEventHandled(aEvent);
return nsHyperTextAccessible::HandleAccEvent(aEvent);
}
#endif
@ -1711,7 +1725,11 @@ nsresult
nsDocAccessible::FireDelayedAccessibleEvent(AccEvent* aEvent)
{
NS_ENSURE_ARG(aEvent);
NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocLoad))
logging::DocLoadEventFired(aEvent);
#endif
if (mNotificationController)
mNotificationController->QueueEvent(aEvent);

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

@ -86,8 +86,8 @@ public:
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
#ifdef DEBUG_ACCDOCMGR
virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
#ifdef DEBUG
virtual nsresult HandleAccEvent(AccEvent* aEvent);
#endif
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);

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

@ -10,6 +10,10 @@
#include "Role.h"
#include "States.h"
#ifdef DEBUG
#include "Logging.h"
#endif
using namespace mozilla;
using namespace mozilla::a11y;
@ -119,13 +123,21 @@ OuterDocAccessible::Shutdown()
// 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)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocDestroy)) {
logging::Msg("A11y outerdoc shutdown");
logging::Address("outerdoc", this);
}
#endif
nsAccessible* childAcc = mChildren.SafeElementAt(0, nsnull);
if (childAcc) {
NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown",
childAcc->GetDocumentNode())
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocDestroy)) {
logging::DocDestroy("outerdoc's child document shutdown",
childAcc->GetDocumentNode());
}
#endif
childAcc->Shutdown();
}
@ -164,9 +176,13 @@ OuterDocAccessible::AppendChild(nsAccessible* aAccessible)
if (!nsAccessibleWrap::AppendChild(aAccessible))
return false;
NS_LOG_ACCDOCCREATE("append document to outerdoc",
aAccessible->GetDocumentNode())
NS_LOG_ACCDOCCREATE_ACCADDRESS("outerdoc", this)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocCreate)) {
logging::DocCreate("append document to outerdoc",
aAccessible->GetDocumentNode());
logging::Address("outerdoc", this);
}
#endif
return true;
}
@ -180,9 +196,13 @@ OuterDocAccessible::RemoveChild(nsAccessible* aAccessible)
return false;
}
NS_LOG_ACCDOCDESTROY_FOR("remove document from outerdoc",
child->GetDocumentNode(), child)
NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
#ifdef DEBUG
if (logging::IsEnabled(logging::eDocDestroy)) {
logging::DocDestroy("remove document from outerdoc", child->GetDocumentNode(),
child->AsDoc());
logging::Address("outerdoc", this);
}
#endif
bool wasRemoved = nsAccessibleWrap::RemoveChild(child);