/* -*- 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 "ProxyAccessible.h" #include "DocAccessibleParent.h" #include "mozilla/unused.h" #include "mozilla/a11y/Platform.h" #include "RelationType.h" #include "mozilla/a11y/Role.h" namespace mozilla { namespace a11y { void ProxyAccessible::Shutdown() { NS_ASSERTION(!mOuterDoc, "Why do we still have a child doc?"); // 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!"); static_cast(mChildren[0])->Destroy(); } mChildren.Clear(); ProxyDestroyed(this); mDoc->RemoveAccessible(this); } void ProxyAccessible::SetChildDoc(DocAccessibleParent* aParent) { if (aParent) { MOZ_ASSERT(mChildren.IsEmpty()); mChildren.AppendElement(aParent); mOuterDoc = true; } else { MOZ_ASSERT(mChildren.Length() == 1); mChildren.Clear(); mOuterDoc = false; } } bool ProxyAccessible::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; } uint64_t ProxyAccessible::State() const { uint64_t state = 0; unused << mDoc->SendState(mID, &state); return state; } void ProxyAccessible::Name(nsString& aName) const { unused << mDoc->SendName(mID, &aName); } void ProxyAccessible::Value(nsString& aValue) const { unused << mDoc->SendValue(mID, &aValue); } void ProxyAccessible::Description(nsString& aDesc) const { unused << mDoc->SendDescription(mID, &aDesc); } void ProxyAccessible::Attributes(nsTArray *aAttrs) const { unused << mDoc->SendAttributes(mID, aAttrs); } nsTArray ProxyAccessible::RelationByType(RelationType aType) const { nsTArray targetIDs; unused << mDoc->SendRelationByType(mID, static_cast(aType), &targetIDs); size_t targetCount = targetIDs.Length(); nsTArray targets(targetCount); for (size_t i = 0; i < targetCount; i++) if (ProxyAccessible* proxy = mDoc->GetAccessible(targetIDs[i])) targets.AppendElement(proxy); return Move(targets); } void ProxyAccessible::Relations(nsTArray* aTypes, nsTArray>* aTargetSets) const { nsTArray ipcRelations; unused << mDoc->SendRelations(mID, &ipcRelations); size_t relationCount = ipcRelations.Length(); aTypes->SetCapacity(relationCount); aTargetSets->SetCapacity(relationCount); for (size_t i = 0; i < relationCount; i++) { uint32_t type = ipcRelations[i].Type(); if (type > static_cast(RelationType::LAST)) continue; size_t targetCount = ipcRelations[i].Targets().Length(); nsTArray targets(targetCount); for (size_t j = 0; j < targetCount; j++) if (ProxyAccessible* proxy = mDoc->GetAccessible(ipcRelations[i].Targets()[j])) targets.AppendElement(proxy); if (targets.IsEmpty()) continue; aTargetSets->AppendElement(Move(targets)); aTypes->AppendElement(static_cast(type)); } } void ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOfset, nsString& aText) const { unused << mDoc->SendTextSubstring(mID, aStartOffset, aEndOfset, &aText); } void ProxyAccessible::GetTextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType, nsString& aText, int32_t* aStartOffset, int32_t* aEndOffset) { unused << mDoc->SendGetTextAfterOffset(mID, aOffset, aBoundaryType, &aText, aStartOffset, aEndOffset); } void ProxyAccessible::GetTextAtOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType, nsString& aText, int32_t* aStartOffset, int32_t* aEndOffset) { unused << mDoc->SendGetTextAtOffset(mID, aOffset, aBoundaryType, &aText, aStartOffset, aEndOffset); } void ProxyAccessible::GetTextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType, nsString& aText, int32_t* aStartOffset, int32_t* aEndOffset) { unused << mDoc->SendGetTextBeforeOffset(mID, aOffset, aBoundaryType, &aText, aStartOffset, aEndOffset); } } }