SymphonyElectron/src/app/child-window-handler.ts
Kiran Niranjan 13e82bac00 Merge TS context isolation branch onto Typescript master branch (#598)
* Typescript 🎉

* Typescript 🎉 (logger, get-guid, string-format and throttle)

* Refactor typescript code

* consolidate all the utility functions to one file

* refactor protocol handler feature

* Typescript:

Add code documentation
Add pre-commit hooks

* Typescript: Fix logger formatting

* Typescript: Add support for react

* Typescript: Completed about app

* Typescript: Completed about app

* Typescript: Completed about app

* Typescript - Fix issues with about-app and add login to convert less to css

* Typescript - Fix loading screen

* Typescript - Add custom title bar

* Typescript - Add method to get locale

* Typescript - Add logic to clean up old logs

* Typescript - Add set badge count api

* Typescript - Complete application menu

* Typescript - Add logic to translate menu items

* Typescript - freeze window.ssf api

* Typescript - Handle popup menu on alt key press

* Typescript - Completed activity detection

* Typescript - Completed screen snippet

* Typescript - Add login to close screen snippet

* Typescript - Completed window actions & snackbar, Updated i18n module

* Typescript - Completed native crypto implementation & fixed bugs

* Typescript - Completed Desktop capturer & screen picker implementation

* Typescript - Optimize window actions

* Typescript - Add support for child window

* Typescript - fix pop url validation issue & browserify preload

* Typescript - Completed context menu implementation and fixed screen snippet

* Typescript - Completed screen sharing indicator and fixed i18n usage issue

* Typescript - Fix i18n locale setting issue

* Typescript - Completed download manager

* Typescript - Completed Basic auth

* Typescript - Network connectivity dialog

* Typescript - Handle certificate error

* Typescript - Add translation for certificate error dialog buttons

* Typescript - Add gulp tasks to compile less, typescript and copy files

* Typescript - Fix some issues with custom title bar, loading screen & screen snippet

* Typescript - Remove ES2015 lib

* :typescript: - Do not inject custom title bar for mac

* :typescript: - Fix screen sharing indicator text and format string

* Typescript - Fix esc to full screen

* Typescript - handle multiple/single instance of the client and add safety checks

* Typescript - Refactor code base

* Typescript - Optimize window validation and fix screen picker issue

* Typescript - Optimize protocol handler

* typescript: logger unit test

* typescript: activityDetection unit test (#560)

* ELECTRON-1022 - Create app bridge that communicates between renderer and preload via postMessage

* ELECTRON-1024 - Add support for screen share and screen sharing indicator

* config unit test (#566)

* ELECTRON-1024 - Fix screen sharing indicator close issue

* ELECTRON-1022 - Bump Symphony version to 5.0.0 (1.55)

* fixing jest coverage output report (#575)

* protocol handle unit test (#576)

* Typescript - Remove unwanted checks in protocol handler and add test cases

* added more tests to increase coverage to 100 for protocol handler

* Typescript download manager unit test (#579)

* adding enzyme

* download manager unit test

* Typescript - Completed notification workflow

* about app unit test

* Typescript - Fix notification styles

* fixing Compiler error: Generic type ReactElement<P, T> (#583)

* fix app path on windows (#580)

* basic auth unit test (#582)

* screen picker unit test (#587)

* screen picker unit test

* screen sharing indicator unit test

* loading screen unit test (#588)

* improving snapshot using snapshotSerializers to remove unnecessary things (#596)

* Typescript - Enforce braces for if/for/do/while statements.

* Typescript - Fix Lint issues and Unit test

* Typescript - Enable eofline (Ensure the file ends with a newline.)

* Typescript - Update logger logic and format

* Typescript - Provide option for user to set custom log path

* Typescript - Fix eofline in css files

* Typescript - ignore spec from compiling and remove unwanted rebuild command
2019-04-02 10:58:09 +05:30

139 lines
5.6 KiB
TypeScript

import { BrowserWindow, WebContents } from 'electron';
import { parse as parseQuerystring } from 'querystring';
import { format, parse, Url } from 'url';
import { isWindowsOS } from '../common/env';
import { getGuid } from '../common/utils';
import { monitorWindowActions, removeWindowEventListener } from './window-actions';
import { ICustomBrowserWindow, windowHandler } from './window-handler';
import { getBounds, injectStyles, preventWindowNavigation } from './window-utils';
const DEFAULT_POP_OUT_WIDTH = 300;
const DEFAULT_POP_OUT_HEIGHT = 600;
const MIN_WIDTH = 300;
const MIN_HEIGHT = 300;
/**
* Verifies if the url is valid and
* forcefully appends https if not present
*
* @param configURL {string}
*/
const getParsedUrl = (configURL: string): Url => {
const parsedUrl = parse(configURL);
if (!parsedUrl.protocol || parsedUrl.protocol !== 'https') {
parsedUrl.protocol = 'https:';
parsedUrl.slashes = true;
}
return parse(format(parsedUrl));
};
export const handleChildWindow = (webContents: WebContents): void => {
const childWindow = (event, newWinUrl, frameName, disposition, newWinOptions): void => {
const mainWindow = windowHandler.getMainWindow();
if (!mainWindow || mainWindow.isDestroyed()) {
return;
}
if (!windowHandler.url) {
return;
}
if (!newWinOptions.webPreferences) {
newWinOptions.webPreferences = {};
}
Object.assign(newWinOptions.webPreferences, webContents);
const newWinParsedUrl = getParsedUrl(newWinUrl);
const mainWinParsedUrl = getParsedUrl(windowHandler.url);
const newWinHost = newWinParsedUrl && newWinParsedUrl.host;
const mainWinHost = mainWinParsedUrl && mainWinParsedUrl.host;
const emptyUrlString = 'about:blank';
const dispositionWhitelist = ['new-window', 'foreground-tab'];
// only allow window.open to succeed is if coming from same hsot,
// otherwise open in default browser.
if ((newWinHost === mainWinHost || newWinUrl === emptyUrlString) && dispositionWhitelist.includes(disposition)) {
const newWinKey = getGuid();
if (!frameName) {
// abort - no frame name provided.
return;
}
const width = newWinOptions.width || DEFAULT_POP_OUT_WIDTH;
const height = newWinOptions.height || DEFAULT_POP_OUT_HEIGHT;
// try getting x and y position from query parameters
const query = newWinParsedUrl && parseQuerystring(newWinParsedUrl.query as string);
if (query && query.x && query.y) {
const newX = Number.parseInt(query.x as string, 10);
const newY = Number.parseInt(query.y as string, 10);
// only accept if both are successfully parsed.
if (Number.isInteger(newX) && Number.isInteger(newY)) {
const newWinRect = { x: newX, y: newY, width, height };
const { x, y } = getBounds(newWinRect, DEFAULT_POP_OUT_WIDTH, DEFAULT_POP_OUT_HEIGHT);
newWinOptions.x = x;
newWinOptions.y = y;
} else {
newWinOptions.x = 0;
newWinOptions.y = 0;
}
} else {
// create new window at slight offset from main window.
const { x, y } = mainWindow.getBounds();
newWinOptions.x = x + 50;
newWinOptions.y = y + 50;
}
newWinOptions.width = Math.max(width, DEFAULT_POP_OUT_WIDTH);
newWinOptions.height = Math.max(height, DEFAULT_POP_OUT_HEIGHT);
newWinOptions.minWidth = MIN_WIDTH;
newWinOptions.minHeight = MIN_HEIGHT;
newWinOptions.alwaysOnTop = mainWindow.isAlwaysOnTop();
newWinOptions.frame = true;
newWinOptions.winKey = newWinKey;
const childWebContents: WebContents = newWinOptions.webContents;
// Event needed to hide native menu bar
childWebContents.once('did-start-loading', () => {
const browserWin = BrowserWindow.fromWebContents(childWebContents);
if (isWindowsOS && browserWin && !browserWin.isDestroyed()) {
browserWin.setMenuBarVisibility(false);
}
});
childWebContents.once('did-finish-load', async () => {
const browserWin: ICustomBrowserWindow = BrowserWindow.fromWebContents(childWebContents) as ICustomBrowserWindow;
if (!browserWin) {
return;
}
windowHandler.addWindow(newWinKey, browserWin);
browserWin.webContents.send('page-load', { isWindowsOS });
// Inserts css on to the window
await injectStyles(browserWin, false);
browserWin.winName = frameName;
browserWin.setAlwaysOnTop(mainWindow.isAlwaysOnTop());
// prevents window from navigating
preventWindowNavigation(browserWin, true);
// Monitor window actions
monitorWindowActions(browserWin);
// Remove all attached event listeners
browserWin.on('close', () => {
removeWindowEventListener(browserWin);
});
// TODO: handle Permission Requests & setCertificateVerifyProc
});
} else {
event.preventDefault();
windowHandler.openUrlInDefaultBrowser(newWinUrl);
}
};
webContents.on('new-window', childWindow);
};