seanchas116 / electron-safe-ipc

Safe communication between main process and renderer processes in Electron
MIT License
26 stars 4 forks source link

Node disabled webview does not receive the message #1

Closed petrfelzmann closed 9 years ago

petrfelzmann commented 9 years ago

Thank you for your code, it is exactly what I need! Particularly the case with node disabled webview. But unfortunately I cannot receive the message in the webview.

The main window loads this web page:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script>
        document.addEventListener("DOMContentLoaded", function() {

            // register console-message event to get working console.log inside webview
            var webview = document.getElementById('webview');
            webview.addEventListener('console-message', function(e) {
                console.log(e.message);
            });

            // send the message           
            var remote = require('remote');
            var ipc = remote.require('electron-safe-ipc/main');
            console.log('sending');
            ipc.send('fromMain', 'foobar');

        });
    </script>
</head>
<body>
    <webview id="webview" src="webview.html"></webview>
</body>
</html>

where webview.html contains the message subscription:

<!DOCTYPE HTML>
<html>
<head>
    <title></title>
    <script src="node_modules/electron-safe-ipc/renderer-bundle.js"></script>
    <script>
        electronSafeIpc.on('fromMain', function (msg) {
            console.log(msg); // never displayed :(
        });
    </script>
</head>
<body>
    <p>Webview content</p>
</body>
</html>

but the message 'foobar' is never displayed in the console.

seanchas116 commented 9 years ago

Thanks, it because current implementation sends messages only to BrowserWindows but not to webviews... (https://github.com/seanchas116/electron-safe-ipc/blob/master/main.js#L30)

Maybe we need another mode to communicate between renderer processes and webviews.

petrfelzmann commented 9 years ago

What that 'mode' could be? I do not have any idea right now...

seanchas116 commented 9 years ago

Requiring this code from renderer instead of remote.require('electron-safe-ipc/main') works:

"use strict";

var EventEmitter = require("events").EventEmitter;
var remote = require("remote");
var protocol = remote.require("protocol");
var arraySlice = Array.prototype.slice;
var url = require("url");
var qs = require("querystring");

var ipc = new EventEmitter();

protocol.registerProtocol("electron-safe-ipc", function (request) {
  // nextTick workaround to prevent crash on exception
  process.nextTick(function () {
    var urlContents = url.parse(request.url);
    var queries = qs.parse(urlContents.query);

    var channel = queries.channel;
    var args = JSON.parse(queries.argsJson);

    ipc.emit.apply(ipc, [channel].concat(args));
  });
  return new protocol.RequestStringJob({data: ""});
});

ipc.send = function() {
  var channel = arguments[0];
  var args = arraySlice.call(arguments, 1);

  [].forEach.call(document.querySelectorAll("webview"), function (webview) {
    var script = "window.__electronSafeIpc && window.__electronSafeIpc("
      + JSON.stringify(channel) + ","
      + JSON.stringify(JSON.stringify(args))
      + ");";
    webview.executeJavaScript(script);
  });
};

module.exports = ipc;
seanchas116 commented 9 years ago

I'll try implementing this in electron-safe-ipc.

petrfelzmann commented 9 years ago

Excellent, thank you! :+1: :star: :clap:

seanchas116 commented 9 years ago

I released 0.5.0 with webview support (https://github.com/seanchas116/electron-safe-ipc#communicate-between-renderer-process-and-webview). Could you check this out?

petrfelzmann commented 9 years ago

:ok_hand: It works, superb! Thx!

seanchas116 commented 9 years ago

Thanks for reporting, too!