refactor: use invoke/invokeSync helpers for <webview> implementation (#16784)
This commit is contained in:
parent
2adbc7836b
commit
bbd1ae315a
4 changed files with 32 additions and 91 deletions
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
const { webContents } = require('electron')
|
const { webContents } = require('electron')
|
||||||
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
|
const { ipcMainInternal } = require('@electron/internal/browser/ipc-main-internal')
|
||||||
|
const ipcMainUtils = require('@electron/internal/browser/ipc-main-internal-utils')
|
||||||
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 {
|
const {
|
||||||
syncMethods,
|
syncMethods,
|
||||||
asyncCallbackMethods,
|
asyncCallbackMethods,
|
||||||
|
@ -341,21 +341,18 @@ const isWebViewTagEnabled = function (contents) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMessage = function (channel, handler) {
|
const handleMessage = function (channel, handler) {
|
||||||
ipcMainInternal.on(channel, (event, ...args) => {
|
ipcMainUtils.handle(channel, (event, ...args) => {
|
||||||
if (isWebViewTagEnabled(event.sender)) {
|
if (isWebViewTagEnabled(event.sender)) {
|
||||||
handler(event, ...args)
|
return handler(event, ...args)
|
||||||
} else {
|
} else {
|
||||||
event.returnValue = null
|
console.error(`<webview> IPC message ${channel} sent by WebContents with <webview> disabled (${event.sender.id})`)
|
||||||
|
throw new Error('<webview> disabled')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', function (event, params, requestId) {
|
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', function (event, params) {
|
||||||
event._replyInternal(`ELECTRON_RESPONSE_${requestId}`, createGuest(event.sender, params))
|
return createGuest(event.sender, params)
|
||||||
})
|
|
||||||
|
|
||||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', function (event, params) {
|
|
||||||
event.returnValue = createGuest(event.sender, params)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, guestInstanceId) {
|
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', function (event, guestInstanceId) {
|
||||||
|
@ -385,36 +382,19 @@ ipcMainInternal.on('ELECTRON_GUEST_VIEW_MANAGER_FOCUS_CHANGE', function (event,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', function (event, requestId, guestInstanceId, method, args, hasCallback) {
|
const allMethods = new Set([
|
||||||
new Promise(resolve => {
|
...syncMethods,
|
||||||
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
...asyncCallbackMethods,
|
||||||
if (!asyncCallbackMethods.has(method) && !asyncPromiseMethods.has(method)) {
|
...asyncPromiseMethods
|
||||||
throw new Error(`Invalid method: ${method}`)
|
])
|
||||||
}
|
|
||||||
if (hasCallback) {
|
|
||||||
guest[method](...args, resolve)
|
|
||||||
} else {
|
|
||||||
resolve(guest[method](...args))
|
|
||||||
}
|
|
||||||
}).then(result => {
|
|
||||||
return [null, result]
|
|
||||||
}, error => {
|
|
||||||
return [errorUtils.serialize(error)]
|
|
||||||
}).then(responseArgs => {
|
|
||||||
event._replyInternal(`ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL_RESPONSE_${requestId}`, ...responseArgs)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_SYNC_CALL', function (event, guestInstanceId, method, args) {
|
handleMessage('ELECTRON_GUEST_VIEW_MANAGER_CALL', function (event, guestInstanceId, method, args) {
|
||||||
try {
|
|
||||||
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
const guest = getGuestForWebContents(guestInstanceId, event.sender)
|
||||||
if (!syncMethods.has(method)) {
|
if (!allMethods.has(method)) {
|
||||||
throw new Error(`Invalid method: ${method}`)
|
throw new Error(`Invalid method: ${method}`)
|
||||||
}
|
}
|
||||||
event.returnValue = [null, guest[method](...args)]
|
|
||||||
} catch (error) {
|
return guest[method](...args)
|
||||||
event.returnValue = [errorUtils.serialize(error)]
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Returns WebContents from its guest id hosted in given webContents.
|
// Returns WebContents from its guest id hosted in given webContents.
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
|
|
||||||
const { webFrame } = require('electron')
|
const { webFrame } = require('electron')
|
||||||
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
|
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
|
||||||
|
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
|
||||||
let requestId = 0
|
|
||||||
|
|
||||||
const WEB_VIEW_EVENTS = {
|
const WEB_VIEW_EVENTS = {
|
||||||
'load-commit': ['url', 'isMainFrame'],
|
'load-commit': ['url', 'isMainFrame'],
|
||||||
|
@ -87,22 +86,20 @@ module.exports = {
|
||||||
ipcRendererInternal.removeAllListeners(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`)
|
ipcRendererInternal.removeAllListeners(`ELECTRON_GUEST_VIEW_INTERNAL_DISPATCH_EVENT-${viewInstanceId}`)
|
||||||
ipcRendererInternal.removeAllListeners(`ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE-${viewInstanceId}`)
|
ipcRendererInternal.removeAllListeners(`ELECTRON_GUEST_VIEW_INTERNAL_IPC_MESSAGE-${viewInstanceId}`)
|
||||||
},
|
},
|
||||||
createGuest: function (params, callback) {
|
createGuest: function (params) {
|
||||||
requestId++
|
return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
|
||||||
ipcRendererInternal.send('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params, requestId)
|
|
||||||
ipcRendererInternal.once(`ELECTRON_RESPONSE_${requestId}`, callback)
|
|
||||||
},
|
},
|
||||||
createGuestSync: function (params) {
|
createGuestSync: function (params) {
|
||||||
return ipcRendererInternal.sendSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST_SYNC', params)
|
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CREATE_GUEST', params)
|
||||||
},
|
},
|
||||||
destroyGuest: function (guestInstanceId) {
|
destroyGuest: function (guestInstanceId) {
|
||||||
ipcRendererInternal.send('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId)
|
ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId)
|
||||||
},
|
},
|
||||||
attachGuest: function (elementInstanceId, guestInstanceId, params, contentWindow) {
|
attachGuest: function (elementInstanceId, guestInstanceId, params, contentWindow) {
|
||||||
const embedderFrameId = webFrame.getWebFrameId(contentWindow)
|
const embedderFrameId = webFrame.getWebFrameId(contentWindow)
|
||||||
if (embedderFrameId < 0) { // this error should not happen.
|
if (embedderFrameId < 0) { // this error should not happen.
|
||||||
throw new Error('Invalid embedder frame')
|
throw new Error('Invalid embedder frame')
|
||||||
}
|
}
|
||||||
ipcRendererInternal.send('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
|
ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_ATTACH_GUEST', embedderFrameId, elementInstanceId, guestInstanceId, params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
|
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
|
||||||
const { WebViewImpl } = require('@electron/internal/renderer/web-view/web-view-impl')
|
const { WebViewImpl } = require('@electron/internal/renderer/web-view/web-view-impl')
|
||||||
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')
|
|
||||||
|
|
||||||
// Helper function to resolve url set in attribute.
|
// Helper function to resolve url set in attribute.
|
||||||
const a = document.createElement('a')
|
const a = document.createElement('a')
|
||||||
|
@ -186,10 +185,7 @@ class SrcAttribute extends WebViewAttribute {
|
||||||
const method = 'loadURL'
|
const method = 'loadURL'
|
||||||
const args = [this.getValue(), opts]
|
const args = [this.getValue(), opts]
|
||||||
|
|
||||||
const [error] = ipcRendererInternal.sendSync('ELECTRON_GUEST_VIEW_MANAGER_SYNC_CALL', guestInstanceId, method, args)
|
ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', guestInstanceId, method, args)
|
||||||
if (error) {
|
|
||||||
throw errorUtils.deserialize(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,9 @@
|
||||||
const { webFrame, deprecate } = require('electron')
|
const { webFrame, deprecate } = require('electron')
|
||||||
|
|
||||||
const v8Util = process.atomBinding('v8_util')
|
const v8Util = process.atomBinding('v8_util')
|
||||||
const { ipcRendererInternal } = require('@electron/internal/renderer/ipc-renderer-internal')
|
const ipcRendererUtils = require('@electron/internal/renderer/ipc-renderer-internal-utils')
|
||||||
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 {
|
const {
|
||||||
syncMethods,
|
syncMethods,
|
||||||
asyncCallbackMethods,
|
asyncCallbackMethods,
|
||||||
|
@ -111,7 +110,7 @@ class WebViewImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
createGuest () {
|
createGuest () {
|
||||||
return guestViewInternal.createGuest(this.buildParams(), (event, guestInstanceId) => {
|
guestViewInternal.createGuest(this.buildParams()).then(guestInstanceId => {
|
||||||
this.attachGuestInstance(guestInstanceId)
|
this.attachGuestInstance(guestInstanceId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -232,12 +231,7 @@ const setupMethods = (WebViewElement) => {
|
||||||
// Forward proto.foo* method calls to WebViewImpl.foo*.
|
// Forward proto.foo* method calls to WebViewImpl.foo*.
|
||||||
const createBlockHandler = function (method) {
|
const createBlockHandler = function (method) {
|
||||||
return function (...args) {
|
return function (...args) {
|
||||||
const [error, result] = ipcRendererInternal.sendSync('ELECTRON_GUEST_VIEW_MANAGER_SYNC_CALL', getGuestInstanceId(this), method, args)
|
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args)
|
||||||
if (error) {
|
|
||||||
throw errorUtils.deserialize(error)
|
|
||||||
} else {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const method of syncMethods) {
|
for (const method of syncMethods) {
|
||||||
|
@ -246,16 +240,7 @@ const setupMethods = (WebViewElement) => {
|
||||||
|
|
||||||
const createNonBlockHandler = function (method) {
|
const createNonBlockHandler = function (method) {
|
||||||
return function (...args) {
|
return function (...args) {
|
||||||
const callback = (typeof args[args.length - 1] === 'function') ? args.pop() : null
|
ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args)
|
||||||
const requestId = getNextId()
|
|
||||||
ipcRendererInternal.once(`ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL_RESPONSE_${requestId}`, function (event, error, result) {
|
|
||||||
if (error == null) {
|
|
||||||
if (callback) callback(result)
|
|
||||||
} else {
|
|
||||||
throw errorUtils.deserialize(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
ipcRendererInternal.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,30 +250,13 @@ const setupMethods = (WebViewElement) => {
|
||||||
|
|
||||||
const createPromiseHandler = function (method) {
|
const createPromiseHandler = function (method) {
|
||||||
return function (...args) {
|
return function (...args) {
|
||||||
return new Promise((resolve, reject) => {
|
return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args)
|
||||||
const callback = (typeof args[args.length - 1] === 'function') ? args.pop() : null
|
|
||||||
const requestId = getNextId()
|
|
||||||
|
|
||||||
ipcRendererInternal.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))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
ipcRendererInternal.send('ELECTRON_GUEST_VIEW_MANAGER_ASYNC_CALL', requestId, getGuestInstanceId(this), method, args, callback != null)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const method of asyncPromiseMethods) {
|
for (const method of asyncPromiseMethods) {
|
||||||
WebViewElement.prototype[method] = createPromiseHandler(method)
|
WebViewElement.prototype[method] = deprecate.promisify(createPromiseHandler(method))
|
||||||
}
|
}
|
||||||
|
|
||||||
WebViewElement.prototype.printToPDF = deprecate.promisify(WebViewElement.prototype.printToPDF)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { setupAttributes, setupMethods, guestViewInternal, webFrame, WebViewImpl }
|
module.exports = { setupAttributes, setupMethods, guestViewInternal, webFrame, WebViewImpl }
|
||||||
|
|
Loading…
Reference in a new issue