mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
add logging and refactor (#26)
This commit is contained in:
12
js/enums/logLevels.js
Normal file
12
js/enums/logLevels.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var keyMirror = require('keymirror');
|
||||||
|
|
||||||
|
module.exports = keyMirror({
|
||||||
|
ERROR: null,
|
||||||
|
CONFLICT: null,
|
||||||
|
WARN: null,
|
||||||
|
ACTION: null,
|
||||||
|
INFO: null,
|
||||||
|
DEBUG: null
|
||||||
|
});
|
||||||
28
js/log.js
Normal file
28
js/log.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
let logWindow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send log messages from main process to logger hosted by
|
||||||
|
* renderer process. Allows main process to use logger
|
||||||
|
* provided by JS.
|
||||||
|
* @param {enum} level enum from ./enums/LogLevel.js
|
||||||
|
* @param {string} details msg to be logged
|
||||||
|
*/
|
||||||
|
function send(level, details) {
|
||||||
|
if (logWindow && level && details) {
|
||||||
|
logWindow.send('log', {
|
||||||
|
logLevel: level,
|
||||||
|
logDetails: details
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLogWindow(win) {
|
||||||
|
logWindow = win;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
send: send,
|
||||||
|
setLogWindow: setLogWindow
|
||||||
|
};
|
||||||
190
js/main.js
190
js/main.js
@@ -1,190 +1,22 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const packageJSON = require('../package.json');
|
|
||||||
const menuTemplate = require('./menuTemplate.js');
|
|
||||||
const path = require('path');
|
|
||||||
const app = electron.app;
|
const app = electron.app;
|
||||||
const nodeURL = require('url');
|
const nodeURL = require('url');
|
||||||
const getConfig = require('./getConfig.js');
|
const getConfig = require('./getConfig.js');
|
||||||
const { isMac, isDevEnv, getGuid } = require('./utils.js');
|
const { isMac } = require('./utils.js');
|
||||||
const loadErrors = require('./dialogs/showLoadError.js');
|
|
||||||
|
|
||||||
// show dialog when certificate errors occur
|
|
||||||
require('./dialogs/showCertError.js');
|
|
||||||
|
|
||||||
// Keep a global reference of the window object, if you don't, the window will
|
|
||||||
// be closed automatically when the JavaScript object is garbage collected.
|
|
||||||
let mainWindow;
|
|
||||||
let windows = {};
|
|
||||||
let willQuitApp = false;
|
|
||||||
let isOnline = true;
|
|
||||||
|
|
||||||
|
// exit early for squirrel installer
|
||||||
if (require('electron-squirrel-startup')) {
|
if (require('electron-squirrel-startup')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createMainWindow (url) {
|
require('./mainApiMgr.js');
|
||||||
let key = getGuid();
|
|
||||||
|
|
||||||
mainWindow = new electron.BrowserWindow({
|
// monitor memory of main process
|
||||||
title: 'Symphony',
|
require('./memoryMonitor.js');
|
||||||
width: 1024, height: 768,
|
|
||||||
show: true,
|
|
||||||
webPreferences: {
|
|
||||||
sandbox: true,
|
|
||||||
nodeIntegration: false,
|
|
||||||
preload: path.join(__dirname, '/preload.js'),
|
|
||||||
winKey: key
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function retry() {
|
const windowMgr = require('./windowMgr.js');
|
||||||
if (isOnline) {
|
|
||||||
mainWindow.webContents && mainWindow.webContents.reload();
|
|
||||||
} else {
|
|
||||||
loadErrors.showNetworkConnectivityError(mainWindow, url, retry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// content can be cached and will still finish load but
|
|
||||||
// we might not have netowrk connectivity, so warn the user.
|
|
||||||
mainWindow.webContents.once('did-finish-load', function() {
|
|
||||||
if (!isOnline) {
|
|
||||||
loadErrors.showNetworkConnectivityError(mainWindow, url, retry);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindow.webContents.once('did-fail-load', function(event, errorCode,
|
|
||||||
errorDesc, validatedURL, isMainFrame) {
|
|
||||||
loadErrors.showLoadFailure(mainWindow, url, errorDesc, errorCode, retry);
|
|
||||||
});
|
|
||||||
|
|
||||||
storeWindowKey(key, mainWindow);
|
|
||||||
mainWindow.loadURL(url);
|
|
||||||
|
|
||||||
const menu = electron.Menu.buildFromTemplate(menuTemplate(app));
|
|
||||||
electron.Menu.setApplicationMenu(menu);
|
|
||||||
|
|
||||||
mainWindow.on('close', function(e) {
|
|
||||||
if (willQuitApp) {
|
|
||||||
mainWindow = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// mac should hide window when hitting x close
|
|
||||||
if (isMac) {
|
|
||||||
mainWindow.hide();
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mainWindow.on('closed', function () {
|
|
||||||
// Dereference the window object, usually you would store windows
|
|
||||||
// in an array if your app supports multi windows, this is the time
|
|
||||||
// when you should delete the corresponding element.
|
|
||||||
mainWindow = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// open external links in default browser - window.open
|
|
||||||
mainWindow.webContents.on('new-window', function(event, url) {
|
|
||||||
event.preventDefault();
|
|
||||||
electron.shell.openExternal(url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function storeWindowKey(key, browserWin) {
|
|
||||||
windows[key] = browserWin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensure events comes from a window that we have created.
|
|
||||||
* @param {EventEmitter} event node emitter event to be tested
|
|
||||||
* @return {Boolean} returns true if exists otherwise false
|
|
||||||
*/
|
|
||||||
function isValidWindow(event) {
|
|
||||||
if (event && event.sender) {
|
|
||||||
// validate that event sender is from window we created
|
|
||||||
let browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
|
||||||
let winKey = event.sender.browserWindowOptions &&
|
|
||||||
event.sender.browserWindowOptions.webPreferences &&
|
|
||||||
event.sender.browserWindowOptions.webPreferences.winKey;
|
|
||||||
|
|
||||||
if (browserWin instanceof electron.BrowserWindow) {
|
|
||||||
let win = windows[winKey];
|
|
||||||
return win && win === browserWin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only permit certain cmds for some windows
|
|
||||||
* @param {EventEmitter} event node emitter event to be tested
|
|
||||||
* @param {String} cmd cmd name
|
|
||||||
* @return {Boolean} true if cmd is allowed for window, otherwise false
|
|
||||||
*/
|
|
||||||
function isCmdAllowed(event, cmd) {
|
|
||||||
if (event && event.sender && cmd) {
|
|
||||||
// validate that event sender is from window we created
|
|
||||||
let browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
|
||||||
|
|
||||||
if (browserWin === mainWindow) {
|
|
||||||
// allow all commands for main window
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
// allow only certain cmds for child windows
|
|
||||||
// e.g., open cmd not allowed for child windows
|
|
||||||
return (arg.cmd !== 'open');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle ipc messages from renderers. Only messages from windows we have
|
|
||||||
* created are allowed.
|
|
||||||
*/
|
|
||||||
electron.ipcMain.on('symphony-msg', (event, arg) => {
|
|
||||||
if (!isValidWindow(event)) {
|
|
||||||
console.log('invalid window try to perform action, ignoring action.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isCmdAllowed(event, arg && arg.cmd)) {
|
|
||||||
console.log('cmd not allowed for this window: ' + arg.cmd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg && arg.cmd === 'isOnline') {
|
|
||||||
isOnline = arg.isOnline;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (arg && arg.cmd === 'open' && arg.url) {
|
|
||||||
let width = arg.width || 1024;
|
|
||||||
let height = arg.height || 768;
|
|
||||||
let title = arg.title || 'Symphony';
|
|
||||||
let winKey = getGuid();
|
|
||||||
|
|
||||||
let childWindow = new electron.BrowserWindow({
|
|
||||||
title: title,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
webPreferences: {
|
|
||||||
sandbox: true,
|
|
||||||
nodeIntegration: false,
|
|
||||||
preload: path.join(__dirname, '/preload.js'),
|
|
||||||
winKey: winKey
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
storeWindowKey(winKey, childWindow);
|
|
||||||
childWindow.loadURL(arg.url);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called when Electron has finished
|
* This method will be called when Electron has finished
|
||||||
@@ -206,17 +38,13 @@ function getUrlAndOpenMainWindow() {
|
|||||||
slahes: true,
|
slahes: true,
|
||||||
pathname: parsedUrl.href
|
pathname: parsedUrl.href
|
||||||
});
|
});
|
||||||
createMainWindow(url);
|
windowMgr.createMainWindow(url);
|
||||||
}).catch(function(err) {
|
}).catch(function(err) {
|
||||||
let title = 'Error loading configuration';
|
let title = 'Error loading configuration';
|
||||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.on('before-quit', function() {
|
|
||||||
willQuitApp = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on('window-all-closed', function () {
|
app.on('window-all-closed', function () {
|
||||||
// On OS X it is common for applications and their menu bar
|
// On OS X it is common for applications and their menu bar
|
||||||
// to stay active until the user quits explicitly with Cmd + Q
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||||
@@ -226,9 +54,9 @@ app.on('window-all-closed', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
app.on('activate', function () {
|
app.on('activate', function () {
|
||||||
if (mainWindow === null) {
|
if (windowMgr.isMainWindow(null)) {
|
||||||
getUrlAndOpenMainWindow();
|
getUrlAndOpenMainWindow();
|
||||||
} else {
|
} else {
|
||||||
mainWindow.show();
|
windowMgr.showMainWindow();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
96
js/mainApiMgr.js
Normal file
96
js/mainApiMgr.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module runs in the main process and handles api calls
|
||||||
|
* from the renderer process.
|
||||||
|
*/
|
||||||
|
const electron = require('electron');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const windowMgr = require('./windowMgr.js');
|
||||||
|
const log = require('./log.js');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure events comes from a window that we have created.
|
||||||
|
* @param {EventEmitter} event node emitter event to be tested
|
||||||
|
* @return {Boolean} returns true if exists otherwise false
|
||||||
|
*/
|
||||||
|
function isValidWindow(event) {
|
||||||
|
if (event && event.sender) {
|
||||||
|
// validate that event sender is from window we created
|
||||||
|
let browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
|
let winKey = event.sender.browserWindowOptions &&
|
||||||
|
event.sender.browserWindowOptions.webPreferences &&
|
||||||
|
event.sender.browserWindowOptions.webPreferences.winKey;
|
||||||
|
|
||||||
|
return windowMgr.hasWindow(browserWin, winKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only these cmds are allowed by main window
|
||||||
|
let cmdBlackList = [ 'open', 'registerLogger' ];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only permit certain cmds for some windows
|
||||||
|
* @param {EventEmitter} event node emitter event to be tested
|
||||||
|
* @param {String} cmd cmd name
|
||||||
|
* @return {Boolean} true if cmd is allowed for window, otherwise false
|
||||||
|
*/
|
||||||
|
function isCmdAllowed(event, cmd) {
|
||||||
|
if (event && event.sender && cmd) {
|
||||||
|
// validate that event sender is from window we created
|
||||||
|
let browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
|
|
||||||
|
if (windowMgr.isMainWindow(browserWin)) {
|
||||||
|
// allow all commands for main window
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// allow only certain cmds for child windows
|
||||||
|
// e.g., open cmd not allowed for child windows
|
||||||
|
return (cmdBlackList.indexOf(cmd) === -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle API related ipc messages from renderers. Only messages from windows
|
||||||
|
* we have created are allowed.
|
||||||
|
*/
|
||||||
|
electron.ipcMain.on('symphony-api', (event, arg) => {
|
||||||
|
if (!isValidWindow(event)) {
|
||||||
|
console.log('invalid window try to perform action, ignoring action.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isCmdAllowed(event, arg && arg.cmd)) {
|
||||||
|
console.log('cmd not allowed for this window: ' + arg.cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.cmd === 'isOnline') {
|
||||||
|
windowMgr.setIsOnline(arg.isOnline);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.cmd === 'registerLogger') {
|
||||||
|
// renderer window that has a registered logger from JS.
|
||||||
|
log.setLogWindow(event.sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.cmd === 'open' && arg.url) {
|
||||||
|
let title = arg.title || 'Symphony';
|
||||||
|
let width = arg.width || 1024;
|
||||||
|
let height = arg.height || 768;
|
||||||
|
windowMgr.createChildWindow(arg.url, title, width, height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
18
js/memoryMonitor.js
Normal file
18
js/memoryMonitor.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const log = require('./log.js');
|
||||||
|
const logLevels = require('./enums/logLevels.js')
|
||||||
|
|
||||||
|
// once a minute
|
||||||
|
setInterval(gatherMemory, 1000 * 60);
|
||||||
|
|
||||||
|
function gatherMemory() {
|
||||||
|
var memory = process.getProcessMemoryInfo();
|
||||||
|
var details =
|
||||||
|
'workingSetSize: ' + memory.workingSetSize +
|
||||||
|
' peakWorkingSetSize: ' + memory.peakWorkingSetSize +
|
||||||
|
' privatesBytes: ' + memory.privatesBytes +
|
||||||
|
' sharedBytes: ' + memory.sharedBytes;
|
||||||
|
log.send(logLevels.INFO, details);
|
||||||
|
}
|
||||||
@@ -19,6 +19,8 @@ const local = {
|
|||||||
ipcRenderer: ipcRenderer
|
ipcRenderer: ipcRenderer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const api = 'symphony-api';
|
||||||
|
|
||||||
// API exposed by Symphony to renderer processes:
|
// API exposed by Symphony to renderer processes:
|
||||||
// Note: certain cmds are only allowed on some windows, this is checked by
|
// Note: certain cmds are only allowed on some windows, this is checked by
|
||||||
// main process.
|
// main process.
|
||||||
@@ -27,21 +29,51 @@ window.SYM_API = {
|
|||||||
|
|
||||||
// only allowed by main window - enforced by main process.
|
// only allowed by main window - enforced by main process.
|
||||||
openWindow: function(url) {
|
openWindow: function(url) {
|
||||||
local.ipcRenderer.send('symphony-msg', {
|
local.ipcRenderer.send(api, {
|
||||||
cmd: 'open',
|
cmd: 'open',
|
||||||
url: url
|
url: url
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
networkStatusChange: function(isOnline) {
|
|
||||||
local.ipcRenderer.send('symphony-msg', {
|
/**
|
||||||
cmd: 'isOnline',
|
* allows JS to register a logger that can be used by electron main process.
|
||||||
isOnline: isOnline
|
* @param {Object} logger function that can be called accepting
|
||||||
});
|
* object: {
|
||||||
|
* logLevel: 'ERROR'|'CONFLICT'|'WARN'|'ACTION'|'INFO'|'DEBUG',
|
||||||
|
* logDetails: String
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* note: only main window is allowed to register a logger, others are
|
||||||
|
* ignored.
|
||||||
|
*/
|
||||||
|
registerLogger: function(logger) {
|
||||||
|
if (typeof logger === 'function') {
|
||||||
|
local.logger = logger;
|
||||||
|
|
||||||
|
// only main window can register
|
||||||
|
local.ipcRenderer.send(api, {
|
||||||
|
cmd: 'registerLogger'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// listen for log message from main process
|
||||||
|
local.ipcRenderer.on('log', (event, arg) => {
|
||||||
|
console.log('got msg:' + arg)
|
||||||
|
if (local.logger && arg && arg.level && arg.msg) {
|
||||||
|
local.logger({
|
||||||
|
logLevel: arg.level,
|
||||||
|
logDetails: arg.msg
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function updateOnlineStatus() {
|
function updateOnlineStatus() {
|
||||||
window.SYM_API.networkStatusChange(navigator.onLine);
|
local.ipcRenderer.send(api, {
|
||||||
|
cmd: 'isOnline',
|
||||||
|
isOnline: navigator.onLine
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('offline', updateOnlineStatus, false);
|
window.addEventListener('offline', updateOnlineStatus, false);
|
||||||
160
js/windowMgr.js
Normal file
160
js/windowMgr.js
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const app = electron.app;
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const menuTemplate = require('./menuTemplate.js');
|
||||||
|
const loadErrors = require('./dialogs/showLoadError.js');
|
||||||
|
const { isMac, getGuid } = require('./utils.js');
|
||||||
|
const log = require('./log.js')
|
||||||
|
const logLevels = require('./enums/logLevels.js');
|
||||||
|
|
||||||
|
// show dialog when certificate errors occur
|
||||||
|
require('./dialogs/showCertError.js');
|
||||||
|
|
||||||
|
// Keep a global reference of the window object, if you don't, the window will
|
||||||
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||||
|
let mainWindow;
|
||||||
|
let windows = {};
|
||||||
|
let willQuitApp = false;
|
||||||
|
let isOnline = true;
|
||||||
|
const preloadScript = path.join(__dirname, '/RendererPreload.js');
|
||||||
|
|
||||||
|
function addWindowKey(key, browserWin) {
|
||||||
|
windows[key] = browserWin;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeWindowKey(key) {
|
||||||
|
delete windows[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMainWindow (url) {
|
||||||
|
let key = getGuid();
|
||||||
|
|
||||||
|
mainWindow = new electron.BrowserWindow({
|
||||||
|
title: 'Symphony',
|
||||||
|
width: 1024, height: 768,
|
||||||
|
show: true,
|
||||||
|
webPreferences: {
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false,
|
||||||
|
preload: preloadScript,
|
||||||
|
winKey: key
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function retry() {
|
||||||
|
if (isOnline) {
|
||||||
|
mainWindow.webContents && mainWindow.webContents.reload();
|
||||||
|
} else {
|
||||||
|
loadErrors.showNetworkConnectivityError(mainWindow, url, retry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// content can be cached and will still finish load but
|
||||||
|
// we might not have netowrk connectivity, so warn the user.
|
||||||
|
mainWindow.webContents.on('did-finish-load', function() {
|
||||||
|
if (!isOnline) {
|
||||||
|
loadErrors.showNetworkConnectivityError(mainWindow, url, retry);
|
||||||
|
} else {
|
||||||
|
log.send(logLevels.INFO, 'main window loaded');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.webContents.on('did-fail-load', function(event, errorCode,
|
||||||
|
errorDesc, validatedURL, isMainFrame) {
|
||||||
|
loadErrors.showLoadFailure(mainWindow, url, errorDesc, errorCode, retry);
|
||||||
|
});
|
||||||
|
|
||||||
|
addWindowKey(key, mainWindow);
|
||||||
|
mainWindow.loadURL(url);
|
||||||
|
|
||||||
|
const menu = electron.Menu.buildFromTemplate(menuTemplate(app));
|
||||||
|
electron.Menu.setApplicationMenu(menu);
|
||||||
|
|
||||||
|
mainWindow.on('close', function(e) {
|
||||||
|
if (willQuitApp) {
|
||||||
|
mainWindow = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// mac should hide window when hitting x close
|
||||||
|
if (isMac) {
|
||||||
|
mainWindow.hide();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainWindow.on('closed', function () {
|
||||||
|
removeWindowKey(key);
|
||||||
|
mainWindow.removeAllEventListeners();
|
||||||
|
// Dereference the window object, usually you would store windows
|
||||||
|
// in an array if your app supports multi windows, this is the time
|
||||||
|
// when you should delete the corresponding element.
|
||||||
|
mainWindow = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// open external links in default browser - window.open
|
||||||
|
mainWindow.webContents.on('new-window', function(event, url) {
|
||||||
|
event.preventDefault();
|
||||||
|
electron.shell.openExternal(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
app.on('before-quit', function() {
|
||||||
|
willQuitApp = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
function showMainWindow() {
|
||||||
|
mainWindow.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMainWindow(win) {
|
||||||
|
return mainWindow === win;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasWindow(win, winKey) {
|
||||||
|
if (win instanceof electron.BrowserWindow) {
|
||||||
|
let browserWin = windows[winKey];
|
||||||
|
return browserWin && win === browserWin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createChildWindow(url, title, width, height) {
|
||||||
|
let winKey = getGuid();
|
||||||
|
|
||||||
|
let childWindow = new electron.BrowserWindow({
|
||||||
|
title: title,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
webPreferences: {
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false,
|
||||||
|
preload: preloadScript,
|
||||||
|
winKey: winKey
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addWindowKey(winKey, childWindow);
|
||||||
|
childWindow.loadURL(url);
|
||||||
|
|
||||||
|
childWindow.on('closed', function() {
|
||||||
|
childWindow.removeAllEventListeners();
|
||||||
|
removeWindowKey(winKey);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setIsOnline(status) {
|
||||||
|
isOnline = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
createMainWindow: createMainWindow,
|
||||||
|
showMainWindow: showMainWindow,
|
||||||
|
isMainWindow: isMainWindow,
|
||||||
|
hasWindow: hasWindow,
|
||||||
|
createChildWindow: createChildWindow,
|
||||||
|
setIsOnline: setIsOnline
|
||||||
|
};
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
"jest": "^19.0.2"
|
"jest": "^19.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"electron-squirrel-startup": "^1.0.0"
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
|
"keymirror": "0.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
tests/README.md
Normal file
2
tests/README.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# to override dependencies
|
||||||
|
- use https://github.com/thlorenz/proxyquire
|
||||||
Reference in New Issue
Block a user