From 5078cae86181735bc50684fd56d50488bc6766f5 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Mon, 28 Aug 2023 16:29:27 +0200 Subject: [PATCH] chore: remove deprecated `ipcRenderer.sendTo()` (#39087) chore: remove deprecated ipcRenderer.sendTo() --- docs/api/ipc-renderer.md | 8 -- docs/api/structures/ipc-renderer-event.md | 3 - docs/breaking-changes.md | 6 ++ filenames.auto.gni | 3 - lib/renderer/api/ipc-renderer.ts | 7 -- lib/renderer/common-init.ts | 8 +- .../browser/api/electron_api_web_contents.cc | 26 ------ shell/browser/api/electron_api_web_contents.h | 4 - .../api/electron_api_web_frame_main.cc | 4 +- .../browser/electron_api_ipc_handler_impl.cc | 10 --- shell/browser/electron_api_ipc_handler_impl.h | 3 - shell/common/api/api.mojom | 11 +-- .../renderer/api/electron_api_ipc_renderer.cc | 18 ----- shell/renderer/electron_api_service_impl.cc | 19 ++--- shell/renderer/electron_api_service_impl.h | 4 +- spec/api-ipc-renderer-spec.ts | 80 +------------------ spec/fixtures/module/preload-ipc-ping-pong.js | 9 --- spec/ts-smoke/electron/renderer.ts | 3 + typings/internal-ambient.d.ts | 1 - 19 files changed, 20 insertions(+), 207 deletions(-) delete mode 100644 spec/fixtures/module/preload-ipc-ping-pong.js diff --git a/docs/api/ipc-renderer.md b/docs/api/ipc-renderer.md index 1238ee50c4f2..6c229a76126f 100644 --- a/docs/api/ipc-renderer.md +++ b/docs/api/ipc-renderer.md @@ -192,14 +192,6 @@ ipcMain.on('port', (e, msg) => { For more information on using `MessagePort` and `MessageChannel`, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel). -### `ipcRenderer.sendTo(webContentsId, channel, ...args)` _Deprecated_ - -* `webContentsId` number -* `channel` string -* `...args` any[] - -Sends a message to a window with `webContentsId` via `channel`. - ### `ipcRenderer.sendToHost(channel, ...args)` * `channel` string diff --git a/docs/api/structures/ipc-renderer-event.md b/docs/api/structures/ipc-renderer-event.md index 4e8b32f47c78..135834f2098d 100644 --- a/docs/api/structures/ipc-renderer-event.md +++ b/docs/api/structures/ipc-renderer-event.md @@ -1,9 +1,6 @@ # IpcRendererEvent Object extends `Event` * `sender` [IpcRenderer](../ipc-renderer.md) - The `IpcRenderer` instance that emitted the event originally -* `senderId` Integer _Deprecated_ - The `webContents.id` that sent the message, you can call `event.sender.sendTo(event.senderId, ...)` to reply to the message, see [ipcRenderer.sendTo][ipc-renderer-sendto] for more information. This only applies to messages sent from a different renderer. Messages sent directly from the main process set `event.senderId` to `0`. -* `senderIsMainFrame` boolean (optional) _Deprecated_ - Whether the message sent via [ipcRenderer.sendTo][ipc-renderer-sendto] was sent by the main frame. This is relevant when `nodeIntegrationInSubFrames` is enabled in the originating `webContents`. * `ports` [MessagePort][][] - A list of MessagePorts that were transferred with this message -[ipc-renderer-sendto]: ../ipc-renderer.md#ipcrenderersendtowebcontentsid-channel-args-deprecated [MessagePort]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md index 7a15b66b1fd4..607437ded406 100644 --- a/docs/breaking-changes.md +++ b/docs/breaking-changes.md @@ -52,6 +52,12 @@ if (ret === null) { } ``` +### Removed: `ipcRenderer.sendTo()` + +The `ipcRenderer.sendTo()` API has been removed. It should be replaced by setting up a [`MessageChannel`](tutorial/message-ports.md#setting-up-a-messagechannel-between-two-renderers) between the renderers. + +The `senderId` and `senderIsMainFrame` properties of `IpcRendererEvent` have been removed as well. + ## Planned Breaking API Changes (27.0) ### Removed: macOS 10.13 / 10.14 support diff --git a/filenames.auto.gni b/filenames.auto.gni index d7aeead8c38e..1d89fc05e329 100644 --- a/filenames.auto.gni +++ b/filenames.auto.gni @@ -144,7 +144,6 @@ auto_filenames = { sandbox_bundle_deps = [ "lib/common/api/native-image.ts", "lib/common/define-properties.ts", - "lib/common/deprecate.ts", "lib/common/ipc-messages.ts", "lib/common/web-view-methods.ts", "lib/common/webpack-globals-provider.ts", @@ -270,7 +269,6 @@ auto_filenames = { "lib/common/api/native-image.ts", "lib/common/api/shell.ts", "lib/common/define-properties.ts", - "lib/common/deprecate.ts", "lib/common/init.ts", "lib/common/ipc-messages.ts", "lib/common/reset-search-paths.ts", @@ -309,7 +307,6 @@ auto_filenames = { "lib/common/api/native-image.ts", "lib/common/api/shell.ts", "lib/common/define-properties.ts", - "lib/common/deprecate.ts", "lib/common/init.ts", "lib/common/ipc-messages.ts", "lib/common/reset-search-paths.ts", diff --git a/lib/renderer/api/ipc-renderer.ts b/lib/renderer/api/ipc-renderer.ts index 1977ce4ed384..b637f1927195 100644 --- a/lib/renderer/api/ipc-renderer.ts +++ b/lib/renderer/api/ipc-renderer.ts @@ -1,5 +1,4 @@ import { EventEmitter } from 'events'; -import * as deprecate from '@electron/internal/common/deprecate'; const { ipc } = process._linkedBinding('electron_renderer_ipc'); @@ -18,12 +17,6 @@ ipcRenderer.sendToHost = function (channel, ...args) { return ipc.sendToHost(channel, args); }; -const sendToDeprecated = deprecate.warnOnce('ipcRenderer.sendTo'); -ipcRenderer.sendTo = function (webContentsId, channel, ...args) { - sendToDeprecated(); - return ipc.sendTo(webContentsId, channel, args); -}; - ipcRenderer.invoke = async function (channel, ...args) { const { error, result } = await ipc.invoke(internal, channel, args); if (error) { diff --git a/lib/renderer/common-init.ts b/lib/renderer/common-init.ts index d4e4bfb910c3..4910ca667166 100644 --- a/lib/renderer/common-init.ts +++ b/lib/renderer/common-init.ts @@ -17,13 +17,9 @@ const isWebView = mainFrame.getWebPreference('isWebView'); // ElectronApiServiceImpl will look for the "ipcNative" hidden object when // invoking the 'onMessage' callback. v8Util.setHiddenValue(global, 'ipcNative', { - onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[], senderId: number, senderIsMainFrame: boolean) { - if (internal && senderId !== 0) { - console.error(`Message ${channel} sent by unexpected WebContents (${senderId})`); - return; - } + onMessage (internal: boolean, channel: string, ports: MessagePort[], args: any[]) { const sender = internal ? ipcRendererInternal : ipcRenderer; - sender.emit(channel, { sender, senderId, ...(senderId ? { senderIsMainFrame } : {}), ports }, ...args); + sender.emit(channel, { sender, ports }, ...args); } }); diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index 4f946d166876..2d0de7c0f603 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -2029,32 +2029,6 @@ void WebContents::MessageSync( internal, channel, std::move(arguments)); } -void WebContents::MessageTo(int32_t web_contents_id, - const std::string& channel, - blink::CloneableMessage arguments, - content::RenderFrameHost* render_frame_host) { - TRACE_EVENT1("electron", "WebContents::MessageTo", "channel", channel); - auto* target_web_contents = FromID(web_contents_id); - - if (target_web_contents) { - content::RenderFrameHost* frame = target_web_contents->MainFrame(); - DCHECK(frame); - - v8::HandleScope handle_scope(JavascriptEnvironment::GetIsolate()); - gin::Handle web_frame_main = - WebFrameMain::From(JavascriptEnvironment::GetIsolate(), frame); - - if (!web_frame_main->CheckRenderFrame()) - return; - - int32_t sender_id = ID(); - bool sender_is_main_frame = render_frame_host->GetParent() == nullptr; - web_frame_main->GetRendererApi()->Message(false /* internal */, channel, - std::move(arguments), sender_id, - sender_is_main_frame); - } -} - void WebContents::MessageHost(const std::string& channel, blink::CloneableMessage arguments, content::RenderFrameHost* render_frame_host) { diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index e1fc66378b3b..fb47ebb90431 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -434,10 +434,6 @@ class WebContents : public ExclusiveAccessContext, blink::CloneableMessage arguments, electron::mojom::ElectronApiIPC::MessageSyncCallback callback, content::RenderFrameHost* render_frame_host); - void MessageTo(int32_t web_contents_id, - const std::string& channel, - blink::CloneableMessage arguments, - content::RenderFrameHost* render_frame_host); void MessageHost(const std::string& channel, blink::CloneableMessage arguments, content::RenderFrameHost* render_frame_host); diff --git a/shell/browser/api/electron_api_web_frame_main.cc b/shell/browser/api/electron_api_web_frame_main.cc index 6bd620b99b00..24952767db2d 100644 --- a/shell/browser/api/electron_api_web_frame_main.cc +++ b/shell/browser/api/electron_api_web_frame_main.cc @@ -184,9 +184,7 @@ void WebFrameMain::Send(v8::Isolate* isolate, if (!CheckRenderFrame()) return; - GetRendererApi()->Message(internal, channel, std::move(message), - 0 /* sender_id */, - false /* sender_is_main_frame */); + GetRendererApi()->Message(internal, channel, std::move(message)); } const mojo::Remote& WebFrameMain::GetRendererApi() { diff --git a/shell/browser/electron_api_ipc_handler_impl.cc b/shell/browser/electron_api_ipc_handler_impl.cc index 2a05bd9d7627..8902622a786c 100644 --- a/shell/browser/electron_api_ipc_handler_impl.cc +++ b/shell/browser/electron_api_ipc_handler_impl.cc @@ -76,16 +76,6 @@ void ElectronApiIPCHandlerImpl::MessageSync(bool internal, } } -void ElectronApiIPCHandlerImpl::MessageTo(int32_t web_contents_id, - const std::string& channel, - blink::CloneableMessage arguments) { - api::WebContents* api_web_contents = api::WebContents::From(web_contents()); - if (api_web_contents) { - api_web_contents->MessageTo(web_contents_id, channel, std::move(arguments), - GetRenderFrameHost()); - } -} - void ElectronApiIPCHandlerImpl::MessageHost(const std::string& channel, blink::CloneableMessage arguments) { api::WebContents* api_web_contents = api::WebContents::From(web_contents()); diff --git a/shell/browser/electron_api_ipc_handler_impl.h b/shell/browser/electron_api_ipc_handler_impl.h index 282003f4947a..1a0ad3a0135d 100644 --- a/shell/browser/electron_api_ipc_handler_impl.h +++ b/shell/browser/electron_api_ipc_handler_impl.h @@ -49,9 +49,6 @@ class ElectronApiIPCHandlerImpl : public mojom::ElectronApiIPC, const std::string& channel, blink::CloneableMessage arguments, MessageSyncCallback callback) override; - void MessageTo(int32_t web_contents_id, - const std::string& channel, - blink::CloneableMessage arguments) override; void MessageHost(const std::string& channel, blink::CloneableMessage arguments) override; diff --git a/shell/common/api/api.mojom b/shell/common/api/api.mojom index fdf082c25c01..3af7f28c1911 100644 --- a/shell/common/api/api.mojom +++ b/shell/common/api/api.mojom @@ -9,9 +9,7 @@ interface ElectronRenderer { Message( bool internal, string channel, - blink.mojom.CloneableMessage arguments, - int32 sender_id, - bool sender_is_main_frame); + blink.mojom.CloneableMessage arguments); ReceivePostMessage(string channel, blink.mojom.TransferableMessage message); @@ -71,13 +69,6 @@ interface ElectronApiIPC { string channel, blink.mojom.CloneableMessage arguments) => (blink.mojom.CloneableMessage result); - // Emits an event from the |ipcRenderer| JavaScript object in the target - // WebContents's main frame, specified by |web_contents_id|. - MessageTo( - int32 web_contents_id, - string channel, - blink.mojom.CloneableMessage arguments); - MessageHost( string channel, blink.mojom.CloneableMessage arguments); diff --git a/shell/renderer/api/electron_api_ipc_renderer.cc b/shell/renderer/api/electron_api_ipc_renderer.cc index 7096a35ae7d7..58feca6ad41b 100644 --- a/shell/renderer/api/electron_api_ipc_renderer.cc +++ b/shell/renderer/api/electron_api_ipc_renderer.cc @@ -77,7 +77,6 @@ class IPCRenderer : public gin::Wrappable, return gin::Wrappable::GetObjectTemplateBuilder(isolate) .SetMethod("send", &IPCRenderer::SendMessage) .SetMethod("sendSync", &IPCRenderer::SendSync) - .SetMethod("sendTo", &IPCRenderer::SendTo) .SetMethod("sendToHost", &IPCRenderer::SendToHost) .SetMethod("invoke", &IPCRenderer::Invoke) .SetMethod("postMessage", &IPCRenderer::PostMessage); @@ -169,23 +168,6 @@ class IPCRenderer : public gin::Wrappable, std::move(transferable_message)); } - void SendTo(v8::Isolate* isolate, - gin_helper::ErrorThrower thrower, - int32_t web_contents_id, - const std::string& channel, - v8::Local arguments) { - if (!electron_ipc_remote_) { - thrower.ThrowError(kIPCMethodCalledAfterContextReleasedError); - return; - } - blink::CloneableMessage message; - if (!electron::SerializeV8Value(isolate, arguments, &message)) { - return; - } - electron_ipc_remote_->MessageTo(web_contents_id, channel, - std::move(message)); - } - void SendToHost(v8::Isolate* isolate, gin_helper::ErrorThrower thrower, const std::string& channel, diff --git a/shell/renderer/electron_api_service_impl.cc b/shell/renderer/electron_api_service_impl.cc index b1c980a72d20..529de045fb34 100644 --- a/shell/renderer/electron_api_service_impl.cc +++ b/shell/renderer/electron_api_service_impl.cc @@ -82,9 +82,7 @@ void EmitIPCEvent(v8::Local context, bool internal, const std::string& channel, std::vector> ports, - v8::Local args, - int32_t sender_id = 0, - bool sender_is_main_frame = false) { + v8::Local args) { auto* isolate = context->GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -93,12 +91,8 @@ void EmitIPCEvent(v8::Local context, v8::MicrotasksScope::kRunMicrotasks); std::vector> argv = { - gin::ConvertToV8(isolate, internal), - gin::ConvertToV8(isolate, channel), - gin::ConvertToV8(isolate, ports), - args, - gin::ConvertToV8(isolate, sender_id), - gin::ConvertToV8(isolate, sender_is_main_frame)}; + gin::ConvertToV8(isolate, internal), gin::ConvertToV8(isolate, channel), + gin::ConvertToV8(isolate, ports), args}; InvokeIpcCallback(context, "onMessage", argv); } @@ -160,9 +154,7 @@ void ElectronApiServiceImpl::OnConnectionError() { void ElectronApiServiceImpl::Message(bool internal, const std::string& channel, - blink::CloneableMessage arguments, - int32_t sender_id, - bool sender_is_main_frame) { + blink::CloneableMessage arguments) { blink::WebLocalFrame* frame = render_frame()->GetWebFrame(); if (!frame) return; @@ -175,8 +167,7 @@ void ElectronApiServiceImpl::Message(bool internal, v8::Local args = gin::ConvertToV8(isolate, arguments); - EmitIPCEvent(context, internal, channel, {}, args, sender_id, - sender_is_main_frame); + EmitIPCEvent(context, internal, channel, {}, args); } void ElectronApiServiceImpl::ReceivePostMessage( diff --git a/shell/renderer/electron_api_service_impl.h b/shell/renderer/electron_api_service_impl.h index 0d35b51283cf..e4488b7f1c79 100644 --- a/shell/renderer/electron_api_service_impl.h +++ b/shell/renderer/electron_api_service_impl.h @@ -34,9 +34,7 @@ class ElectronApiServiceImpl : public mojom::ElectronRenderer, void Message(bool internal, const std::string& channel, - blink::CloneableMessage arguments, - int32_t sender_id, - bool sender_is_main_frame) override; + blink::CloneableMessage arguments) override; void ReceivePostMessage(const std::string& channel, blink::TransferableMessage message) override; void TakeHeapSnapshot(mojo::ScopedHandle file, diff --git a/spec/api-ipc-renderer-spec.ts b/spec/api-ipc-renderer-spec.ts index 23d0c450b7e3..558a93a5e09d 100644 --- a/spec/api-ipc-renderer-spec.ts +++ b/spec/api-ipc-renderer-spec.ts @@ -1,12 +1,9 @@ import { expect } from 'chai'; -import * as path from 'node:path'; -import { ipcMain, BrowserWindow, WebContents, WebPreferences, webContents } from 'electron/main'; +import { ipcMain, BrowserWindow } from 'electron/main'; import { closeWindow } from './lib/window-helpers'; import { once } from 'node:events'; describe('ipcRenderer module', () => { - const fixtures = path.join(__dirname, 'fixtures'); - let w: BrowserWindow; before(async () => { w = new BrowserWindow({ @@ -135,81 +132,6 @@ describe('ipcRenderer module', () => { }); }); - describe('sendTo()', () => { - const generateSpecs = (description: string, webPreferences: WebPreferences) => { - describe(description, () => { - let contents: WebContents; - const payload = 'Hello World!'; - - before(async () => { - contents = (webContents as typeof ElectronInternal.WebContents).create({ - preload: path.join(fixtures, 'module', 'preload-ipc-ping-pong.js'), - ...webPreferences - }); - - await contents.loadURL('about:blank'); - }); - - after(() => { - contents.destroy(); - contents = null as unknown as WebContents; - }); - - it('sends message to WebContents', async () => { - const data = await w.webContents.executeJavaScript(`new Promise(resolve => { - const { ipcRenderer } = require('electron') - ipcRenderer.sendTo(${contents.id}, 'ping', ${JSON.stringify(payload)}) - ipcRenderer.once('pong', (event, data) => resolve(data)) - })`); - expect(data.payload).to.equal(payload); - expect(data.senderIsMainFrame).to.be.true(); - }); - - it('sends message to WebContents from a child frame', async () => { - const frameCreated = once(w.webContents, 'frame-created') as Promise<[any, Electron.FrameCreatedDetails]>; - - const promise = w.webContents.executeJavaScript(`new Promise(resolve => { - const iframe = document.createElement('iframe'); - iframe.src = 'data:text/html,'; - iframe.name = 'iframe'; - document.body.appendChild(iframe); - - const { ipcRenderer } = require('electron'); - ipcRenderer.once('pong', (event, data) => resolve(data)); - })`); - - const [, details] = await frameCreated; - expect(details.frame.name).to.equal('iframe'); - - await once(details.frame, 'dom-ready'); - - details.frame.executeJavaScript(`new Promise(resolve => { - const { ipcRenderer } = require('electron'); - ipcRenderer.sendTo(${contents.id}, 'ping', ${JSON.stringify(payload)}); - })`); - - const data = await promise; - expect(data.payload).to.equal(payload); - expect(data.senderIsMainFrame).to.be.false(); - }); - - it('sends message on channel with non-ASCII characters to WebContents', async () => { - const data = await w.webContents.executeJavaScript(`new Promise(resolve => { - const { ipcRenderer } = require('electron') - ipcRenderer.sendTo(${contents.id}, 'ping-æøåü', ${JSON.stringify(payload)}) - ipcRenderer.once('pong-æøåü', (event, data) => resolve(data)) - })`); - expect(data).to.equal(payload); - }); - }); - }; - - generateSpecs('without sandbox', {}); - generateSpecs('with sandbox', { sandbox: true }); - generateSpecs('with contextIsolation', { contextIsolation: true }); - generateSpecs('with contextIsolation + sandbox', { contextIsolation: true, sandbox: true }); - }); - describe('ipcRenderer.on', () => { it('is not used for internals', async () => { const result = await w.webContents.executeJavaScript(` diff --git a/spec/fixtures/module/preload-ipc-ping-pong.js b/spec/fixtures/module/preload-ipc-ping-pong.js deleted file mode 100644 index 6fb1834628d2..000000000000 --- a/spec/fixtures/module/preload-ipc-ping-pong.js +++ /dev/null @@ -1,9 +0,0 @@ -const { ipcRenderer } = require('electron'); - -ipcRenderer.on('ping', function ({ senderId, senderIsMainFrame }, payload) { - ipcRenderer.sendTo(senderId, 'pong', { payload, senderIsMainFrame }); -}); - -ipcRenderer.on('ping-æøåü', function (event, payload) { - ipcRenderer.sendTo(event.senderId, 'pong-æøåü', payload); -}); diff --git a/spec/ts-smoke/electron/renderer.ts b/spec/ts-smoke/electron/renderer.ts index 16d0f9c02b8e..331594179b88 100644 --- a/spec/ts-smoke/electron/renderer.ts +++ b/spec/ts-smoke/electron/renderer.ts @@ -13,6 +13,9 @@ ipcRenderer.on('asynchronous-reply', (event, arg: any) => { ipcRenderer.send('asynchronous-message', 'ping'); +// @ts-expect-error Removed API +ipcRenderer.sendTo(1, 'test', 'Hello World!'); + // web-frame // https://github.com/electron/electron/blob/main/docs/api/web-frame.md diff --git a/typings/internal-ambient.d.ts b/typings/internal-ambient.d.ts index d4feb411af84..9a94341dd14b 100644 --- a/typings/internal-ambient.d.ts +++ b/typings/internal-ambient.d.ts @@ -17,7 +17,6 @@ declare namespace NodeJS { send(internal: boolean, channel: string, args: any[]): void; sendSync(internal: boolean, channel: string, args: any[]): any; sendToHost(channel: string, args: any[]): void; - sendTo(webContentsId: number, channel: string, args: any[]): void; invoke(internal: boolean, channel: string, args: any[]): Promise<{ error: string, result: T }>; postMessage(channel: string, message: any, transferables: MessagePort[]): void; }