summaryrefslogtreecommitdiffstats
path: root/accessible/generic/Accessible-inl.h
blob: d0f98061ce6d8f3f4812b69ee6684a44d8169b15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* -*- 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/. */

#ifndef mozilla_a11y_Accessible_inl_h_
#define mozilla_a11y_Accessible_inl_h_

#include "DocAccessible.h"
#include "ARIAMap.h"
#include "nsCoreUtils.h"
#include "mozilla/dom/Element.h"
#include "mozilla/PresShell.h"

#ifdef A11Y_LOG
#  include "Logging.h"
#endif

namespace mozilla {
namespace a11y {

inline mozilla::a11y::role Accessible::Role() const {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  if (!roleMapEntry || roleMapEntry->roleRule != kUseMapRole)
    return ARIATransformRole(NativeRole());

  return ARIATransformRole(roleMapEntry->role);
}

inline bool Accessible::HasARIARole() const {
  return mRoleMapEntryIndex != aria::NO_ROLE_MAP_ENTRY_INDEX;
}

inline bool Accessible::IsARIARole(nsAtom* aARIARole) const {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  return roleMapEntry && roleMapEntry->Is(aARIARole);
}

inline bool Accessible::HasStrongARIARole() const {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  return roleMapEntry && roleMapEntry->roleRule == kUseMapRole;
}

inline const nsRoleMapEntry* Accessible::ARIARoleMap() const {
  return aria::GetRoleMapFromIndex(mRoleMapEntryIndex);
}

inline mozilla::a11y::role Accessible::ARIARole() {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  if (!roleMapEntry || roleMapEntry->roleRule != kUseMapRole)
    return mozilla::a11y::roles::NOTHING;

  return ARIATransformRole(roleMapEntry->role);
}

inline void Accessible::SetRoleMapEntry(const nsRoleMapEntry* aRoleMapEntry) {
  mRoleMapEntryIndex = aria::GetIndexFromRoleMap(aRoleMapEntry);
}

inline bool Accessible::IsSearchbox() const {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  return (roleMapEntry && roleMapEntry->Is(nsGkAtoms::searchbox)) ||
         (mContent->IsHTMLElement(nsGkAtoms::input) &&
          mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                                             nsGkAtoms::search, eCaseMatters));
}

inline bool Accessible::HasGenericType(AccGenericType aType) const {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  return (mGenericTypes & aType) ||
         (roleMapEntry && roleMapEntry->IsOfType(aType));
}

inline bool Accessible::NativeHasNumericValue() const {
  return mStateFlags & eHasNumericValue;
}

inline bool Accessible::ARIAHasNumericValue() const {
  const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
  if (!roleMapEntry || roleMapEntry->valueRule == eNoValue) return false;

  if (roleMapEntry->valueRule == eHasValueMinMaxIfFocusable)
    return InteractiveState() & states::FOCUSABLE;

  return true;
}

inline bool Accessible::HasNumericValue() const {
  return NativeHasNumericValue() || ARIAHasNumericValue();
}

inline bool Accessible::IsDefunct() const {
  MOZ_ASSERT(mStateFlags & eIsDefunct || IsApplication() || IsDoc() ||
                 mStateFlags & eSharedNode || mContent,
             "No content");
  return mStateFlags & eIsDefunct;
}

inline void Accessible::ScrollTo(uint32_t aHow) const {
  if (mContent) {
    RefPtr<PresShell> presShell = mDoc->PresShellPtr();
    nsCOMPtr<nsIContent> content = mContent;
    nsCoreUtils::ScrollTo(presShell, content, aHow);
  }
}

inline bool Accessible::InsertAfter(Accessible* aNewChild,
                                    Accessible* aRefChild) {
  MOZ_ASSERT(aNewChild, "No new child to insert");

  if (aRefChild && aRefChild->Parent() != this) {
#ifdef A11Y_LOG
    logging::TreeInfo("broken accessible tree", 0, "parent", this,
                      "prev sibling parent", aRefChild->Parent(), "child",
                      aNewChild, nullptr);
    if (logging::IsEnabled(logging::eVerbose)) {
      logging::Tree("TREE", "Document tree", mDoc);
      logging::DOMTree("TREE", "DOM document tree", mDoc);
    }
#endif
    MOZ_ASSERT_UNREACHABLE("Broken accessible tree");
    mDoc->UnbindFromDocument(aNewChild);
    return false;
  }

  return InsertChildAt(aRefChild ? aRefChild->IndexInParent() + 1 : 0,
                       aNewChild);
}

}  // namespace a11y
}  // namespace mozilla

#endif