feat: add event.senderId property to IPCs sent via ipcRenderer.sendTo (#14395)
This commit is contained in:
		
					parent
					
						
							
								b89848d683
							
						
					
				
			
			
				commit
				
					
						c17a1b37ea
					
				
			
		
					 11 changed files with 90 additions and 31 deletions
				
			
		| 
						 | 
					@ -1556,10 +1556,17 @@ void WebContents::TabTraverse(bool reverse) {
 | 
				
			||||||
bool WebContents::SendIPCMessage(bool all_frames,
 | 
					bool WebContents::SendIPCMessage(bool all_frames,
 | 
				
			||||||
                                 const std::string& channel,
 | 
					                                 const std::string& channel,
 | 
				
			||||||
                                 const base::ListValue& args) {
 | 
					                                 const base::ListValue& args) {
 | 
				
			||||||
 | 
					  return SendIPCMessageWithSender(all_frames, channel, args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool WebContents::SendIPCMessageWithSender(bool all_frames,
 | 
				
			||||||
 | 
					                                           const std::string& channel,
 | 
				
			||||||
 | 
					                                           const base::ListValue& args,
 | 
				
			||||||
 | 
					                                           int32_t sender_id) {
 | 
				
			||||||
  auto* frame_host = web_contents()->GetMainFrame();
 | 
					  auto* frame_host = web_contents()->GetMainFrame();
 | 
				
			||||||
  if (frame_host) {
 | 
					  if (frame_host) {
 | 
				
			||||||
    return frame_host->Send(new AtomFrameMsg_Message(
 | 
					    return frame_host->Send(new AtomFrameMsg_Message(
 | 
				
			||||||
        frame_host->GetRoutingID(), all_frames, channel, args));
 | 
					        frame_host->GetRoutingID(), all_frames, channel, args, sender_id));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return false;
 | 
					  return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2090,7 +2097,7 @@ void WebContents::OnRendererMessageTo(content::RenderFrameHost* frame_host,
 | 
				
			||||||
      isolate(), web_contents_id);
 | 
					      isolate(), web_contents_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (web_contents) {
 | 
					  if (web_contents) {
 | 
				
			||||||
    web_contents->SendIPCMessage(send_to_all, channel, args);
 | 
					    web_contents->SendIPCMessageWithSender(send_to_all, channel, args, ID());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -181,6 +181,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
 | 
				
			||||||
                      const std::string& channel,
 | 
					                      const std::string& channel,
 | 
				
			||||||
                      const base::ListValue& args);
 | 
					                      const base::ListValue& args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool SendIPCMessageWithSender(bool all_frames,
 | 
				
			||||||
 | 
					                                const std::string& channel,
 | 
				
			||||||
 | 
					                                const base::ListValue& args,
 | 
				
			||||||
 | 
					                                int32_t sender_id = 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Send WebInputEvent to the page.
 | 
					  // Send WebInputEvent to the page.
 | 
				
			||||||
  void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
 | 
					  void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,10 +39,11 @@ IPC_MESSAGE_ROUTED4(AtomFrameHostMsg_Message_To,
 | 
				
			||||||
                    std::string /* channel */,
 | 
					                    std::string /* channel */,
 | 
				
			||||||
                    base::ListValue /* arguments */)
 | 
					                    base::ListValue /* arguments */)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IPC_MESSAGE_ROUTED3(AtomFrameMsg_Message,
 | 
					IPC_MESSAGE_ROUTED4(AtomFrameMsg_Message,
 | 
				
			||||||
                    bool /* send_to_all */,
 | 
					                    bool /* send_to_all */,
 | 
				
			||||||
                    std::string /* channel */,
 | 
					                    std::string /* channel */,
 | 
				
			||||||
                    base::ListValue /* arguments */)
 | 
					                    base::ListValue /* arguments */,
 | 
				
			||||||
 | 
					                    int32_t /* sender_id */)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen)
 | 
					IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,12 +36,13 @@ RemoteCallbackFreer::~RemoteCallbackFreer() {}
 | 
				
			||||||
void RemoteCallbackFreer::RunDestructor() {
 | 
					void RemoteCallbackFreer::RunDestructor() {
 | 
				
			||||||
  auto* channel = "ELECTRON_RENDERER_RELEASE_CALLBACK";
 | 
					  auto* channel = "ELECTRON_RENDERER_RELEASE_CALLBACK";
 | 
				
			||||||
  base::ListValue args;
 | 
					  base::ListValue args;
 | 
				
			||||||
 | 
					  int32_t sender_id = 0;
 | 
				
			||||||
  args.AppendString(context_id_);
 | 
					  args.AppendString(context_id_);
 | 
				
			||||||
  args.AppendInteger(object_id_);
 | 
					  args.AppendInteger(object_id_);
 | 
				
			||||||
  auto* frame_host = web_contents()->GetMainFrame();
 | 
					  auto* frame_host = web_contents()->GetMainFrame();
 | 
				
			||||||
  if (frame_host) {
 | 
					  if (frame_host) {
 | 
				
			||||||
    frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(), false,
 | 
					    frame_host->Send(new AtomFrameMsg_Message(frame_host->GetRoutingID(), false,
 | 
				
			||||||
                                              channel, args));
 | 
					                                              channel, args, sender_id));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Observe(nullptr);
 | 
					  Observe(nullptr);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,7 +169,8 @@ bool AtomRenderFrameObserver::OnMessageReceived(const IPC::Message& message) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AtomRenderFrameObserver::OnBrowserMessage(bool send_to_all,
 | 
					void AtomRenderFrameObserver::OnBrowserMessage(bool send_to_all,
 | 
				
			||||||
                                               const std::string& channel,
 | 
					                                               const std::string& channel,
 | 
				
			||||||
                                               const base::ListValue& args) {
 | 
					                                               const base::ListValue& args,
 | 
				
			||||||
 | 
					                                               int32_t sender_id) {
 | 
				
			||||||
  // Don't handle browser messages before document element is created.
 | 
					  // Don't handle browser messages before document element is created.
 | 
				
			||||||
  // When we receive a message from the browser, we try to transfer it
 | 
					  // When we receive a message from the browser, we try to transfer it
 | 
				
			||||||
  // to a web page, and when we do that Blink creates an empty
 | 
					  // to a web page, and when we do that Blink creates an empty
 | 
				
			||||||
| 
						 | 
					@ -182,21 +183,22 @@ void AtomRenderFrameObserver::OnBrowserMessage(bool send_to_all,
 | 
				
			||||||
  if (!frame || !render_frame_->IsMainFrame())
 | 
					  if (!frame || !render_frame_->IsMainFrame())
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  EmitIPCEvent(frame, channel, args);
 | 
					  EmitIPCEvent(frame, channel, args, sender_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Also send the message to all sub-frames.
 | 
					  // Also send the message to all sub-frames.
 | 
				
			||||||
  if (send_to_all) {
 | 
					  if (send_to_all) {
 | 
				
			||||||
    for (blink::WebFrame* child = frame->FirstChild(); child;
 | 
					    for (blink::WebFrame* child = frame->FirstChild(); child;
 | 
				
			||||||
         child = child->NextSibling())
 | 
					         child = child->NextSibling())
 | 
				
			||||||
      if (child->IsWebLocalFrame()) {
 | 
					      if (child->IsWebLocalFrame()) {
 | 
				
			||||||
        EmitIPCEvent(child->ToWebLocalFrame(), channel, args);
 | 
					        EmitIPCEvent(child->ToWebLocalFrame(), channel, args, sender_id);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
					void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
				
			||||||
                                           const std::string& channel,
 | 
					                                           const std::string& channel,
 | 
				
			||||||
                                           const base::ListValue& args) {
 | 
					                                           const base::ListValue& args,
 | 
				
			||||||
 | 
					                                           int32_t sender_id) {
 | 
				
			||||||
  if (!frame)
 | 
					  if (!frame)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -218,6 +220,7 @@ void AtomRenderFrameObserver::EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
				
			||||||
    // Insert the Event object, event.sender is ipc.
 | 
					    // Insert the Event object, event.sender is ipc.
 | 
				
			||||||
    mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
 | 
					    mate::Dictionary event = mate::Dictionary::CreateEmpty(isolate);
 | 
				
			||||||
    event.Set("sender", ipc);
 | 
					    event.Set("sender", ipc);
 | 
				
			||||||
 | 
					    event.Set("senderId", sender_id);
 | 
				
			||||||
    args_vector.insert(args_vector.begin(), event.GetHandle());
 | 
					    args_vector.insert(args_vector.begin(), event.GetHandle());
 | 
				
			||||||
    mate::EmitEvent(isolate, ipc, channel, args_vector);
 | 
					    mate::EmitEvent(isolate, ipc, channel, args_vector);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,8 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  virtual void EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
					  virtual void EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
				
			||||||
                            const std::string& channel,
 | 
					                            const std::string& channel,
 | 
				
			||||||
                            const base::ListValue& args);
 | 
					                            const base::ListValue& args,
 | 
				
			||||||
 | 
					                            int32_t sender_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 private:
 | 
					 private:
 | 
				
			||||||
  bool ShouldNotifyClient(int world_id);
 | 
					  bool ShouldNotifyClient(int world_id);
 | 
				
			||||||
| 
						 | 
					@ -54,7 +55,8 @@ class AtomRenderFrameObserver : public content::RenderFrameObserver {
 | 
				
			||||||
  bool IsIsolatedWorld(int world_id);
 | 
					  bool IsIsolatedWorld(int world_id);
 | 
				
			||||||
  void OnBrowserMessage(bool send_to_all,
 | 
					  void OnBrowserMessage(bool send_to_all,
 | 
				
			||||||
                        const std::string& channel,
 | 
					                        const std::string& channel,
 | 
				
			||||||
                        const base::ListValue& args);
 | 
					                        const base::ListValue& args,
 | 
				
			||||||
 | 
					                        int32_t sender_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  content::RenderFrame* render_frame_;
 | 
					  content::RenderFrame* render_frame_;
 | 
				
			||||||
  RendererClientBase* renderer_client_;
 | 
					  RendererClientBase* renderer_client_;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,7 +107,8 @@ class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {
 | 
				
			||||||
 protected:
 | 
					 protected:
 | 
				
			||||||
  void EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
					  void EmitIPCEvent(blink::WebLocalFrame* frame,
 | 
				
			||||||
                    const std::string& channel,
 | 
					                    const std::string& channel,
 | 
				
			||||||
                    const base::ListValue& args) override {
 | 
					                    const base::ListValue& args,
 | 
				
			||||||
 | 
					                    int32_t sender_id) override {
 | 
				
			||||||
    if (!frame)
 | 
					    if (!frame)
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,7 +117,8 @@ class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver {
 | 
				
			||||||
    auto context = frame->MainWorldScriptContext();
 | 
					    auto context = frame->MainWorldScriptContext();
 | 
				
			||||||
    v8::Context::Scope context_scope(context);
 | 
					    v8::Context::Scope context_scope(context);
 | 
				
			||||||
    v8::Local<v8::Value> argv[] = {mate::ConvertToV8(isolate, channel),
 | 
					    v8::Local<v8::Value> argv[] = {mate::ConvertToV8(isolate, channel),
 | 
				
			||||||
                                   mate::ConvertToV8(isolate, args)};
 | 
					                                   mate::ConvertToV8(isolate, args),
 | 
				
			||||||
 | 
					                                   mate::ConvertToV8(isolate, sender_id)};
 | 
				
			||||||
    renderer_client_->InvokeIpcCallback(
 | 
					    renderer_client_->InvokeIpcCallback(
 | 
				
			||||||
        context, "onMessage",
 | 
					        context, "onMessage",
 | 
				
			||||||
        std::vector<v8::Local<v8::Value>>(argv, argv + node::arraysize(argv)));
 | 
					        std::vector<v8::Local<v8::Value>>(argv, argv + node::arraysize(argv)));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,3 +89,17 @@ Sends a message to a window with `windowid` via `channel`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Like `ipcRenderer.send` but the event will be sent to the `<webview>` element in
 | 
					Like `ipcRenderer.send` but the event will be sent to the `<webview>` element in
 | 
				
			||||||
the host page instead of the main process.
 | 
					the host page instead of the main process.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Event object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The `event` object passed to the `callback` has the following methods:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### `event.senderId`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Returns 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`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[ipc-renderer-sendto]: #ipcrenderersendtowindowid-channel--arg1-arg2-
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,8 +9,8 @@ const ipcNative = process.atomBinding('ipc')
 | 
				
			||||||
// private/public APIs.
 | 
					// private/public APIs.
 | 
				
			||||||
v8Util.setHiddenValue(global, 'ipcNative', ipcNative)
 | 
					v8Util.setHiddenValue(global, 'ipcNative', ipcNative)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ipcNative.onMessage = function (channel, args) {
 | 
					ipcNative.onMessage = function (channel, args, senderId) {
 | 
				
			||||||
  ipcRenderer.emit(channel, {sender: ipcRenderer}, ...args)
 | 
					  ipcRenderer.emit(channel, {sender: ipcRenderer, senderId}, ...args)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ipcNative.onExit = function () {
 | 
					ipcNative.onExit = function () {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,8 +132,6 @@ describe('ipc renderer module', () => {
 | 
				
			||||||
  describe('ipcRenderer.sendTo', () => {
 | 
					  describe('ipcRenderer.sendTo', () => {
 | 
				
			||||||
    let contents = null
 | 
					    let contents = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    beforeEach(() => { contents = webContents.create({}) })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    afterEach(() => {
 | 
					    afterEach(() => {
 | 
				
			||||||
      ipcRenderer.removeAllListeners('pong')
 | 
					      ipcRenderer.removeAllListeners('pong')
 | 
				
			||||||
      contents.destroy()
 | 
					      contents.destroy()
 | 
				
			||||||
| 
						 | 
					@ -141,30 +139,58 @@ describe('ipc renderer module', () => {
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('sends message to WebContents', done => {
 | 
					    it('sends message to WebContents', done => {
 | 
				
			||||||
      const webContentsId = remote.getCurrentWebContents().id
 | 
					      contents = webContents.create({
 | 
				
			||||||
 | 
					        preload: path.join(fixtures, 'module', 'preload-inject-ipc.js')
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ipcRenderer.once('pong', (event, id) => {
 | 
					      const payload = 'Hello World!'
 | 
				
			||||||
        expect(webContentsId).to.equal(id)
 | 
					
 | 
				
			||||||
 | 
					      ipcRenderer.once('pong', (event, data) => {
 | 
				
			||||||
 | 
					        expect(payload).to.equal(data)
 | 
				
			||||||
        done()
 | 
					        done()
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      contents.once('did-finish-load', () => {
 | 
					      contents.once('did-finish-load', () => {
 | 
				
			||||||
        ipcRenderer.sendTo(contents.id, 'ping', webContentsId)
 | 
					        ipcRenderer.sendTo(contents.id, 'ping', payload)
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      contents.loadURL(`file://${path.join(fixtures, 'pages', 'ping-pong.html')}`)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('sends message to WebContents (sanboxed renderer)', done => {
 | 
				
			||||||
 | 
					      contents = webContents.create({
 | 
				
			||||||
 | 
					        preload: path.join(fixtures, 'module', 'preload-inject-ipc.js'),
 | 
				
			||||||
 | 
					        sandbox: true
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const payload = 'Hello World!'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ipcRenderer.once('pong', (event, data) => {
 | 
				
			||||||
 | 
					        expect(payload).to.equal(data)
 | 
				
			||||||
 | 
					        done()
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      contents.once('did-finish-load', () => {
 | 
				
			||||||
 | 
					        ipcRenderer.sendTo(contents.id, 'ping', payload)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      contents.loadURL(`file://${path.join(fixtures, 'pages', 'ping-pong.html')}`)
 | 
					      contents.loadURL(`file://${path.join(fixtures, 'pages', 'ping-pong.html')}`)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('sends message to WebContents (channel has special chars)', done => {
 | 
					    it('sends message to WebContents (channel has special chars)', done => {
 | 
				
			||||||
      const webContentsId = remote.getCurrentWebContents().id
 | 
					      contents = webContents.create({
 | 
				
			||||||
 | 
					        preload: path.join(fixtures, 'module', 'preload-inject-ipc.js')
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      ipcRenderer.once('pong-æøåü', (event, id) => {
 | 
					      const payload = 'Hello World!'
 | 
				
			||||||
        expect(webContentsId).to.equal(id)
 | 
					
 | 
				
			||||||
 | 
					      ipcRenderer.once('pong-æøåü', (event, data) => {
 | 
				
			||||||
 | 
					        expect(payload).to.equal(data)
 | 
				
			||||||
        done()
 | 
					        done()
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      contents.once('did-finish-load', () => {
 | 
					      contents.once('did-finish-load', () => {
 | 
				
			||||||
        ipcRenderer.sendTo(contents.id, 'ping-æøåü', webContentsId)
 | 
					        ipcRenderer.sendTo(contents.id, 'ping-æøåü', payload)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      contents.loadURL(`file://${path.join(fixtures, 'pages', 'ping-pong.html')}`)
 | 
					      contents.loadURL(`file://${path.join(fixtures, 'pages', 'ping-pong.html')}`)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								spec/fixtures/pages/ping-pong.html
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								spec/fixtures/pages/ping-pong.html
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,14 +1,12 @@
 | 
				
			||||||
<html>
 | 
					<html>
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
<script type="text/javascript" charset="utf-8">
 | 
					<script type="text/javascript" charset="utf-8">
 | 
				
			||||||
  const {ipcRenderer} = require('electron')
 | 
					  ipcRenderer.on('ping', function (event, payload) {
 | 
				
			||||||
  ipcRenderer.on('ping', function (event, id) {
 | 
					    ipcRenderer.sendTo(event.senderId, 'pong', payload)
 | 
				
			||||||
    ipcRenderer.sendTo(id, 'pong', id)
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  ipcRenderer.on('ping-æøåü', function (event, id) {
 | 
					  ipcRenderer.on('ping-æøåü', function (event, payload) {
 | 
				
			||||||
    ipcRenderer.sendTo(id, 'pong-æøåü', id)
 | 
					    ipcRenderer.sendTo(event.senderId, 'pong-æøåü', payload)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue