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

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: Rebase tests again and be consistent about backendDOMNodeId 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 * @unrestricted 5 * @unrestricted
6 */ 6 */
7 WebInspector.AccessibilityNode = class extends WebInspector.SDKObject { 7 WebInspector.AccessibilityNode = class extends WebInspector.SDKObject {
8 /** 8 /**
9 * @param {!WebInspector.AccessibilityModel} accessibilityModel 9 * @param {!WebInspector.AccessibilityModel} accessibilityModel
10 * @param {!Protocol.Accessibility.AXNode} payload 10 * @param {!Protocol.Accessibility.AXNode} payload
11 */ 11 */
12 constructor(accessibilityModel, payload) { 12 constructor(accessibilityModel, payload) {
13 super(accessibilityModel.target()); 13 super(accessibilityModel.target());
14 this._accessibilityModel = accessibilityModel; 14 this._accessibilityModel = accessibilityModel;
15 this._agent = accessibilityModel._agent; 15 this._agent = accessibilityModel._agent;
16 16
17 this._id = payload.nodeId; 17 this._id = payload.nodeId;
18 accessibilityModel._setAXNodeForAXId(this._id, this); 18 accessibilityModel._setAXNodeForAXId(this._id, this);
19 19 if (payload.backendDOMNodeId) {
20 accessibilityModel._setAXNodeForBackendDOMNodeId(payload.backendDOMNodeId, this);
21 this._backendDOMNodeId = payload.backendDOMNodeId;
22 this._deferredDOMNode =
23 new WebInspector.DeferredDOMNode(this.target(),
24 payload.backendDOMNodeId);
25 } else {
26 this._backendDOMNodeId = null;
27 this._deferredDOMNode = null;
28 }
20 this._ignored = payload.ignored; 29 this._ignored = payload.ignored;
21 if (this._ignored && 'ignoredReasons' in payload) 30 if (this._ignored && 'ignoredReasons' in payload)
22 this._ignoredReasons = payload.ignoredReasons; 31 this._ignoredReasons = payload.ignoredReasons;
23 32
24 this._role = payload.role || null; 33 this._role = payload.role || null;
25 this._name = payload.name || null; 34 this._name = payload.name || null;
26 this._description = payload.description || null; 35 this._description = payload.description || null;
27 this._value = payload.value || null; 36 this._value = payload.value || null;
28 this._properties = payload.properties || null; 37 this._properties = payload.properties || null;
29 this._parentId = payload.parentId || null;
30 this._childIds = payload.childIds || null; 38 this._childIds = payload.childIds || null;
31 this._domNodeId = payload.domNodeId || null; 39 this._parentNode = null;
32 } 40 }
33 41
34 /** 42 /**
35 * @return {boolean} 43 * @return {boolean}
36 */ 44 */
37 ignored() { 45 ignored() {
38 return this._ignored; 46 return this._ignored;
39 } 47 }
40 48
41 /** 49 /**
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 * @return {?Array<!Protocol.Accessibility.AXProperty>} 101 * @return {?Array<!Protocol.Accessibility.AXProperty>}
94 */ 102 */
95 properties() { 103 properties() {
96 return this._properties || null; 104 return this._properties || null;
97 } 105 }
98 106
99 /** 107 /**
100 * @return {?WebInspector.AccessibilityNode} 108 * @return {?WebInspector.AccessibilityNode}
101 */ 109 */
102 parentNode() { 110 parentNode() {
103 if (!this._parentId) 111 return this._parentNode;
104 return null; 112 }
105 return this._accessibilityModel.axNodeForId(this._parentId); 113
114 /**
115 * @param {?WebInspector.AccessibilityNode} parentNode
116 */
117 _setParentNode(parentNode) {
118 this._parentNode = parentNode;
119 }
120
121 /**
122 * @return {boolean}
123 */
124 isDOMNode() {
125 return !!this._backendDOMNodeId;
126 }
127
128 /**
129 * @return {?number}
130 */
131 backendDOMNodeId() {
132 return this._backendDOMNodeId;
133 }
134
135 /**
136 * @return {?WebInspector.DeferredDOMNode}
137 */
138 deferredDOMNode() {
139 return this._deferredDOMNode;
140 }
141
142 /**
143 * @return {!Array<!WebInspector.AccessibilityNode>}
144 */
145 children() {
146 var children = [];
147 if (!this._childIds)
148 return children;
149
150 for (var childId of this._childIds) {
151 var child = this._accessibilityModel.axNodeForId(childId);
152 if (child)
153 children.push(child);
154 }
155
156 return children;
157 }
158
159 /**
160 * @return {number}
161 */
162 numChildren() {
163 if (!this._childIds)
164 return 0;
165 return this._childIds.length;
166 }
167
168 /**
169 * @return {boolean}
170 */
171 hasOnlyUnloadedChildren() {
172 if (!this._childIds || !this._childIds.length)
173 return false;
174
175 return !this._childIds.some((id) => this._accessibilityModel.axNodeForId(id) !== undefined);
176 }
177
178 /**
179 * TODO(aboxhall): Remove once protocol is stable.
180 * @param {!WebInspector.AccessibilityNode} inspectedNode
181 * @param {string=} leadingSpace
182 * @return {string}
183 */
184 printSelfAndChildren(inspectedNode, leadingSpace) {
185 var string = leadingSpace || '';
186 if (this._role)
187 string += this._role.value;
188 else
189 string += '<no role>';
190 string += (this._name ? ' ' + this._name.value : '');
191 string += ' ' + this._id;
192 if (this._domNode)
193 string += ' (' + this._domNode.nodeName() + ')';
194 if (this === inspectedNode)
195 string += ' *';
196 for (var child of this.children())
197 string += '\n' + child.printSelfAndChildren(inspectedNode, (leadingSpace | | '') + ' ');
198 return string;
106 } 199 }
107 }; 200 };
108 201
109 /** 202 /**
110 * @unrestricted 203 * @unrestricted
111 */ 204 */
112 WebInspector.AccessibilityModel = class extends WebInspector.SDKModel { 205 WebInspector.AccessibilityModel = class extends WebInspector.SDKModel {
113 /** 206 /**
114 * @param {!WebInspector.Target} target 207 * @param {!WebInspector.Target} target
115 */ 208 */
116 constructor(target) { 209 constructor(target) {
117 super(WebInspector.AccessibilityModel, target); 210 super(WebInspector.AccessibilityModel, target);
118 this._agent = target.accessibilityAgent(); 211 this._agent = target.accessibilityAgent();
119 212
120 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */ 213 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */
121 this._axIdToAXNode = new Map(); 214 this._axIdToAXNode = new Map();
215 this._backendDOMNodeIdToAXNode = new Map();
122 } 216 }
123 217
124 /** 218 /**
125 * @param {!WebInspector.Target} target 219 * @param {!WebInspector.Target} target
126 * @return {!WebInspector.AccessibilityModel} 220 * @return {!WebInspector.AccessibilityModel}
127 */ 221 */
128 static fromTarget(target) { 222 static fromTarget(target) {
129 if (!target[WebInspector.AccessibilityModel._symbol]) 223 if (!target[WebInspector.AccessibilityModel._symbol])
130 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Accessi bilityModel(target); 224 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Accessi bilityModel(target);
131 225
132 return target[WebInspector.AccessibilityModel._symbol]; 226 return target[WebInspector.AccessibilityModel._symbol];
133 } 227 }
134 228
229 clear() {
230 this._axIdToAXNode.clear();
231 }
232
233 /**
234 * @param {!WebInspector.DOMNode} node
235 * @return {!Promise}
236 */
237 requestPartialAXTree(node) {
238 /**
239 * @this {WebInspector.AccessibilityModel}
240 * @param {?string} error
241 * @param {!Array<!Protocol.Accessibility.AXNode>=} payloads
242 */
243 function parsePayload(error, payloads) {
244 if (error) {
245 console.error('AccessibilityAgent.getAXNodeChain(): ' + error);
246 return null;
247 }
248
249 if (!payloads)
250 return;
251
252 for (var payload of payloads)
253 new WebInspector.AccessibilityNode(this, payload);
254
255 for (var axNode of this._axIdToAXNode.values()) {
256 for (var axChild of axNode.children()) {
257 axChild._setParentNode(axNode);
258 }
259 }
260 }
261 return this._agent.getPartialAXTree(node.id, true, parsePayload.bind(this));
262 }
263
135 /** 264 /**
136 * @param {string} axId 265 * @param {string} axId
137 * @return {?WebInspector.AccessibilityNode} 266 * @return {?WebInspector.AccessibilityNode}
138 */ 267 */
139 axNodeForId(axId) { 268 axNodeForId(axId) {
140 return this._axIdToAXNode.get(axId); 269 return this._axIdToAXNode.get(axId);
141 } 270 }
142 271
143 /** 272 /**
144 * @param {string} axId 273 * @param {string} axId
145 * @param {!WebInspector.AccessibilityNode} axNode 274 * @param {!WebInspector.AccessibilityNode} axNode
146 */ 275 */
147 _setAXNodeForAXId(axId, axNode) { 276 _setAXNodeForAXId(axId, axNode) {
148 this._axIdToAXNode.set(axId, axNode); 277 this._axIdToAXNode.set(axId, axNode);
149 } 278 }
150 279
151 /** 280 /**
152 * @param {!WebInspector.DOMNode} node 281 * @param {?WebInspector.DOMNode} domNode
153 * @return {!Promise<?Array<!WebInspector.AccessibilityNode>>} 282 * @return {?WebInspector.AccessibilityNode}
154 */ 283 */
155 getAXNodeChain(node) { 284 axNodeForDOMNode(domNode) {
156 this._axIdToAXNode.clear(); 285 if (!domNode)
286 return null;
287 return this._backendDOMNodeIdToAXNode.get(domNode.backendNodeId());
288 }
157 289
158 /** 290 /**
159 * @this {WebInspector.AccessibilityModel} 291 * @param {number} backendDOMNodeId
160 * @param {?string} error 292 * @param {!WebInspector.AccessibilityNode} axNode
161 * @param {!Array<!Protocol.Accessibility.AXNode>=} payloads 293 */
162 * @return {?Array<!WebInspector.AccessibilityNode>} 294 _setAXNodeForBackendDOMNodeId(backendDOMNodeId, axNode) {
163 */ 295 this._backendDOMNodeIdToAXNode.set(backendDOMNodeId,
164 function parsePayload(error, payloads) { 296 axNode);
165 if (error) { 297 }
166 console.error('Protocol.Accessibility.getAXNodeChain(): ' + error);
167 return null;
168 }
169 298
170 if (!payloads) 299 // TODO(aboxhall): Remove once protocol is stable.
171 return null; 300 /**
172 301 * @param {!WebInspector.DOMNode} inspectedNode
173 var nodes = []; 302 */
174 for (var payload of payloads) 303 logTree(inspectedNode) {
175 nodes.push(new WebInspector.AccessibilityNode(this, payload)); 304 var rootNode = inspectedNode;
176 305 while (rootNode.parentNode())
177 return nodes; 306 rootNode = rootNode.parentNode();
178 } 307 console.log(rootNode.printSelfAndChildren(inspectedNode));
179 return this._agent.getAXNodeChain(node.id, true, parsePayload.bind(this));
180 } 308 }
181 }; 309 };
182 310
183 WebInspector.AccessibilityModel._symbol = Symbol('AccessibilityModel'); 311 WebInspector.AccessibilityModel._symbol = Symbol('AccessibilityModel');
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698