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

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: Handle indirect children better Created 4 years, 1 month 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 /** 5 /**
6 * @constructor 6 * @constructor
7 * @extends {WebInspector.SDKObject} 7 * @extends {WebInspector.SDKObject}
8 * @param {!WebInspector.AccessibilityModel} accessibilityModel 8 * @param {!WebInspector.AccessibilityModel} accessibilityModel
9 * @param {!AccessibilityAgent.AXNode} payload 9 * @param {!AccessibilityAgent.AXNode} payload
10 */ 10 */
(...skipping 10 matching lines...) Expand all
21 if (this._ignored && "ignoredReasons" in payload) 21 if (this._ignored && "ignoredReasons" in payload)
22 this._ignoredReasons = payload.ignoredReasons; 22 this._ignoredReasons = payload.ignoredReasons;
23 23
24 this._role = payload.role || null; 24 this._role = payload.role || null;
25 this._name = payload.name || null; 25 this._name = payload.name || null;
26 this._description = payload.description || null; 26 this._description = payload.description || null;
27 this._value = payload.value || null; 27 this._value = payload.value || null;
28 this._properties = payload.properties || null; 28 this._properties = payload.properties || null;
29 this._parentId = payload.parentId || null; 29 this._parentId = payload.parentId || null;
30 this._childIds = payload.childIds || null; 30 this._childIds = payload.childIds || null;
31 this._domNodeId = payload.domNodeId || null; 31 this._backendDomNodeId = payload.backendDomNodeId || null;
32 }; 32 };
33 33
34 WebInspector.AccessibilityNode.prototype = { 34 WebInspector.AccessibilityNode.prototype = {
35 /** 35 /**
36 * @return {boolean} 36 * @return {boolean}
37 */ 37 */
38 ignored: function() 38 ignored: function()
39 { 39 {
40 return this._ignored; 40 return this._ignored;
41 }, 41 },
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 /** 108 /**
109 * @return {?WebInspector.AccessibilityNode} 109 * @return {?WebInspector.AccessibilityNode}
110 */ 110 */
111 parentNode: function() 111 parentNode: function()
112 { 112 {
113 if (!this._parentId) 113 if (!this._parentId)
114 return null; 114 return null;
115 return this._accessibilityModel.axNodeForId(this._parentId); 115 return this._accessibilityModel.axNodeForId(this._parentId);
116 }, 116 },
117 117
118 /**
119 * @return {boolean}
120 */
121 isDOMNode: function()
122 {
123 return !!this._backendDomNodeId;
124 },
125
126 /**
127 * @return {?WebInspector.DOMNode}
128 */
129 domNode: function()
130 {
131 return this._domNode || null;
132 },
133
134 /**
135 * @param {?WebInspector.DOMNode} domNode
136 */
137 _setDOMNode: function(domNode)
138 {
139 this._domNode = domNode;
140 if (domNode)
141 this._accessibilityModel.setAXNodeForDOMNode(domNode, this);
142 },
143
144 /**
145 * @return {!Promise<?WebInspector.DOMNode>}
146 */
147 resolveDOMNode: function()
148 {
149 if (this._domNode)
150 return Promise.resolve(this._domNode);
151 if (!this._backendDomNodeId)
152 return Promise.resolve(/** @type {?WebInspector.DOMNode} */ (null));
153
154 var deferredNode = new WebInspector.DeferredDOMNode(this.target(), this. _backendDomNodeId);
155 return deferredNode.resolvePromise()
156 .then((domNode) => {
157 this._setDOMNode(domNode);
158 return domNode;
159 });
160 },
161
162 /**
163 * @return {!Array<!WebInspector.AccessibilityNode>}
164 */
165 children: function()
166 {
167 var children = [];
168 if (!this._childIds)
169 return children;
170
171 for (var childId of this._childIds) {
172 var child = this._accessibilityModel.axNodeForId(childId);
173 if (child)
174 children.push(child);
175 }
176
177 return children;
178 },
179
180 /**
181 * @return {number}
182 */
183 numChildren: function()
184 {
185 if (!this._childIds)
186 return 0;
187 return this._childIds.length;
188 },
189
190 /**
191 * @return {boolean}
192 */
193 hasOnlyUnloadedChildren: function()
194 {
195 if (!this._childIds || !this._childIds.length)
196 return false;
197
198 return !this._childIds.some((id) => this._accessibilityModel.axNodeForId (id) !== undefined);
199 },
200
201 /**
202 * TODO(aboxhall): Remove once protocol is stable.
203 * @param {!WebInspector.AccessibilityNode} inspectedNode
204 * @param {string=} leadingSpace
205 * @return {string}
206 */
207 printSelfAndChildren: function(inspectedNode, leadingSpace)
208 {
209 var string = leadingSpace || "";
210 if (this._role)
211 string += this._role.value;
212 else
213 string += "<no role>";
214 string += (this._name ? " " + this._name.value : "");
215 string += " " + this._id;
216 if (this._domNode)
217 string += " (" + this._domNode.nodeName() + ")";
218 if (this === inspectedNode)
219 string += " *";
220 for (var child of this.children())
221 string += "\n" + child.printSelfAndChildren(inspectedNode, (leadingS pace || "") + " ");
222 return string;
223 },
224
118 __proto__: WebInspector.SDKObject.prototype 225 __proto__: WebInspector.SDKObject.prototype
119 }; 226 };
120 227
121 /** 228 /**
122 * @constructor 229 * @constructor
123 * @extends {WebInspector.SDKModel} 230 * @extends {WebInspector.SDKModel}
124 * @param {!WebInspector.Target} target 231 * @param {!WebInspector.Target} target
125 */ 232 */
126 WebInspector.AccessibilityModel = function(target) 233 WebInspector.AccessibilityModel = function(target)
127 { 234 {
128 WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target); 235 WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target);
129 this._agent = target.accessibilityAgent(); 236 this._agent = target.accessibilityAgent();
130 237
131 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */ 238 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */
132 this._axIdToAXNode = new Map(); 239 this._axIdToAXNode = new Map();
240 this._domNodeToAXNode = new Map();
133 }; 241 };
134 242
135 WebInspector.AccessibilityModel.prototype = { 243 WebInspector.AccessibilityModel.prototype = {
244 /**
245 * @param {!WebInspector.DOMNode} node
246 * @return {!Promise<?WebInspector.AccessibilityNode>}
247 */
248 setDOMNode: function(node)
dgozman 2016/10/31 21:36:30 setDOMNode is a strange api for a model. It should
aboxhall 2016/10/31 22:45:15 The reason is that the model is centered on the in
249 {
250 this._axIdToAXNode.clear();
251 this._inspectedDOMNode = node;
136 252
137 /** 253 return this._requestPartialAXTree(node);
138 * @param {string} axId
139 * @return {?WebInspector.AccessibilityNode}
140 */
141 axNodeForId: function(axId)
142 {
143 return this._axIdToAXNode.get(axId);
144 },
145
146 /**
147 * @param {string} axId
148 * @param {!WebInspector.AccessibilityNode} axNode
149 */
150 _setAXNodeForAXId: function(axId, axNode)
151 {
152 this._axIdToAXNode.set(axId, axNode);
153 }, 254 },
154 255
155 /** 256 /**
156 * @param {!WebInspector.DOMNode} node 257 * @param {!WebInspector.DOMNode} node
157 * @return {!Promise<?Array<!WebInspector.AccessibilityNode>>} 258 * @return {!Promise}
158 */ 259 */
159 getAXNodeChain: function(node) 260 _requestPartialAXTree: function(node)
160 { 261 {
161 this._axIdToAXNode.clear();
162
163 /** 262 /**
164 * @this {WebInspector.AccessibilityModel} 263 * @this {WebInspector.AccessibilityModel}
165 * @param {?string} error 264 * @param {?string} error
166 * @param {!Array<!AccessibilityAgent.AXNode>=} payloads 265 * @param {!Array<!AccessibilityAgent.AXNode>=} payloads
167 * @return {?Array<!WebInspector.AccessibilityNode>}
168 */ 266 */
169 function parsePayload(error, payloads) 267 function parsePayload(error, payloads)
170 { 268 {
171 if (error) { 269 if (error) {
172 console.error("AccessibilityAgent.getAXNodeChain(): " + error); 270 console.error("AccessibilityAgent.getAXNodeChain(): " + error);
173 return null; 271 return null;
174 } 272 }
175 273
176 if (!payloads) 274 if (!payloads)
177 return null; 275 return;
178 276
179 var nodes = [];
180 for (var payload of payloads) 277 for (var payload of payloads)
181 nodes.push(new WebInspector.AccessibilityNode(this, payload)); 278 new WebInspector.AccessibilityNode(this, payload);
279 }
280 return this._agent.getPartialAXTree(node.id, true, parsePayload.bind(thi s));
281 },
182 282
183 return nodes; 283 /**
184 } 284 * @return {?WebInspector.AccessibilityNode}
185 return this._agent.getAXNodeChain(node.id, true, parsePayload.bind(this) ); 285 */
286 getInspectedAXNode: function()
287 {
288 return this._domNodeToAXNode.get(this._inspectedDOMNode);
289 },
290
291 /**
292 * @param {string} axId
293 * @return {?WebInspector.AccessibilityNode}
294 */
295 axNodeForId: function(axId)
296 {
297 return this._axIdToAXNode.get(axId);
298 },
299
300 /**
301 * @param {string} axId
302 * @param {!WebInspector.AccessibilityNode} axNode
303 */
304 _setAXNodeForAXId: function(axId, axNode)
305 {
306 this._axIdToAXNode.set(axId, axNode);
307 },
308
309 /**
310 * @param {!WebInspector.DOMNode} domNode
311 * @return {?WebInspector.AccessibilityNode}
312 */
313 axNodeForDOMNode: function(domNode)
314 {
315 return this._domNodeToAXNode.get(domNode);
316 },
317
318 /**
319 * @param {!WebInspector.DOMNode} domNode
320 * @param {!WebInspector.AccessibilityNode} axNode
321 */
322 setAXNodeForDOMNode: function(domNode, axNode)
323 {
324 this._domNodeToAXNode.set(domNode, axNode);
325 },
326
327 // TODO(aboxhall): Remove once protocol is stable.
328 logTree: function()
329 {
330 var inspectedNode = this._domNodeToAXNode.get(this._inspectedDOMNode);
331 if (!inspectedNode)
332 return;
333 var rootNode = inspectedNode;
334 while (rootNode.parentNode())
335 rootNode = rootNode.parentNode();
336 console.log(rootNode.printSelfAndChildren(inspectedNode));
337 },
338
339 /**
340 * @return {!Promise}
341 */
342 resolveAllDOMNodes: function()
343 {
344 var promises = [];
345 for (var axNode of this._axIdToAXNode.values())
346 promises.push(axNode.resolveDOMNode());
347 return Promise.all(promises);
186 }, 348 },
187 349
188 __proto__: WebInspector.SDKModel.prototype 350 __proto__: WebInspector.SDKModel.prototype
189 }; 351 };
190 352
191 WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel"); 353 WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel");
192 /** 354 /**
193 * @param {!WebInspector.Target} target 355 * @param {!WebInspector.Target} target
194 * @return {!WebInspector.AccessibilityModel} 356 * @return {!WebInspector.AccessibilityModel}
195 */ 357 */
196 WebInspector.AccessibilityModel.fromTarget = function(target) 358 WebInspector.AccessibilityModel.fromTarget = function(target)
197 { 359 {
198 if (!target[WebInspector.AccessibilityModel._symbol]) 360 if (!target[WebInspector.AccessibilityModel._symbol])
199 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Acces sibilityModel(target); 361 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Acces sibilityModel(target);
200 362
201 return target[WebInspector.AccessibilityModel._symbol]; 363 return target[WebInspector.AccessibilityModel._symbol];
202 }; 364 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698