From 3dc92be74cd9daf61275678bcdfd19c008e451ea Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Thu, 2 Sep 2021 11:13:06 +0200 Subject: [PATCH] feat: add .sendToFrame() / frameId to 'ipc-message' event (#30451) (#30704) --- docs/api/webview-tag.md | 16 +++++++++++++++ lib/browser/guest-view-manager.ts | 8 ++++++-- lib/common/web-view-methods.ts | 1 + lib/renderer/web-view/guest-view-internal.ts | 4 ++-- spec/webview-spec.js | 21 +++++++++++++++++++- 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/docs/api/webview-tag.md b/docs/api/webview-tag.md index 0c5dfd69d2..1931a5339b 100644 --- a/docs/api/webview-tag.md +++ b/docs/api/webview-tag.md @@ -606,6 +606,21 @@ listening to the `channel` event with the [`ipcRenderer`](ipc-renderer.md) modul See [webContents.send](web-contents.md#contentssendchannel-args) for examples. +### `.sendToFrame(frameId, channel, ...args)` + +* `frameId` [number, number] - `[processId, frameId]` +* `channel` String +* `...args` any[] + +Returns `Promise` + +Send an asynchronous message to renderer process via `channel`, you can also +send arbitrary arguments. The renderer process can handle the message by +listening to the `channel` event with the [`ipcRenderer`](ipc-renderer.md) module. + +See [webContents.sendToFrame](web-contents.md#contentssendtoframeframeid-channel-args) for +examples. + ### `.sendInputEvent(event)` * `event` [MouseInputEvent](structures/mouse-input-event.md) | [MouseWheelInputEvent](structures/mouse-wheel-input-event.md) | [KeyboardInputEvent](structures/keyboard-input-event.md) @@ -907,6 +922,7 @@ webview.addEventListener('close', () => { Returns: +* `frameId` [number, number] - pair of `[processId, frameId]`. * `channel` String * `args` any[] diff --git a/lib/browser/guest-view-manager.ts b/lib/browser/guest-view-manager.ts index 4b43fb7e25..f193e9dd5c 100644 --- a/lib/browser/guest-view-manager.ts +++ b/lib/browser/guest-view-manager.ts @@ -100,8 +100,12 @@ const createGuest = function (embedder: Electron.WebContents, params: Record tag', function () { expect(args).to.deep.equal([message]); }); + it('.sendToFrame()', async () => { + loadWebView(webview, { + nodeintegration: 'on', + webpreferences: 'contextIsolation=no', + preload: `${fixtures}/module/preload-ipc.js`, + src: `file://${fixtures}/pages/ipc-message.html` + }); + + const { frameId } = await waitForEvent(webview, 'ipc-message'); + + const message = 'boom!'; + webview.sendToFrame(frameId, 'ping', message); + + const { channel, args } = await waitForEvent(webview, 'ipc-message'); + expect(channel).to.equal('pong'); + expect(args).to.deep.equal([message]); + }); + it('works without script tag in page', async () => { const message = await startLoadingWebViewAndWaitForMessage(webview, { preload: `${fixtures}/module/preload.js`, @@ -529,8 +547,9 @@ describe(' tag', function () { webpreferences: 'contextIsolation=no', src: `file://${fixtures}/pages/ipc-message.html` }); - const { channel, args } = await waitForEvent(webview, 'ipc-message'); + const { frameId, channel, args } = await waitForEvent(webview, 'ipc-message'); + expect(frameId).to.be.an('array').that.has.lengthOf(2); expect(channel).to.equal('channel'); expect(args).to.deep.equal(['arg1', 'arg2']); });