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/. */
9 #include "Accessible-inl.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 "nsISelectionController.h"
20 #include "nsTraceRefcnt.h"
21 #include "nsIWebProgress.h"
23 #include "nsIDocShellTreeItem.h"
25 #include "mozilla/PresShell.h"
26 #include "mozilla/dom/Element.h"
27 #include "mozilla/dom/HTMLBodyElement.h"
28 #include "mozilla/dom/Selection.h"
30 using namespace mozilla
;
31 using namespace mozilla::a11y
;
33 ////////////////////////////////////////////////////////////////////////////////
36 static uint32_t sModules
= 0;
40 logging::EModules mModule
;
43 static ModuleRep sModuleMap
[] = {{"docload", logging::eDocLoad
},
44 {"doccreate", logging::eDocCreate
},
45 {"docdestroy", logging::eDocDestroy
},
46 {"doclifecycle", logging::eDocLifeCycle
},
48 {"events", logging::eEvents
},
49 {"eventTree", logging::eEventTree
},
50 {"platforms", logging::ePlatforms
},
51 {"text", logging::eText
},
52 {"tree", logging::eTree
},
54 {"DOMEvents", logging::eDOMEvents
},
55 {"focus", logging::eFocus
},
56 {"selection", logging::eSelection
},
57 {"notifications", logging::eNotifications
},
59 {"stack", logging::eStack
},
60 {"verbose", logging::eVerbose
}};
62 static void EnableLogging(const char* aModulesStr
) {
64 if (!aModulesStr
) return;
66 const char* token
= aModulesStr
;
67 while (*token
!= '\0') {
68 size_t tokenLen
= strcspn(token
, ",");
69 for (unsigned int idx
= 0; idx
< ArrayLength(sModuleMap
); idx
++) {
70 if (strncmp(token
, sModuleMap
[idx
].mStr
, tokenLen
) == 0) {
71 #if !defined(MOZ_PROFILING) && (!defined(DEBUG) || defined(MOZ_OPTIMIZE))
72 // Stack tracing on profiling enabled or debug not optimized builds.
73 if (strncmp(token
, "stack", tokenLen
) == 0) break;
75 sModules
|= sModuleMap
[idx
].mModule
;
76 printf("\n\nmodule enabled: %s\n", sModuleMap
[idx
].mStr
);
82 if (*token
== ',') token
++; // skip ',' char
86 static void LogDocURI(dom::Document
* aDocumentNode
) {
87 printf("uri: %s", aDocumentNode
->GetDocumentURI()->GetSpecOrDefault().get());
90 static void LogDocShellState(dom::Document
* aDocumentNode
) {
91 printf("docshell busy: ");
93 nsAutoCString docShellBusy
;
94 nsCOMPtr
<nsIDocShell
> docShell
= aDocumentNode
->GetDocShell();
95 nsIDocShell::BusyFlags busyFlags
= nsIDocShell::BUSY_FLAGS_NONE
;
96 docShell
->GetBusyFlags(&busyFlags
);
97 if (busyFlags
== nsIDocShell::BUSY_FLAGS_NONE
) {
100 if (busyFlags
& nsIDocShell::BUSY_FLAGS_BUSY
) {
103 if (busyFlags
& nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD
) {
104 printf(", 'before page load'");
106 if (busyFlags
& nsIDocShell::BUSY_FLAGS_PAGE_LOADING
) {
107 printf(", 'page loading'");
111 static void LogDocType(dom::Document
* aDocumentNode
) {
112 if (aDocumentNode
->IsActive()) {
113 bool isContent
= nsCoreUtils::IsContentDocument(aDocumentNode
);
114 printf("%s document", (isContent
? "content" : "chrome"));
116 printf("document type: [failed]");
120 static void LogDocShellTree(dom::Document
* aDocumentNode
) {
121 if (aDocumentNode
->IsActive()) {
122 nsCOMPtr
<nsIDocShellTreeItem
> treeItem(aDocumentNode
->GetDocShell());
123 nsCOMPtr
<nsIDocShellTreeItem
> parentTreeItem
;
124 treeItem
->GetInProcessParent(getter_AddRefs(parentTreeItem
));
125 nsCOMPtr
<nsIDocShellTreeItem
> rootTreeItem
;
126 treeItem
->GetRootTreeItem(getter_AddRefs(rootTreeItem
));
127 printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;",
128 static_cast<void*>(parentTreeItem
), static_cast<void*>(rootTreeItem
),
129 (nsCoreUtils::IsTabDocument(aDocumentNode
) ? "yes" : "no"));
133 static void LogDocState(dom::Document
* aDocumentNode
) {
134 const char* docState
= nullptr;
135 dom::Document::ReadyState docStateFlag
= aDocumentNode
->GetReadyStateEnum();
136 switch (docStateFlag
) {
137 case dom::Document::READYSTATE_UNINITIALIZED
:
138 docState
= "uninitialized";
140 case dom::Document::READYSTATE_LOADING
:
141 docState
= "loading";
143 case dom::Document::READYSTATE_INTERACTIVE
:
144 docState
= "interactive";
146 case dom::Document::READYSTATE_COMPLETE
:
147 docState
= "complete";
151 printf("doc state: %s", docState
);
152 printf(", %sinitial", aDocumentNode
->IsInitialDocument() ? "" : "not ");
153 printf(", %sshowing", aDocumentNode
->IsShowing() ? "" : "not ");
154 printf(", %svisible", aDocumentNode
->IsVisible() ? "" : "not ");
155 printf(", %svisible considering ancestors",
156 aDocumentNode
->IsVisibleConsideringAncestors() ? "" : "not ");
157 printf(", %sactive", aDocumentNode
->IsActive() ? "" : "not ");
158 printf(", %sresource", aDocumentNode
->IsResourceDoc() ? "" : "not ");
160 dom::Element
* rootEl
= aDocumentNode
->GetBodyElement();
162 rootEl
= aDocumentNode
->GetRootElement();
164 printf(", has %srole content", rootEl
? "" : "no ");
167 static void LogPresShell(dom::Document
* aDocumentNode
) {
168 PresShell
* presShell
= aDocumentNode
->GetPresShell();
169 printf("presshell: %p", static_cast<void*>(presShell
));
171 nsIScrollableFrame
* sf
= nullptr;
173 printf(", is %s destroying", (presShell
->IsDestroying() ? "" : "not"));
174 sf
= presShell
->GetRootScrollFrameAsScrollable();
176 printf(", root scroll frame: %p", static_cast<void*>(sf
));
179 static void LogDocLoadGroup(dom::Document
* aDocumentNode
) {
180 nsCOMPtr
<nsILoadGroup
> loadGroup
= aDocumentNode
->GetDocumentLoadGroup();
181 printf("load group: %p", static_cast<void*>(loadGroup
));
184 static void LogDocParent(dom::Document
* aDocumentNode
) {
185 dom::Document
* parentDoc
= aDocumentNode
->GetInProcessParentDocument();
186 printf("parent DOM document: %p", static_cast<void*>(parentDoc
));
188 printf(", parent acc document: %p",
189 static_cast<void*>(GetExistingDocAccessible(parentDoc
)));
190 printf("\n parent ");
191 LogDocURI(parentDoc
);
196 static void LogDocInfo(dom::Document
* aDocumentNode
, DocAccessible
* aDocument
) {
197 printf(" DOM document: %p, acc document: %p\n ",
198 static_cast<void*>(aDocumentNode
), static_cast<void*>(aDocument
));
202 LogDocURI(aDocumentNode
);
204 LogDocShellState(aDocumentNode
);
206 LogDocType(aDocumentNode
);
208 LogDocShellTree(aDocumentNode
);
210 LogDocState(aDocumentNode
);
212 LogPresShell(aDocumentNode
);
214 LogDocLoadGroup(aDocumentNode
);
216 LogDocParent(aDocumentNode
);
221 static void LogShellLoadType(nsIDocShell
* aDocShell
) {
222 printf("load type: ");
224 uint32_t loadType
= 0;
225 aDocShell
->GetLoadType(&loadType
);
230 case LOAD_NORMAL_REPLACE
:
231 printf("normal replace; ");
233 case LOAD_NORMAL_EXTERNAL
:
234 printf("normal external; ");
239 case LOAD_NORMAL_BYPASS_CACHE
:
240 printf("normal bypass cache; ");
242 case LOAD_NORMAL_BYPASS_PROXY
:
243 printf("normal bypass proxy; ");
245 case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE
:
246 printf("normal bypass proxy and cache; ");
248 case LOAD_NORMAL_ALLOW_MIXED_CONTENT
:
249 printf("normal allow mixed content; ");
251 case LOAD_RELOAD_NORMAL
:
252 printf("reload normal; ");
254 case LOAD_RELOAD_BYPASS_CACHE
:
255 printf("reload bypass cache; ");
257 case LOAD_RELOAD_BYPASS_PROXY
:
258 printf("reload bypass proxy; ");
260 case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE
:
261 printf("reload bypass proxy and cache; ");
263 case LOAD_RELOAD_ALLOW_MIXED_CONTENT
:
264 printf("reload allow mixed content; ");
272 case LOAD_RELOAD_CHARSET_CHANGE
:
273 printf("reload charset change; ");
275 case LOAD_BYPASS_HISTORY
:
276 printf("bypass history; ");
278 case LOAD_STOP_CONTENT
:
279 printf("stop content; ");
281 case LOAD_STOP_CONTENT_AND_REPLACE
:
282 printf("stop content and replace; ");
285 printf("load pushstate; ");
287 case LOAD_REPLACE_BYPASS_CACHE
:
288 printf("replace bypass cache; ");
290 case LOAD_ERROR_PAGE
:
291 printf("error page;");
298 static void LogRequest(nsIRequest
* aRequest
) {
301 aRequest
->GetName(name
);
302 printf(" request spec: %s\n", name
.get());
303 uint32_t loadFlags
= 0;
304 aRequest
->GetLoadFlags(&loadFlags
);
305 printf(" request load flags: %x; ", loadFlags
);
306 if (loadFlags
& nsIChannel::LOAD_DOCUMENT_URI
) printf("document uri; ");
307 if (loadFlags
& nsIChannel::LOAD_RETARGETED_DOCUMENT_URI
)
308 printf("retargeted document uri; ");
309 if (loadFlags
& nsIChannel::LOAD_REPLACE
) printf("replace; ");
310 if (loadFlags
& nsIChannel::LOAD_INITIAL_DOCUMENT_URI
)
311 printf("initial document uri; ");
312 if (loadFlags
& nsIChannel::LOAD_TARGETED
) printf("targeted; ");
313 if (loadFlags
& nsIChannel::LOAD_CALL_CONTENT_SNIFFERS
)
314 printf("call content sniffers; ");
315 if (loadFlags
& nsIChannel::LOAD_BYPASS_URL_CLASSIFIER
) {
316 printf("bypass classify uri; ");
319 printf(" no request");
323 static void LogDocAccState(DocAccessible
* aDocument
) {
324 printf("document acc state: ");
325 if (aDocument
->HasLoadState(DocAccessible::eCompletelyLoaded
))
326 printf("completely loaded;");
327 else if (aDocument
->HasLoadState(DocAccessible::eReady
))
329 else if (aDocument
->HasLoadState(DocAccessible::eDOMLoaded
))
330 printf("DOM loaded;");
331 else if (aDocument
->HasLoadState(DocAccessible::eTreeConstructed
))
332 printf("tree constructed;");
335 static void GetDocLoadEventType(AccEvent
* aEvent
, nsACString
& aEventType
) {
336 uint32_t type
= aEvent
->GetEventType();
337 if (type
== nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
) {
338 aEventType
.AssignLiteral("load stopped");
339 } else if (type
== nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE
) {
340 aEventType
.AssignLiteral("load complete");
341 } else if (type
== nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD
) {
342 aEventType
.AssignLiteral("reload");
343 } else if (type
== nsIAccessibleEvent::EVENT_STATE_CHANGE
) {
344 AccStateChangeEvent
* event
= downcast_accEvent(aEvent
);
345 if (event
->GetState() == states::BUSY
) {
346 aEventType
.AssignLiteral("busy ");
347 if (event
->IsStateEnabled())
348 aEventType
.AppendLiteral("true");
350 aEventType
.AppendLiteral("false");
355 ////////////////////////////////////////////////////////////////////////////////
356 // namespace logging:: document life cycle logging methods
358 static const char* sDocLoadTitle
= "DOCLOAD";
359 static const char* sDocCreateTitle
= "DOCCREATE";
360 static const char* sDocDestroyTitle
= "DOCDESTROY";
361 static const char* sDocEventTitle
= "DOCEVENT";
362 static const char* sFocusTitle
= "FOCUS";
364 void logging::DocLoad(const char* aMsg
, nsIWebProgress
* aWebProgress
,
365 nsIRequest
* aRequest
, uint32_t aStateFlags
) {
366 MsgBegin(sDocLoadTitle
, "%s", aMsg
);
368 nsCOMPtr
<mozIDOMWindowProxy
> DOMWindow
;
369 aWebProgress
->GetDOMWindow(getter_AddRefs(DOMWindow
));
370 nsPIDOMWindowOuter
* window
= nsPIDOMWindowOuter::From(DOMWindow
);
376 nsCOMPtr
<dom::Document
> documentNode
= window
->GetDoc();
382 DocAccessible
* document
= GetExistingDocAccessible(documentNode
);
384 LogDocInfo(documentNode
, document
);
386 nsCOMPtr
<nsIDocShell
> docShell
= window
->GetDocShell();
388 LogShellLoadType(docShell
);
390 LogRequest(aRequest
);
392 printf(" state flags: %x", aStateFlags
);
394 aWebProgress
->GetIsLoadingDocument(&isDocLoading
);
395 printf(", document is %sloading\n", (isDocLoading
? "" : "not "));
400 void logging::DocLoad(const char* aMsg
, dom::Document
* aDocumentNode
) {
401 MsgBegin(sDocLoadTitle
, "%s", aMsg
);
403 DocAccessible
* document
= GetExistingDocAccessible(aDocumentNode
);
404 LogDocInfo(aDocumentNode
, document
);
409 void logging::DocCompleteLoad(DocAccessible
* aDocument
,
410 bool aIsLoadEventTarget
) {
411 MsgBegin(sDocLoadTitle
, "document loaded *completely*");
413 printf(" DOM document: %p, acc document: %p\n",
414 static_cast<void*>(aDocument
->DocumentNode()),
415 static_cast<void*>(aDocument
));
418 LogDocURI(aDocument
->DocumentNode());
422 LogDocAccState(aDocument
);
425 printf(" document is load event target: %s\n",
426 (aIsLoadEventTarget
? "true" : "false"));
431 void logging::DocLoadEventFired(AccEvent
* aEvent
) {
432 nsAutoCString strEventType
;
433 GetDocLoadEventType(aEvent
, strEventType
);
434 if (!strEventType
.IsEmpty()) printf(" fire: %s\n", strEventType
.get());
437 void logging::DocLoadEventHandled(AccEvent
* aEvent
) {
438 nsAutoCString strEventType
;
439 GetDocLoadEventType(aEvent
, strEventType
);
440 if (strEventType
.IsEmpty()) return;
442 MsgBegin(sDocEventTitle
, "handled '%s' event", strEventType
.get());
444 DocAccessible
* document
= aEvent
->GetAccessible()->AsDoc();
445 if (document
) LogDocInfo(document
->DocumentNode(), document
);
450 void logging::DocCreate(const char* aMsg
, dom::Document
* aDocumentNode
,
451 DocAccessible
* aDocument
) {
452 DocAccessible
* document
=
453 aDocument
? aDocument
: GetExistingDocAccessible(aDocumentNode
);
455 MsgBegin(sDocCreateTitle
, "%s", aMsg
);
456 LogDocInfo(aDocumentNode
, document
);
460 void logging::DocDestroy(const char* aMsg
, dom::Document
* aDocumentNode
,
461 DocAccessible
* aDocument
) {
462 DocAccessible
* document
=
463 aDocument
? aDocument
: GetExistingDocAccessible(aDocumentNode
);
465 MsgBegin(sDocDestroyTitle
, "%s", aMsg
);
466 LogDocInfo(aDocumentNode
, document
);
470 void logging::OuterDocDestroy(OuterDocAccessible
* aOuterDoc
) {
471 MsgBegin(sDocDestroyTitle
, "outerdoc shutdown");
472 logging::Address("outerdoc", aOuterDoc
);
476 void logging::FocusNotificationTarget(const char* aMsg
,
477 const char* aTargetDescr
,
478 Accessible
* aTarget
) {
479 MsgBegin(sFocusTitle
, "%s", aMsg
);
480 AccessibleNNode(aTargetDescr
, aTarget
);
484 void logging::FocusNotificationTarget(const char* aMsg
,
485 const char* aTargetDescr
,
486 nsINode
* aTargetNode
) {
487 MsgBegin(sFocusTitle
, "%s", aMsg
);
488 Node(aTargetDescr
, aTargetNode
);
492 void logging::FocusNotificationTarget(const char* aMsg
,
493 const char* aTargetDescr
,
494 nsISupports
* aTargetThing
) {
495 MsgBegin(sFocusTitle
, "%s", aMsg
);
498 nsCOMPtr
<nsINode
> targetNode(do_QueryInterface(aTargetThing
));
500 AccessibleNNode(aTargetDescr
, targetNode
);
502 printf(" %s: %p, window\n", aTargetDescr
,
503 static_cast<void*>(aTargetThing
));
509 void logging::ActiveItemChangeCausedBy(const char* aCause
,
510 Accessible
* aTarget
) {
512 printf(" Caused by: %s\n", aCause
);
513 AccessibleNNode("Item", aTarget
);
517 void logging::ActiveWidget(Accessible
* aWidget
) {
520 AccessibleNNode("Widget", aWidget
);
521 printf(" Widget is active: %s, has operable items: %s\n",
522 (aWidget
&& aWidget
->IsActiveWidget() ? "true" : "false"),
523 (aWidget
&& aWidget
->AreItemsOperable() ? "true" : "false"));
528 void logging::FocusDispatched(Accessible
* aTarget
) {
530 AccessibleNNode("A11y target", aTarget
);
534 void logging::SelChange(dom::Selection
* aSelection
, DocAccessible
* aDocument
,
536 SelectionType type
= aSelection
->GetType();
538 const char* strType
= 0;
539 if (type
== SelectionType::eNormal
)
541 else if (type
== SelectionType::eSpellCheck
)
542 strType
= "spellcheck";
546 bool isIgnored
= !aDocument
|| !aDocument
->IsContentLoaded();
548 "\nSelection changed, selection type: %s, notification %s, reason: %d\n",
549 strType
, (isIgnored
? "ignored" : "pending"), aReason
);
554 void logging::TreeInfo(const char* aMsg
, uint32_t aExtraFlags
, ...) {
555 if (IsEnabledAll(logging::eTree
| aExtraFlags
)) {
557 va_start(vl
, aExtraFlags
);
558 const char* descr
= va_arg(vl
, const char*);
560 Accessible
* acc
= va_arg(vl
, Accessible
*);
561 MsgBegin("TREE", "%s; doc: %p", aMsg
, acc
? acc
->Document() : nullptr);
562 AccessibleInfo(descr
, acc
);
563 while ((descr
= va_arg(vl
, const char*))) {
564 AccessibleInfo(descr
, va_arg(vl
, Accessible
*));
567 MsgBegin("TREE", "%s", aMsg
);
572 if (aExtraFlags
& eStack
) {
578 void logging::TreeInfo(const char* aMsg
, uint32_t aExtraFlags
,
579 const char* aMsg1
, Accessible
* aAcc
, const char* aMsg2
,
581 if (IsEnabledAll(logging::eTree
| aExtraFlags
)) {
582 MsgBegin("TREE", "%s; doc: %p", aMsg
, aAcc
? aAcc
->Document() : nullptr);
583 AccessibleInfo(aMsg1
, aAcc
);
584 Accessible
* acc
= aAcc
? aAcc
->Document()->GetAccessible(aNode
) : nullptr;
586 AccessibleInfo(aMsg2
, acc
);
594 void logging::TreeInfo(const char* aMsg
, uint32_t aExtraFlags
,
595 Accessible
* aParent
) {
596 if (IsEnabledAll(logging::eTree
| aExtraFlags
)) {
597 MsgBegin("TREE", "%s; doc: %p", aMsg
, aParent
->Document());
598 AccessibleInfo("container", aParent
);
599 for (uint32_t idx
= 0; idx
< aParent
->ChildCount(); idx
++) {
600 AccessibleInfo("child", aParent
->GetChildAt(idx
));
606 void logging::Tree(const char* aTitle
, const char* aMsgText
, Accessible
* aRoot
,
607 GetTreePrefix aPrefixFunc
, void* aGetTreePrefixData
) {
608 logging::MsgBegin(aTitle
, "%s", aMsgText
);
611 Accessible
* root
= aRoot
;
614 aPrefixFunc
? aPrefixFunc(aGetTreePrefixData
, root
) : "";
615 printf("%s", NS_ConvertUTF16toUTF8(level
).get());
616 logging::AccessibleInfo(prefix
, root
);
617 if (root
->FirstChild() && !root
->FirstChild()->IsDoc()) {
618 level
.AppendLiteral(u
" ");
619 root
= root
->FirstChild();
622 int32_t idxInParent
= root
!= aRoot
&& root
->mParent
623 ? root
->mParent
->mChildren
.IndexOf(root
)
625 if (idxInParent
!= -1 &&
627 static_cast<int32_t>(root
->mParent
->mChildren
.Length() - 1)) {
628 root
= root
->mParent
->mChildren
.ElementAt(idxInParent
+ 1);
631 while (root
!= aRoot
&& (root
= root
->Parent())) {
633 int32_t idxInParent
= !root
->IsDoc() && root
->mParent
634 ? root
->mParent
->mChildren
.IndexOf(root
)
636 if (idxInParent
!= -1 &&
638 static_cast<int32_t>(root
->mParent
->mChildren
.Length() - 1)) {
639 root
= root
->mParent
->mChildren
.ElementAt(idxInParent
+ 1);
643 } while (root
&& root
!= aRoot
);
648 void logging::DOMTree(const char* aTitle
, const char* aMsgText
,
649 DocAccessible
* aDocument
) {
650 logging::MsgBegin(aTitle
, "%s", aMsgText
);
652 nsINode
* root
= aDocument
->DocumentNode();
654 printf("%s", NS_ConvertUTF16toUTF8(level
).get());
655 logging::Node("", root
);
656 if (root
->GetFirstChild()) {
657 level
.AppendLiteral(u
" ");
658 root
= root
->GetFirstChild();
661 if (root
->GetNextSibling()) {
662 root
= root
->GetNextSibling();
665 while ((root
= root
->GetParentNode())) {
667 if (root
->GetNextSibling()) {
668 root
= root
->GetNextSibling();
676 void logging::MsgBegin(const char* aTitle
, const char* aMsgText
, ...) {
677 printf("\nA11Y %s: ", aTitle
);
680 va_start(argptr
, aMsgText
);
681 vprintf(aMsgText
, argptr
);
684 PRIntervalTime time
= PR_IntervalNow();
685 uint32_t mins
= (PR_IntervalToSeconds(time
) / 60) % 60;
686 uint32_t secs
= PR_IntervalToSeconds(time
) % 60;
687 uint32_t msecs
= PR_IntervalToMilliseconds(time
) % 1000;
688 printf("; %02u:%02u.%03u", mins
, secs
, msecs
);
693 void logging::MsgEnd() { printf(" }\n"); }
695 void logging::SubMsgBegin() { printf(" {\n"); }
697 void logging::SubMsgEnd() { printf(" }\n"); }
699 void logging::MsgEntry(const char* aEntryText
, ...) {
703 va_start(argptr
, aEntryText
);
704 vprintf(aEntryText
, argptr
);
710 void logging::Text(const char* aText
) { printf(" %s\n", aText
); }
712 void logging::Address(const char* aDescr
, Accessible
* aAcc
) {
713 if (!aAcc
->IsDoc()) {
714 printf(" %s accessible: %p, node: %p\n", aDescr
,
715 static_cast<void*>(aAcc
), static_cast<void*>(aAcc
->GetNode()));
718 DocAccessible
* doc
= aAcc
->Document();
719 dom::Document
* docNode
= doc
->DocumentNode();
720 printf(" document: %p, node: %p\n", static_cast<void*>(doc
),
721 static_cast<void*>(docNode
));
728 void logging::Node(const char* aDescr
, nsINode
* aNode
) {
732 printf("%s: null\n", aDescr
);
736 if (aNode
->IsDocument()) {
737 printf("%s: %p, document\n", aDescr
, static_cast<void*>(aNode
));
741 nsINode
* parentNode
= aNode
->GetParentNode();
742 int32_t idxInParent
= parentNode
? parentNode
->ComputeIndexOf(aNode
) : -1;
744 if (aNode
->IsText()) {
745 printf("%s: %p, text node, idx in parent: %d\n", aDescr
,
746 static_cast<void*>(aNode
), idxInParent
);
750 if (!aNode
->IsElement()) {
751 printf("%s: %p, not accessible node type, idx in parent: %d\n", aDescr
,
752 static_cast<void*>(aNode
), idxInParent
);
756 dom::Element
* elm
= aNode
->AsElement();
759 elm
->NodeInfo()->NameAtom()->ToUTF8String(tag
);
761 nsAtom
* idAtom
= elm
->GetID();
763 if (idAtom
) idAtom
->ToUTF8String(id
);
765 printf("%s: %p, %s@id='%s', idx in parent: %d\n", aDescr
,
766 static_cast<void*>(elm
), tag
.get(), id
.get(), idxInParent
);
769 void logging::Document(DocAccessible
* aDocument
) {
770 printf(" Document: %p, document node: %p\n", static_cast<void*>(aDocument
),
771 static_cast<void*>(aDocument
->DocumentNode()));
773 printf(" Document ");
774 LogDocURI(aDocument
->DocumentNode());
778 void logging::AccessibleInfo(const char* aDescr
, Accessible
* aAccessible
) {
779 printf(" %s: %p; ", aDescr
, static_cast<void*>(aAccessible
));
784 if (aAccessible
->IsDefunct()) {
788 if (!aAccessible
->Document() || aAccessible
->Document()->IsDefunct()) {
789 printf("document is shutting down, no info\n");
794 GetAccService()->GetStringRole(aAccessible
->Role(), role
);
795 printf("role: %s", NS_ConvertUTF16toUTF8(role
).get());
798 aAccessible
->Name(name
);
799 if (!name
.IsEmpty()) {
800 printf(", name: '%s'", NS_ConvertUTF16toUTF8(name
).get());
803 printf(", idx: %d", aAccessible
->IndexInParent());
805 nsINode
* node
= aAccessible
->GetNode();
807 printf(", node: null\n");
808 } else if (node
->IsDocument()) {
809 printf(", document node: %p\n", static_cast<void*>(node
));
810 } else if (node
->IsText()) {
811 printf(", text node: %p\n", static_cast<void*>(node
));
812 } else if (node
->IsElement()) {
813 dom::Element
* el
= node
->AsElement();
816 el
->NodeInfo()->NameAtom()->ToUTF8String(tag
);
818 nsAtom
* idAtom
= el
->GetID();
821 idAtom
->ToUTF8String(id
);
824 printf(", element node: %p, %s@id='%s'\n", static_cast<void*>(el
),
825 tag
.get(), id
.get());
829 void logging::AccessibleNNode(const char* aDescr
, Accessible
* aAccessible
) {
830 printf(" %s: %p; ", aDescr
, static_cast<void*>(aAccessible
));
831 if (!aAccessible
) return;
834 GetAccService()->GetStringRole(aAccessible
->Role(), role
);
836 aAccessible
->Name(name
);
838 printf("role: %s, name: '%s';\n", NS_ConvertUTF16toUTF8(role
).get(),
839 NS_ConvertUTF16toUTF8(name
).get());
841 nsAutoCString
nodeDescr(aDescr
);
842 nodeDescr
.AppendLiteral(" node");
843 Node(nodeDescr
.get(), aAccessible
->GetNode());
845 Document(aAccessible
->Document());
848 void logging::AccessibleNNode(const char* aDescr
, nsINode
* aNode
) {
849 DocAccessible
* document
=
850 GetAccService()->GetDocAccessible(aNode
->OwnerDoc());
853 Accessible
* accessible
= document
->GetAccessible(aNode
);
855 AccessibleNNode(aDescr
, accessible
);
860 nsAutoCString
nodeDescr("[not accessible] ");
861 nodeDescr
.Append(aDescr
);
862 Node(nodeDescr
.get(), aNode
);
869 printf(" [contained by not accessible document]:\n");
870 LogDocInfo(aNode
->OwnerDoc(), document
);
874 void logging::DOMEvent(const char* aDescr
, nsINode
* aOrigTarget
,
875 const nsAString
& aEventType
) {
876 logging::MsgBegin("DOMEvents", "event '%s' %s",
877 NS_ConvertUTF16toUTF8(aEventType
).get(), aDescr
);
878 logging::AccessibleNNode("Target", aOrigTarget
);
882 void logging::Stack() {
883 if (IsEnabled(eStack
)) {
884 printf(" stack: \n");
885 nsTraceRefcnt::WalkTheStack(stdout
);
889 ////////////////////////////////////////////////////////////////////////////////
890 // namespace logging:: initialization
892 bool logging::IsEnabled(uint32_t aModules
) { return sModules
& aModules
; }
894 bool logging::IsEnabledAll(uint32_t aModules
) {
895 return (sModules
& aModules
) == aModules
;
898 bool logging::IsEnabled(const nsAString
& aModuleStr
) {
899 for (unsigned int idx
= 0; idx
< ArrayLength(sModuleMap
); idx
++) {
900 if (aModuleStr
.EqualsASCII(sModuleMap
[idx
].mStr
))
901 return sModules
& sModuleMap
[idx
].mModule
;
907 void logging::Enable(const nsCString
& aModules
) {
908 EnableLogging(aModules
.get());
911 void logging::CheckEnv() { EnableLogging(PR_GetEnv("A11YLOG")); }