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

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

Issue 2390783006: [DevTools] Accessibility: Show siblings and children of selected node (Closed)
Patch Set: Handle non-rendered nodes which are not top-level 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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.AccessibilitySubPane} 7 * @extends {WebInspector.AccessibilitySubPane}
8 */ 8 */
9 WebInspector.AXTreePane = function() 9 WebInspector.AXTreePane = function()
10 { 10 {
11 WebInspector.AccessibilitySubPane.call(this, WebInspector.UIString("Accessib ility Tree")); 11 WebInspector.AccessibilitySubPane.call(this, WebInspector.UIString("Accessib ility Tree"));
12 12
13 this._treeOutline = this.createTreeOutline(); 13 this._treeOutline = this.createTreeOutline();
14 14
15 this.element.classList.add("accessibility-computed"); 15 this.element.classList.add("accessibility-computed");
16
17 this._expandedNodes = new Set();
16 }; 18 };
17 19
18 20
19 WebInspector.AXTreePane.prototype = { 21 WebInspector.AXTreePane.prototype = {
20 /** 22 /**
21 * @param {!Array<!WebInspector.AccessibilityNode>} nodes 23 * @param {?WebInspector.AccessibilityNode} axNode
24 * @override
22 */ 25 */
23 setAXNodeAndAncestors: function(nodes) 26 setAXNode : function(axNode)
24 { 27 {
25 this._nodes = nodes; 28 this._axNode = axNode;
26 29
27 var target = this.node().target();
28 var treeOutline = this._treeOutline; 30 var treeOutline = this._treeOutline;
29 treeOutline.removeChildren(); 31 treeOutline.removeChildren();
32
33 // TODO(aboxhall): show no node UI
34 if (!axNode)
35 return;
36
30 treeOutline.element.classList.remove("hidden"); 37 treeOutline.element.classList.remove("hidden");
31 var previous = treeOutline.rootElement(); 38 var previousTreeElement = treeOutline.rootElement();
32 while (nodes.length) { 39 var inspectedNodeTreeElement = new WebInspector.AXNodeTreeElement(axNode , this);
33 var ancestor = nodes.pop(); 40 inspectedNodeTreeElement.setInspected(true);
34 var ancestorTreeElement = new WebInspector.AXNodeTreeElement(ancesto r, target); 41
35 previous.appendChild(ancestorTreeElement); 42 var parent = axNode.parentNode();
36 previous.expand(); 43 if (parent) {
37 previous = ancestorTreeElement; 44 this.setExpanded(parent.domNode(), false);
45
46 var chain = [];
47 var ancestor = parent.parentNode();
48 while (ancestor) {
49 chain.unshift(ancestor);
50 ancestor = ancestor.parentNode();
51 }
52 for (var ancestorNode of chain) {
53 var ancestorTreeElement = new WebInspector.AXNodeTreeElement(anc estorNode, this);
54 previousTreeElement.appendChild(ancestorTreeElement);
55 previousTreeElement.expand();
56 previousTreeElement = ancestorTreeElement;
57 }
58 var parentTreeElement = new WebInspector.AXNodeTreeParentElement(par ent, inspectedNodeTreeElement, this);
59 if (this.isExpanded(parent.domNode()))
60 parentTreeElement.appendSiblings();
61 else
62 parentTreeElement.appendChild(inspectedNodeTreeElement);
63 previousTreeElement.appendChild(parentTreeElement);
64 previousTreeElement.expand();
65 previousTreeElement = parentTreeElement;
66 } else {
67 previousTreeElement.appendChild(inspectedNodeTreeElement);
38 } 68 }
39 previous.selectable = true; 69
40 previous.select(true /* omitFocus */); 70 previousTreeElement.expand();
71
72 for (var child of axNode.children()) {
73 var childTreeElement = new WebInspector.AXNodeTreeElement(child, thi s);
74 inspectedNodeTreeElement.appendChild(childTreeElement);
75 }
76
77 inspectedNodeTreeElement.selectable = true;
78 inspectedNodeTreeElement.select(!this._selectedByUser /* omitFocus */, f alse);
79 if (this.isExpanded(axNode.domNode()))
80 inspectedNodeTreeElement.expand();
81 this.clearSelectedByUser();
82 },
83
84 /**
85 * @param {boolean} selectedByUser
86 */
87 setSelectedByUser: function(selectedByUser)
88 {
89 this._selectedByUser = true;
90 },
91
92 clearSelectedByUser: function()
93 {
94 delete this._selectedByUser;
95 },
96
97 /**
98 * @return {!WebInspector.Target}
99 */
100 target: function()
101 {
102 return this.node().target();
103 },
104
105 /**
106 * @param {?WebInspector.DOMNode} domNode
107 * @param {boolean} expanded
108 */
109 setExpanded: function(domNode, expanded)
110 {
111 if (!domNode)
112 return;
113 if (expanded)
114 this._expandedNodes.add(domNode.id);
115 else
116 this._expandedNodes.delete(domNode.id);
117 },
118
119 /**
120 * @param {?WebInspector.DOMNode} domNode
121 * @return {boolean}
122 */
123 isExpanded: function(domNode)
124 {
125 if (!domNode)
126 return false;
127
128 return this._expandedNodes.has(domNode.id);
41 }, 129 },
42 130
43 __proto__: WebInspector.AccessibilitySubPane.prototype 131 __proto__: WebInspector.AccessibilitySubPane.prototype
44 }; 132 };
45 133
46 /** 134 /**
47 * @constructor 135 * @constructor
48 * @extends {TreeElement} 136 * @extends {TreeElement}
49 * @param {!WebInspector.AccessibilityNode} axNode 137 * @param {!WebInspector.AccessibilityNode} axNode
50 * @param {!WebInspector.Target} target 138 * @param {!WebInspector.AXTreePane} treePane
51 */ 139 */
52 WebInspector.AXNodeTreeElement = function(axNode, target) 140 WebInspector.AXNodeTreeElement = function(axNode, treePane)
53 { 141 {
54 /** @type {!WebInspector.AccessibilityNode} */ 142 /** @type {!WebInspector.AccessibilityNode} */
55 this._axNode = axNode; 143 this._axNode = axNode;
56 144
57 /** @type {!WebInspector.Target} */ 145 /** @type {!WebInspector.AXTreePane} */
58 this._target = target; 146 this._treePane = treePane;
59 147
60 // Pass an empty title, the title gets made later in onattach. 148 // Pass an empty title, the title gets made later in onattach.
61 TreeElement.call(this, ""); 149 TreeElement.call(this, "", true);
62 150
63 this.selectable = false; 151 if (!this._axNode.domNode())
152 this.listItemElement.classList.add("no-dom-node");
153
154 this.selectable = true;
64 }; 155 };
65 156
66 /** @type {!Object<string, string>} */ 157 /** @type {!Object<string, string>} */
67 WebInspector.AXNodeTreeElement.RoleStyles = { 158 WebInspector.AXNodeTreeElement.RoleStyles = {
68 internalRole: "ax-internal-role", 159 internalRole: "ax-internal-role",
69 role: "ax-role", 160 role: "ax-role",
70 }; 161 };
71 162
72 WebInspector.AXNodeTreeElement.prototype = { 163 WebInspector.AXNodeTreeElement.prototype = {
73 /** 164 /**
165 * @return {!WebInspector.AccessibilityNode}
166 */
167 axNode: function()
168 {
169 return this._axNode;
170 },
171
172 /**
173 * @param {boolean} inspected
174 */
175 setInspected: function(inspected)
176 {
177 if (inspected)
178 this.listItemElement.classList.add("inspected");
179 else
180 this.listItemElement.classList.remove("inspected");
181 },
182
183 /**
184 * @override
185 * @return {boolean}
186 */
187 onenter: function()
188 {
189 this.inspectDOMNode();
190 return true;
191 },
192
193 /**
194 * @override
195 * @param {!Event} event
196 * @return {boolean}
197 */
198 ondblclick: function(event)
199 {
200 this.inspectDOMNode();
201 return true;
202 },
203
204 inspectDOMNode: function()
205 {
206 this._treePane.setSelectedByUser(true);
207 WebInspector.Revealer.reveal(this._axNode.domNode());
208 },
209
210 /**
74 * @override 211 * @override
75 */ 212 */
76 onattach: function() 213 onattach: function()
77 { 214 {
78 this._update(); 215 this._update();
79 }, 216 },
80 217
81 _update: function() 218 _update: function()
82 { 219 {
83 this.listItemElement.removeChildren(); 220 this.listItemElement.removeChildren();
84 221
85 if (this._axNode.ignored()) { 222 if (this._axNode.ignored()) {
86 this._appendIgnoredNodeElement(); 223 this._appendIgnoredNodeElement();
87 } else { 224 } else {
88 this._appendRoleElement(this._axNode.role()); 225 this._appendRoleElement(this._axNode.role());
89 if ("name" in this._axNode && this._axNode.name().value) { 226 if ("name" in this._axNode && this._axNode.name().value) {
90 this.listItemElement.createChild("span", "separator").textConten t = "\u00A0"; 227 this.listItemElement.createChild("span", "separator").textConten t = "\u00A0";
91 this._appendNameElement(/** @type {string} */ (this._axNode.name ().value)); 228 this._appendNameElement(/** @type {string} */ (this._axNode.name ().value));
92 } 229 }
93 } 230 }
231
232 if (this._axNode.hasOnlyUnloadedChildren()) {
233 this._hasOnlyUnloadedChildren = true;
234 this.listItemElement.classList.add("children-unloaded");
235 this.setExpandable(true);
236 } else {
237 this.setExpandable(!!this._axNode.numChildren());
238 }
94 }, 239 },
95 240
96 /** 241 /**
242 * @override
243 */
244 expand: function()
245 {
246 if (this._hasOnlyUnloadedChildren)
247 return;
248
249 this._treePane.setExpanded(this._axNode.domNode(), true);
250 TreeElement.prototype.expand.call(this);
251 },
252
253 /**
254 * @override
255 */
256 collapse: function()
257 {
258 if (this._hasOnlyUnloadedChildren)
259 return;
260
261 this._treePane.setExpanded(this._axNode.domNode(), false);
262 TreeElement.prototype.collapse.call(this);
263 },
264
265 /**
97 * @param {string} name 266 * @param {string} name
98 */ 267 */
99 _appendNameElement: function(name) 268 _appendNameElement: function(name)
100 { 269 {
101 var nameElement = createElement("span"); 270 var nameElement = createElement("span");
102 nameElement.textContent = '"' + name + '"'; 271 nameElement.textContent = '"' + name + '"';
103 nameElement.classList.add("ax-readable-string"); 272 nameElement.classList.add("ax-readable-string");
104 this.listItemElement.appendChild(nameElement); 273 this.listItemElement.appendChild(nameElement);
105 }, 274 },
106 275
(...skipping 13 matching lines...) Expand all
120 }, 289 },
121 290
122 _appendIgnoredNodeElement: function() 291 _appendIgnoredNodeElement: function()
123 { 292 {
124 var ignoredNodeElement = createElementWithClass("span", "monospace"); 293 var ignoredNodeElement = createElementWithClass("span", "monospace");
125 ignoredNodeElement.textContent = WebInspector.UIString("Ignored"); 294 ignoredNodeElement.textContent = WebInspector.UIString("Ignored");
126 ignoredNodeElement.classList.add("ax-tree-ignored-node"); 295 ignoredNodeElement.classList.add("ax-tree-ignored-node");
127 this.listItemElement.appendChild(ignoredNodeElement); 296 this.listItemElement.appendChild(ignoredNodeElement);
128 }, 297 },
129 298
299 /**
300 * @param {boolean=} omitFocus
301 * @param {boolean=} selectedByUser
302 * @return {boolean}
303 * @override
304 */
305 select: function(omitFocus, selectedByUser)
306 {
307 this._ensureSelection();
308
309 this._treePane.setSelectedByUser(!!selectedByUser);
310 if (selectedByUser)
311 WebInspector.context.setFlavor(WebInspector.AccessibilityNode, this. _axNode);
312
313 return TreeElement.prototype.select.call(this, omitFocus, selectedByUser );
314 },
315
130 __proto__: TreeElement.prototype 316 __proto__: TreeElement.prototype
131 }; 317 };
318
319 /**
320 * @constructor
321 * @param {!WebInspector.AXNodeTreeParentElement} treeElement
322 */
323 WebInspector.ExpandSiblingsButton = function(treeElement)
324 {
325 this._treeElement = treeElement;
326
327 this.element = createElementWithClass("button", "expand-siblings");
328 this.element.addEventListener("mousedown", this._handleMouseDown.bind(this)) ;
329 };
330
331 WebInspector.ExpandSiblingsButton.prototype = {
332 _handleMouseDown: function(event) {
333 this._treeElement.expandSiblings();
334 event.consume();
335 }
336 };
337
338
339 /**
340 * @constructor
341 * @extends {WebInspector.AXNodeTreeElement}
342 * @param {!WebInspector.AccessibilityNode} axNode
343 * @param {!WebInspector.AXNodeTreeElement} inspectedNodeTreeElement
344 * @param {!WebInspector.AXTreePane} treePane
345 */
346 WebInspector.AXNodeTreeParentElement = function(axNode, inspectedNodeTreeElement , treePane)
347 {
348 this._inspectedNodeTreeElement = inspectedNodeTreeElement;
349 this._treePane = treePane;
350
351 WebInspector.AXNodeTreeElement.call(this, axNode, treePane);
352
353 this._expandSibingsButton = new WebInspector.ExpandSiblingsButton(this);
354 this._partiallyExpanded = false;
355 };
356
357 WebInspector.AXNodeTreeParentElement.prototype = {
358 /**
359 * @override
360 */
361 onattach: function(){
362 WebInspector.AXNodeTreeElement.prototype.onattach.call(this);
363 if (this._treePane.isExpanded(this._axNode.domNode()))
364 this._listItemNode.classList.add("siblings-expanded");
365 if (this._axNode.numChildren() > 1)
366 this._listItemNode.appendChild(this._expandSibingsButton.element);
367 },
368
369 /**
370 * @param {boolean} altKey
371 * @return {boolean}
372 * @override
373 */
374 descendOrExpand: function(altKey)
375 {
376 if (!this.expanded || !this._partiallyExpanded)
377 return TreeElement.prototype.descendOrExpand.call(this, altKey);
378
379 this.expandSiblings();
380 if (altKey)
381 this.expandRecursively();
382 return true;
383 },
384
385 /**
386 * @override
387 */
388 expand: function()
389 {
390 TreeElement.prototype.expand.call(this);
391 this._partiallyExpanded = true;
392 },
393
394 expandSiblings: function()
395 {
396 this._listItemNode.classList.add("siblings-expanded");
397 this.appendSiblings();
398 this.expanded = true;
399 this._partiallyExpanded = false;
400 this._treePane.setExpanded(this._axNode.domNode(), true);
401 },
402
403 appendSiblings: function()
404 {
405 var inspectedAXNode = this._inspectedNodeTreeElement.axNode();
406 var nextIndex = 0;
407 var foundInspectedNode = false;
408 for (var sibling of this._axNode.children()) {
409 var siblingTreeElement = null;
410 if (sibling === inspectedAXNode) {
411 foundInspectedNode = true;
412 continue;
413 }
414 siblingTreeElement = new WebInspector.AXNodeTreeElement(sibling, thi s._treePane);
415 if (foundInspectedNode)
416 this.appendChild(siblingTreeElement);
417 else
418 this.insertChild(siblingTreeElement, nextIndex++);
419 }
420 },
421
422 __proto__: WebInspector.AXNodeTreeElement.prototype
423 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698