Index: chrome/renderer/resources/extensions/automation/automation_node.js |
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js |
index fb851690585913880b3ba70de3c1a2f1ea4dbd09..85d2e4047fd52a64ebb1fef75eafae3140983041 100644 |
--- a/chrome/renderer/resources/extensions/automation/automation_node.js |
+++ b/chrome/renderer/resources/extensions/automation/automation_node.js |
@@ -14,6 +14,14 @@ var schema = requireNative('automationInternal').GetSchemaAdditions(); |
var utils = require('utils'); |
/** |
+ * Maps an id in the form: |
+ * <process_id>_<routing_id> |
+ * to an AutomationNode with role type webArea. |
+ * @type {!Object.<string, string>} |
+ */ |
+var idToWebArea_ = {}; |
+ |
+/** |
* A single node in the Automation tree. |
* @param {AutomationRootNodeImpl} root The root of the tree. |
* @constructor |
@@ -34,24 +42,29 @@ AutomationNodeImpl.prototype = { |
role: '', |
state: { busy: true }, |
isRootNode: false, |
+ loaded: false, |
get root() { |
return this.rootImpl.wrapper; |
}, |
parent: function() { |
+ if (this.role == schema.RoleType.rootWebArea) { |
+ var parentId = this.processID + '_' + this.routingID; |
+ if (idToWebArea_[parentId]) |
+ return idToWebArea_[parentId]; |
+ } |
return this.rootImpl.get(this.parentID); |
}, |
firstChild: function() { |
- var node = this.rootImpl.get(this.childIds[0]); |
- return node; |
+ return this.lookupWebAreaChild_() || this.rootImpl.get(this.childIds[0]); |
}, |
lastChild: function() { |
var childIds = this.childIds; |
- var node = this.rootImpl.get(childIds[childIds.length - 1]); |
- return node; |
+ return this.lookupWebAreaChild_() || |
+ this.rootImpl.get(childIds[childIds.length - 1]); |
}, |
children: function() { |
@@ -113,6 +126,19 @@ AutomationNodeImpl.prototype = { |
} |
}, |
+ load: function(callback) { |
+ if (this.role != schema.RoleType.webArea) |
+ throw 'Unsupported state: can only load webArea nodes.'; |
+ |
+ if (!this.loaded) |
+ automationInternal.enableRenderer(this.processID, this.routingID); |
+ |
+ automationUtil.onTreeLoaded(this.processID, this.routingID, function(root) { |
+ if (callback) |
+ callback(root); |
+ }.bind(this)); |
+ }, |
+ |
dispatchEvent: function(eventType) { |
var path = []; |
var parent = this.parent(); |
@@ -144,6 +170,14 @@ AutomationNodeImpl.prototype = { |
' attributes=' + $JSON.stringify(this.attributes); |
}, |
+ lookupWebAreaChild_: function() { |
+ if (this.role != schema.RoleType.webArea) |
+ return null; |
+ |
+ return automationUtil.idToAutomationRootNode[ |
+ automationUtil.createAutomationRootNodeID(this.processID, this.routingID)]; |
+ }, |
+ |
dispatchEventAtCapturing_: function(event, path) { |
privates(event).impl.eventPhase = Event.CAPTURING_PHASE; |
for (var i = path.length - 1; i >= 0; i--) { |
@@ -353,6 +387,9 @@ AutomationRootNodeImpl.prototype = { |
destroy: function() { |
this.dispatchEvent(schema.EventType.destroyed); |
this.invalidate_(this.wrapper); |
+ idToWebArea_[this.processID + |
+ '_' + |
+ this.routingID] = undefined; |
}, |
onAccessibilityEvent: function(eventParams) { |
@@ -406,19 +443,10 @@ AutomationRootNodeImpl.prototype = { |
nodeImpl[key] = AutomationAttributeDefaults[key]; |
} |
nodeImpl.childIds = []; |
- nodeImpl.loaded = false; |
nodeImpl.id = id; |
delete this.axNodeDataCache_[id]; |
}, |
- load: function(callback) { |
- // TODO(dtseng/aboxhall): Implement. |
- if (!this.loaded) |
- throw 'Unsupported state: root node is not loaded.'; |
- |
- setTimeout(callback, 0); |
- }, |
- |
deleteOldChildren_: function(node, newChildIds) { |
// Create a set of child ids in |src| for fast lookup, and return false |
// if a duplicate is found; |
@@ -495,6 +523,16 @@ AutomationRootNodeImpl.prototype = { |
setData_: function(node, nodeData) { |
var nodeImpl = privates(node).impl; |
+ |
+ if (nodeData.role == schema.RoleType.webArea) { |
+ nodeImpl.processID = nodeData.intAttributes.processId; |
+ nodeImpl.routingID = nodeData.intAttributes.routingId; |
+ idToWebArea_[nodeImpl.processID + |
+ '_' + |
+ nodeImpl.routingID] = node; |
+ delete nodeData.intAttributes['processId']; |
+ delete nodeData.intAttributes['routingId']; |
+ } |
for (var key in AutomationAttributeDefaults) { |
if (key in nodeData) |
nodeImpl[key] = nodeData[key]; |
@@ -599,19 +637,20 @@ var AutomationNode = utils.expose('AutomationNode', |
'makeVisible', |
'setSelection', |
'addEventListener', |
- 'removeEventListener'], |
+ 'removeEventListener', |
+ 'load'], |
readonly: ['isRootNode', |
'role', |
'state', |
'location', |
'attributes', |
+ 'loaded', |
'root'] }); |
var AutomationRootNode = utils.expose('AutomationRootNode', |
AutomationRootNodeImpl, |
{ superclass: AutomationNode, |
- functions: ['load'], |
- readonly: ['loaded'] }); |
+ functions: ['load'] }); |
exports.AutomationNode = AutomationNode; |
exports.AutomationRootNode = AutomationRootNode; |