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