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.
This commit is contained in:
Paul Betts 2015-11-25 15:54:30 -08:00
parent bf5e9e4f4d
commit 789380dfad
2 changed files with 25 additions and 7 deletions

View file

@ -221,3 +221,11 @@ ipcMain.on 'ATOM_BROWSER_GUEST_WEB_CONTENTS', (event, guestInstanceId) ->
ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) -> ipcMain.on 'ATOM_BROWSER_LIST_MODULES', (event) ->
event.returnValue = (name for name of electron) 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

View file

@ -1,4 +1,4 @@
{deprecate, webFrame, remote} = require 'electron' {deprecate, webFrame, remote, ipcRenderer} = require 'electron'
v8Util = process.atomBinding 'v8_util' v8Util = process.atomBinding 'v8_util'
guestViewInternal = require './guest-view-internal' guestViewInternal = require './guest-view-internal'
@ -270,8 +270,6 @@ registerWebViewElement = ->
'isCrashed' 'isCrashed'
'setUserAgent' 'setUserAgent'
'getUserAgent' 'getUserAgent'
'executeJavaScript'
'insertCSS'
'openDevTools' 'openDevTools'
'closeDevTools' 'closeDevTools'
'isDevToolsOpened' 'isDevToolsOpened'
@ -289,20 +287,32 @@ registerWebViewElement = ->
'unselect' 'unselect'
'replace' 'replace'
'replaceMisspelling' 'replaceMisspelling'
'send'
'getId' 'getId'
'inspectServiceWorker' 'inspectServiceWorker'
'print' 'print'
'printToPDF' 'printToPDF'
'sendInputEvent' ]
nonblockMethods = [
'send',
'sendInputEvent',
'executeJavaScript',
'insertCSS'
] ]
# Forward proto.foo* method calls to WebViewImpl.foo*. # Forward proto.foo* method calls to WebViewImpl.foo*.
createHandler = (m) -> createBlockHandler = (m) ->
(args...) -> (args...) ->
internal = v8Util.getHiddenValue this, 'internal' internal = v8Util.getHiddenValue this, 'internal'
internal.webContents[m] args... 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. # Deprecated.
deprecate.rename proto, 'getUrl', 'getURL' deprecate.rename proto, 'getUrl', 'getURL'