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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DocAccessible.h"
8 #include "mozilla/a11y/DocAccessibleParent.h"
9 #include "mozilla/a11y/DocManager.h"
10 #include "mozilla/a11y/Platform.h"
11 #include "mozilla/a11y/RemoteAccessibleBase.h"
12 #include "mozilla/a11y/RemoteAccessible.h"
13 #include "mozilla/a11y/Role.h"
14 #include "mozilla/dom/Element.h"
15 #include "mozilla/dom/BrowserParent.h"
16 #include "mozilla/Unused.h"
17 #include "RelationType.h"
18 #include "xpcAccessibleDocument.h"
23 template <class Derived
>
24 void RemoteAccessibleBase
<Derived
>::Shutdown() {
25 MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
26 xpcAccessibleDocument
* xpcDoc
=
27 GetAccService()->GetCachedXPCDocument(Document());
29 xpcDoc
->NotifyOfShutdown(static_cast<Derived
*>(this));
32 // XXX Ideally this wouldn't be necessary, but it seems OuterDoc accessibles
33 // can be destroyed before the doc they own.
34 uint32_t childCount
= mChildren
.Length();
36 for (uint32_t idx
= 0; idx
< childCount
; idx
++) mChildren
[idx
]->Shutdown();
39 MOZ_CRASH("outer doc has too many documents!");
40 } else if (childCount
== 1) {
41 mChildren
[0]->AsDoc()->Unbind();
46 ProxyDestroyed(static_cast<Derived
*>(this));
47 mDoc
->RemoveAccessible(static_cast<Derived
*>(this));
50 template <class Derived
>
51 void RemoteAccessibleBase
<Derived
>::SetChildDoc(
52 DocAccessibleParent
* aChildDoc
) {
53 MOZ_ASSERT(aChildDoc
);
54 MOZ_ASSERT(mChildren
.Length() == 0);
55 mChildren
.AppendElement(aChildDoc
);
58 template <class Derived
>
59 void RemoteAccessibleBase
<Derived
>::ClearChildDoc(
60 DocAccessibleParent
* aChildDoc
) {
61 MOZ_ASSERT(aChildDoc
);
62 // This is possible if we're replacing one document with another: Doc 1
63 // has not had a chance to remove itself, but was already replaced by Doc 2
64 // in SetChildDoc(). This could result in two subsequent calls to
65 // ClearChildDoc() even though mChildren.Length() == 1.
66 MOZ_ASSERT(mChildren
.Length() <= 1);
67 mChildren
.RemoveElement(aChildDoc
);
70 template <class Derived
>
71 uint32_t RemoteAccessibleBase
<Derived
>::EmbeddedChildCount() const {
72 size_t count
= 0, kids
= mChildren
.Length();
73 for (size_t i
= 0; i
< kids
; i
++) {
74 if (mChildren
[i
]->IsEmbeddedObject()) {
82 template <class Derived
>
83 int32_t RemoteAccessibleBase
<Derived
>::IndexOfEmbeddedChild(
84 const Derived
* aChild
) {
85 size_t index
= 0, kids
= mChildren
.Length();
86 for (size_t i
= 0; i
< kids
; i
++) {
87 if (mChildren
[i
]->IsEmbeddedObject()) {
88 if (mChildren
[i
] == aChild
) {
99 template <class Derived
>
100 Derived
* RemoteAccessibleBase
<Derived
>::EmbeddedChildAt(size_t aChildIdx
) {
101 size_t index
= 0, kids
= mChildren
.Length();
102 for (size_t i
= 0; i
< kids
; i
++) {
103 if (!mChildren
[i
]->IsEmbeddedObject()) {
107 if (index
== aChildIdx
) {
117 template <class Derived
>
118 LocalAccessible
* RemoteAccessibleBase
<Derived
>::OuterDocOfRemoteBrowser()
120 auto tab
= static_cast<dom::BrowserParent
*>(mDoc
->Manager());
121 dom::Element
* frame
= tab
->GetOwnerElement();
122 NS_ASSERTION(frame
, "why isn't the tab in a frame!");
123 if (!frame
) return nullptr;
125 DocAccessible
* chromeDoc
= GetExistingDocAccessible(frame
->OwnerDoc());
127 return chromeDoc
? chromeDoc
->GetAccessible(frame
) : nullptr;
130 template <class Derived
>
131 void RemoteAccessibleBase
<Derived
>::SetParent(Derived
* aParent
) {
132 MOZ_ASSERT(IsDoc(), "we should only reparent documents");
136 MOZ_ASSERT(!aParent
->IsDoc());
137 mParent
= aParent
->ID();
141 template <class Derived
>
142 Derived
* RemoteAccessibleBase
<Derived
>::RemoteParent() const {
143 if (mParent
== kNoParent
) {
147 // if we are not a document then are parent is another proxy in the same
148 // document. That means we can just ask our document for the proxy with our
151 return Document()->GetAccessible(mParent
);
154 // If we are a top level document then our parent is not a proxy.
155 if (AsDoc()->IsTopLevel()) {
159 // Finally if we are a non top level document then our parent id is for a
160 // proxy in our parent document so get the proxy from there.
161 DocAccessibleParent
* parentDoc
= AsDoc()->ParentDoc();
162 MOZ_ASSERT(parentDoc
);
164 return parentDoc
->GetAccessible(mParent
);
167 template class RemoteAccessibleBase
<RemoteAccessible
>;
170 } // namespace mozilla