|
@@ -5,9 +5,7 @@ const { ipcRenderer, remote, webFrame } = require('electron')
|
|
|
const v8Util = process.atomBinding('v8_util')
|
|
|
const guestViewInternal = require('@electron/internal/renderer/web-view/guest-view-internal')
|
|
|
const webViewConstants = require('@electron/internal/renderer/web-view/web-view-constants')
|
|
|
-
|
|
|
-// An unique ID that can represent current context.
|
|
|
-const contextId = v8Util.getHiddenValue(global, 'contextId')
|
|
|
+const errorUtils = require('@electron/internal/common/error-utils')
|
|
|
|
|
|
// ID generator.
|
|
|
let nextId = 0
|
|
@@ -66,7 +64,6 @@ class WebViewImpl {
|
|
|
this.guestInstanceId = void 0
|
|
|
}
|
|
|
|
|
|
- this.webContents = null
|
|
|
this.beforeFirstNavigation = true
|
|
|
this.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId = true
|
|
|
|
|
@@ -188,7 +185,6 @@ class WebViewImpl {
|
|
|
}
|
|
|
this.internalInstanceId = getNextId()
|
|
|
this.guestInstanceId = guestInstanceId
|
|
|
- this.webContents = remote.getGuestWebContents(this.guestInstanceId)
|
|
|
guestViewInternal.attachGuest(this.internalInstanceId, this.guestInstanceId, this.buildParams(), this.internalElement.contentWindow)
|
|
|
// ResizeObserver is a browser global not recognized by "standard".
|
|
|
/* globals ResizeObserver */
|
|
@@ -277,14 +273,9 @@ const registerWebViewElement = function () {
|
|
|
'stopFindInPage',
|
|
|
'downloadURL',
|
|
|
'inspectServiceWorker',
|
|
|
- 'print',
|
|
|
- 'printToPDF',
|
|
|
'showDefinitionForSelection',
|
|
|
- 'capturePage',
|
|
|
'setZoomFactor',
|
|
|
- 'setZoomLevel',
|
|
|
- 'getZoomLevel',
|
|
|
- 'getZoomFactor'
|
|
|
+ 'setZoomLevel'
|
|
|
]
|
|
|
const nonblockMethods = [
|
|
|
'insertCSS',
|
|
@@ -292,17 +283,32 @@ const registerWebViewElement = function () {
|
|
|
'send',
|
|
|
'sendInputEvent',
|
|
|
'setLayoutZoomLevelLimits',
|
|
|
- 'setVisualZoomLevelLimits'
|
|
|
+ 'setVisualZoomLevelLimits',
|
|
|
+ // with callback
|
|
|
+ 'capturePage',
|
|
|
+ 'executeJavaScript',
|
|
|
+ 'getZoomFactor',
|
|
|
+ 'getZoomLevel',
|
|
|
+ 'print',
|
|
|
+ 'printToPDF'
|
|
|
]
|
|
|
|
|
|
+ const getGuestInstanceId = function (self) {
|
|
|
+ const internal = v8Util.getHiddenValue(self, 'internal')
|
|
|
+ if (!internal.guestInstanceId) {
|
|
|
+ throw new Error('The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.')
|
|
|
+ }
|
|
|
+ return internal.guestInstanceId
|
|
|
+ }
|
|
|
+
|
|
|
// Forward proto.foo* method calls to WebViewImpl.foo*.
|
|
|
- const createBlockHandler = function (m) {
|
|
|
+ const createBlockHandler = function (method) {
|
|
|
return function (...args) {
|
|
|
- const internal = v8Util.getHiddenValue(this, 'internal')
|
|
|
- if (internal.webContents) {
|
|
|
- return internal.webContents[m](...args)
|
|
|
+ const [error, result] = ipcRenderer.sendSync('ELECTRON_BROWSER_SYNC_CALL_TO_GUEST_VIEW', getGuestInstanceId(this), method, args)
|
|
|
+ if (error) {
|
|
|
+ throw errorUtils.deserialize(error)
|
|
|
} else {
|
|
|
- throw new Error(`Cannot call ${m} because the webContents is unavailable. The WebView must be attached to the DOM and the dom-ready event emitted before this method can be called.`)
|
|
|
+ return result
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -310,36 +316,31 @@ const registerWebViewElement = function () {
|
|
|
proto[method] = createBlockHandler(method)
|
|
|
}
|
|
|
|
|
|
- const createNonBlockHandler = function (m) {
|
|
|
+ const createNonBlockHandler = function (method) {
|
|
|
return function (...args) {
|
|
|
- const internal = v8Util.getHiddenValue(this, 'internal')
|
|
|
- ipcRenderer.send('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', contextId, null, internal.guestInstanceId, m, ...args)
|
|
|
+ const callback = (typeof args[args.length - 1] === 'function') ? args.pop() : null
|
|
|
+ const requestId = getNextId()
|
|
|
+ ipcRenderer.once(`ELECTRON_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function (event, error, result) {
|
|
|
+ if (error == null) {
|
|
|
+ if (callback) callback(result)
|
|
|
+ } else {
|
|
|
+ throw errorUtils.deserialize(error)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ ipcRenderer.send('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', requestId, getGuestInstanceId(this), method, args, callback != null)
|
|
|
}
|
|
|
}
|
|
|
for (const method of nonblockMethods) {
|
|
|
proto[method] = createNonBlockHandler(method)
|
|
|
}
|
|
|
|
|
|
- proto.executeJavaScript = function (code, hasUserGesture, callback) {
|
|
|
- const internal = v8Util.getHiddenValue(this, 'internal')
|
|
|
- if (typeof hasUserGesture === 'function') {
|
|
|
- callback = hasUserGesture
|
|
|
- hasUserGesture = false
|
|
|
- }
|
|
|
- const requestId = getNextId()
|
|
|
- ipcRenderer.send('ELECTRON_BROWSER_ASYNC_CALL_TO_GUEST_VIEW', contextId, requestId, internal.guestInstanceId, 'executeJavaScript', code, hasUserGesture)
|
|
|
- ipcRenderer.once(`ELECTRON_RENDERER_ASYNC_CALL_TO_GUEST_VIEW_RESPONSE_${requestId}`, function (event, result) {
|
|
|
- if (callback) callback(result)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
// WebContents associated with this webview.
|
|
|
proto.getWebContents = function () {
|
|
|
const internal = v8Util.getHiddenValue(this, 'internal')
|
|
|
- if (!internal.webContents) {
|
|
|
+ if (!internal.guestInstanceId) {
|
|
|
internal.createGuestSync()
|
|
|
}
|
|
|
- return internal.webContents
|
|
|
+ return remote.getGuestWebContents(internal.guestInstanceId)
|
|
|
}
|
|
|
|
|
|
// Focusing the webview should move page focus to the underlying iframe.
|