Home | History | Annotate | Download | only in extensions
      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 <webview> contextMenus API.
      6 // Note that this file mimics custom bindings for chrome.contextMenus API
      7 // which resides in context_menus_custom_bindings.js. The functions in this file
      8 // have an extra instanceId parameter in the beginning, which corresponds to the
      9 // id of the <webview>.
     10 //
     11 // TODO(lazyboy): Share common code /w context_menus_custom_bindings.js.
     12 
     13 var EventBindings = require('event_bindings');
     14 var binding = require('binding').Binding.create('webview');
     15 var contextMenuNatives = requireNative('context_menus');
     16 var sendRequest = require('sendRequest').sendRequest;
     17 
     18 binding.registerCustomHook(function(bindingsAPI) {
     19   var apiFunctions = bindingsAPI.apiFunctions;
     20 
     21   var webviewContextMenus = {};
     22   webviewContextMenus.generatedIdHandlers = {};
     23   webviewContextMenus.stringIdHandlers = {};
     24 
     25   // Per item event handler.
     26   var ename = 'webview.contextMenus';
     27   webviewContextMenus.event = new EventBindings.Event(ename);
     28 
     29   webviewContextMenus.getIdFromCreateProperties = function(prop) {
     30     if (typeof(prop.id) !== 'undefined')
     31       return prop.id;
     32     return prop.generatedId;
     33   };
     34 
     35   webviewContextMenus.handlersForId = function(instanceId, id) {
     36     if (typeof(id) === 'number') {
     37       if (!webviewContextMenus.generatedIdHandlers[instanceId]) {
     38         webviewContextMenus.generatedIdHandlers[instanceId] = {};
     39       }
     40       return webviewContextMenus.generatedIdHandlers[instanceId];
     41     }
     42 
     43     if (!webviewContextMenus.stringIdHandlers[instanceId]) {
     44       webviewContextMenus.stringIdHandlers[instanceId] = {};
     45     }
     46     return webviewContextMenus.stringIdHandlers[instanceId];
     47   };
     48 
     49   webviewContextMenus.ensureListenerSetup = function() {
     50     if (webviewContextMenus.listening) {
     51       return;
     52     }
     53     webviewContextMenus.listening = true;
     54     webviewContextMenus.event.addListener(function() {
     55       // An extension context menu item has been clicked on - fire the onclick
     56       // if there is one.
     57       var id = arguments[0].menuItemId;
     58       var instanceId = arguments[0].webviewInstanceId;
     59       delete arguments[0].webviewInstanceId;
     60       var onclick = webviewContextMenus.handlersForId(instanceId, id)[id];
     61       if (onclick) {
     62         $Function.apply(onclick, null, arguments);
     63       }
     64     });
     65   };
     66 
     67   apiFunctions.setHandleRequest('contextMenusCreate', function() {
     68     var args = arguments;
     69     var id = contextMenuNatives.GetNextContextMenuId();
     70     args[1].generatedId = id;
     71 
     72     var optArgs = {
     73       customCallback: this.customCallback,
     74     };
     75 
     76     sendRequest(this.name, args, this.definition.parameters, optArgs);
     77     return webviewContextMenus.getIdFromCreateProperties(args[1]);
     78   });
     79 
     80   apiFunctions.setCustomCallback('contextMenusCreate',
     81                                  function(name, request, response) {
     82     if (chrome.runtime.lastError) {
     83       return;
     84     }
     85 
     86     var instanceId = request.args[0];
     87     var id = webviewContextMenus.getIdFromCreateProperties(request.args[1]);
     88     var onclick = request.args.length ? request.args[1].onclick : null;
     89     if (onclick) {
     90       webviewContextMenus.ensureListenerSetup();
     91       webviewContextMenus.handlersForId(instanceId, id)[id] = onclick;
     92     }
     93   });
     94 
     95   apiFunctions.setCustomCallback('contextMenusUpdate',
     96                                  function(name, request, response) {
     97     if (chrome.runtime.lastError) {
     98       return;
     99     }
    100     var instanceId = request.args[0];
    101     var id = request.args[1];
    102     if (request.args[2].onclick) {
    103       webviewContextMenus.handlersForId(instanceId, id)[id] =
    104           request.args[2].onclick;
    105     }
    106   });
    107 
    108   apiFunctions.setCustomCallback('contextMenusRemove',
    109                                   function(name, request, response) {
    110     if (chrome.runtime.lastError) {
    111       return;
    112     }
    113     var instanceId = request.args[0];
    114     var id = request.args[1];
    115     delete webviewContextMenus.handlersForId(instanceId, id)[id];
    116   });
    117 
    118   apiFunctions.setCustomCallback('contextMenusRemoveAll',
    119                                  function(name, request, response) {
    120     if (chrome.runtime.lastError) {
    121       return;
    122     }
    123     var instanceId = request.args[0];
    124     webviewContextMenus.stringIdHandlers[instanceId] = {};
    125     webviewContextMenus.generatedIdHandlers[instanceId] = {};
    126   });
    127 
    128 });
    129 
    130 exports.WebView = binding.generate();
    131