Chromium Code Reviews| 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 /** | 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 // Pass an empty title, the title gets made later in onattach. | 142 // Pass an empty title, the title gets made later in onattach. |
| 55 TreeElement.call(this, ""); | 143 TreeElement.call(this, ""); |
| 56 | 144 |
| 57 /** @type {!WebInspector.AccessibilityNode} */ | 145 /** @type {!WebInspector.AccessibilityNode} */ |
| 58 this._axNode = axNode; | 146 this._axNode = axNode; |
| 59 | 147 |
| 60 /** @type {!WebInspector.Target} */ | 148 /** @type {!WebInspector.AXTreePane} */ |
| 61 this._target = target; | 149 this._treePane = treePane; |
| 62 | 150 |
| 63 this.selectable = false; | 151 this.selectable = false; |
| 64 }; | 152 }; |
| 65 | 153 |
| 66 /** @type {!Object<string, string>} */ | 154 /** @type {!Object<string, string>} */ |
| 67 WebInspector.AXNodeTreeElement.RoleStyles = { | 155 WebInspector.AXNodeTreeElement.RoleStyles = { |
| 68 internalRole: "ax-internal-role", | 156 internalRole: "ax-internal-role", |
| 69 role: "ax-role", | 157 role: "ax-role", |
| 70 }; | 158 }; |
| 71 | 159 |
| 72 WebInspector.AXNodeTreeElement.prototype = { | 160 WebInspector.AXNodeTreeElement.prototype = { |
| 73 /** | 161 /** |
| 162 * @return {!WebInspector.AccessibilityNode} | |
| 163 */ | |
| 164 axNode: function() | |
| 165 { | |
| 166 return this._axNode; | |
| 167 }, | |
| 168 | |
| 169 /** | |
| 170 * @param {boolean} inspected | |
| 171 */ | |
| 172 setInspected: function(inspected) | |
| 173 { | |
| 174 if (inspected) | |
| 175 this.listItemElement.classList.add("inspected"); | |
| 176 else | |
| 177 this.listItemElement.classList.remove("inspected"); | |
| 178 }, | |
| 179 | |
| 180 /** | |
| 181 * @override | |
| 182 * @return {boolean} | |
| 183 */ | |
| 184 onenter: function() | |
| 185 { | |
| 186 this.inspectDOMNode(); | |
| 187 return true; | |
| 188 }, | |
| 189 | |
| 190 /** | |
| 191 * @override | |
| 192 * @param {!Event} event | |
| 193 * @return {boolean} | |
| 194 */ | |
| 195 ondblclick: function(event) | |
| 196 { | |
| 197 this.inspectDOMNode(); | |
| 198 return true; | |
| 199 }, | |
| 200 | |
| 201 inspectDOMNode: function() | |
| 202 { | |
| 203 this._treePane.setSelectedByUser(true); | |
| 204 WebInspector.Revealer.reveal(this._axNode.domNode()); | |
| 205 }, | |
| 206 | |
| 207 /** | |
| 74 * @override | 208 * @override |
| 75 */ | 209 */ |
| 76 onattach: function() | 210 onattach: function() |
| 77 { | 211 { |
| 78 this._update(); | 212 this._update(); |
| 79 }, | 213 }, |
| 80 | 214 |
| 81 _update: function() | 215 _update: function() |
| 82 { | 216 { |
| 83 this.listItemElement.removeChildren(); | 217 this.listItemElement.removeChildren(); |
| 84 | 218 |
| 85 if (this._axNode.ignored()) { | 219 if (this._axNode.ignored()) { |
| 86 this._appendIgnoredNodeElement(); | 220 this._appendIgnoredNodeElement(); |
| 87 } else { | 221 } else { |
| 88 this._appendRoleElement(this._axNode.role()); | 222 this._appendRoleElement(this._axNode.role()); |
| 89 if ("name" in this._axNode && this._axNode.name().value) { | 223 if (this._axNode && this._axNode.name().value) { |
| 90 this.listItemElement.createChild("span", "separator").textConten t = "\u00A0"; | 224 this.listItemElement.createChild("span", "separator").textConten t = "\u00A0"; |
| 91 this._appendNameElement(/** @type {string} */ (this._axNode.name ().value)); | 225 this._appendNameElement(/** @type {string} */ (this._axNode.name ().value)); |
| 92 } | 226 } |
| 93 } | 227 } |
| 228 | |
| 229 if (this._axNode.hasOnlyUnloadedChildren()) { | |
| 230 this._hasOnlyUnloadedChildren = true; | |
| 231 this.listItemElement.classList.add("children-unloaded"); | |
| 232 this.setExpandable(true); | |
| 233 } else { | |
| 234 this.setExpandable(!!this._axNode.numChildren()); | |
| 235 } | |
| 94 }, | 236 }, |
| 95 | 237 |
| 96 /** | 238 /** |
| 239 * @override | |
| 240 */ | |
| 241 expand: function() | |
| 242 { | |
| 243 if (this._hasOnlyUnloadedChildren) | |
| 244 return; | |
| 245 | |
| 246 this._treePane.setExpanded(this._axNode.domNode(), true); | |
| 247 TreeElement.prototype.expand.call(this); | |
| 248 }, | |
| 249 | |
| 250 /** | |
| 251 * @override | |
| 252 */ | |
| 253 collapse: function() | |
| 254 { | |
| 255 if (this._hasOnlyUnloadedChildren) | |
| 256 return; | |
| 257 | |
| 258 if (this._treePane) | |
| 259 this._treePane.setExpanded(this._axNode.domNode(), false); | |
| 260 TreeElement.prototype.collapse.call(this); | |
| 261 }, | |
| 262 | |
| 263 /** | |
| 97 * @param {string} name | 264 * @param {string} name |
| 98 */ | 265 */ |
| 99 _appendNameElement: function(name) | 266 _appendNameElement: function(name) |
| 100 { | 267 { |
| 101 var nameElement = createElement("span"); | 268 var nameElement = createElement("span"); |
| 102 nameElement.textContent = '"' + name + '"'; | 269 nameElement.textContent = '"' + name + '"'; |
| 103 nameElement.classList.add("ax-readable-string"); | 270 nameElement.classList.add("ax-readable-string"); |
| 104 this.listItemElement.appendChild(nameElement); | 271 this.listItemElement.appendChild(nameElement); |
| 105 }, | 272 }, |
| 106 | 273 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 120 }, | 287 }, |
| 121 | 288 |
| 122 _appendIgnoredNodeElement: function() | 289 _appendIgnoredNodeElement: function() |
| 123 { | 290 { |
| 124 var ignoredNodeElement = createElementWithClass("span", "monospace"); | 291 var ignoredNodeElement = createElementWithClass("span", "monospace"); |
| 125 ignoredNodeElement.textContent = WebInspector.UIString("Ignored"); | 292 ignoredNodeElement.textContent = WebInspector.UIString("Ignored"); |
| 126 ignoredNodeElement.classList.add("ax-tree-ignored-node"); | 293 ignoredNodeElement.classList.add("ax-tree-ignored-node"); |
| 127 this.listItemElement.appendChild(ignoredNodeElement); | 294 this.listItemElement.appendChild(ignoredNodeElement); |
| 128 }, | 295 }, |
| 129 | 296 |
| 297 /** | |
| 298 * @param {boolean=} omitFocus | |
| 299 * @param {boolean=} selectedByUser | |
| 300 * @return {boolean} | |
| 301 * @override | |
| 302 */ | |
| 303 select: function(omitFocus, selectedByUser) | |
| 304 { | |
| 305 this._ensureSelection(); | |
| 306 | |
| 307 this._treePane.setSelectedByUser(!!selectedByUser); | |
| 308 if (selectedByUser) | |
| 309 WebInspector.context.setFlavor(WebInspector.AccessibilityNode, this. _axNode); | |
|
dgozman
2016/10/31 21:36:30
Where is this flavor being used?
aboxhall
2016/10/31 22:45:15
Ah, thanks for catching - I was using it earlier b
| |
| 310 | |
| 311 return TreeElement.prototype.select.call(this, omitFocus, selectedByUser ); | |
| 312 }, | |
| 313 | |
| 130 __proto__: TreeElement.prototype | 314 __proto__: TreeElement.prototype |
| 131 }; | 315 }; |
| 316 | |
| 317 /** | |
| 318 * @constructor | |
| 319 * @param {!WebInspector.AXNodeTreeParentElement} treeElement | |
| 320 */ | |
| 321 WebInspector.ExpandSiblingsButton = function(treeElement) | |
| 322 { | |
| 323 this._treeElement = treeElement; | |
| 324 | |
| 325 this.element = createElementWithClass("button", "expand-siblings"); | |
| 326 this.element.addEventListener("mousedown", this._handleMouseDown.bind(this)) ; | |
| 327 }; | |
| 328 | |
| 329 WebInspector.ExpandSiblingsButton.prototype = { | |
| 330 _handleMouseDown: function(event) { | |
|
dgozman
2016/10/31 21:36:30
style: { on next line (here and below)
aboxhall
2016/10/31 22:45:15
Done.
| |
| 331 this._treeElement.expandSiblings(); | |
| 332 event.consume(); | |
| 333 } | |
| 334 }; | |
| 335 | |
| 336 | |
| 337 /** | |
| 338 * @constructor | |
| 339 * @extends {WebInspector.AXNodeTreeElement} | |
| 340 * @param {!WebInspector.AccessibilityNode} axNode | |
| 341 * @param {!WebInspector.AXNodeTreeElement} inspectedNodeTreeElement | |
| 342 * @param {!WebInspector.AXTreePane} treePane | |
| 343 */ | |
| 344 WebInspector.AXNodeTreeParentElement = function(axNode, inspectedNodeTreeElement , treePane) | |
| 345 { | |
| 346 WebInspector.AXNodeTreeElement.call(this, axNode, treePane); | |
| 347 | |
| 348 this._inspectedNodeTreeElement = inspectedNodeTreeElement; | |
| 349 this._expandSibingsButton = new WebInspector.ExpandSiblingsButton(this); | |
| 350 this._partiallyExpanded = false; | |
| 351 }; | |
| 352 | |
| 353 WebInspector.AXNodeTreeParentElement.prototype = { | |
| 354 /** | |
| 355 * @override | |
| 356 */ | |
| 357 onattach: function(){ | |
| 358 WebInspector.AXNodeTreeElement.prototype.onattach.call(this); | |
| 359 if (this._treePane.isExpanded(this._axNode.domNode())) | |
| 360 this._listItemNode.classList.add("siblings-expanded"); | |
| 361 if (this._axNode.numChildren() > 1) | |
| 362 this._listItemNode.appendChild(this._expandSibingsButton.element); | |
| 363 }, | |
| 364 | |
| 365 /** | |
| 366 * @param {boolean} altKey | |
| 367 * @return {boolean} | |
| 368 * @override | |
| 369 */ | |
| 370 descendOrExpand: function(altKey) | |
| 371 { | |
| 372 if (!this.expanded || !this._partiallyExpanded) | |
| 373 return TreeElement.prototype.descendOrExpand.call(this, altKey); | |
| 374 | |
| 375 this.expandSiblings(); | |
| 376 if (altKey) | |
| 377 this.expandRecursively(); | |
| 378 return true; | |
| 379 }, | |
| 380 | |
| 381 /** | |
| 382 * @override | |
| 383 */ | |
| 384 expand: function() | |
| 385 { | |
| 386 TreeElement.prototype.expand.call(this); | |
| 387 this._partiallyExpanded = true; | |
| 388 }, | |
| 389 | |
| 390 expandSiblings: function() | |
| 391 { | |
| 392 this._listItemNode.classList.add("siblings-expanded"); | |
| 393 this.appendSiblings(); | |
| 394 this.expanded = true; | |
| 395 this._partiallyExpanded = false; | |
| 396 this._treePane.setExpanded(this._axNode.domNode(), true); | |
| 397 }, | |
| 398 | |
| 399 appendSiblings: function() | |
| 400 { | |
| 401 var inspectedAXNode = this._inspectedNodeTreeElement.axNode(); | |
| 402 var nextIndex = 0; | |
| 403 var foundInspectedNode = false; | |
| 404 for (var sibling of this._axNode.children()) { | |
| 405 var siblingTreeElement = null; | |
| 406 if (sibling === inspectedAXNode) { | |
| 407 foundInspectedNode = true; | |
| 408 continue; | |
| 409 } | |
| 410 siblingTreeElement = new WebInspector.AXNodeTreeElement(sibling, thi s._treePane); | |
| 411 if (foundInspectedNode) | |
| 412 this.appendChild(siblingTreeElement); | |
| 413 else | |
| 414 this.insertChild(siblingTreeElement, nextIndex++); | |
| 415 } | |
| 416 }, | |
| 417 | |
| 418 __proto__: WebInspector.AXNodeTreeElement.prototype | |
| 419 }; | |
| OLD | NEW |