From 789380dfad09ca59950bb8228f3edb3ac5dc039d Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 25 Nov 2015 15:54:30 -0800 Subject: [PATCH] Ensure calling webview.send will not block the renderer When the browser process is busy, calling webview.send (a method that appears on its face to be non-blocking) will actually block, because most webview methods are remoted to a guest view instance in the browser. Instead, define a few methods which will instead send its call over an async IPC message. --- atom/browser/lib/rpc-server.coffee | 8 ++++++++ atom/renderer/lib/web-view/web-view.coffee | 24 +++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index ce63d9189664..8a67d2112ece 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -221,3 +221,11 @@ ipcMain.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) -> ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) -> event.returnValue = (name for name of electron) + +ipcMain.on 'ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', (event, guestInstanceId, method, args...) -> + try + guestViewManager = require './guest-view-manager' + guest = guestViewManager.getGuest(guestInstanceId) + guest[method].apply(guest, args) + catch e + event.returnValue = exceptionToMeta e diff --git a/atom/renderer/lib/web-view/web-view.coffee b/atom/renderer/lib/web-view/web-view.coffee index 5e3f7d6bae56..720e6e84c5d4 100644 --- a/atom/renderer/lib/web-view/web-view.coffee +++ b/atom/renderer/lib/web-view/web-view.coffee @@ -1,4 +1,4 @@ -{deprecate, webFrame, remote} = require 'electron' +{deprecate, webFrame, remote, ipcRenderer} = require 'electron' v8Util = process.atomBinding 'v8_util' guestViewInternal = require './guest-view-internal' @@ -270,8 +270,6 @@ registerWebViewElement = -> 'isCrashed' 'setUserAgent' 'getUserAgent' - 'executeJavaScript' - 'insertCSS' 'openDevTools' 'closeDevTools' 'isDevToolsOpened' @@ -289,20 +287,32 @@ registerWebViewElement = -> 'unselect' 'replace' 'replaceMisspelling' - 'send' 'getId' 'inspectServiceWorker' 'print' 'printToPDF' - 'sendInputEvent' + ] + + nonblockMethods = [ + 'send', + 'sendInputEvent', + 'executeJavaScript', + 'insertCSS' ] # Forward proto.foo* method calls to WebViewImpl.foo*. - createHandler = (m) -> + createBlockHandler = (m) -> (args...) -> internal = v8Util.getHiddenValue this, 'internal' internal.webContents[m] args... - proto[m] = createHandler m for m in methods + proto[m] = createBlockHandler m for m in methods + + createNonBlockHandler = (m) -> + (args...) -> + internal = v8Util.getHiddenValue this, 'internal' + ipcRenderer.send('ATOM_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', internal.guestInstanceId, m, args...) + + proto[m] = createNonBlockHandler m for m in nonblockMethods # Deprecated. deprecate.rename proto, 'getUrl', 'getURL'