mirror of https://github.com/jiahaog/Nativefier
181 lines
4.3 KiB
TypeScript
181 lines
4.3 KiB
TypeScript
import {
|
|
dialog,
|
|
BrowserWindow,
|
|
IpcMainEvent,
|
|
NewWindowWebContentsEvent,
|
|
WebContents,
|
|
} from 'electron';
|
|
import log from 'loglevel';
|
|
|
|
import { linkIsInternal, nativeTabsSupported, openExternal } from './helpers';
|
|
import {
|
|
blockExternalURL,
|
|
createAboutBlankWindow,
|
|
createNewTab,
|
|
injectCSS,
|
|
sendParamsOnDidFinishLoad,
|
|
setProxyRules,
|
|
} from './windowHelpers';
|
|
|
|
export function onNewWindow(
|
|
options,
|
|
setupWindow: (...args) => void,
|
|
event: NewWindowWebContentsEvent,
|
|
urlToGo: string,
|
|
frameName: string,
|
|
disposition:
|
|
| 'default'
|
|
| 'foreground-tab'
|
|
| 'background-tab'
|
|
| 'new-window'
|
|
| 'save-to-disk'
|
|
| 'other',
|
|
parent?: BrowserWindow,
|
|
): Promise<void> {
|
|
log.debug('onNewWindow', {
|
|
event,
|
|
urlToGo,
|
|
frameName,
|
|
disposition,
|
|
parent,
|
|
});
|
|
const preventDefault = (newGuest: BrowserWindow): void => {
|
|
event.preventDefault();
|
|
if (newGuest) {
|
|
event.newGuest = newGuest;
|
|
}
|
|
};
|
|
return onNewWindowHelper(
|
|
options,
|
|
setupWindow,
|
|
urlToGo,
|
|
disposition,
|
|
preventDefault,
|
|
parent,
|
|
);
|
|
}
|
|
|
|
export function onNewWindowHelper(
|
|
options,
|
|
setupWindow: (...args) => void,
|
|
urlToGo: string,
|
|
disposition: string,
|
|
preventDefault,
|
|
parent?: BrowserWindow,
|
|
): Promise<void> {
|
|
log.debug('onNewWindowHelper', {
|
|
urlToGo,
|
|
disposition,
|
|
preventDefault,
|
|
parent,
|
|
});
|
|
try {
|
|
if (!linkIsInternal(options.targetUrl, urlToGo, options.internalUrls)) {
|
|
preventDefault();
|
|
if (options.blockExternalUrls) {
|
|
return blockExternalURL(urlToGo).then(() => null);
|
|
} else {
|
|
return openExternal(urlToGo);
|
|
}
|
|
} else if (urlToGo === 'about:blank') {
|
|
const newWindow = createAboutBlankWindow(options, setupWindow, parent);
|
|
return Promise.resolve(preventDefault(newWindow));
|
|
} else if (nativeTabsSupported()) {
|
|
if (disposition === 'background-tab') {
|
|
const newTab = createNewTab(
|
|
options,
|
|
setupWindow,
|
|
urlToGo,
|
|
false,
|
|
parent,
|
|
);
|
|
return Promise.resolve(preventDefault(newTab));
|
|
} else if (disposition === 'foreground-tab') {
|
|
const newTab = createNewTab(
|
|
options,
|
|
setupWindow,
|
|
urlToGo,
|
|
true,
|
|
parent,
|
|
);
|
|
return Promise.resolve(preventDefault(newTab));
|
|
}
|
|
}
|
|
return Promise.resolve(undefined);
|
|
} catch (err: unknown) {
|
|
return Promise.reject(err);
|
|
}
|
|
}
|
|
|
|
export function onWillNavigate(
|
|
options,
|
|
event: IpcMainEvent,
|
|
urlToGo: string,
|
|
): Promise<void> {
|
|
log.debug('onWillNavigate', { options, event, urlToGo });
|
|
if (!linkIsInternal(options.targetUrl, urlToGo, options.internalUrls)) {
|
|
event.preventDefault();
|
|
if (options.blockExternalUrls) {
|
|
return blockExternalURL(urlToGo).then(() => null);
|
|
} else {
|
|
return openExternal(urlToGo);
|
|
}
|
|
}
|
|
return Promise.resolve(undefined);
|
|
}
|
|
|
|
export function onWillPreventUnload(event: IpcMainEvent): void {
|
|
log.debug('onWillPreventUnload', event);
|
|
|
|
const webContents: WebContents = event.sender;
|
|
if (webContents === undefined) {
|
|
return;
|
|
}
|
|
|
|
const browserWindow = BrowserWindow.fromWebContents(webContents);
|
|
const choice = dialog.showMessageBoxSync(browserWindow, {
|
|
type: 'question',
|
|
buttons: ['Proceed', 'Stay'],
|
|
message: 'You may have unsaved changes, are you sure you want to proceed?',
|
|
title: 'Changes you made may not be saved.',
|
|
defaultId: 0,
|
|
cancelId: 1,
|
|
});
|
|
if (choice === 0) {
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
|
|
export function setupNativefierWindow(options, window: BrowserWindow): void {
|
|
if (options.userAgent) {
|
|
window.webContents.userAgent = options.userAgent;
|
|
}
|
|
|
|
if (options.proxyRules) {
|
|
setProxyRules(window, options.proxyRules);
|
|
}
|
|
|
|
injectCSS(window);
|
|
|
|
window.webContents.on('will-navigate', (event: IpcMainEvent, url: string) => {
|
|
onWillNavigate(options, event, url).catch((err) => {
|
|
log.error('window.webContents.on.will-navigate ERROR', err);
|
|
event.preventDefault();
|
|
});
|
|
});
|
|
window.webContents.on('will-prevent-unload', onWillPreventUnload);
|
|
|
|
sendParamsOnDidFinishLoad(options, window);
|
|
|
|
// @ts-expect-error new-tab isn't in the type definition, but it does exist
|
|
window.on('new-tab', () =>
|
|
createNewTab(
|
|
options,
|
|
setupNativefierWindow,
|
|
options.targetUrl,
|
|
true,
|
|
window,
|
|
),
|
|
);
|
|
}
|