Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: docs/accessibility.md

Issue 2701603002: Update accessibility documentation. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | docs/accessibility/brltty.md » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Accessibility Overview 1 # Accessibility
2 2
3 Accessibility means ensuring that all users, including users with disabilities, 3 * [Accessibility Overview](accessibility/overview.md)
4 have equal access to software. One piece of this involves basic design
5 principles such as using appropriate font sizes and color contrast,
6 avoiding using color to convey important information, and providing keyboard
7 alternatives for anything that is normally accomplished with a pointing device.
8 However, when you see the word "accessibility" in a directory name in Chromium,
9 that code's purpose is to provide full access to Chromium's UI via external
10 accessibility APIs that are utilized by assistive technology.
11 4
12 **Assistive technology** here refers to software or hardware which 5 ## Chrome OS
13 makes use of these APIs to create an alternative interface for the user to
14 accommodate some specific needs, for example:
15 6
16 Assistive technology includes: 7 * [ChromeVox for Developers](accessibility/chromevox.md)
17 8 * [ChromeVox on Desktop Linux](accessibility/chromevox_on_desktop_linux.md)
18 * Screen readers for blind users that describe the screen using 9 * [Updating brltty braille drivers](accessibility/brltty.md)
19 synthesized speech or braille 10 * [Updating the patts speech synthesis engine](accessibility/patts.md)
20 * Voice control applications that let you speak to the computer,
21 * Switch access that lets you control the computer with a small number
22 of physical switches,
23 * Magnifiers that magnify a portion of the screen, and often highlight the
24 cursor and caret for easier viewing, and
25 * Assistive learning and literacy software that helps users who have a hard
26 time reading print, by highlighting and/or speaking selected text
27
28 In addition, because accessibility APIs provide a convenient and universal
29 way to explore and control applications, they're often used for automated
30 testing scripts, and UI automation software like password managers.
31
32 Web browsers play an important role in this ecosystem because they need
33 to not only provide access to their own UI, but also provide access to
34 all of the content of the web.
35
36 Each operating system has its own native accessibility API. While the
37 core APIs tend to be well-documented, it's unfortunately common for
38 screen readers in particular to depend on additional undocumented or
39 vendor-specific APIs in order to fully function, especially with web
40 browsers, because the standard APIs are insufficient to handle the
41 complexity of the web.
42
43 Chromium needs to support all of these operating system and
44 vendor-specific accessibility APIs in order to be usable with the full
45 ecosystem of assistive technology on all platforms. Just like Chromium
46 sometimes mimics the quirks and bugs of older browsers, Chromium often
47 needs to mimic the quirks and bugs of other browsers' implementation
48 of accessibility APIs, too.
49
50 ## Concepts
51
52 While each operating system and vendor accessibility API is different,
53 there are some concepts all of them share.
54
55 1. The *tree*, which models the entire interface as a tree of objects, exposed
56 to assistive technology via accessibility APIs;
57 2. *Events*, which let assistive technology know that a part of the tree has
58 changed somehow;
59 3. *Actions*, which come from assistive technology and ask the interface to
60 change.
61
62 Consider the following small HTML file:
63
64 ```
65 <html>
66 <head>
67 <title>How old are you?</title>
68 </head>
69 <body>
70 <label for="age">Age</label>
71 <input id="age" type="number" name="age" value="42">
72 <div>
73 <button>Back</button>
74 <button>Next</button>
75 </div>
76 </body>
77 </html>
78 ```
79
80 ### The Accessibility Tree and Accessibility Attributes
81
82 Internally, Chromium represents the accessibility tree for that web page
83 using a data structure something like this:
84
85 ```
86 id=1 role=WebArea name="How old are you?"
87 id=2 role=Label name="Age"
88 id=3 role=TextField labelledByIds=[2] value="42"
89 id=4 role=Group
90 id=5 role=Button name="Back"
91 id=6 role=Button name="Next"
92 ```
93
94 Note that the tree structure closely resembles the structure of the
95 HTML elements, but slightly simplified. Each node in the accessibility
96 tree has an ID and a role. Many have a name. The text field has a value,
97 and instead of a name it has labelledByIds, which indicates that its
98 accessible name comes from another node in the tree, the label node
99 with id=2.
100
101 On a particular platform, each node in the accessibility tree is implemented
102 by an object that conforms to a particular protocol.
103
104 On Windows, the root node implements the IAccessible protocol and
105 if you call IAccessible::get_accRole, it returns ROLE_SYSTEM_DOCUMENT,
106 and if you call IAccessible::get_accName, it returns "How old are you?".
107 Other methods let you walk the tree.
108
109 On macOS, the root node implements the NSAccessibility protocol and
110 if you call [NSAccessibility accessibilityRole], it returns @"AXWebArea",
111 and if you call [NSAccessibility accessibilityLabel], it returns
112 "How old are you?".
113
114 The Linux accessibility API, ATK, is more similar to the Windows APIs;
115 they were developed together. (Chrome's support for desktop Linux
116 accessibility is unfinished.)
117
118 The Android accessibility API is of course based on Java. The main
119 data structure is AccessibilityNodeInfo. It doesn't have a role, but
120 if you call AccessibilityNodeInfo.getClassName() on the root node
121 it returns "android.webkit.WebView", and if you call
122 AccessibilityNodeInfo.getContentDescription() it returns "How old are you?".
123
124 On Chrome OS, we use our own accessibility API that closely maps to
125 Chrome's internal accessibility API.
126
127 So while the details of the interface vary, the underlying concepts are
128 similar. Both IAccessible and NSAccessibility have a concept of a role,
129 but IAccessible uses a role of "document" for a web page, while NSAccessibility
130 uses a role of "web area". Both IAccessible and NSAccessibility have a
131 concept of the primary accessible text for a node, but IAccessible calls
132 it the "name" while NSAccessibility calls it the "label", and Android
133 calls it a "content description".
134
135 **Historical note:** The internal names of roles and attributes in
136 Chrome often tend to most closely match the macOS accessibility API
137 because Chromium was originally based on WebKit, where most of the
138 accessibility code was written by Apple. Over time we're slowly
139 migrating internal names to match what those roles and attributes are
140 called in web accessibility standards, like ARIA.
141
142 ### Accessibility Events
143
144 In Chromium's internal terminology, an Accessibility Event always represents
145 communication from the app to the assistive technology, indicating that the
146 accessibility tree changed in some way.
147
148 As an example, if the user were to press the Tab key and the text
149 field from the example above became focused, Chromium would fire a
150 "focus" accessibility event that assistive technology could listen
151 to. A screen reader might then announce the name and current value of
152 the text field. A magnifier might zoom the screen to its bounding
153 box. If the user types some text into the text field, Chromium would
154 fire a "value changed" accessibility event.
155
156 As with nodes in the accessibility tree, each platform has a slightly different
157 API for accessibility events. On Windows we'd fire EVENT_OBJECT_FOCUS for
158 a focus change, and on Mac we'd fire @"AXFocusedUIElementChanged".
159 Those are pretty similar. Sometimes they're quite different - to support
160 live regions (notifications that certain key parts of a web page have changed),
161 on Mac we simply fire @"AXLiveRegionChanged", but on Windows we need to
162 fire IA2_EVENT_TEXT_INSERTED and IA2_EVENT_TEXT_REMOVED events individually
163 on each affected node within the changed region, with additional attributes
164 like "container-live:polite" to indicate that the affected node was part of
165 a live region. This discussion is not meant to explain all of the technical
166 details but just to illustrate that the concepts are similar,
167 but the details of notifying software on each platform about changes can
168 vary quite a bit.
169
170 ### Accessibility Actions
171
172 Each native object that implements a platform's native accessibility API
173 supports a number of actions, which are requests from the assistive
174 technology to control or change the UI. This is the opposite of events,
175 which are messages from Chromium to the assistive technology.
176
177 For example, if the user had a voice control application running, such as
178 Voice Access on Android, the user could just speak the name of one of the
179 buttons on the page, like "Next". Upon recognizing that text and finding
180 that it matches one of the UI elements on the page, the voice control
181 app executes the action to click the button id=6 in Chromium's accessibility
182 tree. Internally we call that action "do default" rather than click, since
183 it represents the default action for any type of control.
184
185 Other examples of actions include setting focus, changing the value of
186 a control, and scrolling the page.
187
188 ### Parameterized attributes
189
190 In addition to accessibility attributes, events, and actions, native
191 accessibility APIs often have so-called "parameterized attributes".
192 The most common example of this is for text - for example there may be
193 a function to retrieve the bounding box for a range of text, or a
194 function to retrieve the text properties (font family, font size,
195 weight, etc.) at a specific character position.
196
197 Parameterized attributes are particularly tricky to implement because
198 of Chromium's multi-process architecture. More on this in the next section.
199
200 ## Chromium's multi-process architecture
201
202 Native accessibility APIs tend to have a *functional* interface, where
203 Chromium implements an interface for a canonical accessible object that
204 includes methods to return various attributes, walk the tree, or perform
205 an action like click(), focus(), or setValue(...).
206
207 In contrast, the web has a largely *declarative* interface. The shape
208 of the accessibility tree is determined by the DOM tree (occasionally
209 influenced by CSS), and the accessible semantics of a DOM element can
210 be modified by adding ARIA attributes.
211
212 One important complication is that all of these native accessibility APIs
213 are *synchronous*, while Chromium is multi-process, with the contents of
214 each web page living in a different process than the process that
215 implements Chromium's UI and the native accessibility APIs. Furthermore,
216 the renderer processes are *sandboxed*, so they can't implement
217 operating system APIs directly.
218
219 If you're unfamiliar with Chrome's multi-process architecture, see
220 [this blog post introducing the concept](
221 https://blog.chromium.org/2008/09/multi-process-architecture.html) or
222 [the design doc on chromium.org](
223 https://www.chromium.org/developers/design-documents/multi-process-architecture)
224 for an intro.
225
226 Chromium's multi-process architecture means that we can't implement
227 accessibility APIs the same way that a single-process browser can -
228 namely, by calling directly into the DOM to compute the result of each
229 API call. For example, on some operating systems there might be an API
230 to get the bounding box for a particular range of characters on the
231 page. In other browsers, this might be implemented by creating a DOM
232 selection object and asking for its bounding box.
233
234 That implementation would be impossible in Chromium because it'd require
235 blocking the main thread while waiting for a response from the renderer
236 process that implements that web page's DOM. (Not only is blocking the
237 main thread strictly disallowed, but the latency of doing this for every
238 API call makes it prohibitively slow anyway.) Instead, Chromium takes an
239 approach where a representation of the entire accessibility tree is
240 cached in the main process. Great care needs to be taken to ensure that
241 this representation is as concise as possible.
242
243 In Chromium, we build a data structure representing all of the
244 information for a web page's accessibility tree, send the data
245 structure from the renderer process to the main browser process, cache
246 it in the main browser process, and implement native accessibility
247 APIs using solely the information in that cache.
248
249 As the accessibility tree changes, tree updates and accessibility events
250 get sent from the renderer process to the browser process. The browser
251 cache is updated atomically in the main thread, so whenever an external
252 client (like assistive technology) calls an accessibility API function,
253 we're always returning something from a complete and consistent snapshot
254 of the accessibility tree. From time to time, the cache may lag what's
255 in the renderer process by a fraction of a second.
256
257 Here are some of the specific challenges faced by this approach and
258 how we've addressed them.
259
260 ### Sparse data
261
262 There are a *lot* of possible accessibility attributes for any given
263 node in an accessibility tree. For example, there are more than 150
264 unique accessibility API methods that Chrome implements on the Windows
265 platform alone. We need to implement all of those APIs, many of which
266 request rather rare or obscure attributes, but storing all possible
267 attribute values in a single struct would be quite wasteful.
268
269 To avoid each accessible node object containing hundreds of fields the
270 data for each accessibility node is stored in a relatively compact
271 data structure, ui::AXNodeData. Every AXNodeData has an integer ID, a
272 role enum, and a couple of other mandatory fields, but everything else
273 is stored in attribute arrays, one for each major data type.
274
275 ```
276 struct AXNodeData {
277 int32_t id;
278 AXRole role;
279 ...
280 std::vector<std::pair<AXStringAttribute, std::string>> string_attributes;
281 std::vector<std::pair<AXIntAttribute, int32_t>> int_attributes;
282 ...
283 }
284 ```
285
286 So if a text field has a placeholder attribute, we can store
287 that by adding an entry to `string_attributes` with an attribute
288 of ui::AX_ATTR_PLACEHOLDER and the placeholder string as the value.
289
290 ### Incremental tree updates
291
292 Web pages change frequently. It'd be terribly inefficient to send a
293 new copy of the accessibility tree every time any part of it changes.
294 However, the accessibility tree can change shape in complicated ways -
295 for example, whole subtrees can be reparented dynamically.
296
297 Rather than writing code to deal with every possible way the
298 accessibility tree could be modified, Chromium has a general-purpose
299 tree serializer class that's designed to send small incremental
300 updates of a tree from one process to another. The tree serializer has
301 just a few requirements:
302
303 * Every node in the tree must have a unique integer ID.
304 * The tree must be acyclic.
305 * The tree serializer must be notified when a node's data changes.
306 * The tree serializer must be notified when the list of child IDs of a
307 node changes.
308
309 The tree serializer doesn't know anything about accessibility attributes.
310 It keeps track of the previous state of the tree, and every time the tree
311 structure changes (based on notifications of a node changing or a node's
312 children changing), it walks the tree and builds up an incremental tree
313 update that serializes as few nodes as possible.
314
315 In the other process, the Unserialization code applies the incremental
316 tree update atomically.
317
318 ### Text bounding boxes
319
320 One challenge faced by Chromium is that accessibility clients want to be
321 able to query the bounding box of an arbitrary range of text - not necessarily
322 just the current cursor position or selection. As discussed above, it's
323 not possible to block Chromium's main browser process while waiting for this
324 information from Blink, so instead we cache enough information to satisfy these
325 queries in the accessibility tree.
326
327 To compactly store the bounding box of every character on the page, we
328 split the text into *inline text boxes*, sometimes called *text runs*.
329 For example, in a typical paragraph, each line of text would be its own
330 inline text box. In general, an inline text box or text run contians a
331 sequence of text characters that are all oriented in the same direction,
332 in a line, with the same font, size, and style.
333
334 Each inline text box stores its own bounding box, and then the relative
335 x-coordinate of each character in its text (assuming left-to-right).
336 From that it's possible to compute the bounding box
337 of any individual character.
338
339 The inline text boxes are part of Chromium's internal accessibility tree.
340 They're used purely internally and aren't ever exposed directly via any
341 native accessibility APIs.
342
343 For example, suppose that a document contains a text field with the text
344 "Hello world", but the field is narrow, so "Hello" is on the first line and
345 "World" is on the second line. Internally Chromium's accessibility tree
346 might look like this:
347
348 ```
349 staticText location=(8, 8) size=(38, 36) name='Hello world'
350 inlineTextBox location=(0, 0) size=(36, 18) name='Hello ' characterOffsets=1 2,19,23,28,36
351 inlineTextBox location=(0, 18) size=(38, 18) name='world' characterOffsets=1 2,20,25,29,37
352 ```
353
354 ### Scrolling, transformations, and animation
355
356 Native accessibility APIs typically want the bounding box of every element in th e
357 tree, either in window coordinates or global screen coordinates. If we
358 stored the global screen coordinates for every node, we'd be constantly
359 re-serializing the whole tree every time the user scrolls or drags the
360 window.
361
362 Instead, we store the bounding box of each node in the accessibility tree
363 relative to its *offset container*, which can be any ancestor. If no offset
364 container is specified, it's assumed to be the root of the tree.
365
366 In addition, any offset container can contain scroll offsets, which can be
367 used to scroll the bounding boxes of anything in that subtree.
368
369 Finally, any offset container can also include an arbitrary 4x4 transformation
370 matrix, which can be used to represent arbitrary 3-D rotations, translations, an d
371 scaling, and more. The transformation matrix applies to the whole subtree.
372
373 Storing coordinates this way means that any time an object scrolls, moves, or
374 animates its position and scale, only the root of the scrolling or animation
375 needs to post updates to the accessibility tree. Everything in the subtree
376 remains valid relative to that offset container.
377
378 Computing the global screen coordinates for an object in the accessibility
379 tree just means walking up its ancestor chain and applying offsets and
380 occasionally multiplying by a 4x4 matrix.
381
382 ### Site isolation / out-of-process iframes
383
384 At one point in time, all of the content of a single Tab or other web view
385 was contained in the same Blink process, and it was possible to serialize
386 the accessibility tree for a whole frame tree in a single pass.
387
388 Today the situation is a bit more complicated, as Chromium supports
389 out-of-process iframes. (It also supports "browser plugins" such as
390 the `<webview>` tag in Chrome packaged apps, which embeds a whole
391 browser inside a browser, but for the purposes of accessibility this
392 is handled the same as frames.)
393
394 Rather than a mix of in-process and out-of-process frames that are handled
395 differently, Chromium builds a separate independent accessibility tree
396 for each frame. Each frame gets its own tree ID, and it keeps track of
397 the tree ID of its parent frame (if any) and any child frames.
398
399 In Chrome's main browser process, the accessibility trees for each frame
400 are cached separately, and when an accessibility client (assistive
401 technology) walks the accessibility tree, Chromium dynamically composes
402 all of the frames into a single virtual accessibility tree on the fly,
403 using those aforementioned tree IDs.
404
405 The node IDs for accessibility trees only need to be unique within a
406 single frame. Where necessary, separate unique IDs are used within
407 Chrome's main browser process. In Chromium accessibility, a "node ID"
408 always means that ID that's only unique within a frame, and a "unique ID"
409 means an ID that's globally unique.
410
411 ## Blink
412
413 Blink constructs an accessibility tree (a hierarchy of [WebAXObject]s) from the
414 page it is rendering. WebAXObject is the public API wrapper around [AXObject],
415 which is the core class of Blink's accessibility tree. AXObject is an abstract
416 class; the most commonly used concrete subclass of it is [AXNodeObject], which
417 wraps a [Node]. In turn, most AXNodeObjects are actually [AXLayoutObject]s,
418 which wrap both a [Node] and a [LayoutObject]. Access to the LayoutObject is
419 important because some elements are only in the AXObject tree depending on their
420 visibility, geometry, linewrapping, and so on. There are some subclasses of
421 AXLayoutObject that implement special-case logic for specific types of Node.
422 There are also other subclasses of AXObject, which are mostly used for testing.
423
424 Note that not all AXLayoutObjects correspond to actual Nodes; some are synthetic
425 layout objects which group related inline elements or similar.
426
427 The central class responsible for dealing with accessibility events in Blink is
428 [AXObjectCacheImpl], which is responsible for caching the corresponding
429 AXObjects for Nodes or LayoutObjects. This class has many methods named
430 `handleFoo`, which are called throughout Blink to notify the AXObjectCacheImpl
431 that it may need to update its tree. Since this class is already aware of all
432 accessibility events in Blink, it is also responsible for relaying accessibility
433 events from Blink to the embedding content layer.
434
435 ## The content layer
436
437 The content layer lives on both sides of the renderer/browser split. The content
438 layer translates WebAXObjects into [AXContentNodeData], which is a subclass of
439 [ui::AXNodeData]. The ui::AXNodeData class and related classes are Chromium's
440 cross-platform accessibility tree. The translation is implemented in
441 [BlinkAXTreeSource]. This translation happens on the renderer side, so the
442 ui::AXNodeData tree now needs to be sent to the browser, which is done by
443 sending [AccessibilityHostMsg_EventParams] with the payload being serialized
444 delta-updates to the tree, so that changes that happen on the renderer side can
445 be reflected on the browser side.
446
447 On the browser side, these IPCs are received by [RenderFrameHostImpl], and then
448 usually forwarded to [BrowserAccessibilityManager] which is responsible for:
449
450 1. Merging AXNodeData trees into one tree of [BrowserAccessibility] objects,
451 by linking to other BrowserAccessibilityManagers. This is important because
452 each page has its own accessibility tree, but each Chromium *window* must
453 have only one accessibility tree, so trees from multiple pages need to be
454 combined (possibly also with trees from Views UI).
455 2. Dispatching outgoing accessibility events to the platform's accessibility
456 APIs. This is done in the platform-specific subclasses of
457 BrowserAccessibilityManager, in a method named `NotifyAccessibilityEvent`.
458 3. Dispatching incoming accessibility actions to the appropriate recipient, via
459 [BrowserAccessibilityDelegate]. For messages destined for a renderer,
460 [RenderFrameHostImpl], which is a BrowserAccessibilityDelegate, is
461 responsible for sending appropriate `AccessibilityMsg_Foo` IPCs to the
462 renderer, where they will be received by [RenderAccessibilityImpl].
463
464 On Chrome OS, RenderFrameHostImpl does not route events to
465 BrowserAccessibilityManager at all, since there is no platform screenreader
466 outside Chromium to integrate with.
467
468 ## Views
469
470 Views generates a [NativeViewAccessibility] for each View, which is used as the
471 delegate for an [AXPlatformNode] representing that View. This part is relatively
472 straightforward, but then the generated tree must be combined with the web
473 accessibility tree, which is handled by BrowserAccessibilityManager.
474
475 ## WebUI
476
477 Since WebUI surfaces have renderer processes as normal, WebUI accessibility goes
478 through the blink-to-content-to-platform pipeline described above. Accessibility
479 for WebUI is largely implemented in JavaScript in [webui-js]; these classes take
480 care of adding ARIA attributes and so on to DOM nodes as needed.
481
482 ## The Chrome OS layer
483
484 The accessibility tree is also exposed via the [chrome.automation API], which
485 gives extension JavaScript access to the accessibility tree, events, and
486 actions. This API is implemented in C++ by [AutomationInternalCustomBindings],
487 which is renderer-side code, and in JavaScript by the [automation API]. The API
488 is defined by [automation.idl], which must be kept synchronized with
489 [ax_enums.idl].
490
491 [AccessibilityHostMsg_EventParams]: https://cs.chromium.org/chromium/src/content /common/accessibility_messages.h?sq=package:chromium&l=75
492 [AutomationInternalCustomBindings]: https://cs.chromium.org/chromium/src/chrome/ renderer/extensions/automation_internal_custom_bindings.h
493 [AXContentNodeData]: https://cs.chromium.org/chromium/src/content/common/ax_cont ent_node_data.h
494 [AXLayoutObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source /modules/accessibility/AXLayoutObject.h
495 [AXNodeObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/m odules/accessibility/AXNodeObject.h
496 [AXObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modul es/accessibility/AXObject.h
497 [AXObjectCacheImpl]: https://cs.chromium.org/chromium/src/third_party/WebKit/Sou rce/modules/accessibility/AXObjectCacheImpl.h
498 [AXPlatformNode]: https://cs.chromium.org/chromium/src/ui/accessibility/platform /ax_platform_node.h
499 [AXTreeSerializer]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_tre e_serializer.h
500 [BlinkAXTreeSource]: https://cs.chromium.org/chromium/src/content/renderer/acces sibility/blink_ax_tree_source.h
501 [BrowserAccessibility]: https://cs.chromium.org/chromium/src/content/browser/acc essibility/browser_accessibility.h
502 [BrowserAccessibilityDelegate]: https://cs.chromium.org/chromium/src/content/bro wser/accessibility/browser_accessibility_manager.h?sq=package:chromium&l=64
503 [BrowserAccessibilityManager]: https://cs.chromium.org/chromium/src/content/brow ser/accessibility/browser_accessibility_manager.h
504 [LayoutObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/c ore/layout/LayoutObject.h
505 [NativeViewAccessibility]: https://cs.chromium.org/chromium/src/ui/views/accessi bility/native_view_accessibility.h
506 [Node]: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/dom/ Node.h
507 [RenderAccessibilityImpl]: https://cs.chromium.org/chromium/src/content/renderer /accessibility/render_accessibility_impl.h
508 [RenderFrameHostImpl]: https://cs.chromium.org/chromium/src/content/browser/fram e_host/render_frame_host_impl.h
509 [ui::AXNodeData]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_node_ data.h
510 [WebAXObject]: https://cs.chromium.org/chromium/src/third_party/WebKit/public/we b/WebAXObject.h
511 [automation API]: https://cs.chromium.org/chromium/src/chrome/renderer/resources /extensions/automation
512 [automation.idl]: https://cs.chromium.org/chromium/src/chrome/common/extensions/ api/automation.idl
513 [ax_enums.idl]: https://cs.chromium.org/chromium/src/ui/accessibility/ax_enums.i dl
514 [chrome.automation API]: https://developer.chrome.com/extensions/automation
515 [webui-js]: https://cs.chromium.org/chromium/src/ui/webui/resources/js/cr/ui/
OLDNEW
« no previous file with comments | « no previous file | docs/accessibility/brltty.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698