diff --git a/docs/api/webview-tag.md b/docs/api/webview-tag.md index d0186c79363b..93ed322a8c3b 100644 --- a/docs/api/webview-tag.md +++ b/docs/api/webview-tag.md @@ -672,6 +672,10 @@ this `webview`. It depends on the [`remote`](remote.md) module, it is therefore not available when this module is disabled. +### `.getWebContentsId()` + +Returns `Number` - The WebContents ID of this `webview`. + ## DOM events The following DOM events are available to the `webview` tag: diff --git a/lib/browser/guest-view-manager.js b/lib/browser/guest-view-manager.js index b5db1ceb06fc..01673497ccbf 100644 --- a/lib/browser/guest-view-manager.js +++ b/lib/browser/guest-view-manager.js @@ -49,27 +49,21 @@ const supportedWebViewEvents = [ 'update-target-url' ] -let nextGuestInstanceId = 0 const guestInstances = {} const embedderElementsMap = {} -// Generate guestInstanceId. -const getNextGuestInstanceId = function () { - return ++nextGuestInstanceId -} - // Create a new guest instance. const createGuest = function (embedder, params) { if (webViewManager == null) { webViewManager = process.electronBinding('web_view_manager') } - const guestInstanceId = getNextGuestInstanceId(embedder) const guest = webContents.create({ isGuest: true, partition: params.partition, embedder: embedder }) + const guestInstanceId = guest.id guestInstances[guestInstanceId] = { guest: guest, embedder: embedder diff --git a/lib/renderer/web-view/web-view-impl.ts b/lib/renderer/web-view/web-view-impl.ts index 6a7fb961a649..6849f3061ebc 100644 --- a/lib/renderer/web-view/web-view-impl.ts +++ b/lib/renderer/web-view/web-view-impl.ts @@ -219,6 +219,14 @@ export const setupAttributes = () => { // I wish eslint wasn't so stupid, but it is // eslint-disable-next-line export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElement) => { + 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.') + } + return internal.guestInstanceId + } + // WebContents associated with this webview. WebViewElement.prototype.getWebContents = function () { if (!remote) { @@ -237,18 +245,10 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem this.contentWindow.focus() } - const getGuestInstanceId = 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: any, ...args: Array) { - return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args) + return function (this: ElectronInternal.WebViewElement, ...args: Array) { + return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args) } } @@ -257,8 +257,8 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem } const createNonBlockHandler = function (method: string) { - return function (this: any, ...args: Array) { - ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args) + return function (this: ElectronInternal.WebViewElement, ...args: Array) { + ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args) } } @@ -267,8 +267,8 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem } const createPromiseHandler = function (method: string) { - return function (this: any, ...args: Array) { - return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args) + return function (this: ElectronInternal.WebViewElement, ...args: Array) { + return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args) } } diff --git a/spec/fixtures/pages/webview-did-attach-event.html b/spec/fixtures/pages/webview-did-attach-event.html index 4c6a0b9e5005..300a8e21ed0f 100644 --- a/spec/fixtures/pages/webview-did-attach-event.html +++ b/spec/fixtures/pages/webview-did-attach-event.html @@ -9,7 +9,7 @@ var {ipcRenderer} = require('electron') var wv = document.querySelector('webview') wv.addEventListener('dom-ready', () => { - ipcRenderer.send('webview-dom-ready', wv.getWebContents().id) + ipcRenderer.send('webview-dom-ready', wv.getWebContentsId()) }) diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 10f89187e109..786464950aed 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -1124,7 +1124,7 @@ describe(' tag', function () { assert.ok(webview.partition) const listener = function (webContents, permission, callback) { - if (webContents.id === webview.getWebContents().id) { + if (webContents.id === webview.getWebContentsId()) { // requestMIDIAccess with sysex requests both midi and midiSysex so // grant the first midi one and then reject the midiSysex one if (requestedPermission === 'midiSysex' && permission === 'midi') { @@ -1210,7 +1210,7 @@ describe(' tag', function () { webview.partition = 'permissionTest' webview.setAttribute('nodeintegration', 'on') session.fromPartition(webview.partition).setPermissionRequestHandler((webContents, permission, callback) => { - if (webContents.id === webview.getWebContents().id) { + if (webContents.id === webview.getWebContentsId()) { assert.strictEqual(permission, 'notifications') setTimeout(() => { callback(true) }, 10) } @@ -1219,6 +1219,15 @@ describe(' tag', function () { }) }) + describe('.getWebContentsId', () => { + it('can return the WebContents ID', async () => { + const src = 'about:blank' + await loadWebView(webview, { src }) + + expect(webview.getWebContentsId()).to.be.equal(webview.getWebContents().id) + }) + }) + describe('.getWebContents', () => { it('can return the webcontents associated', async () => { const src = 'about:blank' diff --git a/typings/internal-electron.d.ts b/typings/internal-electron.d.ts index fa3b238fb24c..471534bb1527 100644 --- a/typings/internal-electron.d.ts +++ b/typings/internal-electron.d.ts @@ -121,6 +121,7 @@ declare namespace ElectronInternal { // Created in web-view-impl public getWebContents(): Electron.WebContents; + public getWebContentsId(): number; } }