diff --git a/.gitignore b/.gitignore index 86fceae..a05abc6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ # compiled output /dist /tmp - +/electron-builds # dependencies /node_modules /bower_components diff --git a/README.md b/README.md index d8c352a..5b49e2e 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ You will need the following things properly installed on your computer. * `ember server` * Visit your app at [http://localhost:4200](http://localhost:4200). +* `ember electron` to run using Electron as stand alone app ### Code Generators @@ -38,6 +39,7 @@ Make use of the many generators for code, try `ember help generate` for more det * `ember build` (development) * `ember build --environment production` (production) +* `ember electron:package` to build Electron binaries or `ember electron:package --platform darwin` to only build an OSX package ### Deploying @@ -50,4 +52,3 @@ Specify what it takes to deploy your app. * Development Browser Extensions * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) - diff --git a/config/environment.js b/config/environment.js index 9e1c33d..93c0c1c 100644 --- a/config/environment.js +++ b/config/environment.js @@ -5,7 +5,7 @@ module.exports = function(environment) { modulePrefix: 'the-scheduler', environment: environment, baseURL: '/', - locationType: 'auto', + locationType: process.env.EMBER_CLI_ELECTRON ? 'hash' : 'auto', EmberENV: { FEATURES: { // Here you can enable experimental features on an ember canary build @@ -40,7 +40,6 @@ module.exports = function(environment) { } if (environment === 'production') { - } return ENV; diff --git a/electron.js b/electron.js new file mode 100644 index 0000000..328f785 --- /dev/null +++ b/electron.js @@ -0,0 +1,90 @@ +/* jshint node: true */ +'use strict'; + +const electron = require('electron'); +const path = require('path'); +const {app, BrowserWindow} = electron; +const dirname = __dirname || path.resolve(path.dirname()); +const emberAppLocation = `file://${dirname}/dist/index.html`; + +let mainWindow = null; + +// Uncomment the lines below to enable Electron's crash reporter +// For more information, see http://electron.atom.io/docs/api/crash-reporter/ + +// electron.crashReporter.start({ +// productName: 'YourName', +// companyName: 'YourCompany', +// submitURL: 'https://your-domain.com/url-to-submit', +// autoSubmit: true +// }); + +app.on('window-all-closed', function onWindowAllClosed() { + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('ready', function onReady() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600 + }); + + delete mainWindow.module; + + // If you want to open up dev tools programmatically, call + // mainWindow.openDevTools(); + + // By default, we'll open the Ember App by directly going to the + // file system. + // + // Please ensure that you have set the locationType option in the + // config/environment.js file to 'hash'. For more information, + // please consult the ember-electron readme. + mainWindow.loadURL(emberAppLocation); + + // If a loading operation goes wrong, we'll send Electron back to + // Ember App entry point + mainWindow.webContents.on('did-fail-load', () => { + mainWindow.loadURL(emberAppLocation); + }); + + mainWindow.webContents.on('crashed', () => { + console.log('Your Ember app (or other code) in the main window has crashed.'); + console.log('This is a serious issue that needs to be handled and/or debugged.'); + }); + + mainWindow.on('unresponsive', () => { + console.log('Your Ember app (or other code) has made the window unresponsive.'); + }); + + mainWindow.on('responsive', () => { + console.log('The main window has become responsive again.'); + }); + + mainWindow.on('closed', () => { + mainWindow = null; + }); + + // Handle an unhandled error in the main thread + // + // Note that 'uncaughtException' is a crude mechanism for exception handling intended to + // be used only as a last resort. The event should not be used as an equivalent to + // "On Error Resume Next". Unhandled exceptions inherently mean that an application is in + // an undefined state. Attempting to resume application code without properly recovering + // from the exception can cause additional unforeseen and unpredictable issues. + // + // Attempting to resume normally after an uncaught exception can be similar to pulling out + // of the power cord when upgrading a computer -- nine out of ten times nothing happens - + // but the 10th time, the system becomes corrupted. + // + // The correct use of 'uncaughtException' is to perform synchronous cleanup of allocated + // resources (e.g. file descriptors, handles, etc) before shutting down the process. It is + // not safe to resume normal operation after 'uncaughtException'. + process.on('uncaughtException', (err) => { + console.log('An exception in the main thread was not handled.'); + console.log('This is a serious issue that needs to be handled and/or debugged.'); + console.log(`Exception: ${err}`); + }); +}); diff --git a/package.json b/package.json index 62f8736..5c908e4 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,10 @@ "license": "MIT", "devDependencies": { "broccoli-asset-rev": "^2.4.2", + "devtron": "1.2.1", + "electron-packager": "7.1.0", + "electron-prebuilt": "1.2.5", + "electron-rebuild": "1.1.5", "ember-ajax": "0.7.1", "ember-bootstrap": "0.7.0", "ember-cli": "2.5.0", @@ -35,11 +39,55 @@ "ember-cli-sri": "^2.1.0", "ember-cli-uglify": "^1.2.0", "ember-data": "^2.5.0", + "ember-electron": "1.7.1", "ember-export-application-global": "^1.0.5", + "ember-inspector": "1.10.0", "ember-load-initializers": "^0.5.1", "ember-localstorage-adapter": "1.0.0-rc.1", "ember-resolver": "^2.0.3", "ember-truth-helpers": "1.2.0", "loader.js": "^4.0.1" + }, + "main": "electron.js", + "ember-electron": { + "WHAT IS THIS?": "Please see the README.md", + "copy-files": [ + "electron.js", + "package.json" + ], + "name": null, + "platform": null, + "arch": null, + "version": null, + "app-bundle-id": null, + "app-category-type": null, + "app-copyright": null, + "app-version": null, + "asar": null, + "asar-unpack": null, + "asar-unpack-dir": null, + "build-version": null, + "cache": null, + "extend-info": null, + "extra-resource": null, + "helper-bundle-id": null, + "icon": null, + "ignore": null, + "out": null, + "osx-sign": { + "identity": null, + "entitlements": null, + "entitlements-inherit": null + }, + "overwrite": null, + "prune": null, + "strict-ssl": null, + "version-string": { + "CompanyName": null, + "FileDescription": null, + "OriginalFilename": null, + "ProductName": null, + "InternalName": null + } } } diff --git a/tests/electron.js b/tests/electron.js new file mode 100644 index 0000000..65d9c8b --- /dev/null +++ b/tests/electron.js @@ -0,0 +1,32 @@ +/* jshint undef: false */ + +const {BrowserWindow, app} = require('electron'); + +let mainWindow = null; + +app.on('window-all-closed', function onWindowAllClosed() { + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('ready', function onReady() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600 + }); + + delete mainWindow.module; + + if (process.env.EMBER_ENV === 'test') { + mainWindow.loadURL('file://' + __dirname + '/index.html'); + } else { + mainWindow.loadURL('file://' + __dirname + '/dist/index.html'); + } + + mainWindow.on('closed', function onClosed() { + mainWindow = null; + }); +}); + +/* jshint undef: true */ diff --git a/tests/package.json b/tests/package.json new file mode 100644 index 0000000..8c61a3e --- /dev/null +++ b/tests/package.json @@ -0,0 +1,4 @@ +{ + "name": "ember-electron-test", + "main": "electron.js" +}