| OLD | NEW |
| 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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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._domNodeId; |
| 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._domNodeId) |
| 152 return Promise.resolve(/** @type {?WebInspector.DOMNode} */ (null)); |
| 153 |
| 154 var deferredNode = new WebInspector.DeferredDOMNode(this.target(), this.
_domNodeId); |
| 155 return deferredNode.resolvePromise() |
| 156 .then((domNode) => { |
| 157 this._setDOMNode(domNode); |
| 158 return domNode; |
| 159 }); |
| 160 }, |
| 161 |
| 162 /** |
| 163 * @return {?number} |
| 164 */ |
| 165 domNodeId: function() |
| 166 { |
| 167 return this._domNodeId || null; |
| 168 }, |
| 169 |
| 170 /** |
| 171 * @return {!Array<!WebInspector.AccessibilityNode>} |
| 172 */ |
| 173 children: function() |
| 174 { |
| 175 var children = []; |
| 176 if (!this._childIds) |
| 177 return children; |
| 178 |
| 179 for (var childId of this._childIds) { |
| 180 var child = this._accessibilityModel.axNodeForId(childId); |
| 181 if (child) |
| 182 children.push(child); |
| 183 } |
| 184 |
| 185 return children; |
| 186 }, |
| 187 |
| 188 /** |
| 189 * @return {number} |
| 190 */ |
| 191 numChildren: function() |
| 192 { |
| 193 if (!this._childIds) |
| 194 return 0; |
| 195 return this._childIds.length; |
| 196 }, |
| 197 |
| 198 /** |
| 199 * @return {boolean} |
| 200 */ |
| 201 hasOnlyUnloadedChildren: function() |
| 202 { |
| 203 if (!this._childIds || !this._childIds.length) |
| 204 return false; |
| 205 |
| 206 return !this._childIds.some((id) => this._accessibilityModel.axNodeForId
(id) !== undefined); |
| 207 }, |
| 208 |
| 209 /** |
| 210 * TODO(aboxhall): Remove once protocol is stable. |
| 211 * @param {!WebInspector.AccessibilityNode} inspectedNode |
| 212 * @param {string=} leadingSpace |
| 213 * @return {string} |
| 214 */ |
| 215 printSelfAndChildren: function(inspectedNode, leadingSpace) |
| 216 { |
| 217 var string = leadingSpace || ""; |
| 218 if (this._role) |
| 219 string += this._role.value; |
| 220 else |
| 221 string += "<no role>"; |
| 222 string += (this._name ? " " + this._name.value : ""); |
| 223 string += " " + this._id; |
| 224 if (this._domNode) |
| 225 string += " (" + this._domNode.nodeName() + ")"; |
| 226 if (this === inspectedNode) |
| 227 string += " *"; |
| 228 for (var child of this.children()) |
| 229 string += "\n" + child.printSelfAndChildren(inspectedNode, (leadingS
pace || "") + " "); |
| 230 return string; |
| 231 }, |
| 232 |
| 118 __proto__: WebInspector.SDKObject.prototype | 233 __proto__: WebInspector.SDKObject.prototype |
| 119 }; | 234 }; |
| 120 | 235 |
| 121 /** | 236 /** |
| 122 * @constructor | 237 * @constructor |
| 123 * @extends {WebInspector.SDKModel} | 238 * @extends {WebInspector.SDKModel} |
| 124 * @param {!WebInspector.Target} target | 239 * @param {!WebInspector.Target} target |
| 125 */ | 240 */ |
| 126 WebInspector.AccessibilityModel = function(target) | 241 WebInspector.AccessibilityModel = function(target) |
| 127 { | 242 { |
| 128 WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target); | 243 WebInspector.SDKModel.call(this, WebInspector.AccessibilityModel, target); |
| 129 this._agent = target.accessibilityAgent(); | 244 this._agent = target.accessibilityAgent(); |
| 130 | 245 |
| 131 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */ | 246 /** @type {!Map<string, !WebInspector.AccessibilityNode>} */ |
| 132 this._axIdToAXNode = new Map(); | 247 this._axIdToAXNode = new Map(); |
| 248 this._domNodeToAXNode = new Map(); |
| 133 }; | 249 }; |
| 134 | 250 |
| 135 WebInspector.AccessibilityModel.prototype = { | 251 WebInspector.AccessibilityModel.prototype = { |
| 252 /** |
| 253 * @param {!WebInspector.DOMNode} node |
| 254 * @return {!Promise<?WebInspector.AccessibilityNode>} |
| 255 */ |
| 256 setDOMNode: function(node) |
| 257 { |
| 258 this._axIdToAXNode.clear(); |
| 259 this._inspectedDOMNode = node; |
| 136 | 260 |
| 137 /** | 261 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 }, | 262 }, |
| 154 | 263 |
| 155 /** | 264 /** |
| 156 * @param {!WebInspector.DOMNode} node | 265 * @param {!WebInspector.DOMNode} node |
| 157 * @return {!Promise<?Array<!WebInspector.AccessibilityNode>>} | 266 * @return {!Promise} |
| 158 */ | 267 */ |
| 159 getAXNodeChain: function(node) | 268 _requestPartialAXTree: function(node) |
| 160 { | 269 { |
| 161 this._axIdToAXNode.clear(); | |
| 162 | |
| 163 /** | 270 /** |
| 164 * @this {WebInspector.AccessibilityModel} | 271 * @this {WebInspector.AccessibilityModel} |
| 165 * @param {?string} error | 272 * @param {?string} error |
| 166 * @param {!Array<!AccessibilityAgent.AXNode>=} payloads | 273 * @param {!Array<!AccessibilityAgent.AXNode>=} payloads |
| 167 * @return {?Array<!WebInspector.AccessibilityNode>} | |
| 168 */ | 274 */ |
| 169 function parsePayload(error, payloads) | 275 function parsePayload(error, payloads) |
| 170 { | 276 { |
| 171 if (error) { | 277 if (error) { |
| 172 console.error("AccessibilityAgent.getAXNodeChain(): " + error); | 278 console.error("AccessibilityAgent.getAXNodeChain(): " + error); |
| 173 return null; | 279 return null; |
| 174 } | 280 } |
| 175 | 281 |
| 176 if (!payloads) | 282 if (!payloads) |
| 177 return null; | 283 return; |
| 178 | 284 |
| 179 var nodes = []; | |
| 180 for (var payload of payloads) | 285 for (var payload of payloads) |
| 181 nodes.push(new WebInspector.AccessibilityNode(this, payload)); | 286 new WebInspector.AccessibilityNode(this, payload); |
| 287 } |
| 288 return this._agent.getPartialAXTree(node.id, parsePayload.bind(this)); |
| 289 }, |
| 182 | 290 |
| 183 return nodes; | 291 /** |
| 184 } | 292 * @return {?WebInspector.AccessibilityNode} |
| 185 return this._agent.getAXNodeChain(node.id, true, parsePayload.bind(this)
); | 293 */ |
| 294 getInspectedAXNode: function() |
| 295 { |
| 296 return this._domNodeToAXNode.get(this._inspectedDOMNode); |
| 297 }, |
| 298 |
| 299 /** |
| 300 * @param {string} axId |
| 301 * @return {?WebInspector.AccessibilityNode} |
| 302 */ |
| 303 axNodeForId: function(axId) |
| 304 { |
| 305 return this._axIdToAXNode.get(axId); |
| 306 }, |
| 307 |
| 308 /** |
| 309 * @param {string} axId |
| 310 * @param {!WebInspector.AccessibilityNode} axNode |
| 311 */ |
| 312 _setAXNodeForAXId: function(axId, axNode) |
| 313 { |
| 314 this._axIdToAXNode.set(axId, axNode); |
| 315 }, |
| 316 |
| 317 /** |
| 318 * @param {!WebInspector.DOMNode} domNode |
| 319 * @return {?WebInspector.AccessibilityNode} |
| 320 */ |
| 321 axNodeForDOMNode: function(domNode) |
| 322 { |
| 323 return this._domNodeToAXNode.get(domNode); |
| 324 }, |
| 325 |
| 326 /** |
| 327 * @param {!WebInspector.DOMNode} domNode |
| 328 * @param {!WebInspector.AccessibilityNode} axNode |
| 329 */ |
| 330 setAXNodeForDOMNode: function(domNode, axNode) |
| 331 { |
| 332 this._domNodeToAXNode.set(domNode, axNode); |
| 333 }, |
| 334 |
| 335 // TODO(aboxhall): Remove once protocol is stable. |
| 336 logTree: function() |
| 337 { |
| 338 var inspectedNode = this._domNodeToAXNode.get(this._inspectedDOMNode); |
| 339 if (!inspectedNode) |
| 340 return; |
| 341 var rootNode = inspectedNode; |
| 342 while (rootNode.parentNode()) |
| 343 rootNode = rootNode.parentNode(); |
| 344 console.log(rootNode.printSelfAndChildren(inspectedNode)); |
| 345 }, |
| 346 |
| 347 /** |
| 348 * @return {!Promise} |
| 349 */ |
| 350 resolveAllDOMNodes: function() |
| 351 { |
| 352 var promises = []; |
| 353 for (var axNode of this._axIdToAXNode.values()) |
| 354 promises.push(axNode.resolveDOMNode()); |
| 355 return Promise.all(promises); |
| 186 }, | 356 }, |
| 187 | 357 |
| 188 __proto__: WebInspector.SDKModel.prototype | 358 __proto__: WebInspector.SDKModel.prototype |
| 189 }; | 359 } |
| 190 | 360 |
| 191 WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel"); | 361 WebInspector.AccessibilityModel._symbol = Symbol("AccessibilityModel"); |
| 192 /** | 362 /** |
| 193 * @param {!WebInspector.Target} target | 363 * @param {!WebInspector.Target} target |
| 194 * @return {!WebInspector.AccessibilityModel} | 364 * @return {!WebInspector.AccessibilityModel} |
| 195 */ | 365 */ |
| 196 WebInspector.AccessibilityModel.fromTarget = function(target) | 366 WebInspector.AccessibilityModel.fromTarget = function(target) |
| 197 { | 367 { |
| 198 if (!target[WebInspector.AccessibilityModel._symbol]) | 368 if (!target[WebInspector.AccessibilityModel._symbol]) |
| 199 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Acces
sibilityModel(target); | 369 target[WebInspector.AccessibilityModel._symbol] = new WebInspector.Acces
sibilityModel(target); |
| 200 | 370 |
| 201 return target[WebInspector.AccessibilityModel._symbol]; | 371 return target[WebInspector.AccessibilityModel._symbol]; |
| 202 } | 372 } |
| OLD | NEW |