Skip to content

Commit

Permalink
Allow Electron process to be accessed from JavaScript FFI. #200
Browse files Browse the repository at this point in the history
The file `index.html` now loads jQuery correctly
if used in the context of an Electron `BrowserWindow`.
This allows us to set `nodeIntegration=true` in
`electron.js` and gives access to Electron’s
main process from the Browser Window.
  • Loading branch information
bradrn authored and HeinrichApfelmus committed Sep 19, 2017
1 parent 21c0360 commit 3d0f808
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -3,8 +3,11 @@
**0.8.2.0** — Snapshot release

* Add `getCookies` function that retrieves the cookies sent with the HTTP request when the browser window connects (to the websocket). [#137][]
* Allow Electron process to be accessed from JavaScript FFI. [#200][] This means that Threepenny is now more useful when used with the [Electron][] framework, see [doc/electron.md](doc/electron.md) for more information on that.

[#137]: https://github.com/HeinrichApfelmus/threepenny-gui/issues/137
[#200]: https://github.com/HeinrichApfelmus/threepenny-gui/issues/200
[electron]: https://electron.atom.io

**0.8.1.0** — Snapshot release

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS
Expand Up @@ -16,6 +16,7 @@ Felipe Lessa <https://github.com/meteficha>
Wesley Massuda <https://github.com/massudaw>
Daniel Mlot <https://github.com/duplode>
JP Moresmau <https://github.com/JPMoresmau>
Brad Neimann <https://github.com/bradrn>
Luke Palmer
Jens Peterson
Jaap van der Plas
Expand Down
30 changes: 29 additions & 1 deletion doc/electron.md
Expand Up @@ -35,7 +35,7 @@ following on startup:
- opens an Electron window which loads the URL of our Threepenny app

To get started with the linked `electron.js` first add
this [package.json]('./electron/package.json') to your project root directory.
this [package.json](./electron/package.json) to your project root directory.
You'll need Node installed and `npm` on your PATH, confirm by running `which
npm`. Now run `npm install` from the project root directory to install the
necessary dependencies.
Expand Down Expand Up @@ -79,6 +79,34 @@ directory:

Now you can simply set `relBin` to `./build/your-app-exe`.

## Accessing electron with FFI

The Haskell FFI can be used to access electron utilities.
For instance, to display a dialog when a button is pressed:

```Haskell
button <- UI.button # set UI.text "Click me!"
on UI.click button $ const $ runFunction $ ffi "require('electron').dialog.showOpenDialog({})"
```

A reference of electron functions can be found at https://electron.atom.io/docs/.

The [jmacro](https://hackage.haskell.org/package/jmacro) library could prove useful for more involved applications, such as showing a modal dialog:

```Haskell
runFunction $ ffi $ show $ renderJs
[jmacro|
var {|BrowserWindow: BrowserWindow|} = remote;
var modal = new BrowserWindow({parent: remote.getCurrentWindow(),
modal: true,
show: false});
modal.setMenu(null);
modal.loadURL('file://' + require('path').join(remote.app.getAppPath(), 'dialog.html'));

modal.once('ready-to-show', \() { modal.show() })
|]
```

## Packaging with electron-packager
This section assumes the app is already setup to run with Electron based on
the [above](#running-with-electron) instructions.
Expand Down
2 changes: 1 addition & 1 deletion doc/electron/electron.js
Expand Up @@ -27,7 +27,7 @@ freeport((err, port) => {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: { nodeIntegration: false },
webPreferences: { nodeIntegration: true },
});

console.log(`Loading URL: ${url}`);
Expand Down
5 changes: 5 additions & 0 deletions js/index.html
Expand Up @@ -3,7 +3,12 @@
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" type="text/css" href="haskell.css"/>

<!-- See https://stackoverflow.com/a/37480521 -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script src="haskell.js"></script>
<script>if (window.module) module = window.module;</script>

<script type="text/javascript" charset="utf-8">
Haskell.initFFI();
</script>
Expand Down

0 comments on commit 3d0f808

Please sign in to comment.