Skip to content

Instantly share code, notes, and snippets.

@mrchaofan
Last active May 13, 2025 09:37
Show Gist options
  • Select an option

  • Save mrchaofan/e47f265042ed012ea23356e395e69f44 to your computer and use it in GitHub Desktop.

Select an option

Save mrchaofan/e47f265042ed012ea23356e395e69f44 to your computer and use it in GitHub Desktop.
const electron = require('electron')
if (parseInt(process.versions.electron.split('.')[0]) <= 30) {
const { EventEmitter } = require('events')
function throwError() {
throw new TypeError('Electron.View兼容错误。')
}
/**
*
* @param {View} view
* @returns {{x: number, y: number, width: number, height: number}}
*/
function convertCoordToWindow(view) {
let bounds = view.getBounds();
let thisView = view;
while (thisView != null) {
bounds = convertCoordToParent(thisView, bounds);
thisView = thisView.parent_;
}
return bounds;
}
/**
*
* @param {View} view
* @param {{x: number, y: number, width: number, height: number}} bounds
* @returns {{x: number, y: number, width: number, height: number}}
*/
function convertCoordToParent(view, bounds) {
const parent = view.parent_;
if (!parent) {
return bounds;
}
const parentBounds = parent.getBounds();
return {
x: bounds.x + parentBounds.x,
y: bounds.y + parentBounds.y,
width: bounds.width,
height: bounds.height,
};
}
/**
*
* @param {View} view
* @returns
*/
function getWindow(view) {
if (view.window_) {
return view.window_
}
if (view.parent_) {
return getWindow(view.parent_)
}
}
/**
*
* @param {View} view
* @param {View} browserWindow
*/
function propagateAddNotifications(view, browserWindow) {
view.children.forEach((view) => {
propagateAddNotifications(view, browserWindow)
})
view.emit('__attach', {
browserWindow
})
}
/**
*
* @param {View} view
* @param {View} browserWindow
*/
function propagateRemoveNotifications(view, browserWindow) {
view.children.forEach((view) => {
propagateRemoveNotifications(view, browserWindow)
})
view.emit('__detach', {
browserWindow
})
}
class View extends EventEmitter {
constructor() {
super();
this.bounds_ = {
x: 0,
y: 0,
width: 0,
height: 0,
}
this.children_ = []
}
get children() {
return this.children_
}
addChildView(view) {
const index = this.children_.findIndex((item) => item === view)
if (index !== -1) {
this.children_.splice(index, 1)
}
view.parent_ = this
this.children_.push(view)
const browserWindow = getWindow(this)
if (browserWindow) {
propagateAddNotifications(view, browserWindow)
}
}
removeChildView(view) {
const index = this.children_.findIndex((item) => item === view)
if (index !== -1) {
view.parent_ = undefined
this.children_.splice(index, 1)
}
const browserWindow = getWindow(this)
if (browserWindow) {
propagateRemoveNotifications(view, browserWindow)
}
}
setBounds(bounds) {
this.bounds_ = bounds
this.emit('bounds-changed', bounds)
}
getBounds() {
return this.bounds_
}
setBackgroundColor(color) {
throwError()
}
setBorderRadius(radius) {
throwError()
}
setVisible(visible) {
throwError()
}
getVisible() {
throwError()
}
}
class WebContentsView extends View {
constructor(options) {
super()
this.browserView_ = new electron.BrowserView(options)
this.webContents = this.browserView_.webContents
this.on('__attach', /**
*
* @param {{
* view: View,
* browserWindow: BrowserWindow
* }} param0
*/
({ browserWindow }) => {
const coord = convertCoordToWindow(this)
browserWindow.addBrowserView(this.browserView_)
this.browserView_.setBounds(coord)
})
this.on('__detach', /**
*
* @param {{
* browserWindow: BrowserWindow
* }} param0
*/
({ browserWindow }) => {
browserWindow.removeBrowserView(this.browserView_)
})
}
setBounds(bounds) {
super.setBounds(bounds)
this.browserView_.setBounds(bounds)
this.emit('bounds-changed', bounds)
}
setBackgroundColor(color) {
this.browserView_.setBackgroundColor(color)
}
setBorderRadius(radius) {
}
}
class BrowserWindow extends electron.BrowserWindow {
constructor(options) {
super(options)
this.contentView_ = new View()
this.contentView_.window_ = this
}
get contentView() {
return this.contentView_
}
}
exports.View = View
exports.WebContentsView = WebContentsView
exports.BrowserWindow = BrowserWindow
exports.BaseWindow = BrowserWindow
} else {
exports.View = electron.View
exports.WebContentsView = electron.WebContentsView
exports.BrowserWindow = electron.BrowserWindow
exports.BaseWindow = electron.BrowserWindow
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment