Browse Source

feat: add <webview>.getWebContentsId() (#17407)

Milan Burda 6 years ago
parent
commit
546466b209

+ 4 - 0
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.
 
+### `<webview>.getWebContentsId()`
+
+Returns `Number` - The WebContents ID of this `webview`.
+
 ## DOM events
 
 The following DOM events are available to the `webview` tag:

+ 1 - 7
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

+ 14 - 14
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<WebViewImpl>(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<WebViewImpl>(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<any>) {
-      return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args)
+    return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
+      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<any>) {
-      ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args)
+    return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
+      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<any>) {
-      return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args)
+    return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
+      return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
     }
   }
 

+ 1 - 1
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())
       })
     </script>
   </body>

+ 11 - 2
spec/webview-spec.js

@@ -1124,7 +1124,7 @@ describe('<webview> 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('<webview> 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('<webview> tag', function () {
     })
   })
 
+  describe('<webview>.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('<webview>.getWebContents', () => {
     it('can return the webcontents associated', async () => {
       const src = 'about:blank'

+ 1 - 0
typings/internal-electron.d.ts

@@ -121,6 +121,7 @@ declare namespace ElectronInternal {
 
     // Created in web-view-impl
     public getWebContents(): Electron.WebContents;
+    public getWebContentsId(): number;
   }
 }