Skip to content

Commit

Permalink
refactor: create PopupView class
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmaddock committed Oct 10, 2020
1 parent 8d8920b commit 30c337a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 37 deletions.
@@ -1,5 +1,6 @@
import { session, ipcMain } from 'electron'
import { session, ipcMain, BrowserWindow } from 'electron'
import { EventEmitter } from 'events'
import { PopupView } from '../popup'
import { ExtensionStore } from '../store'
import { getIconImage } from './common'

Expand All @@ -22,7 +23,8 @@ interface ExtensionActionStore extends Partial<ExtensionAction> {
}

export class BrowserActionAPI {
sessionActionMap = new Map<Electron.Session, Map<string, ExtensionActionStore>>()
private sessionActionMap = new Map<Electron.Session, Map<string, ExtensionActionStore>>()
private popup?: PopupView

constructor(private store: ExtensionStore) {
const setter = (propName: string) => (
Expand Down Expand Up @@ -70,9 +72,11 @@ export class BrowserActionAPI {
return action
}

getPopupPath(session: Electron.Session, extensionId: string, tabId: string) {
private getPopupUrl(session: Electron.Session, extensionId: string, tabId: number) {
const action = this.getAction(session, extensionId)
return action.tabs[tabId] ? action.tabs[tabId].popup?.path : action.popup?.path
const popupPath =
(action.tabs[tabId] && action.tabs[tabId].popup?.path) || action.popup?.path || undefined
return popupPath && `chrome-extension://${extensionId}/${popupPath}`
}

processExtensions(session: Electron.Session, extensions: Electron.Extension[]) {
Expand Down Expand Up @@ -105,6 +109,24 @@ export class BrowserActionAPI {
}

private onClicked(event: Electron.IpcMainInvokeEvent, extensionId: string) {
this.store.emit('action-clicked', event, extensionId)
if (this.popup) {
const toggleExtension = !this.popup.isDestroyed() && this.popup.extensionId === extensionId
this.popup.destroy()
this.popup = undefined
if (toggleExtension) return
}

// TODO: activeTab needs to be refactored to support one active tab per window
const { activeTab } = this.store
if (!activeTab) return

const popupUrl = this.getPopupUrl(activeTab.session, extensionId, activeTab.id)

if (popupUrl) {
const win = BrowserWindow.fromWebContents(activeTab)
if (win) this.popup = new PopupView(extensionId, win, popupUrl)
} else {
// TODO: dispatch click action
}
}
}
15 changes: 0 additions & 15 deletions packages/electron-chrome-extensions/src/browser/index.ts
Expand Up @@ -120,19 +120,4 @@ export class Extensions extends EventEmitter {
this.tabs.onActivated(tab.id)
}
}

createPopup(win: Electron.BrowserWindow, tabId: string, extensionId: string) {
const popupPath =
this.browserAction.getPopupPath(win.webContents.session, extensionId, tabId) || `popup.html`
const popupUrl = `chrome-extension://${extensionId}/${popupPath}`
const popup = new BrowserView()
popup.setBounds({ x: win.getSize()[0] - 256, y: 62, width: 256, height: 400 })
// popup.webContents.loadURL(`chrome-extension://${extension.id}/popup.html?tabId=${win.webContents.id}`)
console.log(`POPUP URL: ${popupUrl}`)
popup.webContents.loadURL(popupUrl)
popup.webContents.openDevTools({ mode: 'detach', activate: true })
popup.setBackgroundColor('#ff0000')
win.addBrowserView(popup)
return popup
}
}
65 changes: 65 additions & 0 deletions packages/electron-chrome-extensions/src/browser/popup.ts
@@ -0,0 +1,65 @@
import { BrowserView, BrowserWindow } from 'electron'

enum PopupGeometry {
// TODO: dynamically set offset based on action button position
OffsetY = 62,
MinWidth = 25,
MinHeight = 25,
MaxWidth = 800,
MaxHeight = 600,
}

export class PopupView {
private view?: BrowserView

constructor(public extensionId: string, private window: BrowserWindow, url: string) {
this.view = new BrowserView({
webPreferences: {
contextIsolation: true,
preferredSizeMode: true,
} as any,
})

// Set default size where preferredSizeMode isn't supported
this.view.setBounds({ x: this.window.getSize()[0] - 256, y: 62, width: 256, height: 400 })

const untypedWebContents = this.view.webContents as any
untypedWebContents.on('preferred-size-changed', this.updatePreferredSize)

this.view.setBackgroundColor('#ff0000')
this.view.webContents.loadURL(url)

// this.view.webContents.openDevTools({ mode: 'detach', activate: true })

this.window.addBrowserView(this.view)
this.view.webContents.focus()

// TODO:
this.view.webContents.once('blur' as any, this.destroy)
}

destroy = () => {
if (!this.view) return

this.window.removeBrowserView(this.view)
if (this.view.webContents.isDevToolsOpened()) {
this.view.webContents.closeDevTools()
}

this.view = undefined
}

isDestroyed() {
return !this.view
}

private updatePreferredSize = (event: Electron.Event, size: Electron.Size) => {
const windowWidth = this.window.getSize()[0]
this.view?.setBounds({
x: windowWidth - size.width,
y: PopupGeometry.OffsetY,
width: Math.min(PopupGeometry.MaxWidth, Math.max(size.width, PopupGeometry.MinWidth)),
height: Math.min(PopupGeometry.MaxHeight, Math.max(size.height, PopupGeometry.MinHeight)),
})
}
}
3 changes: 2 additions & 1 deletion packages/electron-chrome-extensions/src/browser/store.ts
Expand Up @@ -15,7 +15,8 @@ export class ExtensionStore {
}

get activeTab(): Electron.WebContents | undefined {
return this.activeTabId ? this.getTabById(this.activeTabId) : undefined
const tab = this.activeTabId ? this.getTabById(this.activeTabId) : undefined
return tab && !tab.isDestroyed() ? tab : undefined
}
set activeTab(tab: Electron.WebContents | undefined) {
const tabId = tab?.id
Expand Down
16 changes: 0 additions & 16 deletions packages/shell/browser/main.js
Expand Up @@ -115,7 +115,6 @@ class TabbedBrowserWindow {

class Browser {
windows = []
popupView = null

constructor() {
app.whenReady().then(this.init.bind(this))
Expand Down Expand Up @@ -204,21 +203,6 @@ class Browser {
win.tabs.select(tab.id)
})

this.extensions.on('action-clicked', (event, extensionId) => {
const win = this.getWindowFromWebContents(event.sender)
const selectedId = win.tabs.selected ? win.tabs.selected.id : -1

if (this.popupView) {
win.window.removeBrowserView(this.popupView)
if (this.popupView.webContents.isDevToolsOpened()) {
this.popupView.webContents.closeDevTools()
}
this.popupView = undefined
} else {
this.popupView = this.extensions.createPopup(win.window, selectedId, extensionId)
}
})

this.createWindow({ initialUrl: newTabUrl })
}

Expand Down

0 comments on commit 30c337a

Please sign in to comment.