summaryrefslogtreecommitdiffstats
path: root/accessible/ipc/ProxyAccessibleBase.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /accessible/ipc/ProxyAccessibleBase.cpp
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'accessible/ipc/ProxyAccessibleBase.cpp')
-rw-r--r--accessible/ipc/ProxyAccessibleBase.cpp169
1 files changed, 169 insertions, 0 deletions
diff --git a/accessible/ipc/ProxyAccessibleBase.cpp b/accessible/ipc/ProxyAccessibleBase.cpp
new file mode 100644
index 0000000000..d0264ce86c
--- /dev/null
+++ b/accessible/ipc/ProxyAccessibleBase.cpp
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "DocAccessible.h"
+#include "mozilla/a11y/DocAccessibleParent.h"
+#include "mozilla/a11y/DocManager.h"
+#include "mozilla/a11y/Platform.h"
+#include "mozilla/a11y/ProxyAccessibleBase.h"
+#include "mozilla/a11y/ProxyAccessible.h"
+#include "mozilla/a11y/Role.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/BrowserParent.h"
+#include "mozilla/Unused.h"
+#include "RelationType.h"
+#include "xpcAccessibleDocument.h"
+
+namespace mozilla {
+namespace a11y {
+
+template <class Derived>
+void ProxyAccessibleBase<Derived>::Shutdown() {
+ MOZ_DIAGNOSTIC_ASSERT(!IsDoc());
+ xpcAccessibleDocument* xpcDoc =
+ GetAccService()->GetCachedXPCDocument(Document());
+ if (xpcDoc) {
+ xpcDoc->NotifyOfShutdown(static_cast<Derived*>(this));
+ }
+
+ // XXX Ideally this wouldn't be necessary, but it seems OuterDoc accessibles
+ // can be destroyed before the doc they own.
+ uint32_t childCount = mChildren.Length();
+ if (!mOuterDoc) {
+ for (uint32_t idx = 0; idx < childCount; idx++) mChildren[idx]->Shutdown();
+ } else {
+ if (childCount > 1) {
+ MOZ_CRASH("outer doc has too many documents!");
+ } else if (childCount == 1) {
+ mChildren[0]->AsDoc()->Unbind();
+ }
+ }
+
+ mChildren.Clear();
+ ProxyDestroyed(static_cast<Derived*>(this));
+ mDoc->RemoveAccessible(static_cast<Derived*>(this));
+}
+
+template <class Derived>
+void ProxyAccessibleBase<Derived>::SetChildDoc(DocAccessibleParent* aChildDoc) {
+ MOZ_ASSERT(aChildDoc);
+ MOZ_ASSERT(mChildren.Length() == 0);
+ mChildren.AppendElement(aChildDoc);
+ mOuterDoc = true;
+}
+
+template <class Derived>
+void ProxyAccessibleBase<Derived>::ClearChildDoc(
+ DocAccessibleParent* aChildDoc) {
+ MOZ_ASSERT(aChildDoc);
+ // This is possible if we're replacing one document with another: Doc 1
+ // has not had a chance to remove itself, but was already replaced by Doc 2
+ // in SetChildDoc(). This could result in two subsequent calls to
+ // ClearChildDoc() even though mChildren.Length() == 1.
+ MOZ_ASSERT(mChildren.Length() <= 1);
+ mChildren.RemoveElement(aChildDoc);
+}
+
+template <class Derived>
+uint32_t ProxyAccessibleBase<Derived>::EmbeddedChildCount() const {
+ size_t count = 0, kids = mChildren.Length();
+ for (size_t i = 0; i < kids; i++) {
+ if (mChildren[i]->IsEmbeddedObject()) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+template <class Derived>
+int32_t ProxyAccessibleBase<Derived>::IndexOfEmbeddedChild(
+ const Derived* aChild) {
+ size_t index = 0, kids = mChildren.Length();
+ for (size_t i = 0; i < kids; i++) {
+ if (mChildren[i]->IsEmbeddedObject()) {
+ if (mChildren[i] == aChild) {
+ return index;
+ }
+
+ index++;
+ }
+ }
+
+ return -1;
+}
+
+template <class Derived>
+Derived* ProxyAccessibleBase<Derived>::EmbeddedChildAt(size_t aChildIdx) {
+ size_t index = 0, kids = mChildren.Length();
+ for (size_t i = 0; i < kids; i++) {
+ if (!mChildren[i]->IsEmbeddedObject()) {
+ continue;
+ }
+
+ if (index == aChildIdx) {
+ return mChildren[i];
+ }
+
+ index++;
+ }
+
+ return nullptr;
+}
+
+template <class Derived>
+Accessible* ProxyAccessibleBase<Derived>::OuterDocOfRemoteBrowser() const {
+ auto tab = static_cast<dom::BrowserParent*>(mDoc->Manager());
+ dom::Element* frame = tab->GetOwnerElement();
+ NS_ASSERTION(frame, "why isn't the tab in a frame!");
+ if (!frame) return nullptr;
+
+ DocAccessible* chromeDoc = GetExistingDocAccessible(frame->OwnerDoc());
+
+ return chromeDoc ? chromeDoc->GetAccessible(frame) : nullptr;
+}
+
+template <class Derived>
+void ProxyAccessibleBase<Derived>::SetParent(Derived* aParent) {
+ MOZ_ASSERT(IsDoc(), "we should only reparent documents");
+ if (!aParent) {
+ mParent = kNoParent;
+ } else {
+ MOZ_ASSERT(!aParent->IsDoc());
+ mParent = aParent->ID();
+ }
+}
+
+template <class Derived>
+Derived* ProxyAccessibleBase<Derived>::Parent() const {
+ if (mParent == kNoParent) {
+ return nullptr;
+ }
+
+ // if we are not a document then are parent is another proxy in the same
+ // document. That means we can just ask our document for the proxy with our
+ // parent id.
+ if (!IsDoc()) {
+ return Document()->GetAccessible(mParent);
+ }
+
+ // If we are a top level document then our parent is not a proxy.
+ if (AsDoc()->IsTopLevel()) {
+ return nullptr;
+ }
+
+ // Finally if we are a non top level document then our parent id is for a
+ // proxy in our parent document so get the proxy from there.
+ DocAccessibleParent* parentDoc = AsDoc()->ParentDoc();
+ MOZ_ASSERT(parentDoc);
+ MOZ_ASSERT(mParent);
+ return parentDoc->GetAccessible(mParent);
+}
+
+template class ProxyAccessibleBase<ProxyAccessible>;
+
+} // namespace a11y
+} // namespace mozilla