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