| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 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 var Event = require('event_bindings').Event; | 5 var Event = require('event_bindings').Event; |
| 6 var AutomationNode = require('automationNode').AutomationNode; | 6 var AutomationNode = require('automationNode').AutomationNode; |
| 7 | 7 |
| 8 // Maps an attribute to its default value in an invalidated node. | 8 // Maps an attribute to its default value in an invalidated node. |
| 9 // These attributes are taken directly from the Automation idl. | 9 // These attributes are taken directly from the Automation idl. |
| 10 var AutomationAttributeDefaults = { | 10 var AutomationAttributeDefaults = { |
| 11 'id': -1, | 11 'id': -1, |
| 12 'role': '', | 12 'role': '', |
| 13 'state': {} | 13 'state': {} |
| 14 }; | 14 }; |
| 15 | 15 |
| 16 | 16 |
| 17 var AutomationAttributeTypes = [ | 17 var AutomationAttributeTypes = [ |
| 18 'bool_attributes', | 18 'boolAttributes', |
| 19 'float_attributes', | 19 'floatAttributes', |
| 20 'html_attributes', | 20 'htmlAttributes', |
| 21 'int_attributes', | 21 'intAttributes', |
| 22 'intlist_attributes', | 22 'intlistAttributes', |
| 23 'string_attributes' | 23 'stringAttributes' |
| 24 ]; | 24 ]; |
| 25 | 25 |
| 26 | 26 |
| 27 /** | 27 /** |
| 28 * AutomationTree. | 28 * AutomationTree. |
| 29 * | 29 * |
| 30 * An AutomationTree is the javascript end of an AXTree living in the browser. | 30 * An AutomationTree is the javascript end of an AXTree living in the browser. |
| 31 * AutomationTree handles unserializing incremental updates from the source | 31 * AutomationTree handles unserializing incremental updates from the source |
| 32 * AXTree. Each update contains node data that form a complete tree after | 32 * AXTree. Each update contains node data that form a complete tree after |
| 33 * applying the update. | 33 * applying the update. |
| 34 * | 34 * |
| 35 * A brief note about ids used through this class. The source AXTree assigns | 35 * A brief note about ids used through this class. The source AXTree assigns |
| 36 * unique ids per node and we use these ids to build a hash to the actual | 36 * unique ids per node and we use these ids to build a hash to the actual |
| 37 * AutomationNode object. | 37 * AutomationNode object. |
| 38 * Thus, tree traversals amount to a lookup in our hash. | 38 * Thus, tree traversals amount to a lookup in our hash. |
| 39 * | 39 * |
| 40 * The tree itself is identified by the process id and routing id of the |
| 41 * renderer widget host. |
| 40 * @constructor | 42 * @constructor |
| 41 */ | 43 */ |
| 42 var AutomationTree = function(routingId) { | 44 var AutomationTree = function(processID, routingID) { |
| 43 privates(this).impl = new AutomationTreeImpl(routingId); | 45 privates(this).impl = new AutomationTreeImpl(processID, routingID); |
| 44 | |
| 45 /** | |
| 46 * Event fired when a tree update occurs. | |
| 47 * @deprecated TODO(aboxhall/dtseng): remove this event; it should not be | |
| 48 * exposed in the public API. Replace with EventListener style API which | |
| 49 * allows listening for events in the AXEvent enum. | |
| 50 */ | |
| 51 this.onUpdate = new Event(); | |
| 52 }; | 46 }; |
| 53 | 47 |
| 54 | 48 |
| 55 AutomationTree.prototype = { | 49 AutomationTree.prototype = { |
| 56 /** | 50 /** |
| 57 * The root of this automation tree. | 51 * The root of this automation tree. |
| 58 * @type {Object} | 52 * @type {Object} |
| 59 */ | 53 */ |
| 60 get root() { | 54 get root() { |
| 61 return privates(this).impl.root; | 55 return privates(this).impl.root; |
| 62 } | 56 } |
| 63 }; | 57 }; |
| 64 | 58 |
| 65 | 59 |
| 66 var AutomationTreeImpl = function(routingId) { | 60 var AutomationTreeImpl = function(processID, routingID) { |
| 67 this.routingId = routingId; | 61 this.processID = processID; |
| 62 this.routingID = routingID; |
| 68 | 63 |
| 69 /** | 64 /** |
| 70 * Our cache of the native AXTree. | 65 * Our cache of the native AXTree. |
| 71 * @type {!Object.<number, Object>} | 66 * @type {!Object.<number, Object>} |
| 72 * @private | 67 * @private |
| 73 */ | 68 */ |
| 74 this.axNodeDataCache_ = {}; | 69 this.axNodeDataCache_ = {}; |
| 75 }; | 70 }; |
| 76 | 71 |
| 77 AutomationTreeImpl.prototype = { | 72 AutomationTreeImpl.prototype = { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 return false; | 115 return false; |
| 121 | 116 |
| 122 for (var i = 0; i < data.nodes.length; i++) { | 117 for (var i = 0; i < data.nodes.length; i++) { |
| 123 var nodeData = data.nodes[i]; | 118 var nodeData = data.nodes[i]; |
| 124 var node = this.axNodeDataCache_[nodeData.id]; | 119 var node = this.axNodeDataCache_[nodeData.id]; |
| 125 if (!node) { | 120 if (!node) { |
| 126 node = new AutomationNode(this); | 121 node = new AutomationNode(this); |
| 127 } | 122 } |
| 128 | 123 |
| 129 // Update children. | 124 // Update children. |
| 130 var old_child_ids = privates(node).impl.child_ids; | 125 var oldChildIDs = privates(node).impl.childIDs; |
| 131 var new_child_ids = nodeData.child_ids || []; | 126 var newChildIDs = nodeData.childIDs || []; |
| 132 var new_child_ids_hash = {}; | 127 var newChildIDsHash = {}; |
| 133 | 128 |
| 134 for (var j = 0, newId; newId = new_child_ids[j]; j++) { | 129 for (var j = 0, newId; newId = newChildIDs[j]; j++) { |
| 135 // Hash the new child ids for faster lookup. | 130 // Hash the new child ids for faster lookup. |
| 136 new_child_ids_hash[newId] = newId; | 131 newChildIDsHash[newId] = newId; |
| 137 | 132 |
| 138 // We need to update all new children's parent_id regardless. | 133 // We need to update all new children's parent id regardless. |
| 139 var childNode = this.get(newId); | 134 var childNode = this.get(newId); |
| 140 if (!childNode) { | 135 if (!childNode) { |
| 141 childNode = new AutomationNode(this); | 136 childNode = new AutomationNode(this); |
| 142 this.axNodeDataCache_[newId] = childNode; | 137 this.axNodeDataCache_[newId] = childNode; |
| 143 childNode.id = newId; | 138 childNode.id = newId; |
| 144 } | 139 } |
| 145 privates(childNode).impl.index_in_parent = j; | 140 privates(childNode).impl.indexInParent = j; |
| 146 privates(childNode).impl.parent_id = nodeData.id; | 141 privates(childNode).impl.parentID = nodeData.id; |
| 147 } | 142 } |
| 148 | 143 |
| 149 for (var k = 0, oldId; oldId = old_child_ids[k]; k++) { | 144 for (var k = 0, oldId; oldId = oldChildIDs[k]; k++) { |
| 150 // However, we must invalidate all old child ids that are no longer | 145 // However, we must invalidate all old child ids that are no longer |
| 151 // children. | 146 // children. |
| 152 if (!new_child_ids_hash[oldId]) { | 147 if (!newChildIDsHash[oldId]) { |
| 153 this.invalidate(this.get(oldId)); | 148 this.invalidate(this.get(oldId)); |
| 154 } | 149 } |
| 155 } | 150 } |
| 156 | 151 |
| 157 if (nodeData.role == 'root_web_area') { | 152 if (nodeData.role == 'root_web_area') { |
| 158 this.root = node; | 153 this.root = node; |
| 159 didUpdateRoot = true; | 154 didUpdateRoot = true; |
| 160 } | 155 } |
| 161 for (var key in AutomationAttributeDefaults) { | 156 for (var key in AutomationAttributeDefaults) { |
| 162 // This assumes that we sometimes don't get specific attributes (i.e. in | 157 // This assumes that we sometimes don't get specific attributes (i.e. in |
| 163 // tests). Better safe than sorry. | 158 // tests). Better safe than sorry. |
| 164 if (nodeData[key]) { | 159 if (nodeData[key]) { |
| 165 node[key] = nodeData[key]; | 160 node[key] = nodeData[key]; |
| 166 } else { | 161 } else { |
| 167 node[key] = AutomationAttributeDefaults[key]; | 162 node[key] = AutomationAttributeDefaults[key]; |
| 168 } | 163 } |
| 169 } | 164 } |
| 170 node.attributes = {}; | 165 node.attributes = {}; |
| 171 for (var attributeTypeIndex = 0; | 166 for (var attributeTypeIndex = 0; |
| 172 attributeTypeIndex < AutomationAttributeTypes.length; | 167 attributeTypeIndex < AutomationAttributeTypes.length; |
| 173 attributeTypeIndex++) { | 168 attributeTypeIndex++) { |
| 174 var attribute_type = AutomationAttributeTypes[attributeTypeIndex]; | 169 var attributeType = AutomationAttributeTypes[attributeTypeIndex]; |
| 175 for (var attribute_id in nodeData[attribute_type]) { | 170 for (var attributeID in nodeData[attributeType]) { |
| 176 node.attributes[attribute_id] = | 171 node.attributes[attributeID] = |
| 177 nodeData[attribute_type][attribute_id]; | 172 nodeData[attributeType][attributeID]; |
| 178 } | 173 } |
| 179 } | 174 } |
| 180 privates(node).impl.child_ids = new_child_ids; | 175 privates(node).impl.childIDs = newChildIDs; |
| 181 this.axNodeDataCache_[node.id] = node; | 176 this.axNodeDataCache_[node.id] = node; |
| 177 privates(node).impl.notifyEventListeners(data.eventType); |
| 182 } | 178 } |
| 183 return true; | 179 return true; |
| 184 } | 180 } |
| 185 }; | 181 }; |
| 186 | 182 |
| 187 | 183 |
| 188 exports.AutomationTree = AutomationTree; | 184 exports.AutomationTree = AutomationTree; |
| OLD | NEW |