Sending documents to the main (Node.js) process

In this section, we're going to send the document to the main process. Follow these steps to do so:

  1. Import ipcMain into the menu.js file, as shown in the following code:
const { Menu, BrowserWindow, dialog, ipcMain } = require('electron');

Now, we need to implement the saveFile function. You may have done this already in Chapter 2, Building a Markdown Editor.

  1. Add the following code either at the beginning or at the bottom of the menu.js file:
function saveFile(contents) {
const window = BrowserWindow.getFocusedWindow();
const options = {
title: 'Save markdown file',
filters: [
{ name: 'MyFile', extensions: ['md'] }
]
};
dialog.showSaveDialog(window, options, filename => {
if (filename) {
fs.writeFileSync(filename, contents);
}
});
}

The saveFile function expects a contents parameter, which is where we pass the contents of the markdown file. After that, it displays the system Save Dialog, where you can pick the destination and save the file to our local drive.

We are going to listen to the save channel so that we can invoke the saveFile feature. The renderer (Chrome) part should now send the markdown's contents to the save channel to initiate the save dialog.

  1. Update the menu.js file with the listener code, as follows:
ipcMain.on('save', (_, contents) => {
saveFile(contents);
});

  1. Now, you need to update the client-side part. At this point, you have the option to either remove the previous code or have a dual behavior. With the dual behavior, you can save the file using a regular browser. Alternatively, you can send the file's content to Node.js when you're running the Electron shell.

The code for the dual behavior can be created with a simple if... else statement, as follows:

const saveFile = contents => {
if (window.require) {
// send to the node.js
} else {
// invoke download of the file
}
};
  1. Update the saveFile implementation of the Editor.js file according to the following code:
const saveFile = contents => {
// save via node.js process
if (window.require) {
const electron = window.require('electron');
const ipcRenderer = electron.ipcRenderer;

ipcRenderer.send('save', contents);
}
// save via the browser
else {
// ...
}
};
  1. Run the web server and use your preferred browser to test the Cmd + S or Ctrl + S feature.
  2. Run the Electron shell with the npm run electron command and perform the same test once again. Everything should be working as expected.

In the next section, we are going to get the HTML conversion into the application. Similar to the Save channel, we can introduce a separate messaging channel for content conversion. Follow these steps to do so:

  1. Let's put a new keyboard combination into the application. This can be anything you like. For the sake of simplicity, let's use Cmd + Shift + H to generate the HTML. Later in this chapter, we will use Cmd + Shift + P to generate a PDF.
  2. Update the editorDidMount function's implementation with the new keyboard handler, as shown in the following code:
editor.addCommand(
monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.KEY_H,
() => {
const code = editor.getModel().getValue();
generateHTML(code);
}
);
  1. Create the generateHTML function so that you can send the markdown content of the code editor to the generate channel:
const generateHTML = contents => {
if (window.require) {
const electron = window.require('electron');
const ipcRenderer = electron.ipcRenderer;

ipcRenderer.send('generate', {
format: 'html',
text: contents
});
}
};

Note how we pass the format as a payload option. This allows us to have a single channel for all kinds of formats in case we decide to provide support for more than one. This also simplifies the Node.js process as you can have a single function that parses the payload and invokes different features.

  1. Update the code in menu.js with the following stub:
ipcMain.on('generate', (_, payload) => {
if (payload && payload.format) {
switch (payload.format) {
case 'html':
generateHTML(payload.text);
break;
default:
break;
}
}
});

function generateHTML(contents) {
// todo: implementation
}

As you can see, the preceding code is pretty universal, and you can extend the support for different formats without rewriting significant portions of the code.

Now, it's time to use Docker to generate the HTML output from the markdown and invoke the browser to see the results.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset