diff --git a/atom/browser/api/lib/web-contents.js b/atom/browser/api/lib/web-contents.js index 7cd54bfddfb..9486378264b 100644 --- a/atom/browser/api/lib/web-contents.js +++ b/atom/browser/api/lib/web-contents.js @@ -12,9 +12,6 @@ const debuggerBinding = process.atomBinding('debugger'); let slice = [].slice; let nextId = 0; -// Map of requestId and response callback. -let responseCallback = {}; - let getNextId = function() { return ++nextId; }; @@ -108,13 +105,11 @@ let wrapWebContents = function(webContents) { }; } - const asyncWebFrameMethods = function(requestId, method, ...args) { + const asyncWebFrameMethods = function(requestId, method, callback, ...args) { this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args); - ipcMain.once('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE_' + requestId, function(event, result) { - if (responseCallback[requestId]) { - responseCallback[requestId](result); - delete responseCallback[requestId]; - } + ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function(event, result) { + if (callback) + callback(result); }); }; @@ -126,12 +121,10 @@ let wrapWebContents = function(webContents) { callback = hasUserGesture; hasUserGesture = false; } - if (callback != null) - responseCallback[requestId] = callback; if (this.getURL() && !this.isLoading()) - return asyncWebFrameMethods.call(this, requestId, "executeJavaScript", code, hasUserGesture); + return asyncWebFrameMethods.call(this, requestId, "executeJavaScript", callback, code, hasUserGesture); else - return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, "executeJavaScript", code, hasUserGesture)); + return this.once('did-finish-load', asyncWebFrameMethods.bind(this, requestId, "executeJavaScript", callback, code, hasUserGesture)); }; // Dispatch IPC messages to the ipc module. diff --git a/atom/browser/lib/rpc-server.js b/atom/browser/lib/rpc-server.js index 20ee8fbdeae..a31c6e146e8 100644 --- a/atom/browser/lib/rpc-server.js +++ b/atom/browser/lib/rpc-server.js @@ -354,11 +354,17 @@ ipcMain.on('ATOM_BROWSER_GUEST_WEB_CONTENTS', function(event, guestInstanceId) { } }); -ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function(event, guestInstanceId, method, ...args) { +ipcMain.on('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', function(event, requestId, guestInstanceId, method, ...args) { try { let guestViewManager = require('./guest-view-manager'); let guest = guestViewManager.getGuest(guestInstanceId); - return guest[method].apply(guest, args); + if (requestId) { + const responseCallback = function(result) { + event.sender.send(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, result); + }; + args.push(responseCallback); + } + guest[method].apply(guest, args); } catch (error) { return event.returnValue = exceptionToMeta(error); } diff --git a/atom/renderer/api/atom_api_web_frame.cc b/atom/renderer/api/atom_api_web_frame.cc index af9a3c41621..e00b901bfff 100644 --- a/atom/renderer/api/atom_api_web_frame.cc +++ b/atom/renderer/api/atom_api_web_frame.cc @@ -40,7 +40,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback { void completed( const blink::WebVector>& result) override { - if (!callback_.is_null()) + if (!callback_.is_null() && !result.isEmpty() && !result[0].IsEmpty()) // Right now only single results per frame is supported. callback_.Run(result[0]); delete this; diff --git a/atom/renderer/lib/init.js b/atom/renderer/lib/init.js index cf42aa27229..166e64237de 100644 --- a/atom/renderer/lib/init.js +++ b/atom/renderer/lib/init.js @@ -38,7 +38,7 @@ electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, m electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, requestId, method, args) => { const responseCallback = function(result) { - event.sender.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE_' + requestId, result); + event.sender.send(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, result); }; args.push(responseCallback); electron.webFrame[method].apply(electron.webFrame, args); diff --git a/atom/renderer/lib/web-view/web-view.js b/atom/renderer/lib/web-view/web-view.js index 25e5eead2dd..bd128f6fffe 100644 --- a/atom/renderer/lib/web-view/web-view.js +++ b/atom/renderer/lib/web-view/web-view.js @@ -307,7 +307,7 @@ var registerBrowserPluginElement = function() { // Registers custom element. var registerWebViewElement = function() { - var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, webFrameMethods, proto; + var createBlockHandler, createNonBlockHandler, i, j, len, len1, m, methods, nonblockMethods, proto; proto = Object.create(HTMLObjectElement.prototype); proto.createdCallback = function() { return new WebViewImpl(this); @@ -392,12 +392,9 @@ var registerWebViewElement = function() { ]; nonblockMethods = [ 'insertCSS', + 'insertText', 'send', 'sendInputEvent', - ]; - webFrameMethods = [ - 'executeJavaScript', - 'insertText', 'setZoomFactor', 'setZoomLevel', 'setZoomLevelLimits', @@ -424,7 +421,7 @@ var registerWebViewElement = function() { var args, internal; args = 1 <= arguments.length ? slice.call(arguments, 0) : []; internal = v8Util.getHiddenValue(this, 'internal'); - return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', internal.guestInstanceId, m].concat(slice.call(args))); + return ipcRenderer.send.apply(ipcRenderer, ['ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', null, internal.guestInstanceId, m].concat(slice.call(args))); }; }; for (j = 0, len1 = nonblockMethods.length; j < len1; j++) { @@ -432,10 +429,19 @@ var registerWebViewElement = function() { proto[m] = createNonBlockHandler(m); } - // Forward proto.foo* webframe method calls to WebFrame.foo*. - for (let method of webFrameMethods) { - proto[method] = webFrame[method].bind(webFrame); - } + proto.executeJavaScript = function(code, hasUserGesture, callback) { + var internal = v8Util.getHiddenValue(this, 'internal'); + if (typeof hasUserGesture === "function") { + callback = hasUserGesture; + hasUserGesture = false; + } + let requestId = getNextId(); + ipcRenderer.send('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', requestId, internal.guestInstanceId, "executeJavaScript", code, hasUserGesture); + ipcRenderer.once(`ATOM_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function(event, result) { + if (callback) + callback(result); + }); + }; // WebContents associated with this webview. proto.getWebContents = function() {