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/ProxyAccessibleBase.h"
12 #include "mozilla/a11y/ProxyAccessible.h"
13 #include "mozilla/a11y/Role.h"
14 #include "mozilla/dom/Element.h"
15 #include "mozilla/dom/TabParent.h"
16 #include "mozilla/Unused.h"
17 #include "RelationType.h"
18 #include "xpcAccessibleDocument.h"
23 template <class Derived
>
24 void ProxyAccessibleBase
<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 ProxyAccessibleBase
<Derived
>::SetChildDoc(DocAccessibleParent
* aChildDoc
) {
52 MOZ_ASSERT(aChildDoc
);
53 MOZ_ASSERT(mChildren
.Length() == 0);
54 mChildren
.AppendElement(aChildDoc
);
58 template <class Derived
>
59 void ProxyAccessibleBase
<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 ProxyAccessibleBase
<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 ProxyAccessibleBase
<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
* ProxyAccessibleBase
<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 Accessible
* ProxyAccessibleBase
<Derived
>::OuterDocOfRemoteBrowser() const {
119 auto tab
= static_cast<dom::TabParent
*>(mDoc
->Manager());
120 dom::Element
* frame
= tab
->GetOwnerElement();
121 NS_ASSERTION(frame
, "why isn't the tab in a frame!");
122 if (!frame
) return nullptr;
124 DocAccessible
* chromeDoc
= GetExistingDocAccessible(frame
->OwnerDoc());
126 return chromeDoc
? chromeDoc
->GetAccessible(frame
) : nullptr;
129 template <class Derived
>
130 void ProxyAccessibleBase
<Derived
>::SetParent(Derived
* aParent
) {
131 MOZ_ASSERT(IsDoc(), "we should only reparent documents");
135 MOZ_ASSERT(!aParent
->IsDoc());
136 mParent
= aParent
->ID();
140 template <class Derived
>
141 Derived
* ProxyAccessibleBase
<Derived
>::Parent() const {
142 if (mParent
== kNoParent
) {
146 // if we are not a document then are parent is another proxy in the same
147 // document. That means we can just ask our document for the proxy with our
150 return Document()->GetAccessible(mParent
);
153 // If we are a top level document then our parent is not a proxy.
154 if (AsDoc()->IsTopLevel()) {
158 // Finally if we are a non top level document then our parent id is for a
159 // proxy in our parent document so get the proxy from there.
160 DocAccessibleParent
* parentDoc
= AsDoc()->ParentDoc();
161 MOZ_ASSERT(parentDoc
);
163 return parentDoc
->GetAccessible(mParent
);
166 template class ProxyAccessibleBase
<ProxyAccessible
>;
169 } // namespace mozilla