mirror of
https://github.com/Llewellynvdm/nativefier.git
synced 2024-06-03 05:10:47 +00:00
6fb3b92eb8
* Update deps except eslint * Update eslint and lint:fix (WIP, needs manual fixing for remaining 44 problems) * Manually fix remaining eslint errors * Document deprecation of `version-string` as of electron-packager 9.0.0 * Upgrade to Electron 1.7.9 (chrome-58, node-7.9.0, v8-5.8) * npm: Disable generation of package-lock.json and gitignore it --Trying this, package-lock is a pain in PRs. May not be a good idea (obviously we lose deps pinning), will revert if necessary.-- * npm tasks: add dev-up-win for Windows developers, and e2e for end-to-end tests. Update docs. * Move normalizeUrl test to a jest unit test, makes no sense to be in the mocha e2e tests * Switch from babel-preset-es2015 to babel-preset-env, with target.node=4.0. Seem like it's today's most convenient way to support the latest ES and let babel transpile to what makes sense for our currently minimal node version
234 lines
6.5 KiB
JavaScript
234 lines
6.5 KiB
JavaScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { BrowserWindow, shell, ipcMain, dialog } from 'electron';
|
|
import windowStateKeeper from 'electron-window-state';
|
|
import helpers from './../../helpers/helpers';
|
|
import createMenu from './../menu/menu';
|
|
import initContextMenu from './../contextMenu/contextMenu';
|
|
|
|
const {
|
|
isOSX, linkIsInternal, getCssToInject, shouldInjectCss,
|
|
} = helpers;
|
|
|
|
const ZOOM_INTERVAL = 0.1;
|
|
|
|
function maybeHideWindow(window, event, fastQuit, tray) {
|
|
if (isOSX() && !fastQuit) {
|
|
// this is called when exiting from clicking the cross button on the window
|
|
event.preventDefault();
|
|
window.hide();
|
|
} else if (!fastQuit && tray) {
|
|
event.preventDefault();
|
|
window.hide();
|
|
}
|
|
// will close the window on other platforms
|
|
}
|
|
|
|
function maybeInjectCss(browserWindow) {
|
|
if (!shouldInjectCss()) {
|
|
return;
|
|
}
|
|
|
|
const cssToInject = getCssToInject();
|
|
|
|
const injectCss = () => {
|
|
browserWindow.webContents.insertCSS(cssToInject);
|
|
};
|
|
|
|
browserWindow.webContents.on('did-finish-load', () => {
|
|
// remove the injection of css the moment the page is loaded
|
|
browserWindow.webContents.removeListener('did-get-response-details', injectCss);
|
|
});
|
|
|
|
// on every page navigation inject the css
|
|
browserWindow.webContents.on('did-navigate', () => {
|
|
// we have to inject the css in did-get-response-details to prevent the fouc
|
|
// will run multiple times
|
|
browserWindow.webContents.on('did-get-response-details', injectCss);
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {{}} inpOptions AppArgs from nativefier.json
|
|
* @param {function} onAppQuit
|
|
* @param {function} setDockBadge
|
|
* @returns {electron.BrowserWindow}
|
|
*/
|
|
function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
|
|
const options = Object.assign({}, inpOptions);
|
|
const mainWindowState = windowStateKeeper({
|
|
defaultWidth: options.width || 1280,
|
|
defaultHeight: options.height || 800,
|
|
});
|
|
|
|
const mainWindow = new BrowserWindow({
|
|
frame: !options.hideWindowFrame,
|
|
width: mainWindowState.width,
|
|
height: mainWindowState.height,
|
|
minWidth: options.minWidth,
|
|
minHeight: options.minHeight,
|
|
maxWidth: options.maxWidth,
|
|
maxHeight: options.maxHeight,
|
|
x: mainWindowState.x,
|
|
y: mainWindowState.y,
|
|
autoHideMenuBar: !options.showMenuBar,
|
|
// Convert dashes to spaces because on linux the app name is joined with dashes
|
|
title: options.name,
|
|
webPreferences: {
|
|
javascript: true,
|
|
plugins: true,
|
|
// node globals causes problems with sites like messenger.com
|
|
nodeIntegration: false,
|
|
webSecurity: !options.insecure,
|
|
preload: path.join(__dirname, 'static', 'preload.js'),
|
|
zoomFactor: options.zoom,
|
|
},
|
|
// after webpack path here should reference `resources/app/`
|
|
icon: path.join(__dirname, '../', '/icon.png'),
|
|
// set to undefined and not false because explicitly setting to false will disable full screen
|
|
fullscreen: options.fullScreen || undefined,
|
|
});
|
|
|
|
mainWindowState.manage(mainWindow);
|
|
|
|
// after first run, no longer force maximize to be true
|
|
if (options.maximize) {
|
|
mainWindow.maximize();
|
|
options.maximize = undefined;
|
|
fs.writeFileSync(path.join(__dirname, '..', 'nativefier.json'), JSON.stringify(options));
|
|
}
|
|
|
|
let currentZoom = options.zoom;
|
|
|
|
const onZoomIn = () => {
|
|
currentZoom += ZOOM_INTERVAL;
|
|
mainWindow.webContents.send('change-zoom', currentZoom);
|
|
};
|
|
|
|
const onZoomOut = () => {
|
|
currentZoom -= ZOOM_INTERVAL;
|
|
mainWindow.webContents.send('change-zoom', currentZoom);
|
|
};
|
|
|
|
const onZoomReset = () => {
|
|
mainWindow.webContents.send('change-zoom', options.zoom);
|
|
};
|
|
|
|
const clearAppData = () => {
|
|
dialog.showMessageBox(mainWindow, {
|
|
type: 'warning',
|
|
buttons: ['Yes', 'Cancel'],
|
|
defaultId: 1,
|
|
title: 'Clear cache confirmation',
|
|
message: 'This will clear all data (cookies, local storage etc) from this app. Are you sure you wish to proceed?',
|
|
}, (response) => {
|
|
if (response !== 0) {
|
|
return;
|
|
}
|
|
const { session } = mainWindow.webContents;
|
|
session.clearStorageData(() => {
|
|
session.clearCache(() => {
|
|
mainWindow.loadURL(options.targetUrl);
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
const onGoBack = () => {
|
|
mainWindow.webContents.goBack();
|
|
};
|
|
|
|
const onGoForward = () => {
|
|
mainWindow.webContents.goForward();
|
|
};
|
|
|
|
const getCurrentUrl = () => mainWindow.webContents.getURL();
|
|
|
|
const menuOptions = {
|
|
nativefierVersion: options.nativefierVersion,
|
|
appQuit: onAppQuit,
|
|
zoomIn: onZoomIn,
|
|
zoomOut: onZoomOut,
|
|
zoomReset: onZoomReset,
|
|
zoomBuildTimeValue: options.zoom,
|
|
goBack: onGoBack,
|
|
goForward: onGoForward,
|
|
getCurrentUrl,
|
|
clearAppData,
|
|
disableDevTools: options.disableDevTools,
|
|
};
|
|
|
|
createMenu(menuOptions);
|
|
if (!options.disableContextMenu) {
|
|
initContextMenu(mainWindow);
|
|
}
|
|
|
|
if (options.userAgent) {
|
|
mainWindow.webContents.setUserAgent(options.userAgent);
|
|
}
|
|
|
|
maybeInjectCss(mainWindow);
|
|
mainWindow.webContents.on('did-finish-load', () => {
|
|
mainWindow.webContents.send('params', JSON.stringify(options));
|
|
});
|
|
|
|
if (options.counter) {
|
|
mainWindow.on('page-title-updated', (e, title) => {
|
|
const itemCountRegex = /[([{](\d*?)\+?[}\])]/;
|
|
const match = itemCountRegex.exec(title);
|
|
if (match) {
|
|
setDockBadge(match[1]);
|
|
} else {
|
|
setDockBadge('');
|
|
}
|
|
});
|
|
} else {
|
|
ipcMain.on('notification', () => {
|
|
if (!isOSX() || mainWindow.isFocused()) {
|
|
return;
|
|
}
|
|
setDockBadge('•');
|
|
});
|
|
mainWindow.on('focus', () => {
|
|
setDockBadge('');
|
|
});
|
|
}
|
|
|
|
mainWindow.webContents.on('new-window', (event, urlToGo) => {
|
|
if (mainWindow.useDefaultWindowBehaviour) {
|
|
mainWindow.useDefaultWindowBehaviour = false;
|
|
return;
|
|
}
|
|
|
|
if (linkIsInternal(options.targetUrl, urlToGo, options.internalUrls)) {
|
|
return;
|
|
}
|
|
event.preventDefault();
|
|
shell.openExternal(urlToGo);
|
|
});
|
|
|
|
mainWindow.loadURL(options.targetUrl);
|
|
|
|
mainWindow.on('close', (event) => {
|
|
if (mainWindow.isFullScreen()) {
|
|
mainWindow.setFullScreen(false);
|
|
mainWindow.once('leave-full-screen', maybeHideWindow.bind(this, mainWindow, event, options.fastQuit));
|
|
}
|
|
maybeHideWindow(mainWindow, event, options.fastQuit, options.tray);
|
|
});
|
|
|
|
return mainWindow;
|
|
}
|
|
|
|
ipcMain.on('cancelNewWindowOverride', () => {
|
|
const allWindows = BrowserWindow.getAllWindows();
|
|
allWindows.forEach((window) => {
|
|
// eslint-disable-next-line no-param-reassign
|
|
window.useDefaultWindowBehaviour = false;
|
|
});
|
|
});
|
|
|
|
export default createMainWindow;
|