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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js

Issue 2390783006: [DevTools] Accessibility: Show siblings and children of selected node (Closed)
Patch Set: Ready for a first look Created 4 years, 2 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
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5
6 /** 5 /**
7 * @constructor 6 * @constructor
7 * @extends {WebInspector.SDKObject}
8 * @param {!WebInspector.AccessibilityModel} accessibilityModel
9 * @param {!AccessibilityAgent.AXNode} payload
10 */
11 WebInspector.AccessibilityNode = function(accessibilityModel, payload)
12 {
13 WebInspector.SDKObject.call(this, accessibilityModel.target());
14 this._accessibilityModel = accessibilityModel;
15 this._agent = accessibilityModel._agent;
16
17 this._id = payload.nodeId;
18 accessibilityModel.setAXNodeForAXId(this._id, this);
19
20 this._ignored = payload.ignored;
21 if (this._ignored && "ignoredReasons" in payload)
22 this._ignoredReasons = payload.ignoredReasons;
23
24 if ("role" in payload)
25 this._role = payload.role;
26 if ("name" in payload)
27 this._name = payload.name;
28 if ("description" in payload)
29 this._description = payload.description;
30 if ("value" in payload)
31 this._value = payload.value;
32 if ("properties" in payload)
33 this._properties = payload.properties;
34 if ("parentId" in payload)
35 this._parentId = payload.parentId;
36 if ("childIds" in payload)
37 this._childIds = payload.childIds;
38 if ("domNodeId" in payload)
39 this._domNodeId = payload.domNodeId;
40 };
41
42 WebInspector.AccessibilityNode.prototype = {
43 /**
44 * @return {boolean}
45 */
46 ignored: function()
47 {
48 return this._ignored;
49 },
50
51 /**
52 * @return {?Array<!AccessibilityAgent.AXProperty>}
53 */
54 ignoredReasons: function()
55 {
56 return this._ignoredReasons || null;
57 },
58
59 /**
60 * @return {?AccessibilityAgent.AXValue}
61 */
62 role: function()
63 {
64 return this._role || null;
65 },
66
67 /**
68 * @return {!Array<!AccessibilityAgent.AXProperty>}
69 */
70 coreProperties: function()
71 {
72 var properties = [];
73 for (var propertyName of ["name", "description", "value"]) {
74 if (!("_" + propertyName in this))
75 continue;
76 properties.push(/** @type {!AccessibilityAgent.AXProperty} */ ({name : propertyName, value: this["_" + propertyName]}));
77 }
78 return properties;
79 },
80
81 /**
82 * @return {?AccessibilityAgent.AXValue}
83 */
84 name: function()
85 {
86 return this._name || null;
87 },
88
89 /**
90 * @return {?AccessibilityAgent.AXValue}
91 */
92 description: function()
93 {
94 return this._description || null;
95 },
96
97 /**
98 * @return {?AccessibilityAgent.AXValue}
99 */
100 value: function()
101 {
102 return this._value || null;
103 },
104
105 /**
106 * @return {?Array<!AccessibilityAgent.AXProperty>}
107 */
108 properties: function()
109 {
110 return this._properties || null;
111 },
112
113 /**
114 * @return {?WebInspector.AccessibilityNode}
115 */
116 parentNode: function()
117 {
118 if (!this._parentId)
119 return null;
120 return this._accessibilityModel.axNodeForId(this._parentId);
121 },
122
123 /**
124 * @return {boolean}
125 */
126 isDOMNode: function()
127 {
128 return !!this._domNodeId;
129 },
130
131 /**
132 * @return {?WebInspector.DOMNode}
133 */
134 domNode: function()
135 {
136 return this._domNode || null;
137 },
138
139 /**
140 * @param {?WebInspector.DOMNode} domNode
141 */
142 _setDOMNode: function(domNode)
143 {
144 this._domNode = domNode;
145 if (domNode)
146 this._accessibilityModel.setAXNodeForDOMNode(domNode, this);
147 },
148
149 /**
150 * @return {!Promise<?WebInspector.DOMNode>}
151 */
152 resolveDOMNode: function()
153 {
154 if (this._domNode)
155 return Promise.resolve(this._domNode);
156 if (!this._domNodeId)
157 return Promise.resolve(/** @type {?WebInspector.DOMNode} */ (null));
158
159 var deferredNode = new WebInspector.DeferredDOMNode(this.target(), this. _domNodeId);
160 return deferredNode.resolvePromise()
161 .then((domNode) => {
162 this._setDOMNode(domNode);
163 return domNode;
164 });
165 },
166
167 /**
168 * @return {?number}
169 */
170 domNodeId: function()
171 {
172 return this._domNodeId || null;
173 },
174
175 /**
176 * @return {!Array<!WebInspector.AccessibilityNode>}
177 */
178 children: function()
179 {
180 var children = [];
181 if (!this._childIds)
182 return children;
183
184 for (var childId of this._childIds) {
185 var child = this._accessibilityModel.axNodeForId(childId);
186 if (child)
187 children.push(child);
188 }
189
190 return children;
191 },
192
193 /**
194 * @return {number}
195 */
196 numChildren: function()
197 {
198 if (!this._childIds)
199 return 0;
200 return this._childIds.length;
201 },
202
203 /**
204 * @return {boolean}
205 */
206 hasOnlyUnloadedChildren: function()
207 {
208 if (!this._childIds || !this._childIds.length)
209 return false;
210
211 return !this._childIds.some((id) => this._accessibilityModel.axNodeForId (id) !== undefined);
212 },
213
214 /**
215 * Build debugging string for this subtree
216 * @param {!WebInspector.AccessibilityNode} inspectedNode
217 * @param {string=} leadingSpace
218 * @return {string}
219 */
220 printSelfAndChildren: function(inspectedNode, leadingSpace)
221 {
222 var string = leadingSpace || "";
223 if (this._role)
224 string += this._role.value;
225 else
226 string += "<no role>";
227 string += (this._name ? " " + this._name.value : "");
228 string += " " + this._id;
229 if (this._domNode)
230 string += " (" + this._domNode.nodeName() + ")";
231 if (this === inspectedNode)
232 string += " *";
233 for (var child of this.children())
234 string += "\n" + child.printSelfAndChildren(inspectedNode, (leadingS pace || "") + " ");
235 return string;
236 },
237
238 __proto__: WebInspector.SDKObject.prototype
239 };
240
241 /**
242 * @constructor
8 * @extends {WebInspector.SDKModel} 243 * @extends {WebInspector.SDKModel}
9 * @param {!WebInspector.Target} target 244 * @param {!WebInspector.Target} target
10 */ 245 */
11 WebInspector.AccessibilityModel = function(target) 246 WebInspector.AccessibilityModel = function(target)
12 { 247 {
13 WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target); 248 WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target);
14 this._agent = target.accessibilityAgent(); 249 this._agent = target.accessibilityAgent();
250
251 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */
252 this._axIdToAXNode = new Map();
253 this._domNodeToAXNode = new Map();
15 }; 254 };
16 255
17 WebInspector.AccessibilityModel.prototype = { 256 WebInspector.AccessibilityModel.prototype = {
18 /** 257 /**
19 * @param {!DOMAgent.NodeId} nodeId 258 * @param {!WebInspector.DOMNode} node
20 * @return {!Promise.<?Array<!AccessibilityAgent.AXNode>>} 259 * @return {!Promise<?WebInspector.AccessibilityNode>}
21 */ 260 */
22 getAXNodeChain: function(nodeId) 261 setDOMNode: function(node)
262 {
263 this._axIdToAXNode.clear();
264 this._inspectedDOMNode = node;
265
266 return this._requestPartialAXTree(node);
267 },
268
269 /**
270 * @return {?WebInspector.AccessibilityNode}
271 */
272 getInspectedAXNode: function()
273 {
274 this.logTree();
275 return this._domNodeToAXNode.get(this._inspectedDOMNode);
276 },
277
278 /**
279 * @param {string} axId
280 * @return {?WebInspector.AccessibilityNode}
281 */
282 axNodeForId: function(axId)
283 {
284 return this._axIdToAXNode.get(axId);
285 },
286
287 /**
288 * @param {string} axId
289 * @param {!WebInspector.AccessibilityNode} axNode
290 */
291 setAXNodeForAXId: function(axId, axNode)
292 {
293 this._axIdToAXNode.set(axId, axNode);
294 },
295
296 /**
297 * @param {!WebInspector.DOMNode} domNode
298 * @return {?WebInspector.AccessibilityNode}
299 */
300 axNodeForDOMNode: function(domNode)
301 {
302 return this._domNodeToAXNode.get(domNode);
303 },
304
305 /**
306 * @param {!WebInspector.DOMNode} domNode
307 * @param {!WebInspector.AccessibilityNode} axNode
308 */
309 setAXNodeForDOMNode: function(domNode, axNode)
310 {
311 this._domNodeToAXNode.set(domNode, axNode);
312 },
313
314 logTree: function()
315 {
316 var inspectedNode = this._domNodeToAXNode.get(this._inspectedDOMNode);
317 if (!inspectedNode)
318 return;
319 var rootNode = inspectedNode;
320 while (rootNode.parentNode())
321 rootNode = rootNode.parentNode();
322 console.log(rootNode.printSelfAndChildren(inspectedNode));
323 },
324
325 /**
326 * @param {!WebInspector.DOMNode} node
327 * @return {!Promise<?WebInspector.AccessibilityNode>}
328 */
329 _requestPartialAXTree: function(node)
23 { 330 {
24 /** 331 /**
332 * @this {WebInspector.AccessibilityModel}
25 * @param {?string} error 333 * @param {?string} error
26 * @param {!Array<!AccessibilityAgent.AXNode>=} nodes 334 * @param {!Array<!AccessibilityAgent.AXNode>=} payloads
27 * @return {?Array<!AccessibilityAgent.AXNode>}
28 */ 335 */
29 function parsePayload(error, nodes) 336 function parsePayload(error, payloads)
30 { 337 {
31 if (error) 338 if (error) {
32 console.error("AccessibilityAgent.getAXNodeChain(): " + error); 339 console.error("AccessibilityAgent.getAXNodeChain(): " + error);
33 return nodes || null; 340 return null;
341 }
342
343 if (!payloads)
344 return;
345
346 for (var payload of payloads)
347 new WebInspector.AccessibilityNode(this, payload);
34 } 348 }
35 return this._agent.getAXNodeChain(nodeId, true, parsePayload); 349 return this._agent.getPartialAXTree(node.id, parsePayload.bind(this));
350 },
351
352 /**
353 * @return {!Promise}
354 */
355 resolveAllDOMNodes: function()
356 {
357 var promises = [];
358 for (var axNode of this._axIdToAXNode.values())
359 promises.push(axNode.resolveDOMNode());
360 return Promise.all(promises);
36 }, 361 },
37 362
38 __proto__: WebInspector.SDKModel.prototype 363 __proto__: WebInspector.SDKModel.prototype
39 } 364 };
40 365
41 WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel"); 366 WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel");
42 /** 367 /**
43 * @param {!WebInspector.Target} target 368 * @param {!WebInspector.Target} target
44 * @return {!WebInspector.AccessibilityModel} 369 * @return {!WebInspector.AccessibilityModel}
45 */ 370 */
46 WebInspector.AccessibilityModel.fromTarget = function(target) 371 WebInspector.AccessibilityModel.fromTarget = function(target)
47 { 372 {
48 if (!target[WebInspector.AccessibilityModel._symbol]) 373 if (!target[WebInspector.AccessibilityModel._symbol])
49 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Acces sibilityModel(target); 374 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Acces sibilityModel(target);
50 375
51 return target[WebInspector.AccessibilityModel._symbol]; 376 return target[WebInspector.AccessibilityModel._symbol];
52 } 377 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698