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 binding for the contextMenus API.
6
7var binding = require('binding').Binding.create('contextMenus');
8
9var contextMenuNatives = requireNative('context_menus');
10var sendRequest = require('sendRequest').sendRequest;
11var Event = require('event_bindings').Event;
12
13binding.registerCustomHook(function(bindingsAPI) {
14  var apiFunctions = bindingsAPI.apiFunctions;
15
16  var contextMenus = {};
17  contextMenus.generatedIdHandlers = {};
18  contextMenus.stringIdHandlers = {};
19  var eventName = 'contextMenus';
20  contextMenus.event = new Event(eventName);
21  contextMenus.getIdFromCreateProperties = function(prop) {
22    if (typeof(prop.id) !== 'undefined')
23      return prop.id;
24    return prop.generatedId;
25  };
26  contextMenus.handlersForId = function(id) {
27    if (typeof(id) === 'number')
28      return contextMenus.generatedIdHandlers;
29    return contextMenus.stringIdHandlers;
30  };
31  contextMenus.ensureListenerSetup = function() {
32    if (contextMenus.listening) {
33      return;
34    }
35    contextMenus.listening = true;
36    contextMenus.event.addListener(function() {
37      // An extension context menu item has been clicked on - fire the onclick
38      // if there is one.
39      var id = arguments[0].menuItemId;
40      var onclick = contextMenus.handlersForId(id)[id];
41      if (onclick) {
42        $Function.apply(onclick, null, arguments);
43      }
44    });
45  };
46
47  apiFunctions.setHandleRequest('create', function() {
48    var args = arguments;
49    var id = contextMenuNatives.GetNextContextMenuId();
50    args[0].generatedId = id;
51    var optArgs = {
52      customCallback: this.customCallback,
53    };
54    sendRequest(this.name, args, this.definition.parameters, optArgs);
55    return contextMenus.getIdFromCreateProperties(args[0]);
56  });
57
58  apiFunctions.setCustomCallback('create', function(name, request, response) {
59    if (chrome.runtime.lastError) {
60      return;
61    }
62
63    var id = contextMenus.getIdFromCreateProperties(request.args[0]);
64
65    // Set up the onclick handler if we were passed one in the request.
66    var onclick = request.args.length ? request.args[0].onclick : null;
67    if (onclick) {
68      contextMenus.ensureListenerSetup();
69      contextMenus.handlersForId(id)[id] = onclick;
70    }
71  });
72
73  apiFunctions.setCustomCallback('remove', function(name, request, response) {
74    if (chrome.runtime.lastError) {
75      return;
76    }
77    var id = request.args[0];
78    delete contextMenus.handlersForId(id)[id];
79  });
80
81  apiFunctions.setCustomCallback('update', function(name, request, response) {
82    if (chrome.runtime.lastError) {
83      return;
84    }
85    var id = request.args[0];
86    if (request.args[1].onclick) {
87      contextMenus.handlersForId(id)[id] = request.args[1].onclick;
88    }
89  });
90
91  apiFunctions.setCustomCallback('removeAll',
92                                 function(name, request, response) {
93    if (chrome.runtime.lastError) {
94      return;
95    }
96    contextMenus.generatedIdHandlers = {};
97    contextMenus.stringIdHandlers = {};
98  });
99});
100
101exports.binding = binding.generate();
102