accessible/src/base/Logging.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "Logging.h"
michael@0 8
michael@0 9 #include "Accessible-inl.h"
michael@0 10 #include "AccEvent.h"
michael@0 11 #include "DocAccessible.h"
michael@0 12 #include "nsAccessibilityService.h"
michael@0 13 #include "nsCoreUtils.h"
michael@0 14 #include "OuterDocAccessible.h"
michael@0 15
michael@0 16 #include "nsDocShellLoadTypes.h"
michael@0 17 #include "nsIChannel.h"
michael@0 18 #include "nsIInterfaceRequestorUtils.h"
michael@0 19 #include "nsISelectionPrivate.h"
michael@0 20 #include "nsTraceRefcnt.h"
michael@0 21 #include "nsIWebProgress.h"
michael@0 22 #include "prenv.h"
michael@0 23 #include "nsIDocShellTreeItem.h"
michael@0 24 #include "nsIURI.h"
michael@0 25 #include "mozilla/dom/Element.h"
michael@0 26
michael@0 27 using namespace mozilla;
michael@0 28 using namespace mozilla::a11y;
michael@0 29
michael@0 30 ////////////////////////////////////////////////////////////////////////////////
michael@0 31 // Logging helpers
michael@0 32
michael@0 33 static uint32_t sModules = 0;
michael@0 34
michael@0 35 struct ModuleRep {
michael@0 36 const char* mStr;
michael@0 37 logging::EModules mModule;
michael@0 38 };
michael@0 39
michael@0 40 static ModuleRep sModuleMap[] = {
michael@0 41 { "docload", logging::eDocLoad },
michael@0 42 { "doccreate", logging::eDocCreate },
michael@0 43 { "docdestroy", logging::eDocDestroy },
michael@0 44 { "doclifecycle", logging::eDocLifeCycle },
michael@0 45
michael@0 46 { "events", logging::eEvents },
michael@0 47 { "platforms", logging::ePlatforms },
michael@0 48 { "stack", logging::eStack },
michael@0 49 { "text", logging::eText },
michael@0 50 { "tree", logging::eTree },
michael@0 51
michael@0 52 { "DOMEvents", logging::eDOMEvents },
michael@0 53 { "focus", logging::eFocus },
michael@0 54 { "selection", logging::eSelection },
michael@0 55 { "notifications", logging::eNotifications }
michael@0 56 };
michael@0 57
michael@0 58 static void
michael@0 59 EnableLogging(const char* aModulesStr)
michael@0 60 {
michael@0 61 sModules = 0;
michael@0 62 if (!aModulesStr)
michael@0 63 return;
michael@0 64
michael@0 65 const char* token = aModulesStr;
michael@0 66 while (*token != '\0') {
michael@0 67 size_t tokenLen = strcspn(token, ",");
michael@0 68 for (unsigned int idx = 0; idx < ArrayLength(sModuleMap); idx++) {
michael@0 69 if (strncmp(token, sModuleMap[idx].mStr, tokenLen) == 0) {
michael@0 70 #if !defined(MOZ_PROFILING) && (!defined(DEBUG) || defined(MOZ_OPTIMIZE))
michael@0 71 // Stack tracing on profiling enabled or debug not optimized builds.
michael@0 72 if (strncmp(token, "stack", tokenLen) == 0)
michael@0 73 break;
michael@0 74 #endif
michael@0 75 sModules |= sModuleMap[idx].mModule;
michael@0 76 printf("\n\nmodule enabled: %s\n", sModuleMap[idx].mStr);
michael@0 77 break;
michael@0 78 }
michael@0 79 }
michael@0 80 token += tokenLen;
michael@0 81
michael@0 82 if (*token == ',')
michael@0 83 token++; // skip ',' char
michael@0 84 }
michael@0 85 }
michael@0 86
michael@0 87 static void
michael@0 88 LogDocURI(nsIDocument* aDocumentNode)
michael@0 89 {
michael@0 90 nsIURI* uri = aDocumentNode->GetDocumentURI();
michael@0 91 nsAutoCString spec;
michael@0 92 uri->GetSpec(spec);
michael@0 93 printf("uri: %s", spec.get());
michael@0 94 }
michael@0 95
michael@0 96 static void
michael@0 97 LogDocShellState(nsIDocument* aDocumentNode)
michael@0 98 {
michael@0 99 printf("docshell busy: ");
michael@0 100
michael@0 101 nsAutoCString docShellBusy;
michael@0 102 nsCOMPtr<nsIDocShell> docShell = aDocumentNode->GetDocShell();
michael@0 103 uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
michael@0 104 docShell->GetBusyFlags(&busyFlags);
michael@0 105 if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE)
michael@0 106 printf("'none'");
michael@0 107 if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY)
michael@0 108 printf("'busy'");
michael@0 109 if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD)
michael@0 110 printf(", 'before page load'");
michael@0 111 if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)
michael@0 112 printf(", 'page loading'");
michael@0 113
michael@0 114 printf("[failed]");
michael@0 115 }
michael@0 116
michael@0 117 static void
michael@0 118 LogDocType(nsIDocument* aDocumentNode)
michael@0 119 {
michael@0 120 if (aDocumentNode->IsActive()) {
michael@0 121 bool isContent = nsCoreUtils::IsContentDocument(aDocumentNode);
michael@0 122 printf("%s document", (isContent ? "content" : "chrome"));
michael@0 123 } else {
michael@0 124 printf("document type: [failed]");\
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 static void
michael@0 129 LogDocShellTree(nsIDocument* aDocumentNode)
michael@0 130 {
michael@0 131 if (aDocumentNode->IsActive()) {
michael@0 132 nsCOMPtr<nsIDocShellTreeItem> treeItem(aDocumentNode->GetDocShell());
michael@0 133 nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
michael@0 134 treeItem->GetParent(getter_AddRefs(parentTreeItem));
michael@0 135 nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
michael@0 136 treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
michael@0 137 printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;",
michael@0 138 static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem),
michael@0 139 (nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no"));
michael@0 140 }
michael@0 141 }
michael@0 142
michael@0 143 static void
michael@0 144 LogDocState(nsIDocument* aDocumentNode)
michael@0 145 {
michael@0 146 const char* docState = nullptr;
michael@0 147 nsIDocument::ReadyState docStateFlag = aDocumentNode->GetReadyStateEnum();
michael@0 148 switch (docStateFlag) {
michael@0 149 case nsIDocument::READYSTATE_UNINITIALIZED:
michael@0 150 docState = "uninitialized";
michael@0 151 break;
michael@0 152 case nsIDocument::READYSTATE_LOADING:
michael@0 153 docState = "loading";
michael@0 154 break;
michael@0 155 case nsIDocument::READYSTATE_INTERACTIVE:
michael@0 156 docState = "interactive";
michael@0 157 break;
michael@0 158 case nsIDocument::READYSTATE_COMPLETE:
michael@0 159 docState = "complete";
michael@0 160 break;
michael@0 161 }
michael@0 162
michael@0 163 printf("doc state: %s", docState);
michael@0 164 printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not ");
michael@0 165 printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not ");
michael@0 166 printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not ");
michael@0 167 printf(", %svisible considering ancestors", aDocumentNode->IsVisibleConsideringAncestors() ? "" : "not ");
michael@0 168 printf(", %sactive", aDocumentNode->IsActive() ? "" : "not ");
michael@0 169 printf(", %sresource", aDocumentNode->IsResourceDoc() ? "" : "not ");
michael@0 170 printf(", has %srole content",
michael@0 171 nsCoreUtils::GetRoleContent(aDocumentNode) ? "" : "no ");
michael@0 172 }
michael@0 173
michael@0 174 static void
michael@0 175 LogPresShell(nsIDocument* aDocumentNode)
michael@0 176 {
michael@0 177 nsIPresShell* ps = aDocumentNode->GetShell();
michael@0 178 printf("presshell: %p", static_cast<void*>(ps));
michael@0 179
michael@0 180 nsIScrollableFrame* sf = nullptr;
michael@0 181 if (ps) {
michael@0 182 printf(", is %s destroying", (ps->IsDestroying() ? "" : "not"));
michael@0 183 sf = ps->GetRootScrollFrameAsScrollable();
michael@0 184 }
michael@0 185 printf(", root scroll frame: %p", static_cast<void*>(sf));
michael@0 186 }
michael@0 187
michael@0 188 static void
michael@0 189 LogDocLoadGroup(nsIDocument* aDocumentNode)
michael@0 190 {
michael@0 191 nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup();
michael@0 192 printf("load group: %p", static_cast<void*>(loadGroup));
michael@0 193 }
michael@0 194
michael@0 195 static void
michael@0 196 LogDocParent(nsIDocument* aDocumentNode)
michael@0 197 {
michael@0 198 nsIDocument* parentDoc = aDocumentNode->GetParentDocument();
michael@0 199 printf("parent id: %p", static_cast<void*>(parentDoc));
michael@0 200 if (parentDoc) {
michael@0 201 printf("\n parent ");
michael@0 202 LogDocURI(parentDoc);
michael@0 203 printf("\n");
michael@0 204 }
michael@0 205 }
michael@0 206
michael@0 207 static void
michael@0 208 LogDocInfo(nsIDocument* aDocumentNode, DocAccessible* aDocument)
michael@0 209 {
michael@0 210 printf(" DOM document: %p, acc document: %p\n ",
michael@0 211 static_cast<void*>(aDocumentNode), static_cast<void*>(aDocument));
michael@0 212
michael@0 213 // log document info
michael@0 214 if (aDocumentNode) {
michael@0 215 LogDocURI(aDocumentNode);
michael@0 216 printf("\n ");
michael@0 217 LogDocShellState(aDocumentNode);
michael@0 218 printf("; ");
michael@0 219 LogDocType(aDocumentNode);
michael@0 220 printf("\n ");
michael@0 221 LogDocShellTree(aDocumentNode);
michael@0 222 printf("\n ");
michael@0 223 LogDocState(aDocumentNode);
michael@0 224 printf("\n ");
michael@0 225 LogPresShell(aDocumentNode);
michael@0 226 printf("\n ");
michael@0 227 LogDocLoadGroup(aDocumentNode);
michael@0 228 printf(", ");
michael@0 229 LogDocParent(aDocumentNode);
michael@0 230 printf("\n");
michael@0 231 }
michael@0 232 }
michael@0 233
michael@0 234 static void
michael@0 235 LogShellLoadType(nsIDocShell* aDocShell)
michael@0 236 {
michael@0 237 printf("load type: ");
michael@0 238
michael@0 239 uint32_t loadType = 0;
michael@0 240 aDocShell->GetLoadType(&loadType);
michael@0 241 switch (loadType) {
michael@0 242 case LOAD_NORMAL:
michael@0 243 printf("normal; ");
michael@0 244 break;
michael@0 245 case LOAD_NORMAL_REPLACE:
michael@0 246 printf("normal replace; ");
michael@0 247 break;
michael@0 248 case LOAD_NORMAL_EXTERNAL:
michael@0 249 printf("normal external; ");
michael@0 250 break;
michael@0 251 case LOAD_HISTORY:
michael@0 252 printf("history; ");
michael@0 253 break;
michael@0 254 case LOAD_NORMAL_BYPASS_CACHE:
michael@0 255 printf("normal bypass cache; ");
michael@0 256 break;
michael@0 257 case LOAD_NORMAL_BYPASS_PROXY:
michael@0 258 printf("normal bypass proxy; ");
michael@0 259 break;
michael@0 260 case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:
michael@0 261 printf("normal bypass proxy and cache; ");
michael@0 262 break;
michael@0 263 case LOAD_NORMAL_ALLOW_MIXED_CONTENT:
michael@0 264 printf("normal allow mixed content; ");
michael@0 265 break;
michael@0 266 case LOAD_RELOAD_NORMAL:
michael@0 267 printf("reload normal; ");
michael@0 268 break;
michael@0 269 case LOAD_RELOAD_BYPASS_CACHE:
michael@0 270 printf("reload bypass cache; ");
michael@0 271 break;
michael@0 272 case LOAD_RELOAD_BYPASS_PROXY:
michael@0 273 printf("reload bypass proxy; ");
michael@0 274 break;
michael@0 275 case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
michael@0 276 printf("reload bypass proxy and cache; ");
michael@0 277 break;
michael@0 278 case LOAD_RELOAD_ALLOW_MIXED_CONTENT:
michael@0 279 printf("reload allow mixed content; ");
michael@0 280 break;
michael@0 281 case LOAD_LINK:
michael@0 282 printf("link; ");
michael@0 283 break;
michael@0 284 case LOAD_REFRESH:
michael@0 285 printf("refresh; ");
michael@0 286 break;
michael@0 287 case LOAD_RELOAD_CHARSET_CHANGE:
michael@0 288 printf("reload charset change; ");
michael@0 289 break;
michael@0 290 case LOAD_BYPASS_HISTORY:
michael@0 291 printf("bypass history; ");
michael@0 292 break;
michael@0 293 case LOAD_STOP_CONTENT:
michael@0 294 printf("stop content; ");
michael@0 295 break;
michael@0 296 case LOAD_STOP_CONTENT_AND_REPLACE:
michael@0 297 printf("stop content and replace; ");
michael@0 298 break;
michael@0 299 case LOAD_PUSHSTATE:
michael@0 300 printf("load pushstate; ");
michael@0 301 break;
michael@0 302 case LOAD_REPLACE_BYPASS_CACHE:
michael@0 303 printf("replace bypass cache; ");
michael@0 304 break;
michael@0 305 case LOAD_ERROR_PAGE:
michael@0 306 printf("error page;");
michael@0 307 break;
michael@0 308 default:
michael@0 309 printf("unknown");
michael@0 310 }
michael@0 311 }
michael@0 312
michael@0 313 static void
michael@0 314 LogRequest(nsIRequest* aRequest)
michael@0 315 {
michael@0 316 if (aRequest) {
michael@0 317 nsAutoCString name;
michael@0 318 aRequest->GetName(name);
michael@0 319 printf(" request spec: %s\n", name.get());
michael@0 320 uint32_t loadFlags = 0;
michael@0 321 aRequest->GetLoadFlags(&loadFlags);
michael@0 322 printf(" request load flags: %x; ", loadFlags);
michael@0 323 if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI)
michael@0 324 printf("document uri; ");
michael@0 325 if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
michael@0 326 printf("retargeted document uri; ");
michael@0 327 if (loadFlags & nsIChannel::LOAD_REPLACE)
michael@0 328 printf("replace; ");
michael@0 329 if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI)
michael@0 330 printf("initial document uri; ");
michael@0 331 if (loadFlags & nsIChannel::LOAD_TARGETED)
michael@0 332 printf("targeted; ");
michael@0 333 if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS)
michael@0 334 printf("call content sniffers; ");
michael@0 335 if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI)
michael@0 336 printf("classify uri; ");
michael@0 337 } else {
michael@0 338 printf(" no request");
michael@0 339 }
michael@0 340 }
michael@0 341
michael@0 342 static void
michael@0 343 LogDocAccState(DocAccessible* aDocument)
michael@0 344 {
michael@0 345 printf("document acc state: ");
michael@0 346 if (aDocument->HasLoadState(DocAccessible::eCompletelyLoaded))
michael@0 347 printf("completely loaded;");
michael@0 348 else if (aDocument->HasLoadState(DocAccessible::eReady))
michael@0 349 printf("ready;");
michael@0 350 else if (aDocument->HasLoadState(DocAccessible::eDOMLoaded))
michael@0 351 printf("DOM loaded;");
michael@0 352 else if (aDocument->HasLoadState(DocAccessible::eTreeConstructed))
michael@0 353 printf("tree constructed;");
michael@0 354 }
michael@0 355
michael@0 356 static void
michael@0 357 GetDocLoadEventType(AccEvent* aEvent, nsACString& aEventType)
michael@0 358 {
michael@0 359 uint32_t type = aEvent->GetEventType();
michael@0 360 if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) {
michael@0 361 aEventType.AssignLiteral("load stopped");
michael@0 362 } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) {
michael@0 363 aEventType.AssignLiteral("load complete");
michael@0 364 } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) {
michael@0 365 aEventType.AssignLiteral("reload");
michael@0 366 } else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) {
michael@0 367 AccStateChangeEvent* event = downcast_accEvent(aEvent);
michael@0 368 if (event->GetState() == states::BUSY) {
michael@0 369 aEventType.AssignLiteral("busy ");
michael@0 370 if (event->IsStateEnabled())
michael@0 371 aEventType.AppendLiteral("true");
michael@0 372 else
michael@0 373 aEventType.AppendLiteral("false");
michael@0 374 }
michael@0 375 }
michael@0 376 }
michael@0 377
michael@0 378 ////////////////////////////////////////////////////////////////////////////////
michael@0 379 // namespace logging:: document life cycle logging methods
michael@0 380
michael@0 381 static const char* sDocLoadTitle = "DOCLOAD";
michael@0 382 static const char* sDocCreateTitle = "DOCCREATE";
michael@0 383 static const char* sDocDestroyTitle = "DOCDESTROY";
michael@0 384 static const char* sDocEventTitle = "DOCEVENT";
michael@0 385 static const char* sFocusTitle = "FOCUS";
michael@0 386
michael@0 387 void
michael@0 388 logging::DocLoad(const char* aMsg, nsIWebProgress* aWebProgress,
michael@0 389 nsIRequest* aRequest, uint32_t aStateFlags)
michael@0 390 {
michael@0 391 MsgBegin(sDocLoadTitle, aMsg);
michael@0 392
michael@0 393 nsCOMPtr<nsIDOMWindow> DOMWindow;
michael@0 394 aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));
michael@0 395 nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(DOMWindow);
michael@0 396 if (!window) {
michael@0 397 MsgEnd();
michael@0 398 return;
michael@0 399 }
michael@0 400
michael@0 401 nsCOMPtr<nsIDocument> documentNode = window->GetDoc();
michael@0 402 if (!documentNode) {
michael@0 403 MsgEnd();
michael@0 404 return;
michael@0 405 }
michael@0 406
michael@0 407 DocAccessible* document = GetExistingDocAccessible(documentNode);
michael@0 408
michael@0 409 LogDocInfo(documentNode, document);
michael@0 410
michael@0 411 nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
michael@0 412 nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
michael@0 413 printf("\n ");
michael@0 414 LogShellLoadType(docShell);
michael@0 415 printf("\n");
michael@0 416 LogRequest(aRequest);
michael@0 417 printf("\n");
michael@0 418 printf(" state flags: %x", aStateFlags);
michael@0 419 bool isDocLoading;
michael@0 420 aWebProgress->GetIsLoadingDocument(&isDocLoading);
michael@0 421 printf(", document is %sloading\n", (isDocLoading ? "" : "not "));
michael@0 422
michael@0 423 MsgEnd();
michael@0 424 }
michael@0 425
michael@0 426 void
michael@0 427 logging::DocLoad(const char* aMsg, nsIDocument* aDocumentNode)
michael@0 428 {
michael@0 429 MsgBegin(sDocLoadTitle, aMsg);
michael@0 430
michael@0 431 DocAccessible* document = GetExistingDocAccessible(aDocumentNode);
michael@0 432 LogDocInfo(aDocumentNode, document);
michael@0 433
michael@0 434 MsgEnd();
michael@0 435 }
michael@0 436
michael@0 437 void
michael@0 438 logging::DocCompleteLoad(DocAccessible* aDocument, bool aIsLoadEventTarget)
michael@0 439 {
michael@0 440 MsgBegin(sDocLoadTitle, "document loaded *completely*");
michael@0 441
michael@0 442 printf(" DOM document: %p, acc document: %p\n",
michael@0 443 static_cast<void*>(aDocument->DocumentNode()),
michael@0 444 static_cast<void*>(aDocument));
michael@0 445
michael@0 446 printf(" ");
michael@0 447 LogDocURI(aDocument->DocumentNode());
michael@0 448 printf("\n");
michael@0 449
michael@0 450 printf(" ");
michael@0 451 LogDocAccState(aDocument);
michael@0 452 printf("\n");
michael@0 453
michael@0 454 printf(" document is load event target: %s\n",
michael@0 455 (aIsLoadEventTarget ? "true" : "false"));
michael@0 456
michael@0 457 MsgEnd();
michael@0 458 }
michael@0 459
michael@0 460 void
michael@0 461 logging::DocLoadEventFired(AccEvent* aEvent)
michael@0 462 {
michael@0 463 nsAutoCString strEventType;
michael@0 464 GetDocLoadEventType(aEvent, strEventType);
michael@0 465 if (!strEventType.IsEmpty())
michael@0 466 printf(" fire: %s\n", strEventType.get());
michael@0 467 }
michael@0 468
michael@0 469 void
michael@0 470 logging::DocLoadEventHandled(AccEvent* aEvent)
michael@0 471 {
michael@0 472 nsAutoCString strEventType;
michael@0 473 GetDocLoadEventType(aEvent, strEventType);
michael@0 474 if (strEventType.IsEmpty())
michael@0 475 return;
michael@0 476
michael@0 477 MsgBegin(sDocEventTitle, "handled '%s' event", strEventType.get());
michael@0 478
michael@0 479 DocAccessible* document = aEvent->GetAccessible()->AsDoc();
michael@0 480 if (document)
michael@0 481 LogDocInfo(document->DocumentNode(), document);
michael@0 482
michael@0 483 MsgEnd();
michael@0 484 }
michael@0 485
michael@0 486 void
michael@0 487 logging::DocCreate(const char* aMsg, nsIDocument* aDocumentNode,
michael@0 488 DocAccessible* aDocument)
michael@0 489 {
michael@0 490 DocAccessible* document = aDocument ?
michael@0 491 aDocument : GetExistingDocAccessible(aDocumentNode);
michael@0 492
michael@0 493 MsgBegin(sDocCreateTitle, aMsg);
michael@0 494 LogDocInfo(aDocumentNode, document);
michael@0 495 MsgEnd();
michael@0 496 }
michael@0 497
michael@0 498 void
michael@0 499 logging::DocDestroy(const char* aMsg, nsIDocument* aDocumentNode,
michael@0 500 DocAccessible* aDocument)
michael@0 501 {
michael@0 502 DocAccessible* document = aDocument ?
michael@0 503 aDocument : GetExistingDocAccessible(aDocumentNode);
michael@0 504
michael@0 505 MsgBegin(sDocDestroyTitle, aMsg);
michael@0 506 LogDocInfo(aDocumentNode, document);
michael@0 507 MsgEnd();
michael@0 508 }
michael@0 509
michael@0 510 void
michael@0 511 logging::OuterDocDestroy(OuterDocAccessible* aOuterDoc)
michael@0 512 {
michael@0 513 MsgBegin(sDocDestroyTitle, "outerdoc shutdown");
michael@0 514 logging::Address("outerdoc", aOuterDoc);
michael@0 515 MsgEnd();
michael@0 516 }
michael@0 517
michael@0 518 void
michael@0 519 logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr,
michael@0 520 Accessible* aTarget)
michael@0 521 {
michael@0 522 MsgBegin(sFocusTitle, aMsg);
michael@0 523 AccessibleNNode(aTargetDescr, aTarget);
michael@0 524 MsgEnd();
michael@0 525 }
michael@0 526
michael@0 527 void
michael@0 528 logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr,
michael@0 529 nsINode* aTargetNode)
michael@0 530 {
michael@0 531 MsgBegin(sFocusTitle, aMsg);
michael@0 532 Node(aTargetDescr, aTargetNode);
michael@0 533 MsgEnd();
michael@0 534 }
michael@0 535
michael@0 536 void
michael@0 537 logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr,
michael@0 538 nsISupports* aTargetThing)
michael@0 539 {
michael@0 540 MsgBegin(sFocusTitle, aMsg);
michael@0 541
michael@0 542 if (aTargetThing) {
michael@0 543 nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTargetThing));
michael@0 544 if (targetNode)
michael@0 545 AccessibleNNode(aTargetDescr, targetNode);
michael@0 546 else
michael@0 547 printf(" %s: %p, window\n", aTargetDescr,
michael@0 548 static_cast<void*>(aTargetThing));
michael@0 549 }
michael@0 550
michael@0 551 MsgEnd();
michael@0 552 }
michael@0 553
michael@0 554 void
michael@0 555 logging::ActiveItemChangeCausedBy(const char* aCause, Accessible* aTarget)
michael@0 556 {
michael@0 557 SubMsgBegin();
michael@0 558 printf(" Caused by: %s\n", aCause);
michael@0 559 AccessibleNNode("Item", aTarget);
michael@0 560 SubMsgEnd();
michael@0 561 }
michael@0 562
michael@0 563 void
michael@0 564 logging::ActiveWidget(Accessible* aWidget)
michael@0 565 {
michael@0 566 SubMsgBegin();
michael@0 567
michael@0 568 AccessibleNNode("Widget", aWidget);
michael@0 569 printf(" Widget is active: %s, has operable items: %s\n",
michael@0 570 (aWidget && aWidget->IsActiveWidget() ? "true" : "false"),
michael@0 571 (aWidget && aWidget->AreItemsOperable() ? "true" : "false"));
michael@0 572
michael@0 573 SubMsgEnd();
michael@0 574 }
michael@0 575
michael@0 576 void
michael@0 577 logging::FocusDispatched(Accessible* aTarget)
michael@0 578 {
michael@0 579 SubMsgBegin();
michael@0 580 AccessibleNNode("A11y target", aTarget);
michael@0 581 SubMsgEnd();
michael@0 582 }
michael@0 583
michael@0 584 void
michael@0 585 logging::SelChange(nsISelection* aSelection, DocAccessible* aDocument,
michael@0 586 int16_t aReason)
michael@0 587 {
michael@0 588 nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(aSelection));
michael@0 589
michael@0 590 int16_t type = 0;
michael@0 591 privSel->GetType(&type);
michael@0 592
michael@0 593 const char* strType = 0;
michael@0 594 if (type == nsISelectionController::SELECTION_NORMAL)
michael@0 595 strType = "normal";
michael@0 596 else if (type == nsISelectionController::SELECTION_SPELLCHECK)
michael@0 597 strType = "spellcheck";
michael@0 598 else
michael@0 599 strType = "unknown";
michael@0 600
michael@0 601 bool isIgnored = !aDocument || !aDocument->IsContentLoaded();
michael@0 602 printf("\nSelection changed, selection type: %s, notification %s, reason: %d\n",
michael@0 603 strType, (isIgnored ? "ignored" : "pending"), aReason);
michael@0 604
michael@0 605 Stack();
michael@0 606 }
michael@0 607
michael@0 608 void
michael@0 609 logging::MsgBegin(const char* aTitle, const char* aMsgText, ...)
michael@0 610 {
michael@0 611 printf("\nA11Y %s: ", aTitle);
michael@0 612
michael@0 613 va_list argptr;
michael@0 614 va_start(argptr, aMsgText);
michael@0 615 vprintf(aMsgText, argptr);
michael@0 616 va_end(argptr);
michael@0 617
michael@0 618 PRIntervalTime time = PR_IntervalNow();
michael@0 619 uint32_t mins = (PR_IntervalToSeconds(time) / 60) % 60;
michael@0 620 uint32_t secs = PR_IntervalToSeconds(time) % 60;
michael@0 621 uint32_t msecs = PR_IntervalToMilliseconds(time) % 1000;
michael@0 622 printf("; %02d:%02d.%03d", mins, secs, msecs);
michael@0 623
michael@0 624 printf("\n {\n");
michael@0 625 }
michael@0 626
michael@0 627 void
michael@0 628 logging::MsgEnd()
michael@0 629 {
michael@0 630 printf(" }\n");
michael@0 631 }
michael@0 632
michael@0 633 void
michael@0 634 logging::SubMsgBegin()
michael@0 635 {
michael@0 636 printf(" {\n");
michael@0 637 }
michael@0 638
michael@0 639 void
michael@0 640 logging::SubMsgEnd()
michael@0 641 {
michael@0 642 printf(" }\n");
michael@0 643 }
michael@0 644
michael@0 645 void
michael@0 646 logging::MsgEntry(const char* aEntryText, ...)
michael@0 647 {
michael@0 648 printf(" ");
michael@0 649
michael@0 650 va_list argptr;
michael@0 651 va_start(argptr, aEntryText);
michael@0 652 vprintf(aEntryText, argptr);
michael@0 653 va_end(argptr);
michael@0 654
michael@0 655 printf("\n");
michael@0 656 }
michael@0 657
michael@0 658 void
michael@0 659 logging::Text(const char* aText)
michael@0 660 {
michael@0 661 printf(" %s\n", aText);
michael@0 662 }
michael@0 663
michael@0 664 void
michael@0 665 logging::Address(const char* aDescr, Accessible* aAcc)
michael@0 666 {
michael@0 667 if (!aAcc->IsDoc()) {
michael@0 668 printf(" %s accessible: %p, node: %p\n", aDescr,
michael@0 669 static_cast<void*>(aAcc), static_cast<void*>(aAcc->GetNode()));
michael@0 670 }
michael@0 671
michael@0 672 DocAccessible* doc = aAcc->Document();
michael@0 673 nsIDocument* docNode = doc->DocumentNode();
michael@0 674 printf(" document: %p, node: %p\n",
michael@0 675 static_cast<void*>(doc), static_cast<void*>(docNode));
michael@0 676
michael@0 677 printf(" ");
michael@0 678 LogDocURI(docNode);
michael@0 679 printf("\n");
michael@0 680 }
michael@0 681
michael@0 682 void
michael@0 683 logging::Node(const char* aDescr, nsINode* aNode)
michael@0 684 {
michael@0 685 printf(" ");
michael@0 686
michael@0 687 if (!aNode) {
michael@0 688 printf("%s: null\n", aDescr);
michael@0 689 return;
michael@0 690 }
michael@0 691
michael@0 692 if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
michael@0 693 printf("%s: %p, document\n", aDescr, static_cast<void*>(aNode));
michael@0 694 return;
michael@0 695 }
michael@0 696
michael@0 697 nsINode* parentNode = aNode->GetParentNode();
michael@0 698 int32_t idxInParent = parentNode ? parentNode->IndexOf(aNode) : - 1;
michael@0 699
michael@0 700 if (aNode->IsNodeOfType(nsINode::eTEXT)) {
michael@0 701 printf("%s: %p, text node, idx in parent: %d\n",
michael@0 702 aDescr, static_cast<void*>(aNode), idxInParent);
michael@0 703 return;
michael@0 704 }
michael@0 705
michael@0 706 if (!aNode->IsElement()) {
michael@0 707 printf("%s: %p, not accessible node type, idx in parent: %d\n",
michael@0 708 aDescr, static_cast<void*>(aNode), idxInParent);
michael@0 709 return;
michael@0 710 }
michael@0 711
michael@0 712 dom::Element* elm = aNode->AsElement();
michael@0 713
michael@0 714 nsAutoCString tag;
michael@0 715 elm->Tag()->ToUTF8String(tag);
michael@0 716
michael@0 717 nsIAtom* idAtom = elm->GetID();
michael@0 718 nsAutoCString id;
michael@0 719 if (idAtom)
michael@0 720 idAtom->ToUTF8String(id);
michael@0 721
michael@0 722 printf("%s: %p, %s@id='%s', idx in parent: %d\n",
michael@0 723 aDescr, static_cast<void*>(elm), tag.get(), id.get(), idxInParent);
michael@0 724 }
michael@0 725
michael@0 726 void
michael@0 727 logging::Document(DocAccessible* aDocument)
michael@0 728 {
michael@0 729 printf(" Document: %p, document node: %p\n",
michael@0 730 static_cast<void*>(aDocument),
michael@0 731 static_cast<void*>(aDocument->DocumentNode()));
michael@0 732
michael@0 733 printf(" Document ");
michael@0 734 LogDocURI(aDocument->DocumentNode());
michael@0 735 printf("\n");
michael@0 736 }
michael@0 737
michael@0 738 void
michael@0 739 logging::AccessibleNNode(const char* aDescr, Accessible* aAccessible)
michael@0 740 {
michael@0 741 printf(" %s: %p; ", aDescr, static_cast<void*>(aAccessible));
michael@0 742 if (!aAccessible)
michael@0 743 return;
michael@0 744
michael@0 745 nsAutoString role;
michael@0 746 GetAccService()->GetStringRole(aAccessible->Role(), role);
michael@0 747 nsAutoString name;
michael@0 748 aAccessible->Name(name);
michael@0 749
michael@0 750 printf("role: %s, name: '%s';\n", NS_ConvertUTF16toUTF8(role).get(),
michael@0 751 NS_ConvertUTF16toUTF8(name).get());
michael@0 752
michael@0 753 nsAutoCString nodeDescr(aDescr);
michael@0 754 nodeDescr.AppendLiteral(" node");
michael@0 755 Node(nodeDescr.get(), aAccessible->GetNode());
michael@0 756
michael@0 757 Document(aAccessible->Document());
michael@0 758 }
michael@0 759
michael@0 760 void
michael@0 761 logging::AccessibleNNode(const char* aDescr, nsINode* aNode)
michael@0 762 {
michael@0 763 DocAccessible* document =
michael@0 764 GetAccService()->GetDocAccessible(aNode->OwnerDoc());
michael@0 765
michael@0 766 if (document) {
michael@0 767 Accessible* accessible = document->GetAccessible(aNode);
michael@0 768 if (accessible) {
michael@0 769 AccessibleNNode(aDescr, accessible);
michael@0 770 return;
michael@0 771 }
michael@0 772 }
michael@0 773
michael@0 774 nsAutoCString nodeDescr("[not accessible] ");
michael@0 775 nodeDescr.Append(aDescr);
michael@0 776 Node(nodeDescr.get(), aNode);
michael@0 777
michael@0 778 if (document) {
michael@0 779 Document(document);
michael@0 780 return;
michael@0 781 }
michael@0 782
michael@0 783 printf(" [contained by not accessible document]:\n");
michael@0 784 LogDocInfo(aNode->OwnerDoc(), document);
michael@0 785 printf("\n");
michael@0 786 }
michael@0 787
michael@0 788 void
michael@0 789 logging::DOMEvent(const char* aDescr, nsINode* aOrigTarget,
michael@0 790 const nsAString& aEventType)
michael@0 791 {
michael@0 792 logging::MsgBegin("DOMEvents", "event '%s' %s",
michael@0 793 NS_ConvertUTF16toUTF8(aEventType).get(), aDescr);
michael@0 794 logging::AccessibleNNode("Target", aOrigTarget);
michael@0 795 logging::MsgEnd();
michael@0 796 }
michael@0 797
michael@0 798 void
michael@0 799 logging::Stack()
michael@0 800 {
michael@0 801 if (IsEnabled(eStack)) {
michael@0 802 printf(" stack: \n");
michael@0 803 nsTraceRefcnt::WalkTheStack(stdout);
michael@0 804 }
michael@0 805 }
michael@0 806
michael@0 807 ////////////////////////////////////////////////////////////////////////////////
michael@0 808 // namespace logging:: initialization
michael@0 809
michael@0 810 bool
michael@0 811 logging::IsEnabled(uint32_t aModules)
michael@0 812 {
michael@0 813 return sModules & aModules;
michael@0 814 }
michael@0 815
michael@0 816 bool
michael@0 817 logging::IsEnabled(const nsAString& aModuleStr)
michael@0 818 {
michael@0 819 for (unsigned int idx = 0; idx < ArrayLength(sModuleMap); idx++) {
michael@0 820 if (aModuleStr.EqualsASCII(sModuleMap[idx].mStr))
michael@0 821 return sModules & sModuleMap[idx].mModule;
michael@0 822 }
michael@0 823
michael@0 824 return false;
michael@0 825 }
michael@0 826
michael@0 827 void
michael@0 828 logging::Enable(const nsAFlatCString& aModules)
michael@0 829 {
michael@0 830 EnableLogging(aModules.get());
michael@0 831 }
michael@0 832
michael@0 833
michael@0 834 void
michael@0 835 logging::CheckEnv()
michael@0 836 {
michael@0 837 EnableLogging(PR_GetEnv("A11YLOG"));
michael@0 838 }

mercurial