Send message from index.html to online webview


#1

I’m loading an online ReactJS app inside my Electron application through a webview.

Now I want to send a message from Electron index.html to the webview, so I can trigger an action inside the webview.

These are the main files:

index.html:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="./styles.css">
  </head>
  <body>
    <div id="topbar">
      <p>Solitaire</p>
    </div>
    <div id="loader_component" className="loader_component">
      <div id="loader_container">
        <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
          <g>
            <path fill="#000000" transform="translate(20, 20)" d="M34.083 44.139c2.498 3.905 6.874 6.495 11.855 6.495C53.702 50.634 60 44.336 60 36.57c0-7.768-6.298-14.066-14.062-14.066-2.027 0-3.954.429-5.695 1.2a14.014 14.014 0 0 0 3.821-9.636C44.064 6.3 37.766 0 29.998 0c-7.764 0-14.062 6.3-14.062 14.068 0 3.73 1.452 7.121 3.822 9.638a14.006 14.006 0 0 0-5.696-1.202C6.294 22.504 0 28.802 0 36.57c0 7.766 6.294 14.064 14.062 14.064 5.07 0 9.516-2.686 11.99-6.714C24.512 50.416 22.93 58 22.93 58h14.436s-1.695-7.392-3.283-13.861z" />
          </g>
        </svg>
        <p><span className="counter">0</span>%</p>
      </div>
    </div>
    <div id="offline_error">
      <p>Solitaire is not available offline.</p>
    </div>
    <script type="text/javascript" src="index.js"></script>
  </body>
</html>

index.js:

//-----------------------------------------------------------------------
// Helpers
//-----------------------------------------------------------------------
// Function to find parameter
const getParams = (query) => {
  if (!query) {
    return { };
  }

  return (/^[?#]/.test(query) ? query.slice(1) : query)
    .split('&')
    .reduce((params, param) => {
      const [key, value] = param.split('=');
      params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
      return params;
    }, { });
};

//-----------------------------------------------------------------------
// Webview
//-----------------------------------------------------------------------
// Create webview
const webview = document.createElement('webview');

// Handle webview loaded
const handleDomReady = () => {
  console.log('handleDomReady');
  // Hide loader
  const loaderElement = document.getElementById('loader_component');
  loaderElement.style.display = 'none';

  // Show development console for webview
  webview.openDevTools();

  setInterval(() => {
    webview.send('message', 'http://localhost:3000');
    webview.send('message');
  }, 1000);
};

// Setup webview
webview.id = 'webview';
webview.preload = 'preload.js';
// webview.setAttribute('nodeintegration', '');
webview.setAttribute('disablewebsecurity', '');
webview.setAttribute('allowpopups', '');
webview.addEventListener('dom-ready', handleDomReady);
console.log(webview);

// Add webview to body
document.body.appendChild(webview);

//-----------------------------------------------------------------------
// Siteload
//-----------------------------------------------------------------------
// Create timer
let onlineCheckTimer;

// Detect if online
const loadSite = () => {
  const offlineElement = document.getElementById('offline_error');
  if (navigator.onLine) {
    offlineElement.style.display = 'none';
    webview.src = getParams(window.location.search).environment === 'production' ? `https://solitairegamecenter.com/?platform=desktop&version=${getParams(window.location.search).version}` : `http://localhost:3000/?platform=desktop&version=${getParams(window.location.search).version}`;
    clearTimeout(onlineCheckTimer);
  } else {
    offlineElement.style.display = 'block';
  }
};

// Try to load website
onlineCheckTimer = setInterval(loadSite, 1000);
loadSite();

client.js (the website):

window.addEventListener('message', (event) => {
  console.log('message b 1');
  console.log(event.data);
});

preload.js:

// Load electron
const { ipcRenderer } = require('electron');


// Injection technique borrowed from http://stackoverflow.com/questions/840240/injecting-jquery-into-a-page-fails-when-using-google-ajax-libraries-api
window.onload = () => {
  // Load jQuery
  const script = document.createElement('script');
  script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js';
  document.body.appendChild(script);

  // Listen for messages
  ipcRenderer.on('message', () => {
    console.log('Received a message');
  });
};

So I’m sending a message in index.js on line 36 and from what I understand, I should receive that message in client.js, by using the event listener, but I’m not receiving anything.

What am I doing wrong here? Is it even possible to send a message to a webview that has loaded an online site?