123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/TabParent.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());
- NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?");
- 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.
- if (!mOuterDoc) {
- uint32_t childCount = mChildren.Length();
- for (uint32_t idx = 0; idx < childCount; idx++)
- mChildren[idx]->Shutdown();
- } else {
- if (mChildren.Length() != 1)
- MOZ_CRASH("outer doc doesn't own adoc!");
- 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)
- {
- // DocAccessibleParent::AddChildDoc tolerates replacing one document with
- // another. We must reflect that here.
- MOZ_ASSERT(aChildDoc);
- MOZ_ASSERT(mChildren.Length() <= 1);
- if (mChildren.IsEmpty()) {
- mChildren.AppendElement(aChildDoc);
- } else {
- mChildren.ReplaceElementAt(0, 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);
- if (mChildren.RemoveElement(aChildDoc)) {
- mOuterDoc = false;
- }
- }
- template <class Derived>
- bool
- ProxyAccessibleBase<Derived>::MustPruneChildren() const
- {
- // this is the equivalent to nsAccUtils::MustPrune for proxies and should be
- // kept in sync with that.
- if (mRole != roles::MENUITEM && mRole != roles::COMBOBOX_OPTION
- && mRole != roles::OPTION && mRole != roles::ENTRY
- && mRole != roles::FLAT_EQUATION && mRole != roles::PASSWORD_TEXT
- && mRole != roles::PUSHBUTTON && mRole != roles::TOGGLE_BUTTON
- && mRole != roles::GRAPHIC && mRole != roles::SLIDER
- && mRole != roles::PROGRESSBAR && mRole != roles::SEPARATOR)
- return false;
- if (mChildren.Length() != 1)
- return false;
- return mChildren[0]->Role() == roles::TEXT_LEAF
- || mChildren[0]->Role() == roles::STATICTEXT;
- }
- 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::TabParent*>(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 ProxyAccessibleBase<ProxyAccessible>;
- } // namespace a11y
- } // namespace mozilla
|