2016-01-24 13:20:29 +00:00
|
|
|
import 'source-map-support/register';
|
2016-01-29 14:04:41 +00:00
|
|
|
import fs from 'fs';
|
|
|
|
import path from 'path';
|
2018-11-05 02:03:52 +00:00
|
|
|
import { app, crashReporter, globalShortcut } from 'electron';
|
2017-04-29 14:52:12 +00:00
|
|
|
import electronDownload from 'electron-dl';
|
|
|
|
|
2016-01-29 14:04:41 +00:00
|
|
|
import createLoginWindow from './components/login/loginWindow';
|
|
|
|
import createMainWindow from './components/mainWindow/mainWindow';
|
2017-10-05 23:32:48 +00:00
|
|
|
import createTrayIcon from './components/trayIcon/trayIcon';
|
2016-01-29 14:04:41 +00:00
|
|
|
import helpers from './helpers/helpers';
|
2016-02-23 08:46:14 +00:00
|
|
|
import inferFlash from './helpers/inferFlash';
|
2016-01-24 13:20:29 +00:00
|
|
|
|
Support packaging nativefier applications into Squirrel-based installers (#744)
[Squirrel](https://github.com/Squirrel/Squirrel.Windows) is *"an installation and update
framework for Windows desktop apps "*.
This PR adds `electron-squirrel-startup`, allowing to package nativefier applications
into squirrel-based setup installers. Squirrel require this entrypoint to perform
desktop and startup menu creations, without showing the UI on setup launches.
- References: https://github.com/mongodb-js/electron-squirrel-startup
- Resolves `electron-winstaller` and `electron-installer-windows` support of desktop / startup menu shortcuts for nativefier packaged applications.
- The `electron-squirrel-startup` entrypoint has no effect on both Linux and Darwin, only on Windows
- Supporting it directly inside `nativefier` avoids having to "hack" around the existing `main.js`
and including dependencies from `electron-squirrel-startup` in an intermediate package
to be included in a third layer for the final installer executable
- The following script based on both `nativefier` and `electron-winstaller` templates
represents a portable proof of concept for this merge request :
```js
var nativefier = require('nativefier').default;
var electronInstaller = require('electron-winstaller');
var options = {
name: 'Web WhatsApp',
targetUrl: 'http://web.whatsapp.com',
platform: 'windows',
arch: 'x64',
version: '0.36.4',
out: '.',
overwrite: false,
asar: false,
counter: false,
bounce: false,
width: 1280,
height: 800,
showMenuBar: false,
fastQuit: false,
userAgent: 'Mozilla ...',
ignoreCertificate: false,
ignoreGpuBlacklist: false,
enableEs3Apis: false,
insecure: false,
honest: false,
zoom: 1.0,
singleInstance: false,
fileDownloadOptions: {
saveAs: true
},
processEnvs: {
GOOGLE_API_KEY: '<your-google-api-key>'
}
};
nativefier(options, function(error, appPath) {
if (error) {
console.error(error);
return;
}
console.log('App has been nativefied to', appPath);
resultPromise = electronInstaller.createWindowsInstaller({
appDirectory: 'Web WhatsApp-win32-x64',
outputDirectory: './',
authors: 'Web WhatsApp',
exe: 'Web WhatsApp.exe'
});
resultPromise.then(() => console.log('It worked!'), e => console.log(`No dice: ${e.message}`));
});
```
2019-02-08 14:57:32 +00:00
|
|
|
const electronSquirrelStartup = require('electron-squirrel-startup');
|
|
|
|
|
|
|
|
// Entrypoint for electron-squirrel-startup.
|
|
|
|
// See https://github.com/jiahaog/nativefier/pull/744 for sample use case
|
|
|
|
if (electronSquirrelStartup) {
|
|
|
|
app.quit();
|
|
|
|
}
|
|
|
|
|
2017-04-29 14:52:12 +00:00
|
|
|
const { isOSX } = helpers;
|
2016-01-19 11:53:10 +00:00
|
|
|
|
2016-01-22 11:57:39 +00:00
|
|
|
const APP_ARGS_FILE_PATH = path.join(__dirname, '..', 'nativefier.json');
|
2016-01-29 14:04:41 +00:00
|
|
|
const appArgs = JSON.parse(fs.readFileSync(APP_ARGS_FILE_PATH, 'utf8'));
|
2015-07-06 02:31:09 +00:00
|
|
|
|
2018-01-26 14:59:58 +00:00
|
|
|
const fileDownloadOptions = Object.assign({}, appArgs.fileDownloadOptions);
|
|
|
|
electronDownload(fileDownloadOptions);
|
|
|
|
|
2017-08-16 14:20:43 +00:00
|
|
|
if (appArgs.processEnvs) {
|
|
|
|
Object.keys(appArgs.processEnvs).forEach((key) => {
|
|
|
|
/* eslint-env node */
|
|
|
|
process.env[key] = appArgs.processEnvs[key];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-01-29 14:04:41 +00:00
|
|
|
let mainWindow;
|
2016-01-23 02:09:47 +00:00
|
|
|
|
2016-03-26 07:06:50 +00:00
|
|
|
if (typeof appArgs.flashPluginDir === 'string') {
|
2017-04-29 14:52:12 +00:00
|
|
|
app.commandLine.appendSwitch('ppapi-flash-path', appArgs.flashPluginDir);
|
2016-03-26 07:06:50 +00:00
|
|
|
} else if (appArgs.flashPluginDir) {
|
2017-04-29 14:52:12 +00:00
|
|
|
const flashPath = inferFlash();
|
|
|
|
app.commandLine.appendSwitch('ppapi-flash-path', flashPath);
|
2016-02-23 08:46:14 +00:00
|
|
|
}
|
|
|
|
|
2016-02-23 13:31:47 +00:00
|
|
|
if (appArgs.ignoreCertificate) {
|
2017-04-29 14:52:12 +00:00
|
|
|
app.commandLine.appendSwitch('ignore-certificate-errors');
|
2016-01-25 15:42:28 +00:00
|
|
|
}
|
|
|
|
|
2018-04-22 19:56:10 +00:00
|
|
|
if (appArgs.disableGpu) {
|
|
|
|
app.disableHardwareAcceleration();
|
|
|
|
}
|
|
|
|
|
2017-07-13 16:23:07 +00:00
|
|
|
if (appArgs.ignoreGpuBlacklist) {
|
|
|
|
app.commandLine.appendSwitch('ignore-gpu-blacklist');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (appArgs.enableEs3Apis) {
|
|
|
|
app.commandLine.appendSwitch('enable-es3-apis');
|
|
|
|
}
|
|
|
|
|
2017-07-05 13:07:31 +00:00
|
|
|
if (appArgs.diskCacheSize) {
|
|
|
|
app.commandLine.appendSwitch('disk-cache-size', appArgs.diskCacheSize);
|
|
|
|
}
|
|
|
|
|
2017-10-05 22:44:03 +00:00
|
|
|
if (appArgs.basicAuthUsername) {
|
2018-05-24 07:02:44 +00:00
|
|
|
app.commandLine.appendSwitch(
|
|
|
|
'basic-auth-username',
|
|
|
|
appArgs.basicAuthUsername,
|
|
|
|
);
|
2017-10-05 22:44:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (appArgs.basicAuthPassword) {
|
2018-05-24 07:02:44 +00:00
|
|
|
app.commandLine.appendSwitch(
|
|
|
|
'basic-auth-password',
|
|
|
|
appArgs.basicAuthPassword,
|
|
|
|
);
|
2017-10-05 22:44:03 +00:00
|
|
|
}
|
|
|
|
|
2016-01-23 07:12:53 +00:00
|
|
|
// do nothing for setDockBadge if not OSX
|
|
|
|
let setDockBadge = () => {};
|
2016-01-23 18:02:23 +00:00
|
|
|
|
2016-01-23 07:12:53 +00:00
|
|
|
if (isOSX()) {
|
2018-04-14 21:17:25 +00:00
|
|
|
let currentBadgeCount = 0;
|
|
|
|
|
|
|
|
setDockBadge = (count, bounce = false) => {
|
|
|
|
app.dock.setBadge(count);
|
|
|
|
if (bounce && count > currentBadgeCount) app.dock.bounce();
|
|
|
|
currentBadgeCount = count;
|
|
|
|
};
|
2016-01-23 07:12:53 +00:00
|
|
|
}
|
|
|
|
|
2016-01-29 14:04:41 +00:00
|
|
|
app.on('window-all-closed', () => {
|
2017-04-29 14:52:12 +00:00
|
|
|
if (!isOSX() || appArgs.fastQuit) {
|
|
|
|
app.quit();
|
|
|
|
}
|
2015-07-05 06:08:13 +00:00
|
|
|
});
|
|
|
|
|
2016-01-29 14:04:41 +00:00
|
|
|
app.on('activate', (event, hasVisibleWindows) => {
|
2017-04-29 14:52:12 +00:00
|
|
|
if (isOSX()) {
|
2017-11-14 13:05:01 +00:00
|
|
|
// this is called when the dock is clicked
|
2017-04-29 14:52:12 +00:00
|
|
|
if (!hasVisibleWindows) {
|
|
|
|
mainWindow.show();
|
2016-01-21 04:25:33 +00:00
|
|
|
}
|
2017-04-29 14:52:12 +00:00
|
|
|
}
|
2016-01-21 04:25:33 +00:00
|
|
|
});
|
|
|
|
|
2016-01-29 14:04:41 +00:00
|
|
|
app.on('before-quit', () => {
|
2017-04-29 14:52:12 +00:00
|
|
|
// not fired when the close button on the window is clicked
|
|
|
|
if (isOSX()) {
|
|
|
|
// need to force a quit as a workaround here to simulate the osx app hiding behaviour
|
|
|
|
// Somehow sokution at https://github.com/atom/electron/issues/444#issuecomment-76492576 does not work,
|
|
|
|
// e.prevent default appears to persist
|
|
|
|
|
|
|
|
// might cause issues in the future as before-quit and will-quit events are not called
|
|
|
|
app.exit(0);
|
|
|
|
}
|
2016-01-21 04:25:33 +00:00
|
|
|
});
|
|
|
|
|
2016-10-09 05:52:50 +00:00
|
|
|
if (appArgs.crashReporter) {
|
2017-04-29 14:52:12 +00:00
|
|
|
app.on('will-finish-launching', () => {
|
|
|
|
crashReporter.start({
|
2017-07-21 19:55:39 +00:00
|
|
|
companyName: appArgs.companyName || '',
|
2017-04-29 14:52:12 +00:00
|
|
|
productName: appArgs.name,
|
|
|
|
submitURL: appArgs.crashReporter,
|
2018-05-01 23:29:03 +00:00
|
|
|
uploadToServer: true,
|
2016-10-09 05:52:50 +00:00
|
|
|
});
|
2017-04-29 14:52:12 +00:00
|
|
|
});
|
2016-10-09 05:52:50 +00:00
|
|
|
}
|
|
|
|
|
2019-03-25 15:16:28 +00:00
|
|
|
// quit if singleInstance mode and there's already another instance running
|
|
|
|
const shouldQuit = appArgs.singleInstance && !app.requestSingleInstanceLock();
|
|
|
|
if (shouldQuit) {
|
|
|
|
app.quit();
|
|
|
|
} else {
|
|
|
|
app.on('second-instance', () => {
|
|
|
|
if (mainWindow) {
|
|
|
|
if (!mainWindow.isVisible()) {
|
|
|
|
// try
|
|
|
|
mainWindow.show();
|
|
|
|
}
|
|
|
|
if (mainWindow.isMinimized()) {
|
|
|
|
// minimized
|
|
|
|
mainWindow.restore();
|
|
|
|
}
|
|
|
|
mainWindow.focus();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
app.on('ready', () => {
|
|
|
|
mainWindow = createMainWindow(appArgs, app.quit, setDockBadge);
|
|
|
|
createTrayIcon(appArgs, mainWindow);
|
|
|
|
|
|
|
|
// Register global shortcuts
|
|
|
|
if (appArgs.globalShortcuts) {
|
|
|
|
appArgs.globalShortcuts.forEach((shortcut) => {
|
|
|
|
globalShortcut.register(shortcut.key, () => {
|
|
|
|
shortcut.inputEvents.forEach((inputEvent) => {
|
|
|
|
mainWindow.webContents.sendInputEvent(inputEvent);
|
|
|
|
});
|
2018-11-05 02:03:52 +00:00
|
|
|
});
|
|
|
|
});
|
2019-03-25 15:16:28 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2015-07-05 06:08:13 +00:00
|
|
|
|
2018-05-01 23:24:35 +00:00
|
|
|
app.on('new-window-for-tab', () => {
|
|
|
|
mainWindow.emit('new-tab');
|
|
|
|
});
|
|
|
|
|
2016-01-29 14:04:41 +00:00
|
|
|
app.on('login', (event, webContents, request, authInfo, callback) => {
|
2017-11-14 13:05:01 +00:00
|
|
|
// for http authentication
|
2017-04-29 14:52:12 +00:00
|
|
|
event.preventDefault();
|
2017-10-05 22:44:03 +00:00
|
|
|
|
2018-05-24 07:02:44 +00:00
|
|
|
if (
|
|
|
|
appArgs.basicAuthUsername !== null &&
|
|
|
|
appArgs.basicAuthPassword !== null
|
|
|
|
) {
|
2017-10-05 22:44:03 +00:00
|
|
|
callback(appArgs.basicAuthUsername, appArgs.basicAuthPassword);
|
|
|
|
} else {
|
|
|
|
createLoginWindow(callback);
|
|
|
|
}
|
2016-01-21 18:39:52 +00:00
|
|
|
});
|