diff options
Diffstat (limited to 'accessible/generic/BaseAccessibles.cpp')
-rw-r--r-- | accessible/generic/BaseAccessibles.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/accessible/generic/BaseAccessibles.cpp b/accessible/generic/BaseAccessibles.cpp new file mode 100644 index 000000000..bcb262a97 --- /dev/null +++ b/accessible/generic/BaseAccessibles.cpp @@ -0,0 +1,264 @@ +/* -*- 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 "BaseAccessibles.h" + +#include "Accessible-inl.h" +#include "HyperTextAccessibleWrap.h" +#include "nsAccessibilityService.h" +#include "nsAccUtils.h" +#include "nsCoreUtils.h" +#include "Role.h" +#include "States.h" +#include "nsIURI.h" + +using namespace mozilla::a11y; + +//////////////////////////////////////////////////////////////////////////////// +// LeafAccessible +//////////////////////////////////////////////////////////////////////////////// + +LeafAccessible:: + LeafAccessible(nsIContent* aContent, DocAccessible* aDoc) : + AccessibleWrap(aContent, aDoc) +{ + mStateFlags |= eNoKidsFromDOM; +} + +NS_IMPL_ISUPPORTS_INHERITED0(LeafAccessible, Accessible) + +//////////////////////////////////////////////////////////////////////////////// +// LeafAccessible: Accessible public + +Accessible* +LeafAccessible::ChildAtPoint(int32_t aX, int32_t aY, + EWhichChildAtPoint aWhichChild) +{ + // Don't walk into leaf accessibles. + return this; +} + +bool +LeafAccessible::InsertChildAt(uint32_t aIndex, Accessible* aChild) +{ + NS_NOTREACHED("InsertChildAt called on leaf accessible!"); + return false; +} + +bool +LeafAccessible::RemoveChild(Accessible* aChild) +{ + NS_NOTREACHED("RemoveChild called on leaf accessible!"); + return false; +} + +bool +LeafAccessible::IsAcceptableChild(nsIContent* aEl) const +{ + // No children for leaf accessible. + return false; +} + + +//////////////////////////////////////////////////////////////////////////////// +// LinkableAccessible +//////////////////////////////////////////////////////////////////////////////// + +NS_IMPL_ISUPPORTS_INHERITED0(LinkableAccessible, AccessibleWrap) + +//////////////////////////////////////////////////////////////////////////////// +// LinkableAccessible. nsIAccessible + +void +LinkableAccessible::TakeFocus() +{ + if (Accessible* actionAcc = ActionWalk()) { + actionAcc->TakeFocus(); + } else { + AccessibleWrap::TakeFocus(); + } +} + +uint64_t +LinkableAccessible::NativeLinkState() const +{ + bool isLink; + Accessible* actionAcc = + const_cast<LinkableAccessible*>(this)->ActionWalk(&isLink); + if (isLink) { + return states::LINKED | (actionAcc->LinkState() & states::TRAVERSED); + } + + return 0; +} + +void +LinkableAccessible::Value(nsString& aValue) +{ + aValue.Truncate(); + + Accessible::Value(aValue); + if (!aValue.IsEmpty()) { + return; + } + + bool isLink; + Accessible* actionAcc = ActionWalk(&isLink); + if (isLink) { + actionAcc->Value(aValue); + } +} + +uint8_t +LinkableAccessible::ActionCount() +{ + bool isLink, isOnclick, isLabelWithControl; + ActionWalk(&isLink, &isOnclick, &isLabelWithControl); + return (isLink || isOnclick || isLabelWithControl) ? 1 : 0; +} + +Accessible* +LinkableAccessible::ActionWalk(bool* aIsLink, bool* aIsOnclick, + bool* aIsLabelWithControl) +{ + if (aIsOnclick) { + *aIsOnclick = false; + } + if (aIsLink) { + *aIsLink = false; + } + if (aIsLabelWithControl) { + *aIsLabelWithControl = false; + } + + if (nsCoreUtils::HasClickListener(mContent)) { + if (aIsOnclick) { + *aIsOnclick = true; + } + return nullptr; + } + + // XXX: The logic looks broken since the click listener may be registered + // on non accessible node in parent chain but this node is skipped when tree + // is traversed. + Accessible* walkUpAcc = this; + while ((walkUpAcc = walkUpAcc->Parent()) && !walkUpAcc->IsDoc()) { + if (walkUpAcc->LinkState() & states::LINKED) { + if (aIsLink) { + *aIsLink = true; + } + return walkUpAcc; + } + + if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) { + if (aIsOnclick) { + *aIsOnclick = true; + } + return walkUpAcc; + } + + if (nsCoreUtils::IsLabelWithControl(walkUpAcc->GetContent())) { + if (aIsLabelWithControl) { + *aIsLabelWithControl = true; + } + return walkUpAcc; + } + } + return nullptr; +} + +void +LinkableAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) +{ + aName.Truncate(); + + // Action 0 (default action): Jump to link + if (aIndex == eAction_Jump) { + bool isOnclick, isLink, isLabelWithControl; + ActionWalk(&isLink, &isOnclick, &isLabelWithControl); + if (isLink) { + aName.AssignLiteral("jump"); + } else if (isOnclick || isLabelWithControl) { + aName.AssignLiteral("click"); + } + } +} + +bool +LinkableAccessible::DoAction(uint8_t aIndex) +{ + if (aIndex != eAction_Jump) { + return false; + } + + if (Accessible* actionAcc = ActionWalk()) { + return actionAcc->DoAction(aIndex); + } + + return AccessibleWrap::DoAction(aIndex); +} + +KeyBinding +LinkableAccessible::AccessKey() const +{ + if (const Accessible* actionAcc = + const_cast<LinkableAccessible*>(this)->ActionWalk()) { + return actionAcc->AccessKey(); + } + + return Accessible::AccessKey(); +} + +//////////////////////////////////////////////////////////////////////////////// +// LinkableAccessible: HyperLinkAccessible + +already_AddRefed<nsIURI> +LinkableAccessible::AnchorURIAt(uint32_t aAnchorIndex) +{ + bool isLink; + Accessible* actionAcc = ActionWalk(&isLink); + if (isLink) { + NS_ASSERTION(actionAcc->IsLink(), "HyperLink isn't implemented."); + + if (actionAcc->IsLink()) { + return actionAcc->AnchorURIAt(aAnchorIndex); + } + } + + return nullptr; +} + + +//////////////////////////////////////////////////////////////////////////////// +// DummyAccessible +//////////////////////////////////////////////////////////////////////////////// + +uint64_t +DummyAccessible::NativeState() +{ + return 0; +} +uint64_t +DummyAccessible::NativeInteractiveState() const +{ + return 0; +} + +uint64_t +DummyAccessible::NativeLinkState() const +{ + return 0; +} + +bool +DummyAccessible::NativelyUnavailable() const +{ + return false; +} + +void +DummyAccessible::ApplyARIAState(uint64_t* aState) const +{ +} |