| Index: docs/accessibility.md
|
| diff --git a/docs/accessibility.md b/docs/accessibility.md
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5029490c48d5376f8a5a9e906038df9c0ee00e67
|
| --- /dev/null
|
| +++ b/docs/accessibility.md
|
| @@ -0,0 +1,158 @@
|
| +# Accessibility Overview
|
| +
|
| +This document describes how accessibility is implemented throughout Chromium at
|
| +a high level.
|
| +
|
| +## Concepts
|
| +
|
| +The three central concepts of accessibility are:
|
| +
|
| +1. The *tree*, which models the entire interface as a tree of objects, exposed
|
| + to screenreaders or other accessibility software;
|
| +2. *Events*, which let accessibility software know that a part of the tree has
|
| + changed somehow;
|
| +3. *Actions*, which come from accessibility software and ask the interface to
|
| + change.
|
| +
|
| +Here's an example of an accessibility tree looks like. The following HTML:
|
| +
|
| +```
|
| +<select title="Select A">
|
| + <option value="1">Option 1</option>
|
| + <option value="2" selected>Option 2</option>
|
| + <option value="3">Option 3</option>
|
| +</select>
|
| +```
|
| +
|
| +has a generated accessibility tree like this:
|
| +
|
| +```
|
| +0: AXMenuList title="Select A"
|
| +1: AXMenuListOption title="Option 1"
|
| +2: AXMenuListOption title="Option 2" selected
|
| +3: AXMenuListOption title="Option 3"
|
| +```
|
| +
|
| +Given that accessibility tree, an example of the events generated when selecting
|
| +"Option 1" might be:
|
| +
|
| +```
|
| +AXMenuListItemUnselected 2
|
| +AXMenuListItemSelected 1
|
| +AXMenuListValueChanged 0
|
| +```
|
| +
|
| +An example of a command used to change the selection from "Option 1" to "Option
|
| +3" might be:
|
| +
|
| +```
|
| +AccessibilityMsg_DoDefaultAction 3
|
| +```
|
| +
|
| +All three concepts are handled at several layers in Chromium.
|
| +
|
| +## Blink
|
| +
|
| +Blink constructs an accessibility tree (a hierarchy of [WebAXObject]s) from the
|
| +page it is rendering. WebAXObject is the public API wrapper around [AXObject],
|
| +which is the core class of Blink's accessibility tree. AXObject is an abstract
|
| +class; the most commonly used concrete subclass of it is [AXNodeObject], which
|
| +wraps a [Node]. In turn, most AXNodeObjects are actually [AXLayoutObject]s,
|
| +which wrap both a [Node] and a [LayoutObject]. Access to the LayoutObject is
|
| +important because some elements are only in the AXObject tree depending on their
|
| +visibility, geometry, linewrapping, and so on. There are some subclasses of
|
| +AXLayoutObject that implement special-case logic for specific types of Node.
|
| +There are also other subclasses of AXObject, which are mostly used for testing.
|
| +
|
| +Note that not all AXLayoutObjects correspond to actual Nodes; some are synthetic
|
| +layout objects which group related inline elements or similar.
|
| +
|
| +The central class responsible for dealing with accessibility events in Blink is
|
| +[AXObjectCacheImpl], which is responsible for caching the corresponding
|
| +AXObjects for Nodes or LayoutObjects. This class has many methods named
|
| +`handleFoo`, which are called throughout Blink to notify the AXObjectCacheImpl
|
| +that it may need to update its tree. Since this class is already aware of all
|
| +accessibility events in Blink, it is also responsible for relaying accessibility
|
| +events from Blink to the embedding content layer.
|
| +
|
| +## The content layer
|
| +
|
| +The content layer lives on both sides of the renderer/browser split. The content
|
| +layer translates WebAXObjects into [AXContentNodeData], which is a subclass of
|
| +[ui::AXNodeData]. The ui::AXNodeData class and related classes are Chromium's
|
| +cross-platform accessibility tree. The translation is implemented in
|
| +[BlinkAXTreeSource]. This translation happens on the renderer side, so the
|
| +ui::AXNodeData tree now needs to be sent to the browser, which is done by
|
| +sending [AccessibilityHostMsg_EventParams] with the payload being serialized
|
| +delta-updates to the tree, so that changes that happen on the renderer side can
|
| +be reflected on the browser side.
|
| +
|
| +On the browser side, these IPCs are received by [RenderFrameHostImpl], and then
|
| +usually forwarded to [BrowserAccessibilityManager] which is responsible for:
|
| +
|
| +1. Merging AXNodeData trees into one tree of [BrowserAccessibility] objects,
|
| + by linking to other BrowserAccessibilityManagers. This is important because
|
| + each page has its own accessibility tree, but each Chromium *window* must
|
| + have only one accessibility tree, so trees from multiple pages need to be
|
| + combined (possibly also with trees from Views UI).
|
| +2. Dispatching outgoing accessibility events to the platform's accessibility
|
| + APIs. This is done in the platform-specific subclasses of
|
| + BrowserAccessibilityManager, in a method named `NotifyAccessibilityEvent`.
|
| +3. Dispatching incoming accessibility actions to the appropriate recipient, via
|
| + [BrowserAccessibilityDelegate]. For messages destined for a renderer,
|
| + [RenderFrameHostImpl], which is a BrowserAccessibilityDelegate, is
|
| + responsible for sending appropriate `AccessibilityMsg_Foo` IPCs to the
|
| + renderer, where they will be received by [RenderAccessibilityImpl].
|
| +
|
| +On Chrome OS, RenderFrameHostImpl does not route events to
|
| +BrowserAccessibilityManager at all, since there is no platform screenreader
|
| +outside Chrome to integrate with.
|
| +
|
| +## Views
|
| +
|
| +Views generates a [NativeViewAccessibility] for each View, which is used as the
|
| +delegate for an [AXPlatformNode] representing that View. This part is relatively
|
| +straightforward, but then the generated tree must be combined with the web
|
| +accessibility tree, which is handled by BrowserAccessibilityManager.
|
| +
|
| +## WebUI
|
| +
|
| +Since WebUI surfaces have renderer processes as normal, WebUI accessibility goes
|
| +through the blink-to-content-to-platform pipeline described above. Accessibility
|
| +for WebUI is largely implemented in JavaScript in [webui-js]; these classes take
|
| +care of adding ARIA attributes and so on to DOM nodes as needed.
|
| +
|
| +## The Chrome OS layer
|
| +
|
| +The accessibility tree is also exposed via the [chrome.automation API], which
|
| +gives extension JavaScript access to the accessibility tree, events, and
|
| +actions. This API is implemented in C++ by [AutomationInternalCustomBindings],
|
| +which is renderer-side code, and in JavaScript by the [automation API]. The API
|
| +is defined by [automation.idl], which must be kept synchronized with
|
| +[ax_enums.idl].
|
| +
|
| +[AccessibilityHostMsg_EventParams]: https://cs.chromium.org/chromium/src/content/common/accessibility_messages.h?sq=package:chromium&l=75
|
| +[AutomationInternalCustomBindings]: https://cs.chromium.org/chromium/src/chrome/renderer/extensions/automation_internal_custom_bindings.h
|
| +[AXContentNodeData]: https://cs.chromium.org/chromium/src/content/common/ax_content_node_data.h
|
| +[AXLayoutObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.h
|
| +[AXNodeObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h
|
| +[AXObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/accessibility/AXObject.h
|
| +[AXObjectCacheImpl]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/accessibility/AXObjectCacheImpl.h
|
| +[AXPlatformNode]: https://cs.chromium.org/chromium/src/ui/accessibility/platform/ax_platform_node.h
|
| +[AXTreeSerializer]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_tree_serializer.h
|
| +[BlinkAXTreeSource]: https://cs.chromium.org/chromium/src/content/renderer/accessibility/blink_ax_tree_source.h
|
| +[BrowserAccessibility]: https://cs.chromium.org/chromium/src/content/browser/accessibility/browser_accessibility.h
|
| +[BrowserAccessibilityDelegate]: https://cs.chromium.org/chromium/src/content/browser/accessibility/browser_accessibility_manager.h?sq=package:chromium&l=64
|
| +[BrowserAccessibilityManager]: https://cs.chromium.org/chromium/src/content/browser/accessibility/browser_accessibility_manager.h
|
| +[LayoutObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/layout/LayoutObject.h
|
| +[NativeViewAccessibility]: https://cs.chromium.org/chromium/src/ui/views/accessibility/native_view_accessibility.h
|
| +[Node]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/dom/Node.h
|
| +[RenderAccessibilityImpl]: https://cs.chromium.org/chromium/src/content/renderer/accessibility/render_accessibility_impl.h
|
| +[RenderFrameHostImpl]: https://cs.chromium.org/chromium/src/content/browser/frame_host/render_frame_host_impl.h
|
| +[ui::AXNodeData]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_node_data.h
|
| +[WebAXObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/public/web/WebAXObject.h
|
| +[automation API]: https://cs.chromium.org/chromium/src/chrome/renderer/resources/extensions/automation
|
| +[automation.idl]: https://cs.chromium.org/chromium/src/chrome/common/extensions/api/automation.idl
|
| +[ax_enums.idl]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_enums.idl
|
| +[chrome.automation API]: https://developer.chrome.com/extensions/automation
|
| +[webui-js]: https://cs.chromium.org/chromium/src/ui/webui/resources/js/cr/ui/
|
|
|