2
2
mirror of https://github.com/Llewellynvdm/nativefier.git synced 2024-09-29 04:39:04 +00:00
nativefier/src/build/buildApp.js
FabulousCupcake d0a0614ba3 Add --browserwindow-options to completely expose Electron options (PR #835)
This adds a new flag `--browserwindow-options`, taking a stringified JSON object as input.  
It will be inserted directly into the options when BrowserConfig is initialized.

This allows total configurability of the electron BrowserWindow configuration via nativefier.

An example use case is added to the documentation, which modifies the default font family in the browser.

#### References

- https://github.com/electron/electron/blob/master/docs/api/browser-window.md#new-browserwindowoptions
  - See the following for electron v3.1.7
  - https://github.com/electron/electron/blob/v3.1.7/docs/api/browser-window.md#new-browserwindowoptions
2019-08-22 21:37:49 +02:00

163 lines
4.6 KiB
JavaScript

import fs from 'fs';
import crypto from 'crypto';
import _ from 'lodash';
import path from 'path';
import ncp from 'ncp';
const copy = ncp.ncp;
const log = require('loglevel');
/**
* Only picks certain app args to pass to nativefier.json
* @param options
*/
function selectAppArgs(options) {
return {
name: options.name,
targetUrl: options.targetUrl,
counter: options.counter,
bounce: options.bounce,
width: options.width,
height: options.height,
minWidth: options.minWidth,
minHeight: options.minHeight,
maxWidth: options.maxWidth,
maxHeight: options.maxHeight,
x: options.x,
y: options.y,
showMenuBar: options.showMenuBar,
fastQuit: options.fastQuit,
userAgent: options.userAgent,
nativefierVersion: options.nativefierVersion,
ignoreCertificate: options.ignoreCertificate,
disableGpu: options.disableGpu,
ignoreGpuBlacklist: options.ignoreGpuBlacklist,
enableEs3Apis: options.enableEs3Apis,
insecure: options.insecure,
flashPluginDir: options.flashPluginDir,
diskCacheSize: options.diskCacheSize,
fullScreen: options.fullScreen,
hideWindowFrame: options.hideWindowFrame,
maximize: options.maximize,
disableContextMenu: options.disableContextMenu,
disableDevTools: options.disableDevTools,
zoom: options.zoom,
internalUrls: options.internalUrls,
crashReporter: options.crashReporter,
singleInstance: options.singleInstance,
clearCache: options.clearCache,
appCopyright: options.appCopyright,
appVersion: options.appVersion,
buildVersion: options.buildVersion,
win32metadata: options.win32metadata,
versionString: options.versionString,
processEnvs: options.processEnvs,
fileDownloadOptions: options.fileDownloadOptions,
tray: options.tray,
basicAuthUsername: options.basicAuthUsername,
basicAuthPassword: options.basicAuthPassword,
alwaysOnTop: options.alwaysOnTop,
titleBarStyle: options.titleBarStyle,
globalShortcuts: options.globalShortcuts,
browserwindowOptions: options.browserwindowOptions,
backgroundColor: options.backgroundColor,
darwinDarkModeSupport: options.darwinDarkModeSupport,
};
}
function maybeCopyScripts(srcs, dest) {
if (!srcs) {
return new Promise((resolve) => {
resolve();
});
}
const promises = srcs.map(
(src) =>
new Promise((resolve, reject) => {
if (!fs.existsSync(src)) {
reject(new Error('Error copying injection files: file not found'));
return;
}
let destFileName;
if (path.extname(src) === '.js') {
destFileName = 'inject.js';
} else if (path.extname(src) === '.css') {
destFileName = 'inject.css';
} else {
resolve();
return;
}
copy(src, path.join(dest, 'inject', destFileName), (error) => {
if (error) {
reject(new Error(`Error Copying injection files: ${error}`));
return;
}
resolve();
});
}),
);
return new Promise((resolve, reject) => {
Promise.all(promises)
.then(() => {
resolve();
})
.catch((error) => {
reject(error);
});
});
}
function normalizeAppName(appName, url) {
// use a simple 3 byte random string to prevent collision
const hash = crypto.createHash('md5');
hash.update(url);
const postFixHash = hash.digest('hex').substring(0, 6);
const normalized = _.kebabCase(appName.toLowerCase());
return `${normalized}-nativefier-${postFixHash}`;
}
function changeAppPackageJsonName(appPath, name, url) {
const packageJsonPath = path.join(appPath, '/package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath));
packageJson.name = normalizeAppName(name, url);
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson));
}
/**
* Creates a temporary directory and copies the './app folder' inside,
* and adds a text file with the configuration for the single page app.
*
* @param {string} src
* @param {string} dest
* @param {{}} options
* @param callback
*/
function buildApp(src, dest, options, callback) {
const appArgs = selectAppArgs(options);
copy(src, dest, (error) => {
if (error) {
callback(`Error Copying temporary directory: ${error}`);
return;
}
fs.writeFileSync(
path.join(dest, '/nativefier.json'),
JSON.stringify(appArgs),
);
maybeCopyScripts(options.inject, dest)
.catch((err) => {
log.warn(err);
})
.then(() => {
changeAppPackageJsonName(dest, appArgs.name, appArgs.targetUrl);
callback();
});
});
}
export default buildApp;