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