Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js |
| index 826d4e1c20dc28d8d003e8a49293577cdeba3b05..649f4d569f791e1ff48b74c8a8a358e302e00c4a 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/accessibility/AccessibilityModel.js |
| @@ -16,7 +16,16 @@ WebInspector.AccessibilityNode = class extends WebInspector.SDKObject { |
| this._id = payload.nodeId; |
| accessibilityModel._setAXNodeForAXId(this._id, this); |
| - |
| + if (payload.backendDOMNodeId) { |
| + accessibilityModel._setAXNodeForBackendDOMNodeId(payload.backendDOMNodeId, this); |
| + this._backendDOMNodeId = payload.backendDOMNodeId; |
| + this._deferredDOMNode = |
| + new WebInspector.DeferredDOMNode(this.target(), |
| + payload.backendDOMNodeId); |
| + } else { |
| + this._backendDOMNodeId = null; |
| + this._deferredDOMNode = null; |
| + } |
| this._ignored = payload.ignored; |
| if (this._ignored && 'ignoredReasons' in payload) |
| this._ignoredReasons = payload.ignoredReasons; |
| @@ -26,9 +35,8 @@ WebInspector.AccessibilityNode = class extends WebInspector.SDKObject { |
| this._description = payload.description || null; |
| this._value = payload.value || null; |
| this._properties = payload.properties || null; |
| - this._parentId = payload.parentId || null; |
| this._childIds = payload.childIds || null; |
| - this._domNodeId = payload.domNodeId || null; |
| + this._parentNode = null; |
| } |
| /** |
| @@ -100,9 +108,94 @@ WebInspector.AccessibilityNode = class extends WebInspector.SDKObject { |
| * @return {?WebInspector.AccessibilityNode} |
| */ |
| parentNode() { |
| - if (!this._parentId) |
| - return null; |
| - return this._accessibilityModel.axNodeForId(this._parentId); |
| + return this._parentNode; |
| + } |
| + |
| + /** |
| + * @param {?WebInspector.AccessibilityNode} parentNode |
| + */ |
| + _setParentNode(parentNode) { |
| + this._parentNode = parentNode; |
| + } |
| + |
| + /** |
| + * @return {boolean} |
| + */ |
| + isDOMNode() { |
| + return !!this._backendDOMNodeId; |
| + } |
| + |
| + /** |
| + * @return {?number} |
| + */ |
| + backendDOMNodeId() { |
| + return this._backendDOMNodeId; |
| + } |
| + |
| + /** |
| + * @return WebInspector.DeferredDOMNode |
|
dgozman
2016/11/04 23:22:45
{?....}
aboxhall
2016/11/07 19:54:43
Weird presubmit didn't catch that, done.
|
| + */ |
| + deferredDOMNode() { |
| + return this._deferredDOMNode; |
| + } |
| + |
| + /** |
| + * @return {!Array<!WebInspector.AccessibilityNode>} |
| + */ |
| + children() { |
| + var children = []; |
| + if (!this._childIds) |
| + return children; |
| + |
| + for (var childId of this._childIds) { |
| + var child = this._accessibilityModel.axNodeForId(childId); |
| + if (child) |
| + children.push(child); |
| + } |
| + |
| + return children; |
| + } |
| + |
| + /** |
| + * @return {number} |
| + */ |
| + numChildren() { |
| + if (!this._childIds) |
| + return 0; |
| + return this._childIds.length; |
| + } |
| + |
| + /** |
| + * @return {boolean} |
| + */ |
| + hasOnlyUnloadedChildren() { |
| + if (!this._childIds || !this._childIds.length) |
| + return false; |
| + |
| + return !this._childIds.some((id) => this._accessibilityModel.axNodeForId(id) !== undefined); |
| + } |
| + |
| + /** |
| + * TODO(aboxhall): Remove once protocol is stable. |
| + * @param {!WebInspector.AccessibilityNode} inspectedNode |
| + * @param {string=} leadingSpace |
| + * @return {string} |
| + */ |
| + printSelfAndChildren(inspectedNode, leadingSpace) { |
| + var string = leadingSpace || ''; |
| + if (this._role) |
| + string += this._role.value; |
| + else |
| + string += '<no role>'; |
| + string += (this._name ? ' ' + this._name.value : ''); |
| + string += ' ' + this._id; |
| + if (this._domNode) |
| + string += ' (' + this._domNode.nodeName() + ')'; |
| + if (this === inspectedNode) |
| + string += ' *'; |
| + for (var child of this.children()) |
| + string += '\n' + child.printSelfAndChildren(inspectedNode, (leadingSpace || '') + ' '); |
| + return string; |
| } |
| }; |
| @@ -119,6 +212,7 @@ WebInspector.AccessibilityModel = class extends WebInspector.SDKModel { |
| /** @type {!Map<string, !WebInspector.AccessibilityNode>} */ |
| this._axIdToAXNode = new Map(); |
| + this._backendDOMNodeIdToAXNode = new Map(); |
| } |
| /** |
| @@ -132,51 +226,85 @@ WebInspector.AccessibilityModel = class extends WebInspector.SDKModel { |
| return target[WebInspector.AccessibilityModel._symbol]; |
| } |
| - /** |
| - * @param {string} axId |
| - * @return {?WebInspector.AccessibilityNode} |
| - */ |
| - axNodeForId(axId) { |
| - return this._axIdToAXNode.get(axId); |
| - } |
| - |
| - /** |
| - * @param {string} axId |
| - * @param {!WebInspector.AccessibilityNode} axNode |
| - */ |
| - _setAXNodeForAXId(axId, axNode) { |
| - this._axIdToAXNode.set(axId, axNode); |
| + clear() { |
| + this._axIdToAXNode.clear(); |
| } |
| /** |
| * @param {!WebInspector.DOMNode} node |
| - * @return {!Promise<?Array<!WebInspector.AccessibilityNode>>} |
| + * @return {!Promise} |
| */ |
| - getAXNodeChain(node) { |
| - this._axIdToAXNode.clear(); |
| - |
| + requestPartialAXTree(node) { |
| /** |
| * @this {WebInspector.AccessibilityModel} |
| * @param {?string} error |
| * @param {!Array<!Protocol.Accessibility.AXNode>=} payloads |
| - * @return {?Array<!WebInspector.AccessibilityNode>} |
| */ |
| function parsePayload(error, payloads) { |
| if (error) { |
| - console.error('Protocol.Accessibility.getAXNodeChain(): ' + error); |
| + console.error('AccessibilityAgent.getAXNodeChain(): ' + error); |
| return null; |
| } |
| if (!payloads) |
| - return null; |
| + return; |
| - var nodes = []; |
| for (var payload of payloads) |
| - nodes.push(new WebInspector.AccessibilityNode(this, payload)); |
| + new WebInspector.AccessibilityNode(this, payload); |
| - return nodes; |
| + for (var axNode of this._axIdToAXNode.values()) { |
| + for (var axChild of axNode.children()) { |
| + axChild._setParentNode(axNode); |
| + } |
| + } |
| } |
| - return this._agent.getAXNodeChain(node.id, true, parsePayload.bind(this)); |
| + return this._agent.getPartialAXTree(node.id, true, parsePayload.bind(this)); |
| + } |
| + |
| + /** |
| + * @param {string} axId |
| + * @return {?WebInspector.AccessibilityNode} |
| + */ |
| + axNodeForId(axId) { |
| + return this._axIdToAXNode.get(axId); |
| + } |
| + |
| + /** |
| + * @param {string} axId |
| + * @param {!WebInspector.AccessibilityNode} axNode |
| + */ |
| + _setAXNodeForAXId(axId, axNode) { |
| + this._axIdToAXNode.set(axId, axNode); |
| + } |
| + |
| + /** |
| + * @param {?WebInspector.DOMNode} domNode |
| + * @return {?WebInspector.AccessibilityNode} |
| + */ |
| + axNodeForDOMNode(domNode) { |
| + if (!domNode) |
| + return null; |
| + return this._backendDOMNodeIdToAXNode.get(domNode.backendNodeId()); |
| + } |
| + |
| + /** |
| + * @param {number} backendDOMNodeId |
| + * @param {!WebInspector.AccessibilityNode} axNode |
| + */ |
| + _setAXNodeForBackendDOMNodeId(backendDOMNodeId, axNode) { |
| + this._backendDOMNodeIdToAXNode.set(backendDOMNodeId, |
| + axNode); |
| + } |
| + |
| + // TODO(aboxhall): Remove once protocol is stable. |
| + /** |
| + * @param {!WebInspector.DOMNode} inspectedNode |
| + */ |
| + logTree(inspectedNode) { |
| + var rootNode = inspectedNode; |
| + while (rootNode.parentNode()) |
| + rootNode = rootNode.parentNode(); |
| + console.log(rootNode.printSelfAndChildren(inspectedNode)); |
| } |
| }; |