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

This commit is contained in:
Milan Burda 2019-03-26 02:57:27 +01:00 committed by Cheng Zhao
parent 9e26dfaa06
commit 546466b209
6 changed files with 32 additions and 24 deletions

View file

@ -672,6 +672,10 @@ this `webview`.
It depends on the [`remote`](remote.md) module, It depends on the [`remote`](remote.md) module,
it is therefore not available when this module is disabled. it is therefore not available when this module is disabled.
### `<webview>.getWebContentsId()`
Returns `Number` - The WebContents ID of this `webview`.
## DOM events ## DOM events
The following DOM events are available to the `webview` tag: The following DOM events are available to the `webview` tag:

View file

@ -49,27 +49,21 @@ const supportedWebViewEvents = [
'update-target-url' 'update-target-url'
] ]
let nextGuestInstanceId = 0
const guestInstances = {} const guestInstances = {}
const embedderElementsMap = {} const embedderElementsMap = {}
// Generate guestInstanceId.
const getNextGuestInstanceId = function () {
return ++nextGuestInstanceId
}
// Create a new guest instance. // Create a new guest instance.
const createGuest = function (embedder, params) { const createGuest = function (embedder, params) {
if (webViewManager == null) { if (webViewManager == null) {
webViewManager = process.electronBinding('web_view_manager') webViewManager = process.electronBinding('web_view_manager')
} }
const guestInstanceId = getNextGuestInstanceId(embedder)
const guest = webContents.create({ const guest = webContents.create({
isGuest: true, isGuest: true,
partition: params.partition, partition: params.partition,
embedder: embedder embedder: embedder
}) })
const guestInstanceId = guest.id
guestInstances[guestInstanceId] = { guestInstances[guestInstanceId] = {
guest: guest, guest: guest,
embedder: embedder embedder: embedder

View file

@ -219,6 +219,14 @@ export const setupAttributes = () => {
// I wish eslint wasn't so stupid, but it is // I wish eslint wasn't so stupid, but it is
// eslint-disable-next-line // eslint-disable-next-line
export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElement) => { 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. // WebContents associated with this webview.
WebViewElement.prototype.getWebContents = function () { WebViewElement.prototype.getWebContents = function () {
if (!remote) { if (!remote) {
@ -237,18 +245,10 @@ export const setupMethods = (WebViewElement: typeof ElectronInternal.WebViewElem
this.contentWindow.focus() 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*. // Forward proto.foo* method calls to WebViewImpl.foo*.
const createBlockHandler = function (method: string) { const createBlockHandler = function (method: string) {
return function (this: any, ...args: Array<any>) { return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
return ipcRendererUtils.invokeSync('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args) 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) { const createNonBlockHandler = function (method: string) {
return function (this: any, ...args: Array<any>) { return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args) 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) { const createPromiseHandler = function (method: string) {
return function (this: any, ...args: Array<any>) { return function (this: ElectronInternal.WebViewElement, ...args: Array<any>) {
return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', getGuestInstanceId(this), method, args) return ipcRendererUtils.invoke('ELECTRON_GUEST_VIEW_MANAGER_CALL', this.getWebContentsId(), method, args)
} }
} }

View file

@ -9,7 +9,7 @@
var {ipcRenderer} = require('electron') var {ipcRenderer} = require('electron')
var wv = document.querySelector('webview') var wv = document.querySelector('webview')
wv.addEventListener('dom-ready', () => { wv.addEventListener('dom-ready', () => {
ipcRenderer.send('webview-dom-ready', wv.getWebContents().id) ipcRenderer.send('webview-dom-ready', wv.getWebContentsId())
}) })
</script> </script>
</body> </body>

View file

@ -1124,7 +1124,7 @@ describe('<webview> tag', function () {
assert.ok(webview.partition) assert.ok(webview.partition)
const listener = function (webContents, permission, callback) { 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 // requestMIDIAccess with sysex requests both midi and midiSysex so
// grant the first midi one and then reject the midiSysex one // grant the first midi one and then reject the midiSysex one
if (requestedPermission === 'midiSysex' && permission === 'midi') { if (requestedPermission === 'midiSysex' && permission === 'midi') {
@ -1210,7 +1210,7 @@ describe('<webview> tag', function () {
webview.partition = 'permissionTest' webview.partition = 'permissionTest'
webview.setAttribute('nodeintegration', 'on') webview.setAttribute('nodeintegration', 'on')
session.fromPartition(webview.partition).setPermissionRequestHandler((webContents, permission, callback) => { session.fromPartition(webview.partition).setPermissionRequestHandler((webContents, permission, callback) => {
if (webContents.id === webview.getWebContents().id) { if (webContents.id === webview.getWebContentsId()) {
assert.strictEqual(permission, 'notifications') assert.strictEqual(permission, 'notifications')
setTimeout(() => { callback(true) }, 10) 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', () => { describe('<webview>.getWebContents', () => {
it('can return the webcontents associated', async () => { it('can return the webcontents associated', async () => {
const src = 'about:blank' const src = 'about:blank'

View file

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