feat: 新增包文件
This commit is contained in:
153
packages/chrome-ui/tabs.js
Normal file
153
packages/chrome-ui/tabs.js
Normal file
@@ -0,0 +1,153 @@
|
||||
const { EventEmitter } = require('events')
|
||||
const { WebContentsView } = require('electron')
|
||||
|
||||
const toolbarHeight = 64
|
||||
|
||||
class Tab {
|
||||
constructor(parentWindow, wcvOpts = {}) {
|
||||
this.invalidateLayout = this.invalidateLayout.bind(this)
|
||||
|
||||
// Delete undefined properties which cause WebContentsView constructor to
|
||||
// throw. This should probably be fixed in Electron upstream.
|
||||
if (wcvOpts.hasOwnProperty('webContents') && !wcvOpts.webContents) delete wcvOpts.webContents
|
||||
if (wcvOpts.hasOwnProperty('webPreferences') && !wcvOpts.webPreferences)
|
||||
delete wcvOpts.webPreferences
|
||||
|
||||
this.view = new WebContentsView(wcvOpts)
|
||||
this.id = this.view.webContents.id
|
||||
this.window = parentWindow
|
||||
this.webContents = this.view.webContents
|
||||
this.window.contentView.addChildView(this.view)
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.destroyed) return
|
||||
|
||||
this.destroyed = true
|
||||
|
||||
this.hide()
|
||||
|
||||
this.window.contentView.removeChildView(this.view)
|
||||
this.window = undefined
|
||||
|
||||
if (!this.webContents.isDestroyed()) {
|
||||
if (this.webContents.isDevToolsOpened()) {
|
||||
this.webContents.closeDevTools()
|
||||
}
|
||||
|
||||
// TODO: why is this no longer called?
|
||||
this.webContents.emit('destroyed')
|
||||
|
||||
this.webContents.destroy()
|
||||
}
|
||||
|
||||
this.webContents = undefined
|
||||
this.view = undefined
|
||||
}
|
||||
|
||||
loadURL(url) {
|
||||
return this.view.webContents.loadURL(url)
|
||||
}
|
||||
|
||||
show() {
|
||||
this.invalidateLayout()
|
||||
this.startResizeListener()
|
||||
this.view.setVisible(true)
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.stopResizeListener()
|
||||
this.view.setVisible(false)
|
||||
}
|
||||
|
||||
reload() {
|
||||
this.view.webContents.reload()
|
||||
}
|
||||
|
||||
invalidateLayout() {
|
||||
const [width, height] = this.window.getSize()
|
||||
const padding = 4
|
||||
this.view.setBounds({
|
||||
x: padding,
|
||||
y: toolbarHeight,
|
||||
width: width - padding * 2,
|
||||
height: height - toolbarHeight - padding,
|
||||
})
|
||||
this.view.setBorderRadius(8)
|
||||
}
|
||||
|
||||
// Replacement for BrowserView.setAutoResize. This could probably be better...
|
||||
startResizeListener() {
|
||||
this.stopResizeListener()
|
||||
this.window.on('resize', this.invalidateLayout)
|
||||
}
|
||||
stopResizeListener() {
|
||||
this.window.off('resize', this.invalidateLayout)
|
||||
}
|
||||
}
|
||||
|
||||
class Tabs extends EventEmitter {
|
||||
tabList = []
|
||||
selected = null
|
||||
|
||||
constructor(browserWindow) {
|
||||
super()
|
||||
this.window = browserWindow
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.tabList.forEach((tab) => tab.destroy())
|
||||
this.tabList = []
|
||||
|
||||
this.selected = undefined
|
||||
|
||||
if (this.window) {
|
||||
this.window.destroy()
|
||||
this.window = undefined
|
||||
}
|
||||
}
|
||||
|
||||
get(tabId) {
|
||||
return this.tabList.find((tab) => tab.id === tabId)
|
||||
}
|
||||
|
||||
create(webContentsViewOptions) {
|
||||
const tab = new Tab(this.window, webContentsViewOptions)
|
||||
this.tabList.push(tab)
|
||||
if (!this.selected) this.selected = tab
|
||||
tab.show() // must be attached to window
|
||||
this.emit('tab-created', tab)
|
||||
this.select(tab.id)
|
||||
return tab
|
||||
}
|
||||
|
||||
remove(tabId) {
|
||||
const tabIndex = this.tabList.findIndex((tab) => tab.id === tabId)
|
||||
if (tabIndex < 0) {
|
||||
throw new Error(`Tabs.remove: unable to find tab.id = ${tabId}`)
|
||||
}
|
||||
const tab = this.tabList[tabIndex]
|
||||
this.tabList.splice(tabIndex, 1)
|
||||
tab.destroy()
|
||||
if (this.selected === tab) {
|
||||
this.selected = undefined
|
||||
const nextTab = this.tabList[tabIndex] || this.tabList[tabIndex - 1]
|
||||
if (nextTab) this.select(nextTab.id)
|
||||
}
|
||||
this.emit('tab-destroyed', tab)
|
||||
if (this.tabList.length === 0) {
|
||||
this.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
select(tabId) {
|
||||
const tab = this.get(tabId)
|
||||
if (!tab) return
|
||||
if (this.selected) this.selected.hide()
|
||||
tab.show()
|
||||
this.selected = tab
|
||||
this.emit('tab-selected', tab)
|
||||
}
|
||||
}
|
||||
|
||||
exports.Tabs = Tabs
|
||||
Reference in New Issue
Block a user