OLD | NEW |
(Empty) | |
| 1 # Accessibility Overview |
| 2 |
| 3 This document describes how accessibility is implemented throughout Chromium at |
| 4 a high level. |
| 5 |
| 6 ## Concepts |
| 7 |
| 8 The three central concepts of accessibility are: |
| 9 |
| 10 1. The *tree*, which models the entire interface as a tree of objects, exposed |
| 11 to screenreaders or other accessibility software; |
| 12 2. *Events*, which let accessibility software know that a part of the tree has |
| 13 changed somehow; |
| 14 3. *Actions*, which come from accessibility software and ask the interface to |
| 15 change. |
| 16 |
| 17 Here's an example of an accessibility tree looks like. The following HTML: |
| 18 |
| 19 ``` |
| 20 <select title="Select A"> |
| 21 <option value="1">Option 1</option> |
| 22 <option value="2" selected>Option 2</option> |
| 23 <option value="3">Option 3</option> |
| 24 </select> |
| 25 ``` |
| 26 |
| 27 has a generated accessibility tree like this: |
| 28 |
| 29 ``` |
| 30 0: AXMenuList title="Select A" |
| 31 1: AXMenuListOption title="Option 1" |
| 32 2: AXMenuListOption title="Option 2" selected |
| 33 3: AXMenuListOption title="Option 3" |
| 34 ``` |
| 35 |
| 36 Given that accessibility tree, an example of the events generated when selecting |
| 37 "Option 1" might be: |
| 38 |
| 39 ``` |
| 40 AXMenuListItemUnselected 2 |
| 41 AXMenuListItemSelected 1 |
| 42 AXMenuListValueChanged 0 |
| 43 ``` |
| 44 |
| 45 An example of a command used to change the selection from "Option 1" to "Option |
| 46 3" might be: |
| 47 |
| 48 ``` |
| 49 AccessibilityMsg_DoDefaultAction 3 |
| 50 ``` |
| 51 |
| 52 All three concepts are handled at several layers in Chromium. |
| 53 |
| 54 ## Blink |
| 55 |
| 56 Blink constructs an accessibility tree (a hierarchy of [WebAXObject]s) from the |
| 57 page it is rendering. WebAXObject is the public API wrapper around [AXObject], |
| 58 which is the core class of Blink's accessibility tree. AXObject is an abstract |
| 59 class; the most commonly used concrete subclass of it is [AXNodeObject], which |
| 60 wraps a [Node]. In turn, most AXNodeObjects are actually [AXLayoutObject]s, |
| 61 which wrap both a [Node] and a [LayoutObject]. Access to the LayoutObject is |
| 62 important because some elements are only in the AXObject tree depending on their |
| 63 visibility, geometry, linewrapping, and so on. There are some subclasses of |
| 64 AXLayoutObject that implement special-case logic for specific types of Node. |
| 65 There are also other subclasses of AXObject, which are mostly used for testing. |
| 66 |
| 67 Note that not all AXLayoutObjects correspond to actual Nodes; some are synthetic |
| 68 layout objects which group related inline elements or similar. |
| 69 |
| 70 The central class responsible for dealing with accessibility events in Blink is |
| 71 [AXObjectCacheImpl], which is responsible for caching the corresponding |
| 72 AXObjects for Nodes or LayoutObjects. This class has many methods named |
| 73 `handleFoo`, which are called throughout Blink to notify the AXObjectCacheImpl |
| 74 that it may need to update its tree. Since this class is already aware of all |
| 75 accessibility events in Blink, it is also responsible for relaying accessibility |
| 76 events from Blink to the embedding content layer. |
| 77 |
| 78 ## The content layer |
| 79 |
| 80 The content layer lives on both sides of the renderer/browser split. The content |
| 81 layer translates WebAXObjects into [AXContentNodeData], which is a subclass of |
| 82 [ui::AXNodeData]. The ui::AXNodeData class and related classes are Chromium's |
| 83 cross-platform accessibility tree. The translation is implemented in |
| 84 [BlinkAXTreeSource]. This translation happens on the renderer side, so the |
| 85 ui::AXNodeData tree now needs to be sent to the browser, which is done by |
| 86 sending [AccessibilityHostMsg_EventParams] with the payload being serialized |
| 87 delta-updates to the tree, so that changes that happen on the renderer side can |
| 88 be reflected on the browser side. |
| 89 |
| 90 On the browser side, these IPCs are received by [RenderFrameHostImpl], and then |
| 91 usually forwarded to [BrowserAccessibilityManager] which is responsible for: |
| 92 |
| 93 1. Merging AXNodeData trees into one tree of [BrowserAccessibility] objects, |
| 94 by linking to other BrowserAccessibilityManagers. This is important because |
| 95 each page has its own accessibility tree, but each Chromium *window* must |
| 96 have only one accessibility tree, so trees from multiple pages need to be |
| 97 combined (possibly also with trees from Views UI). |
| 98 2. Dispatching outgoing accessibility events to the platform's accessibility |
| 99 APIs. This is done in the platform-specific subclasses of |
| 100 BrowserAccessibilityManager, in a method named `NotifyAccessibilityEvent`. |
| 101 3. Dispatching incoming accessibility actions to the appropriate recipient, via |
| 102 [BrowserAccessibilityDelegate]. For messages destined for a renderer, |
| 103 [RenderFrameHostImpl], which is a BrowserAccessibilityDelegate, is |
| 104 responsible for sending appropriate `AccessibilityMsg_Foo` IPCs to the |
| 105 renderer, where they will be received by [RenderAccessibilityImpl]. |
| 106 |
| 107 On Chrome OS, RenderFrameHostImpl does not route events to |
| 108 BrowserAccessibilityManager at all, since there is no platform screenreader |
| 109 outside Chrome to integrate with. |
| 110 |
| 111 ## Views |
| 112 |
| 113 Views generates a [NativeViewAccessibility] for each View, which is used as the |
| 114 delegate for an [AXPlatformNode] representing that View. This part is relatively |
| 115 straightforward, but then the generated tree must be combined with the web |
| 116 accessibility tree, which is handled by BrowserAccessibilityManager. |
| 117 |
| 118 ## WebUI |
| 119 |
| 120 Since WebUI surfaces have renderer processes as normal, WebUI accessibility goes |
| 121 through the blink-to-content-to-platform pipeline described above. Accessibility |
| 122 for WebUI is largely implemented in JavaScript in [webui-js]; these classes take |
| 123 care of adding ARIA attributes and so on to DOM nodes as needed. |
| 124 |
| 125 ## The Chrome OS layer |
| 126 |
| 127 The accessibility tree is also exposed via the [chrome.automation API], which |
| 128 gives extension JavaScript access to the accessibility tree, events, and |
| 129 actions. This API is implemented in C++ by [AutomationInternalCustomBindings], |
| 130 which is renderer-side code, and in JavaScript by the [automation API]. The API |
| 131 is defined by [automation.idl], which must be kept synchronized with |
| 132 [ax_enums.idl]. |
| 133 |
| 134 [AccessibilityHostMsg_EventParams]: https://cs.chromium.org/chromium/src/content
/common/accessibility_messages.h?sq=package:chromium&l=75 |
| 135 [AutomationInternalCustomBindings]: https://cs.chromium.org/chromium/src/chrome/
renderer/extensions/automation_internal_custom_bindings.h |
| 136 [AXContentNodeData]: https://cs.chromium.org/chromium/src/content/common/ax_cont
ent_node_data.h |
| 137 [AXLayoutObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source
/modules/accessibility/AXLayoutObject.h |
| 138 [AXNodeObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/m
odules/accessibility/AXNodeObject.h |
| 139 [AXObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modul
es/accessibility/AXObject.h |
| 140 [AXObjectCacheImpl]: https://cs.chromium.org/chromium/src/third_party/WebKit/Sou
rce/modules/accessibility/AXObjectCacheImpl.h |
| 141 [AXPlatformNode]: https://cs.chromium.org/chromium/src/ui/accessibility/platform
/ax_platform_node.h |
| 142 [AXTreeSerializer]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_tre
e_serializer.h |
| 143 [BlinkAXTreeSource]: https://cs.chromium.org/chromium/src/content/renderer/acces
sibility/blink_ax_tree_source.h |
| 144 [BrowserAccessibility]: https://cs.chromium.org/chromium/src/content/browser/acc
essibility/browser_accessibility.h |
| 145 [BrowserAccessibilityDelegate]: https://cs.chromium.org/chromium/src/content/bro
wser/accessibility/browser_accessibility_manager.h?sq=package:chromium&l=64 |
| 146 [BrowserAccessibilityManager]: https://cs.chromium.org/chromium/src/content/brow
ser/accessibility/browser_accessibility_manager.h |
| 147 [LayoutObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/c
ore/layout/LayoutObject.h |
| 148 [NativeViewAccessibility]: https://cs.chromium.org/chromium/src/ui/views/accessi
bility/native_view_accessibility.h |
| 149 [Node]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/dom/
Node.h |
| 150 [RenderAccessibilityImpl]: https://cs.chromium.org/chromium/src/content/renderer
/accessibility/render_accessibility_impl.h |
| 151 [RenderFrameHostImpl]: https://cs.chromium.org/chromium/src/content/browser/fram
e_host/render_frame_host_impl.h |
| 152 [ui::AXNodeData]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_node_
data.h |
| 153 [WebAXObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/public/we
b/WebAXObject.h |
| 154 [automation API]: https://cs.chromium.org/chromium/src/chrome/renderer/resources
/extensions/automation |
| 155 [automation.idl]: https://cs.chromium.org/chromium/src/chrome/common/extensions/
api/automation.idl |
| 156 [ax_enums.idl]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_enums.i
dl |
| 157 [chrome.automation API]: https://developer.chrome.com/extensions/automation |
| 158 [webui-js]: https://cs.chromium.org/chromium/src/ui/webui/resources/js/cr/ui/ |
OLD | NEW |