Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / resources / extensions / automation_custom_bindings.js
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
3 // found in the LICENSE file.
4
5 // Custom bindings for the automation API.
6 var automation = require('binding').Binding.create('automation');
7 var automationInternal =
8     require('binding').Binding.create('automationInternal').generate();
9 var eventBindings = require('event_bindings');
10 var Event = eventBindings.Event;
11 var AutomationNode = require('automationNode').AutomationNode;
12 var AutomationTree = require('automationTree').AutomationTree;
13
14 // TODO(aboxhall): Look into using WeakMap
15 var routingIdToAutomationTree = {};
16 var routingIdToCallback = {};
17
18 automation.registerCustomHook(function(bindingsAPI) {
19   var apiFunctions = bindingsAPI.apiFunctions;
20
21   apiFunctions.setHandleRequest('getTree', function(callback) {
22     // enableCurrentTab() ensures the renderer for the current tab has
23     // accessibility enabled, and fetches its routing id to use as a key in the
24     // routingIdToAutomationTree map. The callback to enableCurrentTab is bound
25     // to the callback passed in to getTree(), so that once the tree is
26     // available (either due to having been cached earlier, or after an
27     // accessibility event occurs which causes the tree to be populated), the
28     // callback can be called.
29     automationInternal.enableCurrentTab(function(rid) {
30       var targetTree = routingIdToAutomationTree[rid];
31       if (!targetTree) {
32         // If we haven't cached the tree, hold the callback until the tree is
33         // populated by the initial onAccessibilityEvent call.
34         if (rid in routingIdToCallback)
35           routingIdToCallback[rid].push(callback);
36         else
37           routingIdToCallback[rid] = [callback];
38       } else {
39         callback(targetTree);
40       }
41     });
42   });
43 });
44
45 // Listen to the automationInternal.onaccessibilityEvent event, which is
46 // essentially a proxy for the AccessibilityHostMsg_Events IPC from the
47 // renderer.
48 automationInternal.onAccessibilityEvent.addListener(function(data) {
49   var rid = data.routing_id;
50   var targetTree = routingIdToAutomationTree[rid];
51   if (!targetTree) {
52     // If this is the first time we've gotten data for this tree, it will
53     // contain all of the tree's data, so create a new tree which will be
54     // bootstrapped from |data|.
55     targetTree = new AutomationTree(rid);
56     routingIdToAutomationTree[rid] = targetTree;
57   }
58   if (privates(targetTree).impl.update(data)) {
59     // TODO(aboxhall/dtseng): remove and replace with EventListener style API
60     targetTree.onUpdate.dispatch();
61   }
62
63   // TODO(aboxhall/dtseng): call appropriate event listeners based on
64   // data.event_type.
65
66   // If the tree wasn't available when getTree() was called, the callback will
67   // have been cached in routingIdToCallback, so call and delete it now that we
68   // have the tree.
69   if (rid in routingIdToCallback) {
70     for (var i = 0; i < routingIdToCallback[rid].length; i++) {
71       var callback = routingIdToCallback[rid][i];
72       callback(targetTree);
73     }
74     delete routingIdToCallback[rid];
75   }
76 });
77
78 exports.binding = automation.generate();