OLD | NEW |
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/ | |
OLD | NEW |