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