/src/mozilla-central/accessible/base/nsAccessibilityService.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #ifndef __nsAccessibilityService_h__ |
7 | | #define __nsAccessibilityService_h__ |
8 | | |
9 | | #include "mozilla/a11y/DocManager.h" |
10 | | #include "mozilla/a11y/FocusManager.h" |
11 | | #include "mozilla/a11y/Platform.h" |
12 | | #include "mozilla/a11y/Role.h" |
13 | | #include "mozilla/a11y/SelectionManager.h" |
14 | | #include "mozilla/Preferences.h" |
15 | | |
16 | | #include "nsIObserver.h" |
17 | | #include "nsIAccessibleEvent.h" |
18 | | #include "nsIEventListenerService.h" |
19 | | #include "xpcAccessibilityService.h" |
20 | | |
21 | | class nsImageFrame; |
22 | | class nsIArray; |
23 | | class nsIPersistentProperties; |
24 | | class nsPluginFrame; |
25 | | class nsITreeView; |
26 | | |
27 | | namespace mozilla { |
28 | | |
29 | | namespace dom { |
30 | | class DOMStringList; |
31 | | } |
32 | | |
33 | | namespace a11y { |
34 | | |
35 | | class ApplicationAccessible; |
36 | | class xpcAccessibleApplication; |
37 | | |
38 | | /** |
39 | | * Return focus manager. |
40 | | */ |
41 | | FocusManager* FocusMgr(); |
42 | | |
43 | | /** |
44 | | * Return selection manager. |
45 | | */ |
46 | | SelectionManager* SelectionMgr(); |
47 | | |
48 | | /** |
49 | | * Returns the application accessible. |
50 | | */ |
51 | | ApplicationAccessible* ApplicationAcc(); |
52 | | xpcAccessibleApplication* XPCApplicationAcc(); |
53 | | |
54 | | typedef Accessible* (New_Accessible)(Element* aElement, Accessible* aContext); |
55 | | |
56 | | struct MarkupAttrInfo { |
57 | | nsStaticAtom** name; |
58 | | nsStaticAtom** value; |
59 | | |
60 | | nsStaticAtom** DOMAttrName; |
61 | | nsStaticAtom** DOMAttrValue; |
62 | | }; |
63 | | |
64 | | struct HTMLMarkupMapInfo { |
65 | | nsStaticAtom** tag; |
66 | | New_Accessible* new_func; |
67 | | a11y::role role; |
68 | | MarkupAttrInfo attrs[4]; |
69 | | }; |
70 | | |
71 | | #ifdef MOZ_XUL |
72 | | struct XULMarkupMapInfo { |
73 | | nsStaticAtom** tag; |
74 | | New_Accessible* new_func; |
75 | | }; |
76 | | #endif |
77 | | |
78 | | /** |
79 | | * PREF_ACCESSIBILITY_FORCE_DISABLED preference change callback. |
80 | | */ |
81 | | void PrefChanged(const char* aPref, void* aClosure); |
82 | | |
83 | | /** |
84 | | * Read and normalize PREF_ACCESSIBILITY_FORCE_DISABLED preference. |
85 | | */ |
86 | | EPlatformDisabledState ReadPlatformDisabledState(); |
87 | | |
88 | | } // namespace a11y |
89 | | } // namespace mozilla |
90 | | |
91 | | class nsAccessibilityService final : public mozilla::a11y::DocManager, |
92 | | public mozilla::a11y::FocusManager, |
93 | | public mozilla::a11y::SelectionManager, |
94 | | public nsIListenerChangeListener, |
95 | | public nsIObserver |
96 | | { |
97 | | public: |
98 | | typedef mozilla::a11y::Accessible Accessible; |
99 | | typedef mozilla::a11y::DocAccessible DocAccessible; |
100 | | |
101 | | // nsIListenerChangeListener |
102 | | NS_IMETHOD ListenersChanged(nsIArray* aEventChanges) override; |
103 | | |
104 | | protected: |
105 | | ~nsAccessibilityService(); |
106 | | |
107 | | public: |
108 | | NS_DECL_ISUPPORTS_INHERITED |
109 | | NS_DECL_NSIOBSERVER |
110 | | |
111 | | Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell, |
112 | | bool aCanCreate); |
113 | | already_AddRefed<Accessible> |
114 | | CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent, |
115 | | Accessible* aContext); |
116 | | |
117 | | /** |
118 | | * Adds/remove ATK root accessible for gtk+ native window to/from children |
119 | | * of the application accessible. |
120 | | */ |
121 | | Accessible* AddNativeRootAccessible(void* aAtkAccessible); |
122 | | void RemoveNativeRootAccessible(Accessible* aRootAccessible); |
123 | | |
124 | | bool HasAccessible(nsINode* aDOMNode); |
125 | | |
126 | | /** |
127 | | * Get a string equivalent for an accessible role value. |
128 | | */ |
129 | | void GetStringRole(uint32_t aRole, nsAString& aString); |
130 | | |
131 | | /** |
132 | | * Get a string equivalent for an accessible state/extra state. |
133 | | */ |
134 | | already_AddRefed<mozilla::dom::DOMStringList> |
135 | | GetStringStates(uint64_t aStates) const; |
136 | | void GetStringStates(uint32_t aState, uint32_t aExtraState, |
137 | | nsISupports **aStringStates); |
138 | | |
139 | | /** |
140 | | * Get a string equivalent for an accessible event value. |
141 | | */ |
142 | | void GetStringEventType(uint32_t aEventType, nsAString& aString); |
143 | | |
144 | | /** |
145 | | * Get a string equivalent for an accessible event value. |
146 | | */ |
147 | | void GetStringEventType(uint32_t aEventType, nsACString& aString); |
148 | | |
149 | | /** |
150 | | * Get a string equivalent for an accessible relation type. |
151 | | */ |
152 | | void GetStringRelationType(uint32_t aRelationType, nsAString& aString); |
153 | | |
154 | | // nsAccesibilityService |
155 | | /** |
156 | | * Notification used to update the accessible tree when deck panel is |
157 | | * switched. |
158 | | */ |
159 | | void DeckPanelSwitched(nsIPresShell* aPresShell, nsIContent* aDeckNode, |
160 | | nsIFrame* aPrevBoxFrame, nsIFrame* aCurrentBoxFrame); |
161 | | |
162 | | /** |
163 | | * Notification used to update the accessible tree when new content is |
164 | | * inserted. |
165 | | */ |
166 | | void ContentRangeInserted(nsIPresShell* aPresShell, |
167 | | nsIContent* aStartChild, |
168 | | nsIContent* aEndChild); |
169 | | |
170 | | /** |
171 | | * Notification used to update the accessible tree when content is removed. |
172 | | */ |
173 | | void ContentRemoved(nsIPresShell* aPresShell, nsIContent* aChild); |
174 | | |
175 | | void UpdateText(nsIPresShell* aPresShell, nsIContent* aContent); |
176 | | |
177 | | /** |
178 | | * Update XUL:tree accessible tree when treeview is changed. |
179 | | */ |
180 | | void TreeViewChanged(nsIPresShell* aPresShell, nsIContent* aContent, |
181 | | nsITreeView* aView); |
182 | | |
183 | | /** |
184 | | * Notify of input@type="element" value change. |
185 | | */ |
186 | | void RangeValueChanged(nsIPresShell* aPresShell, nsIContent* aContent); |
187 | | |
188 | | /** |
189 | | * Update list bullet accessible. |
190 | | */ |
191 | | void UpdateListBullet(nsIPresShell* aPresShell, |
192 | | nsIContent* aHTMLListItemContent, |
193 | | bool aHasBullet); |
194 | | |
195 | | /** |
196 | | * Update the image map. |
197 | | */ |
198 | | void UpdateImageMap(nsImageFrame* aImageFrame); |
199 | | |
200 | | /** |
201 | | * Update the label accessible tree when rendered @value is changed. |
202 | | */ |
203 | | void UpdateLabelValue(nsIPresShell* aPresShell, nsIContent* aLabelElm, |
204 | | const nsString& aNewValue); |
205 | | |
206 | | /** |
207 | | * Notify accessibility that anchor jump has been accomplished to the given |
208 | | * target. Used by layout. |
209 | | */ |
210 | | void NotifyOfAnchorJumpTo(nsIContent *aTarget); |
211 | | |
212 | | /** |
213 | | * Notify that presshell is activated. |
214 | | */ |
215 | | void PresShellActivated(nsIPresShell* aPresShell); |
216 | | |
217 | | /** |
218 | | * Recreate an accessible for the given content node in the presshell. |
219 | | */ |
220 | | void RecreateAccessible(nsIPresShell* aPresShell, nsIContent* aContent); |
221 | | |
222 | | void FireAccessibleEvent(uint32_t aEvent, Accessible* aTarget); |
223 | | |
224 | | // nsAccessibiltiyService |
225 | | |
226 | | /** |
227 | | * Return true if accessibility service has been shutdown. |
228 | | */ |
229 | | static bool IsShutdown() |
230 | 0 | { |
231 | 0 | return gConsumers == 0; |
232 | 0 | }; |
233 | | |
234 | | /** |
235 | | * Creates an accessible for the given DOM node. |
236 | | * |
237 | | * @param aNode [in] the given node |
238 | | * @param aContext [in] context the accessible is created in |
239 | | * @param aIsSubtreeHidden [out, optional] indicates whether the node's |
240 | | * frame and its subtree is hidden |
241 | | */ |
242 | | Accessible* CreateAccessible(nsINode* aNode, Accessible* aContext, |
243 | | bool* aIsSubtreeHidden = nullptr); |
244 | | |
245 | | mozilla::a11y::role MarkupRole(const nsIContent* aContent) const |
246 | 0 | { |
247 | 0 | const mozilla::a11y::HTMLMarkupMapInfo* markupMap = |
248 | 0 | mHTMLMarkupMap.Get(aContent->NodeInfo()->NameAtom()); |
249 | 0 | return markupMap ? markupMap->role : mozilla::a11y::roles::NOTHING; |
250 | 0 | } |
251 | | |
252 | | /** |
253 | | * Set the object attribute defined by markup for the given element. |
254 | | */ |
255 | | void MarkupAttributes(const nsIContent* aContent, |
256 | | nsIPersistentProperties* aAttributes) const; |
257 | | |
258 | | /** |
259 | | * A list of possible accessibility service consumers. Accessibility service |
260 | | * can only be shut down when there are no remaining consumers. |
261 | | * |
262 | | * eXPCOM - accessibility service is used by XPCOM. |
263 | | * |
264 | | * eMainProcess - accessibility service was started by main process in the |
265 | | * content process. |
266 | | * |
267 | | * ePlatformAPI - accessibility service is used by the platform api in the |
268 | | * main process. |
269 | | */ |
270 | | enum ServiceConsumer |
271 | | { |
272 | | eXPCOM = 1 << 0, |
273 | | eMainProcess = 1 << 1, |
274 | | ePlatformAPI = 1 << 2, |
275 | | }; |
276 | | |
277 | | private: |
278 | | // nsAccessibilityService creation is controlled by friend |
279 | | // GetOrCreateAccService, keep constructors private. |
280 | | nsAccessibilityService(); |
281 | | nsAccessibilityService(const nsAccessibilityService&); |
282 | | nsAccessibilityService& operator =(const nsAccessibilityService&); |
283 | | |
284 | | private: |
285 | | /** |
286 | | * Initialize accessibility service. |
287 | | */ |
288 | | bool Init(); |
289 | | |
290 | | /** |
291 | | * Shutdowns accessibility service. |
292 | | */ |
293 | | void Shutdown(); |
294 | | |
295 | | /** |
296 | | * Create an accessible whose type depends on the given frame. |
297 | | */ |
298 | | already_AddRefed<Accessible> |
299 | | CreateAccessibleByFrameType(nsIFrame* aFrame, nsIContent* aContent, |
300 | | Accessible* aContext); |
301 | | |
302 | | /** |
303 | | * Notify observers about change of the accessibility service's consumers. |
304 | | */ |
305 | | void NotifyOfConsumersChange(); |
306 | | |
307 | | /** |
308 | | * Get a JSON string representing the accessibility service consumers. |
309 | | */ |
310 | | void GetConsumers(nsAString& aString); |
311 | | |
312 | | /** |
313 | | * Set accessibility service consumers. |
314 | | */ |
315 | | void SetConsumers(uint32_t aConsumers, bool aNotify = true); |
316 | | |
317 | | /** |
318 | | * Unset accessibility service consumers. |
319 | | */ |
320 | | void UnsetConsumers(uint32_t aConsumers); |
321 | | |
322 | | /** |
323 | | * Reference for accessibility service instance. |
324 | | */ |
325 | | static nsAccessibilityService* gAccessibilityService; |
326 | | |
327 | | /** |
328 | | * Reference for application accessible instance. |
329 | | */ |
330 | | static mozilla::a11y::ApplicationAccessible* gApplicationAccessible; |
331 | | static mozilla::a11y::xpcAccessibleApplication* gXPCApplicationAccessible; |
332 | | |
333 | | /** |
334 | | * Contains a set of accessibility service consumers. |
335 | | */ |
336 | | static uint32_t gConsumers; |
337 | | |
338 | | nsDataHashtable<nsPtrHashKey<const nsAtom>, const mozilla::a11y::HTMLMarkupMapInfo*> mHTMLMarkupMap; |
339 | | #ifdef MOZ_XUL |
340 | | nsDataHashtable<nsPtrHashKey<const nsAtom>, const mozilla::a11y::XULMarkupMapInfo*> mXULMarkupMap; |
341 | | #endif |
342 | | |
343 | | friend nsAccessibilityService* GetAccService(); |
344 | | friend nsAccessibilityService* GetOrCreateAccService(uint32_t); |
345 | | friend void MaybeShutdownAccService(uint32_t); |
346 | | friend void mozilla::a11y::PrefChanged(const char*, void*); |
347 | | friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr(); |
348 | | friend mozilla::a11y::SelectionManager* mozilla::a11y::SelectionMgr(); |
349 | | friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc(); |
350 | | friend mozilla::a11y::xpcAccessibleApplication* mozilla::a11y::XPCApplicationAcc(); |
351 | | friend class xpcAccessibilityService; |
352 | | }; |
353 | | |
354 | | /** |
355 | | * Return the accessibility service instance. (Handy global function) |
356 | | */ |
357 | | inline nsAccessibilityService* |
358 | | GetAccService() |
359 | | { |
360 | | return nsAccessibilityService::gAccessibilityService; |
361 | | } |
362 | | |
363 | | /** |
364 | | * Return accessibility service instance; creating one if necessary. |
365 | | */ |
366 | | nsAccessibilityService* GetOrCreateAccService( |
367 | | uint32_t aNewConsumer = nsAccessibilityService::ePlatformAPI); |
368 | | |
369 | | /** |
370 | | * Shutdown accessibility service if needed. |
371 | | */ |
372 | | void MaybeShutdownAccService(uint32_t aFormerConsumer); |
373 | | |
374 | | /** |
375 | | * Return true if we're in a content process and not B2G. |
376 | | */ |
377 | | inline bool |
378 | | IPCAccessibilityActive() |
379 | 0 | { |
380 | 0 | return XRE_IsContentProcess(); |
381 | 0 | } |
382 | | |
383 | | /** |
384 | | * Map nsIAccessibleEvents constants to strings. Used by |
385 | | * nsAccessibilityService::GetStringEventType() method. |
386 | | */ |
387 | | static const char kEventTypeNames[][40] = { |
388 | | "unknown", // |
389 | | "show", // EVENT_SHOW |
390 | | "hide", // EVENT_HIDE |
391 | | "reorder", // EVENT_REORDER |
392 | | "active decendent change", // EVENT_ACTIVE_DECENDENT_CHANGED |
393 | | "focus", // EVENT_FOCUS |
394 | | "state change", // EVENT_STATE_CHANGE |
395 | | "location change", // EVENT_LOCATION_CHANGE |
396 | | "name changed", // EVENT_NAME_CHANGE |
397 | | "description change", // EVENT_DESCRIPTION_CHANGE |
398 | | "value change", // EVENT_VALUE_CHANGE |
399 | | "help change", // EVENT_HELP_CHANGE |
400 | | "default action change", // EVENT_DEFACTION_CHANGE |
401 | | "action change", // EVENT_ACTION_CHANGE |
402 | | "accelerator change", // EVENT_ACCELERATOR_CHANGE |
403 | | "selection", // EVENT_SELECTION |
404 | | "selection add", // EVENT_SELECTION_ADD |
405 | | "selection remove", // EVENT_SELECTION_REMOVE |
406 | | "selection within", // EVENT_SELECTION_WITHIN |
407 | | "alert", // EVENT_ALERT |
408 | | "foreground", // EVENT_FOREGROUND |
409 | | "menu start", // EVENT_MENU_START |
410 | | "menu end", // EVENT_MENU_END |
411 | | "menupopup start", // EVENT_MENUPOPUP_START |
412 | | "menupopup end", // EVENT_MENUPOPUP_END |
413 | | "capture start", // EVENT_CAPTURE_START |
414 | | "capture end", // EVENT_CAPTURE_END |
415 | | "movesize start", // EVENT_MOVESIZE_START |
416 | | "movesize end", // EVENT_MOVESIZE_END |
417 | | "contexthelp start", // EVENT_CONTEXTHELP_START |
418 | | "contexthelp end", // EVENT_CONTEXTHELP_END |
419 | | "dragdrop start", // EVENT_DRAGDROP_START |
420 | | "dragdrop end", // EVENT_DRAGDROP_END |
421 | | "dialog start", // EVENT_DIALOG_START |
422 | | "dialog end", // EVENT_DIALOG_END |
423 | | "scrolling start", // EVENT_SCROLLING_START |
424 | | "scrolling end", // EVENT_SCROLLING_END |
425 | | "minimize start", // EVENT_MINIMIZE_START |
426 | | "minimize end", // EVENT_MINIMIZE_END |
427 | | "document load complete", // EVENT_DOCUMENT_LOAD_COMPLETE |
428 | | "document reload", // EVENT_DOCUMENT_RELOAD |
429 | | "document load stopped", // EVENT_DOCUMENT_LOAD_STOPPED |
430 | | "document attributes changed", // EVENT_DOCUMENT_ATTRIBUTES_CHANGED |
431 | | "document content changed", // EVENT_DOCUMENT_CONTENT_CHANGED |
432 | | "property changed", // EVENT_PROPERTY_CHANGED |
433 | | "page changed", // EVENT_PAGE_CHANGED |
434 | | "text attribute changed", // EVENT_TEXT_ATTRIBUTE_CHANGED |
435 | | "text caret moved", // EVENT_TEXT_CARET_MOVED |
436 | | "text changed", // EVENT_TEXT_CHANGED |
437 | | "text inserted", // EVENT_TEXT_INSERTED |
438 | | "text removed", // EVENT_TEXT_REMOVED |
439 | | "text updated", // EVENT_TEXT_UPDATED |
440 | | "text selection changed", // EVENT_TEXT_SELECTION_CHANGED |
441 | | "visible data changed", // EVENT_VISIBLE_DATA_CHANGED |
442 | | "text column changed", // EVENT_TEXT_COLUMN_CHANGED |
443 | | "section changed", // EVENT_SECTION_CHANGED |
444 | | "table caption changed", // EVENT_TABLE_CAPTION_CHANGED |
445 | | "table model changed", // EVENT_TABLE_MODEL_CHANGED |
446 | | "table summary changed", // EVENT_TABLE_SUMMARY_CHANGED |
447 | | "table row description changed", // EVENT_TABLE_ROW_DESCRIPTION_CHANGED |
448 | | "table row header changed", // EVENT_TABLE_ROW_HEADER_CHANGED |
449 | | "table row insert", // EVENT_TABLE_ROW_INSERT |
450 | | "table row delete", // EVENT_TABLE_ROW_DELETE |
451 | | "table row reorder", // EVENT_TABLE_ROW_REORDER |
452 | | "table column description changed", // EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED |
453 | | "table column header changed", // EVENT_TABLE_COLUMN_HEADER_CHANGED |
454 | | "table column insert", // EVENT_TABLE_COLUMN_INSERT |
455 | | "table column delete", // EVENT_TABLE_COLUMN_DELETE |
456 | | "table column reorder", // EVENT_TABLE_COLUMN_REORDER |
457 | | "window activate", // EVENT_WINDOW_ACTIVATE |
458 | | "window create", // EVENT_WINDOW_CREATE |
459 | | "window deactivate", // EVENT_WINDOW_DEACTIVATE |
460 | | "window destroy", // EVENT_WINDOW_DESTROY |
461 | | "window maximize", // EVENT_WINDOW_MAXIMIZE |
462 | | "window minimize", // EVENT_WINDOW_MINIMIZE |
463 | | "window resize", // EVENT_WINDOW_RESIZE |
464 | | "window restore", // EVENT_WINDOW_RESTORE |
465 | | "hyperlink end index changed", // EVENT_HYPERLINK_END_INDEX_CHANGED |
466 | | "hyperlink number of anchors changed", // EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED |
467 | | "hyperlink selected link changed", // EVENT_HYPERLINK_SELECTED_LINK_CHANGED |
468 | | "hypertext link activated", // EVENT_HYPERTEXT_LINK_ACTIVATED |
469 | | "hypertext link selected", // EVENT_HYPERTEXT_LINK_SELECTED |
470 | | "hyperlink start index changed", // EVENT_HYPERLINK_START_INDEX_CHANGED |
471 | | "hypertext changed", // EVENT_HYPERTEXT_CHANGED |
472 | | "hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED |
473 | | "object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED |
474 | | "virtual cursor changed", // EVENT_VIRTUALCURSOR_CHANGED |
475 | | "text value change", // EVENT_TEXT_VALUE_CHANGE |
476 | | "scrolling", // EVENT_SCROLLING |
477 | | }; |
478 | | |
479 | | #endif |