fix: correctly handle IPC for promise-based methods (#16433)
This commit is contained in:
parent
4d0b2ac9be
commit
720197f9c8
3 changed files with 44 additions and 8 deletions
|
@ -4,7 +4,11 @@ const { webContents } = require('electron')
|
||||||
const ipcMain = require('@electron/internal/browser/ipc-main-internal')
|
const ipcMain = require('@electron/internal/browser/ipc-main-internal')
|
||||||
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
|
const parseFeaturesString = require('@electron/internal/common/parse-features-string')
|
||||||
const errorUtils = require('@electron/internal/common/error-utils')
|
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.
|
// Doesn't exist in early initialization.
|
||||||
let webViewManager = null
|
let webViewManager = null
|
||||||
|
@ -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) {
|
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', function (event, requestId, guestInstanceId, method, args, hasCallback) {
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
||||||
if (!asyncMethods.has(method)) {
|
if (!asyncCallbackMethods.has(method) && !asyncPromiseMethods.has(method)) {
|
||||||
throw new Error(`Invalid method: ${method}`)
|
throw new Error(`Invalid method: ${method}`)
|
||||||
}
|
}
|
||||||
if (hasCallback) {
|
if (hasCallback) {
|
||||||
|
|
|
@ -50,18 +50,20 @@ exports.syncMethods = new Set([
|
||||||
'setZoomLevel'
|
'setZoomLevel'
|
||||||
])
|
])
|
||||||
|
|
||||||
exports.asyncMethods = new Set([
|
exports.asyncCallbackMethods = new Set([
|
||||||
'insertCSS',
|
'insertCSS',
|
||||||
'insertText',
|
'insertText',
|
||||||
'send',
|
'send',
|
||||||
'sendInputEvent',
|
'sendInputEvent',
|
||||||
'setLayoutZoomLevelLimits',
|
'setLayoutZoomLevelLimits',
|
||||||
'setVisualZoomLevelLimits',
|
'setVisualZoomLevelLimits',
|
||||||
// with callback
|
|
||||||
'capturePage',
|
|
||||||
'executeJavaScript',
|
|
||||||
'getZoomFactor',
|
'getZoomFactor',
|
||||||
'getZoomLevel',
|
'getZoomLevel',
|
||||||
'print',
|
'print',
|
||||||
'printToPDF'
|
'printToPDF'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
exports.asyncPromiseMethods = new Set([
|
||||||
|
'capturePage',
|
||||||
|
'executeJavaScript'
|
||||||
|
])
|
||||||
|
|
|
@ -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 guestViewInternal = require('@electron/internal/renderer/web-view/guest-view-internal')
|
||||||
const webViewConstants = require('@electron/internal/renderer/web-view/web-view-constants')
|
const webViewConstants = require('@electron/internal/renderer/web-view/web-view-constants')
|
||||||
const errorUtils = require('@electron/internal/common/error-utils')
|
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.
|
// ID generator.
|
||||||
let nextId = 0
|
let nextId = 0
|
||||||
|
@ -254,9 +258,35 @@ const setupMethods = (WebViewElement) => {
|
||||||
ipcRenderer.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
|
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)
|
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 }
|
module.exports = { setupAttributes, setupMethods, guestViewInternal, webFrame, WebViewImpl }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue