Skip to content

Commit

Permalink
getting stdin to work with examples
Browse files Browse the repository at this point in the history
  • Loading branch information
mattdesl committed Jan 20, 2016
1 parent f7545d6 commit 37f0280
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -4,4 +4,5 @@ node_modules
.DS_Store
bundle.js
example/streetview.png
example/markdown.png
!test/fixtures/node_modules
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -129,8 +129,9 @@ Result:

See the [example/](./example/) folder for more ideas, and the [package.json](./package.json) scripts which run them.

- [example/markdown.js](./example/markdown.js) - Renders a `.md` file with GitHub Flavored Markdown to a PNG image
- [example/es2015.js](./example/es2015.js) - ES2015 transpiling
- [example/geolocate.js](./example/geolocate.js) - prints current latitude,longitude to `stdout`
- [example/geolocate.js](./example/geolocate.js) - prints current `[ latitude, longitude ]` to `stdout`
- [example/http.js](./example/http.js) - a simple Node.js server that you can throw break points into

## Features
Expand Down
5 changes: 4 additions & 1 deletion bin/index.js
Expand Up @@ -5,9 +5,12 @@ const path = require('path');
const serverPath = path.join(__dirname, '../server.js');

var args = [ serverPath ].concat(process.argv.slice(2));
var proc = spawn(electron, args);
var proc = spawn(electron, args, {
stdio: [ process.stdin, 'pipe', 'pipe' ]
});
proc.stdout.pipe(process.stdout);
proc.stderr.pipe(process.stderr);

proc.on('close', function (code) {
process.exit(code);
});
41 changes: 41 additions & 0 deletions example/markdown.js
@@ -0,0 +1,41 @@
/*
This demo renders markdown documents to an image.
- Reads markdown from stdin
- Renders it to the document.body with GFM
- Shows the browser window and captures the screen
- Writes PNG to process.stdout
npm run markdown
*/

var marked = require('marked');
var remote = require('electron').remote;

var css = require.resolve('github-markdown-css/github-markdown.css');
var cssFile = require('fs').readFileSync(css, 'utf8');
require('insert-css')(cssFile);

require('get-stdin')()
.then(function (src) {
capture(src.toString());
}, function (err) {
console.error(err);
process.exit(1);
});

function capture (md) {
document.body.className = 'markdown-body';
document.body.innerHTML = marked(md);

var browserWindow = remote.getCurrentWindow();
browserWindow.show();
browserWindow.setContentSize(720, 640);
setTimeout(function () {
browserWindow.capturePage(function (data) {
process.stdout.write(data.toPng());
window.close();
});
}, 500);
}
29 changes: 23 additions & 6 deletions lib/preload.js
Expand Up @@ -8,11 +8,9 @@
var ipc = electron.ipcRenderer;
var _process = remote.process;
var cwd = _process.cwd();

// setup renderer process to look a bit more like node
process.chdir(cwd);
process.argv = _process.argv;
process.exit = _process.exit.bind(_process);

// setup process to be more like Node.js
hookProcess();

// if we should pipe DevTools console back to terminal
if (remote.getGlobal('__electronConsoleHook')) {
Expand All @@ -27,7 +25,7 @@
// When there is an uncaught exception in the entry
// script, we may want to quit the devtool (i.e. for CI)
// or just print an error in DevTools console (i.e. for dev)
var shouldQuit = remote.getGlobal('__shouldElectronQuitOnError');
var shouldQuit = remote.getGlobal('__electronQuitOnError');
if (shouldQuit) {
window.onerror = function (a, b, c, d, err) {
fatalError(err);
Expand Down Expand Up @@ -63,4 +61,23 @@
function fatalError (err) {
ipc.send('error', JSON.stringify(serialize(err)));
}

function hookProcess () {
// setup renderer process to look a bit more like node
process.chdir(cwd);
process.argv = _process.argv;
process.exit = _process.exit.bind(_process);

var isTTY = remote.getGlobal('__electronProcessTTY');
process.stdin.isTTY = isTTY.stdin;
process.stdout.isTTY = isTTY.stdout;
process.stderr.isTTY = isTTY.stderr;
process.stdin._read = function () {
this.push('');
};

ipc.on('stdin', function (event, data) {
process.stdin.push(data);
});
}
})();
5 changes: 5 additions & 0 deletions package.json
Expand Up @@ -32,12 +32,17 @@
"cross-spawn-async": "^2.1.6",
"electron-canvas-to-buffer": "^1.0.3",
"faucet": "0.0.1",
"get-stdin": "^5.0.1",
"github-markdown-css": "^2.2.0",
"google-panorama-by-location": "^4.1.1",
"google-panorama-equirectangular": "^1.2.0",
"insert-css": "^0.2.0",
"marked": "^0.3.5",
"tape": "^4.4.0"
},
"scripts": {
"test": "node test/index.js | faucet",
"markdown": "./bin/index.js example/markdown.js -hqc < README.md > example/markdown.png",
"http": "./bin/index.js example/http -w",
"geolocate": "./bin/index.js example/geolocate.js -qch",
"es2015": "./bin/index.js example/es2015.js -w -i example/es2015.html",
Expand Down
40 changes: 34 additions & 6 deletions server.js
Expand Up @@ -29,15 +29,21 @@ app.commandLine.appendSwitch('disable-http-cache');
app.commandLine.appendSwitch('v', 0);
app.commandLine.appendSwitch('vmodule', 'console=0');

global.__shouldElectronQuitOnError = true; // true until app starts
process.stdin.pause();
global.__electronQuitOnError = true; // true until app starts
global.__electronEntryFile = argv._[0];
global.__electronConsoleHook = argv.console;
global.__electronBrowserResolve = argv.browserField;
global.__electronProcessTTY = {
stdin: process.stdin.isTTY,
stdout: process.stdout.isTTY,
stderr: process.stderr.isTTY
};

var exitWithCode1 = false;
process.on('uncaughtException', function (err) {
console.error(err);
if (global.__shouldElectronQuitOnError) {
if (global.__electronQuitOnError) {
exitWithCode1 = true;
app.quit();
}
Expand All @@ -52,6 +58,8 @@ if (argv.index) {
}
var htmlData = fs.readFileSync(htmlFile);

// var isTTY = process.stdin.isTTY;

var watcher = null;
var mainWindow = null;
app.on('window-all-closed', function () {
Expand Down Expand Up @@ -128,25 +136,45 @@ app.on('ready', function () {
});

webContents.once('did-finish-load', function () {
global.__shouldElectronQuitOnError = argv.quit;
if (!argv.headless) webContents.openDevTools();
global.__electronQuitOnError = argv.quit;
if (!argv.headless) {
webContents.openDevTools();
webContents.once('devtools-opened', sendStdin);
} else {
// TODO: Find out why this timeout is necessary.
// stdin is not triggering if sent immediately
setTimeout(function () {
sendStdin();
}, 500);
}
});

mainWindow.loadURL(mainIndexURL);
mainWindow.on('closed', function () {
mainWindow = null;
});

function sendStdin () {
process.stdin
.on('data', function (data) {
mainWindow.send('stdin', data);
})
.on('end', function () {
mainWindow.send('stdin', null);
})
.resume();
}

function bail (err) {
console.error(err.stack ? err.stack : err);
if (global.__shouldElectronQuitOnError) {
if (global.__electronQuitOnError) {
exitWithCode1 = true;
if (mainWindow) mainWindow.close();
}
}

function fatal (err) {
global.__shouldElectronQuitOnError = true;
global.__electronQuitOnError = true;
bail(err);
}
});

0 comments on commit 37f0280

Please sign in to comment.