diff --git a/docs/api/breaking-changes.md b/docs/api/breaking-changes.md index 8e945438548d8..7b75f8ea6785e 100644 --- a/docs/api/breaking-changes.md +++ b/docs/api/breaking-changes.md @@ -59,6 +59,47 @@ these kinds of objects will throw a 'could not be cloned' error. [SCA]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm +### `.getWebContents()` + +This API is implemented using the `remote` module, which has both performance +and security implications. Therefore its usage should be explicit. + +```js +// Deprecated +webview.getWebContents() +// Replace with +const { remote } = require('electron') +remote.webContents.fromId(webview.getWebContentsId()) +``` + +However, it is recommended to avoid using the `remote` module altogether. + +```js +// main +const { ipcMain, webContents } = require('electron') + +const getGuestForWebContents = function (webContentsId, contents) { + const guest = webContents.fromId(webContentsId) + if (!guest) { + throw new Error(`Invalid webContentsId: ${webContentsId}`) + } + if (guest.hostWebContents !== contents) { + throw new Error(`Access denied to webContents`) + } + return guest +} + +ipcMain.handle('openDevTools', (event, webContentsId) => { + const guest = getGuestForWebContents(webContentsId, event.sender) + guest.openDevTools() +}) + +// renderer +const { ipcRenderer } = require('electron') + +ipcRenderer.invoke('openDevTools', webview.getWebContentsId()) +``` + ## Planned Breaking API Changes (7.0) ### Node Headers URL diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 69758f61d990c..ef7b23df7a428 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1393,11 +1393,13 @@ An example of showing devtools in a `` tag: diff --git a/docs/api/webview-tag.md b/docs/api/webview-tag.md index ed78287199aba..ee0366a0931a9 100644 --- a/docs/api/webview-tag.md +++ b/docs/api/webview-tag.md @@ -648,7 +648,7 @@ Sets the maximum and minimum layout-based (i.e. non-visual) zoom level. Shows pop-up dictionary that searches the selected word on the page. -### `.getWebContents()` +### `.getWebContents()` _Deprecated_ Returns [`WebContents`](web-contents.md) - The web contents associated with this `webview`. diff --git a/lib/renderer/web-view/web-view-impl.ts b/lib/renderer/web-view/web-view-impl.ts index 2ec4db66cc75e..2ed5420b6feff 100644 --- a/lib/renderer/web-view/web-view-impl.ts +++ b/lib/renderer/web-view/web-view-impl.ts @@ -219,9 +219,9 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem WebViewElement.prototype.getWebContentsId = function () { const internal = v8Util.getHiddenValue(this, '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.') + internal.createGuestSync() } - return internal.guestInstanceId + return internal.guestInstanceId! } // WebContents associated with this webview. @@ -238,15 +238,29 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem return remote.getGuestWebContents(internal.guestInstanceId!) } + WebViewElement.prototype.getWebContents = electron.deprecate.moveAPI( + WebViewElement.prototype.getWebContents, + 'webview.getWebContents()', + 'remote.webContents.fromId(webview.getWebContentsId())' + ) as any + // Focusing the webview should move page focus to the underlying iframe. WebViewElement.prototype.focus = function () { this.contentWindow.focus() } + const getWebContentsId = function (self: any) { + 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 (method: string) { return function (this: ElectronInternal.WebViewElement, ...args: Array) { - return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args) + return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', getWebContentsId(this), method, args) } } @@ -256,7 +270,7 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem const createNonBlockHandler = function (method: string) { return function (this: ElectronInternal.WebViewElement, ...args: Array) { - return ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args) + return ipcRendererInternal.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getWebContentsId(this), method, args) } } diff --git a/spec/fixtures/pages/webview-devtools.html b/spec/fixtures/pages/webview-devtools.html index 8928c4ea79883..fb54b9b18aeb1 100644 --- a/spec/fixtures/pages/webview-devtools.html +++ b/spec/fixtures/pages/webview-devtools.html @@ -8,7 +8,8 @@