summaryrefslogtreecommitdiffstats
path: root/accessible/android/ProxyAccessibleWrap.h
blob: 40286fcc45e7de2fdfd3dd1be7ade13722e537d8 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* -*- 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_ProxyAccessibleWrap_h
#define MOZILLA_A11Y_ProxyAccessibleWrap_h

#include "AccessibleWrap.h"
#include "DocAccessibleParent.h"

namespace mozilla {
namespace a11y {

/**
 * A wrapper for Accessible proxies. The public methods here should be overriden
 * from AccessibleWrap or its super classes.
 * This gives us an abstraction layer so SessionAccessibility doesn't have
 * to distinguish between a local or remote accessibles.
 * NOTE: This shouldn't be regarded as a full Accessible implementation.
 */
class ProxyAccessibleWrap : public AccessibleWrap {
 public:
  explicit ProxyAccessibleWrap(ProxyAccessible* aProxy);

  virtual void Shutdown() override;

  // Accessible

  virtual already_AddRefed<nsIPersistentProperties> Attributes() override;

  virtual uint32_t ChildCount() const override;

  virtual Accessible* GetChildAt(uint32_t aIndex) const override;

  virtual ENameValueFlag Name(nsString& aName) const override;

  virtual void Value(nsString& aValue) const override;

  virtual uint64_t State() override;

  virtual nsIntRect Bounds() const override;

  MOZ_CAN_RUN_SCRIPT
  virtual void ScrollTo(uint32_t aHow) const override;

  virtual uint8_t ActionCount() const override;

  virtual bool DoAction(uint8_t aIndex) const override;

  // AccessibleWrap

  virtual void SetTextContents(const nsAString& aText) override;

  virtual void GetTextContents(nsAString& aText) override;

  virtual bool GetSelectionBounds(int32_t* aStartOffset,
                                  int32_t* aEndOffset) override;

  virtual void PivotTo(int32_t aGranularity, bool aForward,
                       bool aInclusive) override;

  virtual void NavigateText(int32_t aGranularity, int32_t aStartOffset,
                            int32_t aEndOffset, bool aForward,
                            bool aSelect) override;

  virtual void SetSelection(int32_t aStart, int32_t aEnd) override;

  virtual void Cut() override;

  virtual void Copy() override;

  virtual void Paste() override;

  virtual void ExploreByTouch(float aX, float aY) override;

  virtual void WrapperDOMNodeID(nsString& aDOMNodeID) override;

 private:
  virtual role WrapperRole() override;

  virtual AccessibleWrap* WrapperParent() override;

  virtual bool WrapperRangeInfo(double* aCurVal, double* aMinVal,
                                double* aMaxVal, double* aStep) override;
};

class DocProxyAccessibleWrap : public ProxyAccessibleWrap {
 public:
  explicit DocProxyAccessibleWrap(DocAccessibleParent* aProxy)
      : ProxyAccessibleWrap(aProxy) {
    mGenericTypes |= eDocument;

    if (aProxy->IsTopLevel()) {
      mID = kNoID;
    } else {
      mID = AcquireID();
    }
  }

  virtual void Shutdown() override {
    if (mID) {
      auto doc = static_cast<DocAccessibleParent*>(Proxy());
      if (!doc->IsTopLevel()) {
        MOZ_ASSERT(mID != kNoID, "A non root accessible must have an id");
        ReleaseID(mID);
      }
    }
    mID = 0;
    mBits.proxy = nullptr;
    mStateFlags |= eIsDefunct;
  }

  DocProxyAccessibleWrap* ParentDocument() {
    DocAccessibleParent* proxy = static_cast<DocAccessibleParent*>(Proxy());
    MOZ_ASSERT(proxy);
    if (DocAccessibleParent* parent = proxy->ParentDoc()) {
      return reinterpret_cast<DocProxyAccessibleWrap*>(parent->GetWrapper());
    }

    return nullptr;
  }

  DocProxyAccessibleWrap* GetChildDocumentAt(uint32_t aIndex) {
    auto doc = Proxy()->AsDoc();
    if (doc && doc->ChildDocCount() > aIndex) {
      return reinterpret_cast<DocProxyAccessibleWrap*>(
          doc->ChildDocAt(aIndex)->GetWrapper());
    }

    return nullptr;
  }

  void AddID(uint32_t aID, AccessibleWrap* aAcc) {
    mIDToAccessibleMap.Put(aID, aAcc);
  }
  void RemoveID(uint32_t aID) { mIDToAccessibleMap.Remove(aID); }
  AccessibleWrap* GetAccessibleByID(uint32_t aID) const {
    return mIDToAccessibleMap.Get(aID);
  }

 private:
  /*
   * This provides a mapping from 32 bit id to accessible objects.
   */
  nsDataHashtable<nsUint32HashKey, AccessibleWrap*> mIDToAccessibleMap;
};
}  // namespace a11y
}  // namespace mozilla

#endif