Browse Source

chore: remove deprecated `ipcRenderer.sendTo()` (#39087)

chore: remove deprecated ipcRenderer.sendTo()
Milan Burda 1 year ago
parent
commit
5078cae861

+ 0 - 8
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

+ 0 - 3
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

+ 6 - 0
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

+ 0 - 3
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",

+ 0 - 7
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) {

+ 2 - 6
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);
   }
 });
 

+ 0 - 26
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<WebFrameMain> 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) {

+ 0 - 4
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);

+ 1 - 3
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<mojom::ElectronRenderer>& WebFrameMain::GetRendererApi() {

+ 0 - 10
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());

+ 0 - 3
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;
 

+ 1 - 10
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);

+ 0 - 18
shell/renderer/api/electron_api_ipc_renderer.cc

@@ -77,7 +77,6 @@ class IPCRenderer : public gin::Wrappable<IPCRenderer>,
     return gin::Wrappable<IPCRenderer>::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<IPCRenderer>,
                                              std::move(transferable_message));
   }
 
-  void SendTo(v8::Isolate* isolate,
-              gin_helper::ErrorThrower thrower,
-              int32_t web_contents_id,
-              const std::string& channel,
-              v8::Local<v8::Value> 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,

+ 5 - 14
shell/renderer/electron_api_service_impl.cc

@@ -82,9 +82,7 @@ void EmitIPCEvent(v8::Local<v8::Context> context,
                   bool internal,
                   const std::string& channel,
                   std::vector<v8::Local<v8::Value>> ports,
-                  v8::Local<v8::Value> args,
-                  int32_t sender_id = 0,
-                  bool sender_is_main_frame = false) {
+                  v8::Local<v8::Value> args) {
   auto* isolate = context->GetIsolate();
 
   v8::HandleScope handle_scope(isolate);
@@ -93,12 +91,8 @@ void EmitIPCEvent(v8::Local<v8::Context> context,
                                    v8::MicrotasksScope::kRunMicrotasks);
 
   std::vector<v8::Local<v8::Value>> 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<v8::Value> args = gin::ConvertToV8(isolate, arguments);
 
-  EmitIPCEvent(context, internal, channel, {}, args, sender_id,
-               sender_is_main_frame);
+  EmitIPCEvent(context, internal, channel, {}, args);
 }
 
 void ElectronApiServiceImpl::ReceivePostMessage(

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

+ 1 - 79
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(`

+ 0 - 9
spec/fixtures/module/preload-ipc-ping-pong.js

@@ -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);
-});

+ 3 - 0
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
 

+ 0 - 1
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<T>(internal: boolean, channel: string, args: any[]): Promise<{ error: string, result: T }>;
     postMessage(channel: string, message: any, transferables: MessagePort[]): void;
   }