OLD | NEW |
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 * @unrestricted | 5 * @unrestricted |
6 */ | 6 */ |
7 Accessibility.AXTreePane = class extends Accessibility.AccessibilitySubPane { | 7 Accessibility.AXTreePane = class extends Accessibility.AccessibilitySubPane { |
8 /** | 8 /** |
9 * @param {!Accessibility.AccessibilitySidebarView} axSidebarView | 9 * @param {!Accessibility.AccessibilitySidebarView} axSidebarView |
10 */ | 10 */ |
11 constructor(axSidebarView) { | 11 constructor(axSidebarView) { |
12 super(Common.UIString('Accessibility Tree')); | 12 super(Common.UIString('Accessibility Tree')); |
13 | 13 |
14 this._axSidebarView = axSidebarView; | 14 this._axSidebarView = axSidebarView; |
15 this._treeOutline = this.createTreeOutline(); | 15 this._treeOutline = this.createTreeOutline(); |
16 this._treeOutline.setPaddingSize(12); | 16 this._treeOutline.setPaddingSize(12); |
17 | 17 |
18 this.element.classList.add('accessibility-computed'); | 18 this.element.classList.add('accessibility-computed'); |
19 | |
20 this._expandedNodes = new Set(); | |
21 } | 19 } |
22 | 20 |
23 /** | 21 /** |
24 * @param {?Accessibility.AccessibilityNode} axNode | 22 * @param {?Accessibility.AccessibilityNode} axNode |
25 * @override | 23 * @override |
26 */ | 24 */ |
27 setAXNode(axNode) { | 25 setAXNode(axNode) { |
28 this._axNode = axNode; | 26 this._axNode = axNode; |
29 | 27 |
30 var treeOutline = this._treeOutline; | 28 var treeOutline = this._treeOutline; |
31 treeOutline.removeChildren(); | 29 treeOutline.removeChildren(); |
32 | 30 |
33 // TODO(aboxhall): show no node UI | 31 // TODO(aboxhall): show no node UI |
34 if (!axNode) | 32 if (!axNode) |
35 return; | 33 return; |
36 | 34 |
37 treeOutline.element.classList.remove('hidden'); | 35 treeOutline.element.classList.remove('hidden'); |
38 var previousTreeElement = treeOutline.rootElement(); | 36 var previousTreeElement = treeOutline.rootElement(); |
39 var inspectedNodeTreeElement = new Accessibility.AXNodeTreeElement(axNode, t
his); | 37 var inspectedNodeTreeElement = new Accessibility.AXNodeTreeElement(axNode, t
his); |
40 inspectedNodeTreeElement.setInspected(true); | 38 inspectedNodeTreeElement.setInspected(true); |
41 | 39 |
42 var parent = axNode.parentNode(); | 40 var parent = axNode.parentNode(); |
43 if (parent) { | 41 if (parent) { |
44 this.setExpanded(parent.backendDOMNodeId(), false); | 42 var ancestorChain = []; |
45 | 43 var ancestor = parent; |
46 var chain = []; | |
47 var ancestor = parent.parentNode(); | |
48 while (ancestor) { | 44 while (ancestor) { |
49 chain.unshift(ancestor); | 45 ancestorChain.unshift(ancestor); |
50 ancestor = ancestor.parentNode(); | 46 ancestor = ancestor.parentNode(); |
51 } | 47 } |
52 for (var ancestorNode of chain) { | 48 for (var ancestorNode of ancestorChain) { |
53 var ancestorTreeElement = new Accessibility.AXNodeTreeElement(ancestorNo
de, this); | 49 var ancestorTreeElement = new Accessibility.AXNodeTreeElement(ancestorNo
de, this); |
54 previousTreeElement.appendChild(ancestorTreeElement); | 50 previousTreeElement.appendChild(ancestorTreeElement); |
55 previousTreeElement.expand(); | 51 previousTreeElement.expand(); |
56 previousTreeElement = ancestorTreeElement; | 52 previousTreeElement = ancestorTreeElement; |
57 } | 53 } |
58 var parentTreeElement = new Accessibility.AXNodeTreeParentElement(parent,
inspectedNodeTreeElement, this); | |
59 previousTreeElement.appendChild(parentTreeElement); | |
60 if (this.isExpanded(parent.backendDOMNodeId())) | |
61 parentTreeElement.appendSiblings(); | |
62 else | |
63 parentTreeElement.appendChild(inspectedNodeTreeElement); | |
64 previousTreeElement.expand(); | |
65 previousTreeElement = parentTreeElement; | |
66 } else { | |
67 previousTreeElement.appendChild(inspectedNodeTreeElement); | |
68 } | 54 } |
69 | 55 |
| 56 previousTreeElement.appendChild(inspectedNodeTreeElement); |
70 previousTreeElement.expand(); | 57 previousTreeElement.expand(); |
71 | 58 |
72 for (var child of axNode.children()) { | |
73 var childTreeElement = new Accessibility.AXNodeTreeElement(child, this); | |
74 inspectedNodeTreeElement.appendChild(childTreeElement); | |
75 } | |
76 | |
77 inspectedNodeTreeElement.selectable = true; | 59 inspectedNodeTreeElement.selectable = true; |
78 inspectedNodeTreeElement.select(!this._selectedByUser /* omitFocus */, false
); | 60 inspectedNodeTreeElement.select(!this._selectedByUser /* omitFocus */, false
); |
79 if (this.isExpanded(axNode.backendDOMNodeId())) | 61 inspectedNodeTreeElement.expand(); |
80 inspectedNodeTreeElement.expand(); | |
81 this.clearSelectedByUser(); | 62 this.clearSelectedByUser(); |
82 } | 63 } |
83 | 64 |
84 /** | 65 /** |
85 * @param {!Accessibility.AccessibilityNode} axNode | 66 * @param {!Accessibility.AccessibilityNode} axNode |
86 */ | 67 */ |
87 setSelectedNode(axNode) { | 68 setSelectedNode(axNode) { |
88 if (axNode.parentNode()) { | 69 if (axNode.parentNode()) { |
89 Common.Revealer.reveal(axNode.deferredDOMNode()); | 70 Common.Revealer.reveal(axNode.deferredDOMNode()); |
90 } else { | 71 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
106 clearSelectedByUser() { | 87 clearSelectedByUser() { |
107 delete this._selectedByUser; | 88 delete this._selectedByUser; |
108 } | 89 } |
109 | 90 |
110 /** | 91 /** |
111 * @return {!SDK.Target} | 92 * @return {!SDK.Target} |
112 */ | 93 */ |
113 target() { | 94 target() { |
114 return this.node().target(); | 95 return this.node().target(); |
115 } | 96 } |
116 | |
117 /** | |
118 * @param {?number} backendDOMNodeId | |
119 * @param {boolean} expanded | |
120 */ | |
121 setExpanded(backendDOMNodeId, expanded) { | |
122 if (!backendDOMNodeId) | |
123 return; | |
124 if (expanded) | |
125 this._expandedNodes.add(backendDOMNodeId); | |
126 else | |
127 this._expandedNodes.delete(backendDOMNodeId); | |
128 } | |
129 | |
130 /** | |
131 * @param {?number} backendDOMNodeId | |
132 * @return {boolean} | |
133 */ | |
134 isExpanded(backendDOMNodeId) { | |
135 if (!backendDOMNodeId) | |
136 return false; | |
137 | |
138 return this._expandedNodes.has(backendDOMNodeId); | |
139 } | |
140 }; | 97 }; |
141 | 98 |
142 Accessibility.InspectNodeButton = class { | 99 Accessibility.InspectNodeButton = class { |
143 /** | 100 /** |
144 * @param {!Accessibility.AccessibilityNode} axNode | 101 * @param {!Accessibility.AccessibilityNode} axNode |
145 * @param {!Accessibility.AXTreePane} treePane | 102 * @param {!Accessibility.AXTreePane} treePane |
146 */ | 103 */ |
147 constructor(axNode, treePane) { | 104 constructor(axNode, treePane) { |
148 this._axNode = axNode; | 105 this._axNode = axNode; |
149 this._treePane = treePane; | 106 this._treePane = treePane; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 /** | 197 /** |
241 * @override | 198 * @override |
242 * @param {!Event} event | 199 * @param {!Event} event |
243 * @return {boolean} | 200 * @return {boolean} |
244 */ | 201 */ |
245 ondblclick(event) { | 202 ondblclick(event) { |
246 this.inspectDOMNode(); | 203 this.inspectDOMNode(); |
247 return true; | 204 return true; |
248 } | 205 } |
249 | 206 |
| 207 /** |
| 208 * @override |
| 209 */ |
| 210 onpopulate() { |
| 211 for (var child of this._axNode.children()) { |
| 212 var childTreeElement = new Accessibility.AXNodeTreeElement(child, this._tr
eePane); |
| 213 this.appendChild(childTreeElement); |
| 214 if (childTreeElement.isExpandable() && !child.hasOnlyUnloadedChildren()) |
| 215 childTreeElement.expand(); |
| 216 } |
| 217 } |
| 218 |
250 inspectDOMNode() { | 219 inspectDOMNode() { |
251 this._treePane.setSelectedByUser(true); | 220 this._treePane.setSelectedByUser(true); |
252 this._treePane.setSelectedNode(this._axNode); | 221 this._treePane.setSelectedNode(this._axNode); |
253 } | 222 } |
254 | 223 |
255 /** | 224 /** |
256 * @override | 225 * @override |
257 */ | 226 */ |
258 onattach() { | 227 onattach() { |
259 this._update(); | 228 this._update(); |
260 } | 229 } |
261 | 230 |
262 _update() { | 231 _update() { |
263 this.titleElement().removeChildren(); | 232 this.titleElement().removeChildren(); |
264 | 233 |
265 if (this._axNode.ignored()) { | 234 if (this._axNode.ignored()) { |
266 this._appendIgnoredNodeElement(); | 235 this._appendIgnoredNodeElement(); |
267 } else { | 236 } else { |
268 this._appendRoleElement(this._axNode.role()); | 237 this._appendRoleElement(this._axNode.role()); |
269 if (this._axNode.name().value) { | 238 if (this._axNode.name() && this._axNode.name().value) { |
270 this.titleElement().createChild('span', 'separator').textContent = '\u00
A0'; | 239 this.titleElement().createChild('span', 'separator').textContent = '\u00
A0'; |
271 this._appendNameElement(/** @type {string} */ (this._axNode.name().value
)); | 240 this._appendNameElement(/** @type {string} */ (this._axNode.name().value
)); |
272 } | 241 } |
273 } | 242 } |
274 | 243 |
275 if (this._axNode.hasOnlyUnloadedChildren()) { | 244 if (this._axNode.hasOnlyUnloadedChildren()) { |
276 this.titleElement().classList.add('children-unloaded'); | 245 this.listItemElement.classList.add('children-unloaded'); |
277 this.setExpandable(true); | 246 this.setExpandable(true); |
278 } else { | 247 } else { |
279 this.setExpandable(!!this._axNode.numChildren()); | 248 this.setExpandable(!!this._axNode.numChildren()); |
280 } | 249 } |
281 | 250 |
282 if (!this._axNode.isDOMNode()) | 251 if (!this._axNode.isDOMNode()) |
283 this.titleElement().classList.add('no-dom-node'); | 252 this.listItemElement.classList.add('no-dom-node'); |
284 this.titleElement().appendChild(this._inspectNodeButton.element); | 253 this.titleElement().appendChild(this._inspectNodeButton.element); |
285 } | 254 } |
286 | 255 |
287 /** | 256 /** |
288 * @override | 257 * @override |
289 */ | 258 */ |
290 expand() { | 259 expand() { |
291 if (!this._axNode || this._axNode.hasOnlyUnloadedChildren()) | 260 if (!this._axNode || this._axNode.hasOnlyUnloadedChildren()) |
292 return; | 261 return; |
293 | |
294 this._treePane.setExpanded(this._axNode.backendDOMNodeId(), true); | |
295 super.expand(); | 262 super.expand(); |
296 } | 263 } |
297 | 264 |
298 /** | 265 /** |
299 * @override | 266 * @override |
300 */ | 267 */ |
301 collapse() { | 268 collapse() { |
302 if (!this._axNode || this._axNode.hasOnlyUnloadedChildren()) | 269 if (!this._axNode || this._axNode.hasOnlyUnloadedChildren()) |
303 return; | 270 return; |
304 | 271 |
305 if (this._treePane) | |
306 this._treePane.setExpanded(this._axNode.backendDOMNodeId(), false); | |
307 super.collapse(); | 272 super.collapse(); |
308 } | 273 } |
309 | 274 |
310 /** | 275 /** |
311 * @param {string} name | 276 * @param {string} name |
312 */ | 277 */ |
313 _appendNameElement(name) { | 278 _appendNameElement(name) { |
314 var nameElement = createElement('span'); | 279 var nameElement = createElement('span'); |
315 nameElement.textContent = '"' + name + '"'; | 280 nameElement.textContent = '"' + name + '"'; |
316 nameElement.classList.add('ax-readable-string'); | 281 nameElement.classList.add('ax-readable-string'); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 return super.select(omitFocus, selectedByUser); | 315 return super.select(omitFocus, selectedByUser); |
351 } | 316 } |
352 }; | 317 }; |
353 | 318 |
354 /** @type {!Object<string, string>} */ | 319 /** @type {!Object<string, string>} */ |
355 Accessibility.AXNodeTreeElement.RoleStyles = { | 320 Accessibility.AXNodeTreeElement.RoleStyles = { |
356 internalRole: 'ax-internal-role', | 321 internalRole: 'ax-internal-role', |
357 role: 'ax-role', | 322 role: 'ax-role', |
358 }; | 323 }; |
359 | 324 |
360 /** | |
361 * @unrestricted | |
362 */ | |
363 Accessibility.ExpandSiblingsButton = class { | |
364 /** | |
365 * @param {!Accessibility.AXNodeTreeParentElement} treeElement | |
366 * @param {number} numSiblings | |
367 */ | |
368 constructor(treeElement, numSiblings) { | |
369 this._treeElement = treeElement; | |
370 | |
371 this.element = createElementWithClass('button', 'expand-siblings'); | |
372 this.element.textContent = Common.UIString((numSiblings === 1 ? '+ %d node'
: '+ %d nodes'), numSiblings); | |
373 this.element.addEventListener('mousedown', this._handleMouseDown.bind(this))
; | |
374 } | |
375 | |
376 /** | |
377 * @param {!Event} event | |
378 */ | |
379 _handleMouseDown(event) { | |
380 this._treeElement.expandSiblings(); | |
381 event.consume(); | |
382 } | |
383 }; | |
384 | |
385 /** | |
386 * @unrestricted | |
387 */ | |
388 Accessibility.AXNodeTreeParentElement = class extends Accessibility.AXNodeTreeEl
ement { | |
389 /** | |
390 * @param {!Accessibility.AccessibilityNode} axNode | |
391 * @param {!Accessibility.AXNodeTreeElement} inspectedNodeTreeElement | |
392 * @param {!Accessibility.AXTreePane} treePane | |
393 */ | |
394 constructor(axNode, inspectedNodeTreeElement, treePane) { | |
395 super(axNode, treePane); | |
396 | |
397 this._inspectedNodeTreeElement = inspectedNodeTreeElement; | |
398 var numSiblings = axNode.children().length - 1; | |
399 this._expandSiblingsButton = new Accessibility.ExpandSiblingsButton(this, nu
mSiblings); | |
400 this._partiallyExpanded = false; | |
401 } | |
402 | |
403 /** | |
404 * @override | |
405 */ | |
406 onattach() { | |
407 super.onattach(); | |
408 if (this._treePane.isExpanded(this._axNode.backendDOMNodeId())) | |
409 this.listItemElement.classList.add('siblings-expanded'); | |
410 if (this._axNode.numChildren() > 1) | |
411 this.titleElement().insertBefore(this._expandSiblingsButton.element, this.
_inspectNodeButton.element); | |
412 } | |
413 | |
414 /** | |
415 * @param {boolean} altKey | |
416 * @return {boolean} | |
417 * @override | |
418 */ | |
419 descendOrExpand(altKey) { | |
420 if (!this.expanded || !this._partiallyExpanded) | |
421 return super.descendOrExpand(altKey); | |
422 | |
423 this.expandSiblings(); | |
424 if (altKey) | |
425 this.expandRecursively(); | |
426 return true; | |
427 } | |
428 | |
429 /** | |
430 * @override | |
431 */ | |
432 expand() { | |
433 super.expand(); | |
434 this._partiallyExpanded = true; | |
435 } | |
436 | |
437 expandSiblings() { | |
438 this.listItemElement.classList.add('siblings-expanded'); | |
439 this.appendSiblings(); | |
440 this.expanded = true; | |
441 this._partiallyExpanded = false; | |
442 this._treePane.setExpanded(this._axNode.backendDOMNodeId(), true); | |
443 } | |
444 | |
445 appendSiblings() { | |
446 var inspectedAXNode = this._inspectedNodeTreeElement.axNode(); | |
447 var nextIndex = 0; | |
448 var foundInspectedNode = false; | |
449 for (var sibling of this._axNode.children()) { | |
450 var siblingTreeElement = null; | |
451 if (sibling === inspectedAXNode) { | |
452 foundInspectedNode = true; | |
453 continue; | |
454 } | |
455 siblingTreeElement = new Accessibility.AXNodeTreeElement(sibling, this._tr
eePane); | |
456 if (foundInspectedNode) | |
457 this.appendChild(siblingTreeElement); | |
458 else | |
459 this.insertChild(siblingTreeElement, nextIndex++); | |
460 } | |
461 } | |
462 }; | |
OLD | NEW |