Skip to content

Commit

Permalink
fix: correctly handle IPC for promise-based methods (electron#16433)
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere authored and akisctx committed Jan 22, 2019
1 parent 3e8601b commit 8b78839
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
8 changes: 6 additions & 2 deletions lib/browser/guest-view-manager.js
Expand Up @@ -4,7 +4,11 @@ const { webContents } = require('electron')
const ipcMain = require('@electron/internal/browser/ipc-main-internal')
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
const errorUtils = require('@electron/internal/common/error-utils')
const { syncMethods, asyncMethods } = require('@electron/internal/common/web-view-methods')
const {
syncMethods,
asyncCallbackMethods,
asyncPromiseMethods
} = require('@electron/internal/common/web-view-methods')

// Doesn't exist in early initialization.
let webViewManager = null
Expand Down Expand Up @@ -383,7 +387,7 @@ ipcMain.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event, focus, g
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', function (event, requestId, guestInstanceId, method, args, hasCallback) {
new Promise(resolve => {
const guest = getGuestForWebContents(guestInstanceId, event.sender)
if (!asyncMethods.has(method)) {
if (!asyncCallbackMethods.has(method) && !asyncPromiseMethods.has(method)) {
throw new Error(`Invalid method: ${method}`)
}
if (hasCallback) {
Expand Down
10 changes: 6 additions & 4 deletions lib/common/web-view-methods.js
Expand Up @@ -50,18 +50,20 @@ exports.syncMethods = new Set([
'setZoomLevel'
])

exports.asyncMethods = new Set([
exports.asyncCallbackMethods = new Set([
'insertCSS',
'insertText',
'send',
'sendInputEvent',
'setLayoutZoomLevelLimits',
'setVisualZoomLevelLimits',
// with callback
'capturePage',
'executeJavaScript',
'getZoomFactor',
'getZoomLevel',
'print',
'printToPDF'
])

exports.asyncPromiseMethods = new Set([
'capturePage',
'executeJavaScript'
])
34 changes: 32 additions & 2 deletions lib/renderer/web-view/web-view-impl.js
Expand Up @@ -7,7 +7,11 @@ const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
const guestViewInternal = require('@electron/internal/renderer/web-view/guest-view-internal')
const webViewConstants = require('@electron/internal/renderer/web-view/web-view-constants')
const errorUtils = require('@electron/internal/common/error-utils')
const { syncMethods, asyncMethods } = require('@electron/internal/common/web-view-methods')
const {
syncMethods,
asyncCallbackMethods,
asyncPromiseMethods
} = require('@electron/internal/common/web-view-methods')

// ID generator.
let nextId = 0
Expand Down Expand Up @@ -254,9 +258,35 @@ const setupMethods = (WebViewElement) => {
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
}
}
for (const method of asyncMethods) {

for (const method of asyncCallbackMethods) {
WebViewElement.prototype[method] = createNonBlockHandler(method)
}

const createPromiseHandler = function (method) {
return function (...args) {
return new Promise((resolve, reject) => {
const callback = (typeof args[args.length - 1] === 'function') ? args.pop() : null
const requestId = getNextId()

ipcRenderer.once(`ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL_RESPONSE_${requestId}`, function (event, error, result) {
if (error == null) {
if (callback) {
callback(result)
}
resolve(result)
} else {
reject(errorUtils.deserialize(error))
}
})
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
})
}
}

for (const method of asyncPromiseMethods) {
WebViewElement.prototype[method] = createPromiseHandler(method)
}
}

module.exports = { setupAttributes, setupMethods, guestViewInternal, webFrame, WebViewImpl }

0 comments on commit 8b78839

Please sign in to comment.