1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/base/Logging.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,838 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "Logging.h" 1.11 + 1.12 +#include "Accessible-inl.h" 1.13 +#include "AccEvent.h" 1.14 +#include "DocAccessible.h" 1.15 +#include "nsAccessibilityService.h" 1.16 +#include "nsCoreUtils.h" 1.17 +#include "OuterDocAccessible.h" 1.18 + 1.19 +#include "nsDocShellLoadTypes.h" 1.20 +#include "nsIChannel.h" 1.21 +#include "nsIInterfaceRequestorUtils.h" 1.22 +#include "nsISelectionPrivate.h" 1.23 +#include "nsTraceRefcnt.h" 1.24 +#include "nsIWebProgress.h" 1.25 +#include "prenv.h" 1.26 +#include "nsIDocShellTreeItem.h" 1.27 +#include "nsIURI.h" 1.28 +#include "mozilla/dom/Element.h" 1.29 + 1.30 +using namespace mozilla; 1.31 +using namespace mozilla::a11y; 1.32 + 1.33 +//////////////////////////////////////////////////////////////////////////////// 1.34 +// Logging helpers 1.35 + 1.36 +static uint32_t sModules = 0; 1.37 + 1.38 +struct ModuleRep { 1.39 + const char* mStr; 1.40 + logging::EModules mModule; 1.41 +}; 1.42 + 1.43 +static ModuleRep sModuleMap[] = { 1.44 + { "docload", logging::eDocLoad }, 1.45 + { "doccreate", logging::eDocCreate }, 1.46 + { "docdestroy", logging::eDocDestroy }, 1.47 + { "doclifecycle", logging::eDocLifeCycle }, 1.48 + 1.49 + { "events", logging::eEvents }, 1.50 + { "platforms", logging::ePlatforms }, 1.51 + { "stack", logging::eStack }, 1.52 + { "text", logging::eText }, 1.53 + { "tree", logging::eTree }, 1.54 + 1.55 + { "DOMEvents", logging::eDOMEvents }, 1.56 + { "focus", logging::eFocus }, 1.57 + { "selection", logging::eSelection }, 1.58 + { "notifications", logging::eNotifications } 1.59 +}; 1.60 + 1.61 +static void 1.62 +EnableLogging(const char* aModulesStr) 1.63 +{ 1.64 + sModules = 0; 1.65 + if (!aModulesStr) 1.66 + return; 1.67 + 1.68 + const char* token = aModulesStr; 1.69 + while (*token != '\0') { 1.70 + size_t tokenLen = strcspn(token, ","); 1.71 + for (unsigned int idx = 0; idx < ArrayLength(sModuleMap); idx++) { 1.72 + if (strncmp(token, sModuleMap[idx].mStr, tokenLen) == 0) { 1.73 +#if !defined(MOZ_PROFILING) && (!defined(DEBUG) || defined(MOZ_OPTIMIZE)) 1.74 + // Stack tracing on profiling enabled or debug not optimized builds. 1.75 + if (strncmp(token, "stack", tokenLen) == 0) 1.76 + break; 1.77 +#endif 1.78 + sModules |= sModuleMap[idx].mModule; 1.79 + printf("\n\nmodule enabled: %s\n", sModuleMap[idx].mStr); 1.80 + break; 1.81 + } 1.82 + } 1.83 + token += tokenLen; 1.84 + 1.85 + if (*token == ',') 1.86 + token++; // skip ',' char 1.87 + } 1.88 +} 1.89 + 1.90 +static void 1.91 +LogDocURI(nsIDocument* aDocumentNode) 1.92 +{ 1.93 + nsIURI* uri = aDocumentNode->GetDocumentURI(); 1.94 + nsAutoCString spec; 1.95 + uri->GetSpec(spec); 1.96 + printf("uri: %s", spec.get()); 1.97 +} 1.98 + 1.99 +static void 1.100 +LogDocShellState(nsIDocument* aDocumentNode) 1.101 +{ 1.102 + printf("docshell busy: "); 1.103 + 1.104 + nsAutoCString docShellBusy; 1.105 + nsCOMPtr<nsIDocShell> docShell = aDocumentNode->GetDocShell(); 1.106 + uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE; 1.107 + docShell->GetBusyFlags(&busyFlags); 1.108 + if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) 1.109 + printf("'none'"); 1.110 + if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) 1.111 + printf("'busy'"); 1.112 + if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) 1.113 + printf(", 'before page load'"); 1.114 + if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) 1.115 + printf(", 'page loading'"); 1.116 + 1.117 + printf("[failed]"); 1.118 +} 1.119 + 1.120 +static void 1.121 +LogDocType(nsIDocument* aDocumentNode) 1.122 +{ 1.123 + if (aDocumentNode->IsActive()) { 1.124 + bool isContent = nsCoreUtils::IsContentDocument(aDocumentNode); 1.125 + printf("%s document", (isContent ? "content" : "chrome")); 1.126 + } else { 1.127 + printf("document type: [failed]");\ 1.128 + } 1.129 +} 1.130 + 1.131 +static void 1.132 +LogDocShellTree(nsIDocument* aDocumentNode) 1.133 +{ 1.134 + if (aDocumentNode->IsActive()) { 1.135 + nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell()); 1.136 + nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; 1.137 + treeItem->GetParent(getter_AddRefs(parentTreeItem)); 1.138 + nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; 1.139 + treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); 1.140 + printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;", 1.141 + static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem), 1.142 + (nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no")); 1.143 + } 1.144 +} 1.145 + 1.146 +static void 1.147 +LogDocState(nsIDocument* aDocumentNode) 1.148 +{ 1.149 + const char* docState = nullptr; 1.150 + nsIDocument::ReadyState docStateFlag = aDocumentNode->GetReadyStateEnum(); 1.151 + switch (docStateFlag) { 1.152 + case nsIDocument::READYSTATE_UNINITIALIZED: 1.153 + docState = "uninitialized"; 1.154 + break; 1.155 + case nsIDocument::READYSTATE_LOADING: 1.156 + docState = "loading"; 1.157 + break; 1.158 + case nsIDocument::READYSTATE_INTERACTIVE: 1.159 + docState = "interactive"; 1.160 + break; 1.161 + case nsIDocument::READYSTATE_COMPLETE: 1.162 + docState = "complete"; 1.163 + break; 1.164 + } 1.165 + 1.166 + printf("doc state: %s", docState); 1.167 + printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not "); 1.168 + printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not "); 1.169 + printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not "); 1.170 + printf(", %svisible considering ancestors", aDocumentNode->IsVisibleConsideringAncestors() ? "" : "not "); 1.171 + printf(", %sactive", aDocumentNode->IsActive() ? "" : "not "); 1.172 + printf(", %sresource", aDocumentNode->IsResourceDoc() ? "" : "not "); 1.173 + printf(", has %srole content", 1.174 + nsCoreUtils::GetRoleContent(aDocumentNode) ? "" : "no "); 1.175 +} 1.176 + 1.177 +static void 1.178 +LogPresShell(nsIDocument* aDocumentNode) 1.179 +{ 1.180 + nsIPresShell* ps = aDocumentNode->GetShell(); 1.181 + printf("presshell: %p", static_cast<void*>(ps)); 1.182 + 1.183 + nsIScrollableFrame* sf = nullptr; 1.184 + if (ps) { 1.185 + printf(", is %s destroying", (ps->IsDestroying() ? "" : "not")); 1.186 + sf = ps->GetRootScrollFrameAsScrollable(); 1.187 + } 1.188 + printf(", root scroll frame: %p", static_cast<void*>(sf)); 1.189 +} 1.190 + 1.191 +static void 1.192 +LogDocLoadGroup(nsIDocument* aDocumentNode) 1.193 +{ 1.194 + nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup(); 1.195 + printf("load group: %p", static_cast<void*>(loadGroup)); 1.196 +} 1.197 + 1.198 +static void 1.199 +LogDocParent(nsIDocument* aDocumentNode) 1.200 +{ 1.201 + nsIDocument* parentDoc = aDocumentNode->GetParentDocument(); 1.202 + printf("parent id: %p", static_cast<void*>(parentDoc)); 1.203 + if (parentDoc) { 1.204 + printf("\n parent "); 1.205 + LogDocURI(parentDoc); 1.206 + printf("\n"); 1.207 + } 1.208 +} 1.209 + 1.210 +static void 1.211 +LogDocInfo(nsIDocument* aDocumentNode, DocAccessible* aDocument) 1.212 +{ 1.213 + printf(" DOM document: %p, acc document: %p\n ", 1.214 + static_cast<void*>(aDocumentNode), static_cast<void*>(aDocument)); 1.215 + 1.216 + // log document info 1.217 + if (aDocumentNode) { 1.218 + LogDocURI(aDocumentNode); 1.219 + printf("\n "); 1.220 + LogDocShellState(aDocumentNode); 1.221 + printf("; "); 1.222 + LogDocType(aDocumentNode); 1.223 + printf("\n "); 1.224 + LogDocShellTree(aDocumentNode); 1.225 + printf("\n "); 1.226 + LogDocState(aDocumentNode); 1.227 + printf("\n "); 1.228 + LogPresShell(aDocumentNode); 1.229 + printf("\n "); 1.230 + LogDocLoadGroup(aDocumentNode); 1.231 + printf(", "); 1.232 + LogDocParent(aDocumentNode); 1.233 + printf("\n"); 1.234 + } 1.235 +} 1.236 + 1.237 +static void 1.238 +LogShellLoadType(nsIDocShell* aDocShell) 1.239 +{ 1.240 + printf("load type: "); 1.241 + 1.242 + uint32_t loadType = 0; 1.243 + aDocShell->GetLoadType(&loadType); 1.244 + switch (loadType) { 1.245 + case LOAD_NORMAL: 1.246 + printf("normal; "); 1.247 + break; 1.248 + case LOAD_NORMAL_REPLACE: 1.249 + printf("normal replace; "); 1.250 + break; 1.251 + case LOAD_NORMAL_EXTERNAL: 1.252 + printf("normal external; "); 1.253 + break; 1.254 + case LOAD_HISTORY: 1.255 + printf("history; "); 1.256 + break; 1.257 + case LOAD_NORMAL_BYPASS_CACHE: 1.258 + printf("normal bypass cache; "); 1.259 + break; 1.260 + case LOAD_NORMAL_BYPASS_PROXY: 1.261 + printf("normal bypass proxy; "); 1.262 + break; 1.263 + case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE: 1.264 + printf("normal bypass proxy and cache; "); 1.265 + break; 1.266 + case LOAD_NORMAL_ALLOW_MIXED_CONTENT: 1.267 + printf("normal allow mixed content; "); 1.268 + break; 1.269 + case LOAD_RELOAD_NORMAL: 1.270 + printf("reload normal; "); 1.271 + break; 1.272 + case LOAD_RELOAD_BYPASS_CACHE: 1.273 + printf("reload bypass cache; "); 1.274 + break; 1.275 + case LOAD_RELOAD_BYPASS_PROXY: 1.276 + printf("reload bypass proxy; "); 1.277 + break; 1.278 + case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: 1.279 + printf("reload bypass proxy and cache; "); 1.280 + break; 1.281 + case LOAD_RELOAD_ALLOW_MIXED_CONTENT: 1.282 + printf("reload allow mixed content; "); 1.283 + break; 1.284 + case LOAD_LINK: 1.285 + printf("link; "); 1.286 + break; 1.287 + case LOAD_REFRESH: 1.288 + printf("refresh; "); 1.289 + break; 1.290 + case LOAD_RELOAD_CHARSET_CHANGE: 1.291 + printf("reload charset change; "); 1.292 + break; 1.293 + case LOAD_BYPASS_HISTORY: 1.294 + printf("bypass history; "); 1.295 + break; 1.296 + case LOAD_STOP_CONTENT: 1.297 + printf("stop content; "); 1.298 + break; 1.299 + case LOAD_STOP_CONTENT_AND_REPLACE: 1.300 + printf("stop content and replace; "); 1.301 + break; 1.302 + case LOAD_PUSHSTATE: 1.303 + printf("load pushstate; "); 1.304 + break; 1.305 + case LOAD_REPLACE_BYPASS_CACHE: 1.306 + printf("replace bypass cache; "); 1.307 + break; 1.308 + case LOAD_ERROR_PAGE: 1.309 + printf("error page;"); 1.310 + break; 1.311 + default: 1.312 + printf("unknown"); 1.313 + } 1.314 +} 1.315 + 1.316 +static void 1.317 +LogRequest(nsIRequest* aRequest) 1.318 +{ 1.319 + if (aRequest) { 1.320 + nsAutoCString name; 1.321 + aRequest->GetName(name); 1.322 + printf(" request spec: %s\n", name.get()); 1.323 + uint32_t loadFlags = 0; 1.324 + aRequest->GetLoadFlags(&loadFlags); 1.325 + printf(" request load flags: %x; ", loadFlags); 1.326 + if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI) 1.327 + printf("document uri; "); 1.328 + if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) 1.329 + printf("retargeted document uri; "); 1.330 + if (loadFlags & nsIChannel::LOAD_REPLACE) 1.331 + printf("replace; "); 1.332 + if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI) 1.333 + printf("initial document uri; "); 1.334 + if (loadFlags & nsIChannel::LOAD_TARGETED) 1.335 + printf("targeted; "); 1.336 + if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) 1.337 + printf("call content sniffers; "); 1.338 + if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI) 1.339 + printf("classify uri; "); 1.340 + } else { 1.341 + printf(" no request"); 1.342 + } 1.343 +} 1.344 + 1.345 +static void 1.346 +LogDocAccState(DocAccessible* aDocument) 1.347 +{ 1.348 + printf("document acc state: "); 1.349 + if (aDocument->HasLoadState(DocAccessible::eCompletelyLoaded)) 1.350 + printf("completely loaded;"); 1.351 + else if (aDocument->HasLoadState(DocAccessible::eReady)) 1.352 + printf("ready;"); 1.353 + else if (aDocument->HasLoadState(DocAccessible::eDOMLoaded)) 1.354 + printf("DOM loaded;"); 1.355 + else if (aDocument->HasLoadState(DocAccessible::eTreeConstructed)) 1.356 + printf("tree constructed;"); 1.357 +} 1.358 + 1.359 +static void 1.360 +GetDocLoadEventType(AccEvent* aEvent, nsACString& aEventType) 1.361 +{ 1.362 + uint32_t type = aEvent->GetEventType(); 1.363 + if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) { 1.364 + aEventType.AssignLiteral("load stopped"); 1.365 + } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) { 1.366 + aEventType.AssignLiteral("load complete"); 1.367 + } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) { 1.368 + aEventType.AssignLiteral("reload"); 1.369 + } else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) { 1.370 + AccStateChangeEvent* event = downcast_accEvent(aEvent); 1.371 + if (event->GetState() == states::BUSY) { 1.372 + aEventType.AssignLiteral("busy "); 1.373 + if (event->IsStateEnabled()) 1.374 + aEventType.AppendLiteral("true"); 1.375 + else 1.376 + aEventType.AppendLiteral("false"); 1.377 + } 1.378 + } 1.379 +} 1.380 + 1.381 +//////////////////////////////////////////////////////////////////////////////// 1.382 +// namespace logging:: document life cycle logging methods 1.383 + 1.384 +static const char* sDocLoadTitle = "DOCLOAD"; 1.385 +static const char* sDocCreateTitle = "DOCCREATE"; 1.386 +static const char* sDocDestroyTitle = "DOCDESTROY"; 1.387 +static const char* sDocEventTitle = "DOCEVENT"; 1.388 +static const char* sFocusTitle = "FOCUS"; 1.389 + 1.390 +void 1.391 +logging::DocLoad(const char* aMsg, nsIWebProgress* aWebProgress, 1.392 + nsIRequest* aRequest, uint32_t aStateFlags) 1.393 +{ 1.394 + MsgBegin(sDocLoadTitle, aMsg); 1.395 + 1.396 + nsCOMPtr<nsIDOMWindow> DOMWindow; 1.397 + aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow)); 1.398 + nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(DOMWindow); 1.399 + if (!window) { 1.400 + MsgEnd(); 1.401 + return; 1.402 + } 1.403 + 1.404 + nsCOMPtr<nsIDocument> documentNode = window->GetDoc(); 1.405 + if (!documentNode) { 1.406 + MsgEnd(); 1.407 + return; 1.408 + } 1.409 + 1.410 + DocAccessible* document = GetExistingDocAccessible(documentNode); 1.411 + 1.412 + LogDocInfo(documentNode, document); 1.413 + 1.414 + nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow)); 1.415 + nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav)); 1.416 + printf("\n "); 1.417 + LogShellLoadType(docShell); 1.418 + printf("\n"); 1.419 + LogRequest(aRequest); 1.420 + printf("\n"); 1.421 + printf(" state flags: %x", aStateFlags); 1.422 + bool isDocLoading; 1.423 + aWebProgress->GetIsLoadingDocument(&isDocLoading); 1.424 + printf(", document is %sloading\n", (isDocLoading ? "" : "not ")); 1.425 + 1.426 + MsgEnd(); 1.427 +} 1.428 + 1.429 +void 1.430 +logging::DocLoad(const char* aMsg, nsIDocument* aDocumentNode) 1.431 +{ 1.432 + MsgBegin(sDocLoadTitle, aMsg); 1.433 + 1.434 + DocAccessible* document = GetExistingDocAccessible(aDocumentNode); 1.435 + LogDocInfo(aDocumentNode, document); 1.436 + 1.437 + MsgEnd(); 1.438 +} 1.439 + 1.440 +void 1.441 +logging::DocCompleteLoad(DocAccessible* aDocument, bool aIsLoadEventTarget) 1.442 +{ 1.443 + MsgBegin(sDocLoadTitle, "document loaded *completely*"); 1.444 + 1.445 + printf(" DOM document: %p, acc document: %p\n", 1.446 + static_cast<void*>(aDocument->DocumentNode()), 1.447 + static_cast<void*>(aDocument)); 1.448 + 1.449 + printf(" "); 1.450 + LogDocURI(aDocument->DocumentNode()); 1.451 + printf("\n"); 1.452 + 1.453 + printf(" "); 1.454 + LogDocAccState(aDocument); 1.455 + printf("\n"); 1.456 + 1.457 + printf(" document is load event target: %s\n", 1.458 + (aIsLoadEventTarget ? "true" : "false")); 1.459 + 1.460 + MsgEnd(); 1.461 +} 1.462 + 1.463 +void 1.464 +logging::DocLoadEventFired(AccEvent* aEvent) 1.465 +{ 1.466 + nsAutoCString strEventType; 1.467 + GetDocLoadEventType(aEvent, strEventType); 1.468 + if (!strEventType.IsEmpty()) 1.469 + printf(" fire: %s\n", strEventType.get()); 1.470 +} 1.471 + 1.472 +void 1.473 +logging::DocLoadEventHandled(AccEvent* aEvent) 1.474 +{ 1.475 + nsAutoCString strEventType; 1.476 + GetDocLoadEventType(aEvent, strEventType); 1.477 + if (strEventType.IsEmpty()) 1.478 + return; 1.479 + 1.480 + MsgBegin(sDocEventTitle, "handled '%s' event", strEventType.get()); 1.481 + 1.482 + DocAccessible* document = aEvent->GetAccessible()->AsDoc(); 1.483 + if (document) 1.484 + LogDocInfo(document->DocumentNode(), document); 1.485 + 1.486 + MsgEnd(); 1.487 +} 1.488 + 1.489 +void 1.490 +logging::DocCreate(const char* aMsg, nsIDocument* aDocumentNode, 1.491 + DocAccessible* aDocument) 1.492 +{ 1.493 + DocAccessible* document = aDocument ? 1.494 + aDocument : GetExistingDocAccessible(aDocumentNode); 1.495 + 1.496 + MsgBegin(sDocCreateTitle, aMsg); 1.497 + LogDocInfo(aDocumentNode, document); 1.498 + MsgEnd(); 1.499 +} 1.500 + 1.501 +void 1.502 +logging::DocDestroy(const char* aMsg, nsIDocument* aDocumentNode, 1.503 + DocAccessible* aDocument) 1.504 +{ 1.505 + DocAccessible* document = aDocument ? 1.506 + aDocument : GetExistingDocAccessible(aDocumentNode); 1.507 + 1.508 + MsgBegin(sDocDestroyTitle, aMsg); 1.509 + LogDocInfo(aDocumentNode, document); 1.510 + MsgEnd(); 1.511 +} 1.512 + 1.513 +void 1.514 +logging::OuterDocDestroy(OuterDocAccessible* aOuterDoc) 1.515 +{ 1.516 + MsgBegin(sDocDestroyTitle, "outerdoc shutdown"); 1.517 + logging::Address("outerdoc", aOuterDoc); 1.518 + MsgEnd(); 1.519 +} 1.520 + 1.521 +void 1.522 +logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr, 1.523 + Accessible* aTarget) 1.524 +{ 1.525 + MsgBegin(sFocusTitle, aMsg); 1.526 + AccessibleNNode(aTargetDescr, aTarget); 1.527 + MsgEnd(); 1.528 +} 1.529 + 1.530 +void 1.531 +logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr, 1.532 + nsINode* aTargetNode) 1.533 +{ 1.534 + MsgBegin(sFocusTitle, aMsg); 1.535 + Node(aTargetDescr, aTargetNode); 1.536 + MsgEnd(); 1.537 +} 1.538 + 1.539 +void 1.540 +logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr, 1.541 + nsISupports* aTargetThing) 1.542 +{ 1.543 + MsgBegin(sFocusTitle, aMsg); 1.544 + 1.545 + if (aTargetThing) { 1.546 + nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTargetThing)); 1.547 + if (targetNode) 1.548 + AccessibleNNode(aTargetDescr, targetNode); 1.549 + else 1.550 + printf(" %s: %p, window\n", aTargetDescr, 1.551 + static_cast<void*>(aTargetThing)); 1.552 + } 1.553 + 1.554 + MsgEnd(); 1.555 +} 1.556 + 1.557 +void 1.558 +logging::ActiveItemChangeCausedBy(const char* aCause, Accessible* aTarget) 1.559 +{ 1.560 + SubMsgBegin(); 1.561 + printf(" Caused by: %s\n", aCause); 1.562 + AccessibleNNode("Item", aTarget); 1.563 + SubMsgEnd(); 1.564 +} 1.565 + 1.566 +void 1.567 +logging::ActiveWidget(Accessible* aWidget) 1.568 +{ 1.569 + SubMsgBegin(); 1.570 + 1.571 + AccessibleNNode("Widget", aWidget); 1.572 + printf(" Widget is active: %s, has operable items: %s\n", 1.573 + (aWidget && aWidget->IsActiveWidget() ? "true" : "false"), 1.574 + (aWidget && aWidget->AreItemsOperable() ? "true" : "false")); 1.575 + 1.576 + SubMsgEnd(); 1.577 +} 1.578 + 1.579 +void 1.580 +logging::FocusDispatched(Accessible* aTarget) 1.581 +{ 1.582 + SubMsgBegin(); 1.583 + AccessibleNNode("A11y target", aTarget); 1.584 + SubMsgEnd(); 1.585 +} 1.586 + 1.587 +void 1.588 +logging::SelChange(nsISelection* aSelection, DocAccessible* aDocument, 1.589 + int16_t aReason) 1.590 +{ 1.591 + nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection)); 1.592 + 1.593 + int16_t type = 0; 1.594 + privSel->GetType(&type); 1.595 + 1.596 + const char* strType = 0; 1.597 + if (type == nsISelectionController::SELECTION_NORMAL) 1.598 + strType = "normal"; 1.599 + else if (type == nsISelectionController::SELECTION_SPELLCHECK) 1.600 + strType = "spellcheck"; 1.601 + else 1.602 + strType = "unknown"; 1.603 + 1.604 + bool isIgnored = !aDocument || !aDocument->IsContentLoaded(); 1.605 + printf("\nSelection changed, selection type: %s, notification %s, reason: %d\n", 1.606 + strType, (isIgnored ? "ignored" : "pending"), aReason); 1.607 + 1.608 + Stack(); 1.609 +} 1.610 + 1.611 +void 1.612 +logging::MsgBegin(const char* aTitle, const char* aMsgText, ...) 1.613 +{ 1.614 + printf("\nA11Y %s: ", aTitle); 1.615 + 1.616 + va_list argptr; 1.617 + va_start(argptr, aMsgText); 1.618 + vprintf(aMsgText, argptr); 1.619 + va_end(argptr); 1.620 + 1.621 + PRIntervalTime time = PR_IntervalNow(); 1.622 + uint32_t mins = (PR_IntervalToSeconds(time) / 60) % 60; 1.623 + uint32_t secs = PR_IntervalToSeconds(time) % 60; 1.624 + uint32_t msecs = PR_IntervalToMilliseconds(time) % 1000; 1.625 + printf("; %02d:%02d.%03d", mins, secs, msecs); 1.626 + 1.627 + printf("\n {\n"); 1.628 +} 1.629 + 1.630 +void 1.631 +logging::MsgEnd() 1.632 +{ 1.633 + printf(" }\n"); 1.634 +} 1.635 + 1.636 +void 1.637 +logging::SubMsgBegin() 1.638 +{ 1.639 + printf(" {\n"); 1.640 +} 1.641 + 1.642 +void 1.643 +logging::SubMsgEnd() 1.644 +{ 1.645 + printf(" }\n"); 1.646 +} 1.647 + 1.648 +void 1.649 +logging::MsgEntry(const char* aEntryText, ...) 1.650 +{ 1.651 + printf(" "); 1.652 + 1.653 + va_list argptr; 1.654 + va_start(argptr, aEntryText); 1.655 + vprintf(aEntryText, argptr); 1.656 + va_end(argptr); 1.657 + 1.658 + printf("\n"); 1.659 +} 1.660 + 1.661 +void 1.662 +logging::Text(const char* aText) 1.663 +{ 1.664 + printf(" %s\n", aText); 1.665 +} 1.666 + 1.667 +void 1.668 +logging::Address(const char* aDescr, Accessible* aAcc) 1.669 +{ 1.670 + if (!aAcc->IsDoc()) { 1.671 + printf(" %s accessible: %p, node: %p\n", aDescr, 1.672 + static_cast<void*>(aAcc), static_cast<void*>(aAcc->GetNode())); 1.673 + } 1.674 + 1.675 + DocAccessible* doc = aAcc->Document(); 1.676 + nsIDocument* docNode = doc->DocumentNode(); 1.677 + printf(" document: %p, node: %p\n", 1.678 + static_cast<void*>(doc), static_cast<void*>(docNode)); 1.679 + 1.680 + printf(" "); 1.681 + LogDocURI(docNode); 1.682 + printf("\n"); 1.683 +} 1.684 + 1.685 +void 1.686 +logging::Node(const char* aDescr, nsINode* aNode) 1.687 +{ 1.688 + printf(" "); 1.689 + 1.690 + if (!aNode) { 1.691 + printf("%s: null\n", aDescr); 1.692 + return; 1.693 + } 1.694 + 1.695 + if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) { 1.696 + printf("%s: %p, document\n", aDescr, static_cast<void*>(aNode)); 1.697 + return; 1.698 + } 1.699 + 1.700 + nsINode* parentNode = aNode->GetParentNode(); 1.701 + int32_t idxInParent = parentNode ? parentNode->IndexOf(aNode) : - 1; 1.702 + 1.703 + if (aNode->IsNodeOfType(nsINode::eTEXT)) { 1.704 + printf("%s: %p, text node, idx in parent: %d\n", 1.705 + aDescr, static_cast<void*>(aNode), idxInParent); 1.706 + return; 1.707 + } 1.708 + 1.709 + if (!aNode->IsElement()) { 1.710 + printf("%s: %p, not accessible node type, idx in parent: %d\n", 1.711 + aDescr, static_cast<void*>(aNode), idxInParent); 1.712 + return; 1.713 + } 1.714 + 1.715 + dom::Element* elm = aNode->AsElement(); 1.716 + 1.717 + nsAutoCString tag; 1.718 + elm->Tag()->ToUTF8String(tag); 1.719 + 1.720 + nsIAtom* idAtom = elm->GetID(); 1.721 + nsAutoCString id; 1.722 + if (idAtom) 1.723 + idAtom->ToUTF8String(id); 1.724 + 1.725 + printf("%s: %p, %s@id='%s', idx in parent: %d\n", 1.726 + aDescr, static_cast<void*>(elm), tag.get(), id.get(), idxInParent); 1.727 +} 1.728 + 1.729 +void 1.730 +logging::Document(DocAccessible* aDocument) 1.731 +{ 1.732 + printf(" Document: %p, document node: %p\n", 1.733 + static_cast<void*>(aDocument), 1.734 + static_cast<void*>(aDocument->DocumentNode())); 1.735 + 1.736 + printf(" Document "); 1.737 + LogDocURI(aDocument->DocumentNode()); 1.738 + printf("\n"); 1.739 +} 1.740 + 1.741 +void 1.742 +logging::AccessibleNNode(const char* aDescr, Accessible* aAccessible) 1.743 +{ 1.744 + printf(" %s: %p; ", aDescr, static_cast<void*>(aAccessible)); 1.745 + if (!aAccessible) 1.746 + return; 1.747 + 1.748 + nsAutoString role; 1.749 + GetAccService()->GetStringRole(aAccessible->Role(), role); 1.750 + nsAutoString name; 1.751 + aAccessible->Name(name); 1.752 + 1.753 + printf("role: %s, name: '%s';\n", NS_ConvertUTF16toUTF8(role).get(), 1.754 + NS_ConvertUTF16toUTF8(name).get()); 1.755 + 1.756 + nsAutoCString nodeDescr(aDescr); 1.757 + nodeDescr.AppendLiteral(" node"); 1.758 + Node(nodeDescr.get(), aAccessible->GetNode()); 1.759 + 1.760 + Document(aAccessible->Document()); 1.761 +} 1.762 + 1.763 +void 1.764 +logging::AccessibleNNode(const char* aDescr, nsINode* aNode) 1.765 +{ 1.766 + DocAccessible* document = 1.767 + GetAccService()->GetDocAccessible(aNode->OwnerDoc()); 1.768 + 1.769 + if (document) { 1.770 + Accessible* accessible = document->GetAccessible(aNode); 1.771 + if (accessible) { 1.772 + AccessibleNNode(aDescr, accessible); 1.773 + return; 1.774 + } 1.775 + } 1.776 + 1.777 + nsAutoCString nodeDescr("[not accessible] "); 1.778 + nodeDescr.Append(aDescr); 1.779 + Node(nodeDescr.get(), aNode); 1.780 + 1.781 + if (document) { 1.782 + Document(document); 1.783 + return; 1.784 + } 1.785 + 1.786 + printf(" [contained by not accessible document]:\n"); 1.787 + LogDocInfo(aNode->OwnerDoc(), document); 1.788 + printf("\n"); 1.789 +} 1.790 + 1.791 +void 1.792 +logging::DOMEvent(const char* aDescr, nsINode* aOrigTarget, 1.793 + const nsAString& aEventType) 1.794 +{ 1.795 + logging::MsgBegin("DOMEvents", "event '%s' %s", 1.796 + NS_ConvertUTF16toUTF8(aEventType).get(), aDescr); 1.797 + logging::AccessibleNNode("Target", aOrigTarget); 1.798 + logging::MsgEnd(); 1.799 +} 1.800 + 1.801 +void 1.802 +logging::Stack() 1.803 +{ 1.804 + if (IsEnabled(eStack)) { 1.805 + printf(" stack: \n"); 1.806 + nsTraceRefcnt::WalkTheStack(stdout); 1.807 + } 1.808 +} 1.809 + 1.810 +//////////////////////////////////////////////////////////////////////////////// 1.811 +// namespace logging:: initialization 1.812 + 1.813 +bool 1.814 +logging::IsEnabled(uint32_t aModules) 1.815 +{ 1.816 + return sModules & aModules; 1.817 +} 1.818 + 1.819 +bool 1.820 +logging::IsEnabled(const nsAString& aModuleStr) 1.821 +{ 1.822 + for (unsigned int idx = 0; idx < ArrayLength(sModuleMap); idx++) { 1.823 + if (aModuleStr.EqualsASCII(sModuleMap[idx].mStr)) 1.824 + return sModules & sModuleMap[idx].mModule; 1.825 + } 1.826 + 1.827 + return false; 1.828 +} 1.829 + 1.830 +void 1.831 +logging::Enable(const nsAFlatCString& aModules) 1.832 +{ 1.833 + EnableLogging(aModules.get()); 1.834 +} 1.835 + 1.836 + 1.837 +void 1.838 +logging::CheckEnv() 1.839 +{ 1.840 + EnableLogging(PR_GetEnv("A11YLOG")); 1.841 +}