1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "DocAccessibleWrap.h"
9 #include "SessionAccessibility.h"
10 #include "mozilla/a11y/RemoteAccessible.h"
11 #include "mozilla/Components.h"
12 #include "nsIAccessibleEvent.h"
13 #include "nsIAccessiblePivot.h"
14 #include "nsIStringBundle.h"
15 #include "TextLeafRange.h"
17 #define ROLE_STRINGS_URL "chrome://global/locale/AccessFu.properties"
19 using namespace mozilla
;
20 using namespace mozilla::a11y
;
22 static nsTHashMap
<nsStringHashKey
, nsString
> sLocalizedStrings
;
24 void a11y::PlatformInit() {
26 nsCOMPtr
<nsIStringBundleService
> stringBundleService
=
27 components::StringBundle::Service();
28 if (!stringBundleService
) return;
30 nsCOMPtr
<nsIStringBundle
> stringBundle
;
31 nsCOMPtr
<nsIStringBundleService
> sbs
= components::StringBundle::Service();
33 NS_WARNING("Failed to get string bundle service");
37 rv
= sbs
->CreateBundle(ROLE_STRINGS_URL
, getter_AddRefs(stringBundle
));
39 NS_WARNING("Failed to get string bundle");
43 nsString localizedStr
;
44 // Preload the state required localized string.
45 rv
= stringBundle
->GetStringFromName("stateRequired", localizedStr
);
46 if (NS_SUCCEEDED(rv
)) {
47 sLocalizedStrings
.InsertOrUpdate(u
"stateRequired"_ns
, localizedStr
);
50 // Preload heading level localized descriptions 1 thru 6.
51 for (int32_t level
= 1; level
<= 6; level
++) {
53 token
.AppendPrintf("heading-%d", level
);
55 nsAutoString formatString
;
56 formatString
.AppendInt(level
);
57 AutoTArray
<nsString
, 1> formatParams
;
58 formatParams
.AppendElement(formatString
);
59 rv
= stringBundle
->FormatStringFromName("headingLevel", formatParams
,
61 if (NS_SUCCEEDED(rv
)) {
62 sLocalizedStrings
.InsertOrUpdate(token
, localizedStr
);
66 // Preload any roles that have localized versions
67 #define ROLE(geckoRole, stringRole, ariaRole, atkRole, macRole, macSubrole, \
68 msaaRole, ia2Role, androidClass, nameRule) \
69 rv = stringBundle->GetStringFromName(stringRole, localizedStr); \
70 if (NS_SUCCEEDED(rv)) { \
71 sLocalizedStrings.InsertOrUpdate(u##stringRole##_ns, localizedStr); \
78 void a11y::PlatformShutdown() { sLocalizedStrings
.Clear(); }
80 void a11y::ProxyCreated(RemoteAccessible
* aProxy
) {
81 SessionAccessibility::RegisterAccessible(aProxy
);
84 void a11y::ProxyDestroyed(RemoteAccessible
* aProxy
) {
85 SessionAccessibility::UnregisterAccessible(aProxy
);
88 void a11y::PlatformEvent(Accessible
* aTarget
, uint32_t aEventType
) {
89 RefPtr
<SessionAccessibility
> sessionAcc
=
90 SessionAccessibility::GetInstanceFor(aTarget
);
96 case nsIAccessibleEvent::EVENT_REORDER
:
97 sessionAcc
->SendWindowContentChangedEvent();
99 case nsIAccessibleEvent::EVENT_SCROLLING_START
:
100 if (Accessible
* result
= AccessibleWrap::DoPivot(
101 aTarget
, java::SessionAccessibility::HTML_GRANULARITY_DEFAULT
,
103 sessionAcc
->SendAccessibilityFocusedEvent(result
, false);
111 void a11y::PlatformStateChangeEvent(Accessible
* aTarget
, uint64_t aState
,
113 RefPtr
<SessionAccessibility
> sessionAcc
=
114 SessionAccessibility::GetInstanceFor(aTarget
);
120 if (aState
& states::CHECKED
) {
121 sessionAcc
->SendClickedEvent(
122 aTarget
, java::SessionAccessibility::FLAG_CHECKABLE
|
123 (aEnabled
? java::SessionAccessibility::FLAG_CHECKED
: 0));
126 if (aState
& states::EXPANDED
) {
127 sessionAcc
->SendClickedEvent(
129 java::SessionAccessibility::FLAG_EXPANDABLE
|
130 (aEnabled
? java::SessionAccessibility::FLAG_EXPANDED
: 0));
133 if (aState
& states::SELECTED
) {
134 sessionAcc
->SendSelectedEvent(aTarget
, aEnabled
);
137 if (aState
& states::BUSY
) {
138 sessionAcc
->SendWindowStateChangedEvent(aTarget
);
142 void a11y::PlatformFocusEvent(Accessible
* aTarget
,
143 const LayoutDeviceIntRect
& aCaretRect
) {
144 if (RefPtr
<SessionAccessibility
> sessionAcc
=
145 SessionAccessibility::GetInstanceFor(aTarget
)) {
146 sessionAcc
->SendFocusEvent(aTarget
);
150 void a11y::PlatformCaretMoveEvent(Accessible
* aTarget
, int32_t aOffset
,
151 bool aIsSelectionCollapsed
,
152 int32_t aGranularity
,
153 const LayoutDeviceIntRect
& aCaretRect
,
155 RefPtr
<SessionAccessibility
> sessionAcc
=
156 SessionAccessibility::GetInstanceFor(aTarget
);
161 if (!aTarget
->IsDoc() && !aFromUser
&& !aIsSelectionCollapsed
) {
162 // Pivot to the caret's position if it has an expanded selection.
163 // This is used mostly for find in page.
164 Accessible
* leaf
= TextLeafPoint::GetCaret(aTarget
).ActualizeCaret().mAcc
;
167 if (Accessible
* result
= AccessibleWrap::DoPivot(
168 leaf
, java::SessionAccessibility::HTML_GRANULARITY_DEFAULT
, true,
170 sessionAcc
->SendAccessibilityFocusedEvent(result
, false);
175 sessionAcc
->SendTextSelectionChangedEvent(aTarget
, aOffset
);
178 void a11y::PlatformTextChangeEvent(Accessible
* aTarget
, const nsAString
& aStr
,
179 int32_t aStart
, uint32_t aLen
,
180 bool aIsInsert
, bool aFromUser
) {
181 RefPtr
<SessionAccessibility
> sessionAcc
=
182 SessionAccessibility::GetInstanceFor(aTarget
);
185 sessionAcc
->SendTextChangedEvent(aTarget
, aStr
, aStart
, aLen
, aIsInsert
,
190 void a11y::PlatformShowHideEvent(Accessible
* aTarget
, Accessible
* aParent
,
191 bool aInsert
, bool aFromUser
) {
192 // We rely on the window content changed events to be dispatched
193 // after the viewport cache is refreshed.
196 void a11y::PlatformSelectionEvent(Accessible
*, Accessible
*, uint32_t) {}
198 void a11y::PlatformScrollingEvent(Accessible
* aTarget
, uint32_t aEventType
,
199 uint32_t aScrollX
, uint32_t aScrollY
,
200 uint32_t aMaxScrollX
, uint32_t aMaxScrollY
) {
201 if (aEventType
== nsIAccessibleEvent::EVENT_SCROLLING
) {
202 RefPtr
<SessionAccessibility
> sessionAcc
=
203 SessionAccessibility::GetInstanceFor(aTarget
);
206 sessionAcc
->SendScrollingEvent(aTarget
, aScrollX
, aScrollY
, aMaxScrollX
,
212 void a11y::PlatformAnnouncementEvent(Accessible
* aTarget
,
213 const nsAString
& aAnnouncement
,
214 uint16_t aPriority
) {
215 RefPtr
<SessionAccessibility
> sessionAcc
=
216 SessionAccessibility::GetInstanceFor(aTarget
);
219 sessionAcc
->SendAnnouncementEvent(aTarget
, aAnnouncement
, aPriority
);
223 bool a11y::LocalizeString(const nsAString
& aToken
, nsAString
& aLocalized
) {
224 MOZ_ASSERT(XRE_IsParentProcess());
226 auto str
= sLocalizedStrings
.Lookup(aToken
);
228 aLocalized
.Assign(*str
);