From 5fbc6ac4699d0354b2d4cf925b4c5e0a835c817f Mon Sep 17 00:00:00 2001 From: vsvipul Date: Sat, 20 Jul 2019 04:39:00 +0530 Subject: [PATCH] BrowserView: Remove webview usage and initialize BrowserView. Removes all instances of webview from main.ts and adds an initial working instance of BrowserView. --- app/main/index.ts | 2 +- app/main/view.ts | 52 +++++++++++- app/main/viewmanager.ts | 11 ++- app/renderer/js/main.ts | 173 +++++++++++++++++----------------------- package-lock.json | 6 +- 5 files changed, 133 insertions(+), 111 deletions(-) diff --git a/app/main/index.ts b/app/main/index.ts index 4a360845e..8c3a14c33 100644 --- a/app/main/index.ts +++ b/app/main/index.ts @@ -263,7 +263,7 @@ app.on('ready', () => { page.send('toggle-autohide-menubar', showMenubar, true); }); - ipcMain.on('toggle-sidebar', () => { + ipcMain.on('fix-bounds', () => { ViewManager.fixBounds(); }); diff --git a/app/main/view.ts b/app/main/view.ts index 6358e04d3..e93cfaf65 100644 --- a/app/main/view.ts +++ b/app/main/view.ts @@ -1,6 +1,6 @@ 'use strict'; -import { BrowserView } from 'electron'; +import { BrowserView, BrowserWindow } from 'electron'; import ConfigUtil = require('../renderer/js/utils/config-util'); const shouldSilentWebview = ConfigUtil.getConfigItem('silent'); @@ -17,7 +17,7 @@ export class View extends BrowserView { index: number; url: string; zoomFactor: number; - loading: true; + loading: boolean; badgeCount: number; customCSS: boolean; @@ -33,7 +33,7 @@ export class View extends BrowserView { this.index = props.index; this.url = props.url; this.zoomFactor = 1.0; - this.loading = true; + this.loading = false; this.badgeCount = 0; this.customCSS = ConfigUtil.getConfigItem('customCSS'); this.registerListeners(); @@ -45,6 +45,34 @@ export class View extends BrowserView { this.webContents.setAudioMuted(true); }); } + + this.webContents.addListener('did-navigate-in-page', () => { + const isSettingsPage = this.url.includes('renderer/preference.html'); + if (isSettingsPage) { + return; + } + this.canGoBackButton(); + }); + + this.webContents.addListener('did-navigate', () => { + this.canGoBackButton(); + }); + + this.webContents.addListener('did-start-loading', () => { + const isSettingsPage = this.url.includes('renderer/preference.html'); + if (!isSettingsPage) { + this.sendAction('switch-loading', true, this.url); + } + }); + + this.webContents.addListener('dom-ready', () => { + this.loading = false; + this.sendAction('switch-loading', false, this.url); + }); + + this.webContents.addListener('did-stop-loading', () => { + this.sendAction('switch-loading', false, this.url); + }); } zoomIn(): void { @@ -90,4 +118,22 @@ export class View extends BrowserView { toggleDevTools(): void { this.webContents.toggleDevTools(); } + + canGoBackButton(): void { + if (this.webContents.canGoBack()) { + this.sendAction('switch-back', true); + } else { + this.sendAction('switch-back', false); + } + } + + sendAction(action: any, ...params: any[]): void { + const win = BrowserWindow.getAllWindows()[0]; + + if (process.platform === 'darwin') { + win.restore(); + } + + win.webContents.send(action, ...params); + } } diff --git a/app/main/viewmanager.ts b/app/main/viewmanager.ts index 7c4ef87f1..dd918d58d 100644 --- a/app/main/viewmanager.ts +++ b/app/main/viewmanager.ts @@ -41,12 +41,9 @@ class ViewManager { }); ipcMain.on('call-view-function', (e: Event, name: string, ...params: any[]) => { - const fn = this.views[this.selectedIndex][name as keyof View]; - if (typeof fn === 'function') { - // Type checking requires spread elements to match up with a rest parameter. - // So, using a workaround here. - (fn as any)(...params); - } + // Type checking requires spread elements to match up with a rest parameter. + // So, using a workaround here. + (this.views[this.selectedIndex] as any)[name as keyof View](...params); }); } @@ -67,6 +64,8 @@ class ViewManager { return; } this.selectedIndex = index; + // console.log('setting null'); + mainWindow.setBrowserView(null); if (!view.webContents.getURL()) { const { url } = view; view.webContents.loadURL(url); diff --git a/app/renderer/js/main.ts b/app/renderer/js/main.ts index 305f83d8f..5b067f0c3 100644 --- a/app/renderer/js/main.ts +++ b/app/renderer/js/main.ts @@ -12,7 +12,6 @@ const { session, app, Menu, dialog } = remote; require('./tray'); import DomainUtil = require('./utils/domain-util'); -import WebView = require('./components/webview'); import ServerTab = require('./components/server-tab'); import FunctionalTab = require('./components/functional-tab'); import ConfigUtil = require('./utils/config-util'); @@ -156,13 +155,13 @@ class ServerManagerView { const proxyEnabled = ConfigUtil.getConfigItem('useManualProxy') || ConfigUtil.getConfigItem('useSystemProxy'); if (proxyEnabled) { - session.fromPartition('persist:webviewsession').setProxy({ + session.fromPartition('persist:view').setProxy({ pacScript: ConfigUtil.getConfigItem('proxyPAC', ''), proxyRules: ConfigUtil.getConfigItem('proxyRules', ''), proxyBypassRules: ConfigUtil.getConfigItem('proxyBypass', '') }, resolve); } else { - session.fromPartition('persist:webviewsession').setProxy({ + session.fromPartition('persist:view').setProxy({ pacScript: '', proxyRules: '', proxyBypassRules: '' @@ -240,8 +239,11 @@ class ServerManagerView { DomainUtil.updateSavedServer(servers[i].url, i); this.activateTab(i); } + const lastActiveTab = ConfigUtil.getConfigItem('lastActiveTab'); // Open last active tab - this.activateTab(ConfigUtil.getConfigItem('lastActiveTab')); + this.activateTab(lastActiveTab); + // Open last active view + ipcRenderer.send('view-select', ConfigUtil.getConfigItem('lastActiveTab')); // Remove focus from the settings icon at sidebar bottom this.$settingsButton.classList.remove('active'); } else { @@ -261,30 +263,17 @@ class ServerManagerView { tabIndex, onHover: this.onHover.bind(this, index), onHoverOut: this.onHoverOut.bind(this, index), - webview: new WebView({ - $root: this.$webviewsContainer, - index, - tabIndex, - url: server.url, - role: 'server', - name: CommonUtil.decodeString(server.alias), - isActive: () => { - return index === this.activeTabIndex; - }, - switchLoading: (loading: boolean, url: string) => { - if (!loading && this.loading[url]) { - this.loading[url] = false; - } else if (loading && !this.loading[url]) { - this.loading[url] = true; - } - this.showLoading(this.loading[this.tabs[this.activeTabIndex].webview.props.url]); - }, - onNetworkError: this.openNetworkTroubleshooting.bind(this), - onTitleChange: this.updateBadge.bind(this), - nodeIntegration: false, - preload: true - }) + url: server.url })); + const props = { + index, + url: server.url, + role: 'server', + name: CommonUtil.decodeString(server.alias), + nodeIntegration: false, + preload: true + }; + ipcRenderer.send('view-create', props); this.loading[server.url] = true; } @@ -313,7 +302,7 @@ class ServerManagerView { ipcRenderer.send('forward-message', 'toggle-dnd', dndUtil.dnd, dndUtil.newSettings); }); this.$reloadButton.addEventListener('click', () => { - this.tabs[this.activeTabIndex].webview.reload(); + ipcRenderer.send('call-view-function', 'reload'); }); this.$addServerButton.addEventListener('click', () => { this.openSettings('AddServer'); @@ -322,7 +311,7 @@ class ServerManagerView { this.openSettings('General'); }); this.$backButton.addEventListener('click', () => { - this.tabs[this.activeTabIndex].webview.back(); + ipcRenderer.send('call-view-function', 'back'); }); this.sidebarHoverEvent(this.$addServerButton, this.$addServerTooltip, true); @@ -345,7 +334,7 @@ class ServerManagerView { } getCurrentActiveServer(): string { - return this.tabs[this.activeTabIndex].webview.props.url; + return this.tabs[this.activeTabIndex].props.url; } displayInitialCharLogo($img: HTMLImageElement, index: number): void { @@ -427,31 +416,17 @@ class ServerManagerView { tabIndex, onClick: this.activateTab.bind(this, this.functionalTabs[tabProps.name]), onDestroy: this.destroyTab.bind(this, tabProps.name, this.functionalTabs[tabProps.name]), - webview: new WebView({ - $root: this.$webviewsContainer, - index: this.functionalTabs[tabProps.name], - tabIndex, - url: tabProps.url, - role: 'function', - name: tabProps.name, - isActive: () => { - return this.functionalTabs[tabProps.name] === this.activeTabIndex; - }, - switchLoading: (loading: AnyObject, url: string) => { - if (!loading && this.loading[url]) { - this.loading[url] = false; - } else if (loading && !this.loading[url]) { - this.loading[url] = true; - } - this.showLoading(this.loading[this.tabs[this.activeTabIndex].webview.props.url]); - }, - onNetworkError: this.openNetworkTroubleshooting.bind(this), - onTitleChange: this.updateBadge.bind(this), - nodeIntegration: true, - preload: false - }) + url: tabProps.url })); - + const props = { + index: this.functionalTabs[tabProps.name], + url: tabProps.url, + role: 'function', + name: tabProps.name, + nodeIntegration: true, + preload: false + }; + ipcRenderer.send('view-create', props); // To show loading indicator the first time a functional tab is opened, indicator is // closed when the functional tab DOM is ready, handled in webview.js this.$webviewsContainer.classList.remove('loaded'); @@ -466,7 +441,7 @@ class ServerManagerView { url: `file://${rendererDirectory}/preference.html#${nav}` }); this.$settingsButton.classList.add('active'); - this.tabs[this.functionalTabs.Settings].webview.send('switch-settings-nav', nav); + ipcRenderer.send('forward-message-view', 'switch-settings-nav', nav); } openAbout(): void { @@ -501,10 +476,6 @@ class ServerManagerView { this.tabs.forEach((tab: ServerOrFunctionalTab) => { const proto = Object.create(Object.getPrototypeOf(tab)); const tabClone = Object.assign(proto, tab); - - tabClone.webview = { props: {} }; - tabClone.webview.props.name = tab.webview.props.name; - delete tabClone.props.webview; tabs.push(tabClone); }); @@ -528,16 +499,11 @@ class ServerManagerView { } } - try { - this.tabs[index].webview.canGoBackButton(); - } catch (err) { - } - this.activeTabIndex = index; this.tabs[index].activate(); - - this.showLoading(this.loading[this.tabs[this.activeTabIndex].webview.props.url]); - + ipcRenderer.send('view-select', index); + this.showLoading(this.loading[this.tabs[this.activeTabIndex].props.url]); + ipcRenderer.send('call-view-function', 'canGoBackButton'); ipcRenderer.send('update-menu', { // JSON stringify this.tabs to avoid a crash // util.inspect is being used to handle circular references @@ -559,10 +525,6 @@ class ServerManagerView { } destroyTab(name: string, index: number): void { - if (this.tabs[index].webview.loading) { - return; - } - this.tabs[index].destroy(); delete this.tabs[index]; @@ -578,6 +540,8 @@ class ServerManagerView { // Show loading indicator this.$webviewsContainer.classList.remove('loaded'); + ipcRenderer.send('view-destroy-all'); + // Clear global variables this.activeTabIndex = -1; this.tabs = []; @@ -606,25 +570,19 @@ class ServerManagerView { } updateBadge(): void { - let messageCountAll = 0; - for (const tab of this.tabs) { - if (tab && tab instanceof ServerTab && tab.updateBadge) { - const count = tab.webview.badgeCount; - messageCountAll += count; - tab.updateBadge(count); - } - } - - ipcRenderer.send('update-badge', messageCountAll); + // let messageCountAll = 0; + // for (const tab of this.tabs) { + // if (tab && tab instanceof ServerTab && tab.updateBadge) { + // const count = tab.webview.badgeCount; + // messageCountAll += count; + // tab.updateBadge(count); + // } + // } + // ipcRenderer.send('update-badge', messageCountAll); } updateGeneralSettings(setting: string, value: any): void { - const selector = 'webview:not([class*=disabled])'; - const webview: Electron.WebviewTag = document.querySelector(selector); - if (webview) { - const webContents = webview.getWebContents(); - webContents.send(setting, value); - } + ipcRenderer.send('forward-message-view', setting, value); } toggleSidebar(show: boolean): void { @@ -633,6 +591,12 @@ class ServerManagerView { } else { this.$sidebar.classList.add('sidebar-hide'); } + this.fixBounds(); + } + + // Fixes bounds for view + fixBounds(): void { + ipcRenderer.send('fix-bounds'); } // Toggles the dnd button icon. @@ -675,9 +639,9 @@ class ServerManagerView { registerIpcs(): void { const webviewListeners: AnyObject = { - 'webview-reload': 'reload', + // 'webview-reload': 'reload', back: 'back', - focus: 'focus', + // focus: 'focus', forward: 'forward', zoomIn: 'zoomIn', zoomOut: 'zoomOut', @@ -689,10 +653,7 @@ class ServerManagerView { for (const key in webviewListeners) { ipcRenderer.on(key, () => { - const activeWebview = this.tabs[this.activeTabIndex].webview; - if (activeWebview) { - activeWebview[webviewListeners[key] as string](); - } + ipcRenderer.send('view-call-function', webviewListeners[key]); }); } @@ -765,18 +726,17 @@ class ServerManagerView { tabs: this.tabsForIpc, activeTabIndex: this.activeTabIndex }); + this.fixBounds(); return; } this.updateGeneralSettings('toggle-menubar-setting', autoHideMenubar); + this.fixBounds(); }); ipcRenderer.on('toggle-dnd', (event: Event, state: boolean, newSettings: SettingsOptions) => { this.toggleDNDButton(state); ipcRenderer.send('forward-message', 'toggle-silent', newSettings.silent); - const selector = 'webview:not([class*=disabled])'; - const webview: Electron.WebviewTag = document.querySelector(selector); - const webContents = webview.getWebContents(); - webContents.send('toggle-dnd', state, newSettings); + ipcRenderer.send('forward-message-view', 'toggle-dnd', state, newSettings); }); ipcRenderer.on('update-realm-name', (event: Event, serverURL: string, realmName: string) => { @@ -787,7 +747,7 @@ class ServerManagerView { const serverTooltips = document.querySelectorAll(serverTooltipSelector); serverTooltips[index].innerHTML = escape(realmName); this.tabs[index].props.name = escape(realmName); - this.tabs[index].webview.props.name = realmName; + // this.tabs[index].webview.props.name = realmName; domain.alias = escape(realmName); DomainUtil.db.push(`/domains[${index}]`, domain, true); @@ -879,6 +839,23 @@ class ServerManagerView { ipcRenderer.on('new-server', () => { this.openSettings('AddServer'); }); + + ipcRenderer.on('switch-back', (e: Event, state: boolean) => { + if (state === true) { + this.$backButton.classList.remove('disable'); + } else { + this.$backButton.classList.add('disable'); + } + }); + + ipcRenderer.on('switch-loading', (e: Event, loading: boolean, url: string) => { + if (!loading && this.loading[url]) { + this.loading[url] = false; + } else if (loading && !this.loading[url]) { + this.loading[url] = true; + } + this.showLoading(this.loading[this.tabs[this.activeTabIndex].props.url]); + }); } } diff --git a/package-lock.json b/package-lock.json index 8920efa9d..98d1f6658 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2669,9 +2669,9 @@ "dev": true }, "electron": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/electron/-/electron-5.0.6.tgz", - "integrity": "sha512-0L53lv26eDhaaNxL6DqXGQrQOEAYbrQg40stRSb2pzrY06kwPbABzXEiaCvEsBuKUQ+9OQBbVyyvXRbLJlun/A==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/electron/-/electron-5.0.7.tgz", + "integrity": "sha512-OMMz8DhatxLuBFbnW7KYcAUjflGYFn0IQEtKR0iZhMAm89FgNOd9SVbxXWAGNxvRR6C0gORXwhTh6BCqqqcR6Q==", "dev": true, "requires": { "@types/node": "^10.12.18",