mirror of
https://github.com/rubickCenter/rubick
synced 2025-06-06 10:34:08 +08:00
197 lines
5.8 KiB
TypeScript
197 lines
5.8 KiB
TypeScript
import { BrowserView, BrowserWindow, session } from 'electron';
|
|
import path from 'path';
|
|
import commonConst from '../../common/utils/commonConst';
|
|
import { PLUGIN_INSTALL_DIR as baseDir } from '@/common/constans/main';
|
|
import localConfig from '@/main/common/initLocalConfig';
|
|
|
|
const getRelativePath = (indexPath) => {
|
|
return commonConst.windows()
|
|
? indexPath.replace('file://', '')
|
|
: indexPath.replace('file:', '');
|
|
};
|
|
|
|
const getPreloadPath = (plugin, pluginIndexPath) => {
|
|
const { name, preload, tplPath, indexPath } = plugin;
|
|
if (!preload) return;
|
|
if (commonConst.dev()) {
|
|
if (name === 'rubick-system-feature') {
|
|
return path.resolve(__static, `../feature/public/preload.js`);
|
|
}
|
|
if (tplPath) {
|
|
return path.resolve(getRelativePath(indexPath), `./`, preload);
|
|
}
|
|
return path.resolve(getRelativePath(pluginIndexPath), `../`, preload);
|
|
}
|
|
if (tplPath) {
|
|
return path.resolve(getRelativePath(indexPath), `./`, preload);
|
|
}
|
|
return path.resolve(getRelativePath(pluginIndexPath), `../`, preload);
|
|
};
|
|
|
|
const viewPoolManager = () => {
|
|
const viewPool: any = {
|
|
views: [],
|
|
};
|
|
const maxLen = 4;
|
|
return {
|
|
getView(pluginName) {
|
|
return viewPool.views.find((view) => view.pluginName === pluginName);
|
|
},
|
|
addView(pluginName, view) {
|
|
if (this.getView(pluginName)) return;
|
|
if (viewPool.views.length > maxLen) {
|
|
viewPool.views.shift();
|
|
}
|
|
viewPool.views.push({
|
|
pluginName,
|
|
view,
|
|
});
|
|
},
|
|
};
|
|
};
|
|
|
|
export default () => {
|
|
let view;
|
|
const viewInstance = viewPoolManager();
|
|
|
|
const viewReadyFn = async (window, { pluginSetting, ext }) => {
|
|
if (!view) return;
|
|
const height = pluginSetting && pluginSetting.height;
|
|
window.setSize(800, height || 600);
|
|
view.setBounds({ x: 0, y: 60, width: 800, height: height || 540 });
|
|
view.setAutoResize({ width: true, height: true });
|
|
executeHooks('PluginEnter', ext);
|
|
executeHooks('PluginReady', ext);
|
|
const config = await localConfig.getConfig();
|
|
const darkMode = config.perf.common.darkMode;
|
|
darkMode &&
|
|
view.webContents.executeJavaScript(
|
|
`document.body.classList.add("dark");window.rubick.theme="dark"`
|
|
);
|
|
window.webContents.executeJavaScript(`window.pluginLoaded()`);
|
|
};
|
|
|
|
const init = (plugin, window: BrowserWindow) => {
|
|
if (view === null || view === undefined) {
|
|
createView(plugin, window);
|
|
// if (viewInstance.getView(plugin.name) && !commonConst.dev()) {
|
|
// view = viewInstance.getView(plugin.name).view;
|
|
// window.setBrowserView(view);
|
|
// view.inited = true;
|
|
// viewReadyFn(window, plugin);
|
|
// } else {
|
|
// createView(plugin, window);
|
|
// viewInstance.addView(plugin.name, view);
|
|
// }
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
require('@electron/remote/main').enable(view.webContents);
|
|
}
|
|
};
|
|
|
|
const createView = (plugin, window: BrowserWindow) => {
|
|
const {
|
|
tplPath,
|
|
indexPath,
|
|
development,
|
|
name,
|
|
main = 'index.html',
|
|
pluginSetting,
|
|
ext,
|
|
} = plugin;
|
|
let pluginIndexPath = tplPath || indexPath;
|
|
let preloadPath;
|
|
let darkMode;
|
|
// 开发环境
|
|
if (commonConst.dev() && development) {
|
|
pluginIndexPath = development;
|
|
const pluginPath = path.resolve(baseDir, 'node_modules', name);
|
|
preloadPath = `file://${path.join(pluginPath, './', main)}`;
|
|
}
|
|
// 再尝试去找
|
|
if (plugin.name === 'rubick-system-feature' && !pluginIndexPath) {
|
|
pluginIndexPath = commonConst.dev()
|
|
? 'http://localhost:8081/#/'
|
|
: `file://${__static}/feature/index.html`;
|
|
}
|
|
if (!pluginIndexPath) {
|
|
const pluginPath = path.resolve(baseDir, 'node_modules', name);
|
|
pluginIndexPath = `file://${path.join(pluginPath, './', main)}`;
|
|
}
|
|
const preload = getPreloadPath(plugin, preloadPath || pluginIndexPath);
|
|
|
|
const ses = session.fromPartition('<' + name + '>');
|
|
ses.setPreloads([`${__static}/preload.js`]);
|
|
|
|
view = new BrowserView({
|
|
webPreferences: {
|
|
webSecurity: false,
|
|
nodeIntegration: true,
|
|
contextIsolation: false,
|
|
devTools: true,
|
|
webviewTag: true,
|
|
preload,
|
|
session: ses,
|
|
defaultFontSize: 14,
|
|
defaultFontFamily: {
|
|
standard: 'system-ui',
|
|
serif: 'system-ui',
|
|
},
|
|
spellcheck: false,
|
|
},
|
|
});
|
|
window.setBrowserView(view);
|
|
view.webContents.loadURL(pluginIndexPath);
|
|
view.webContents.once('dom-ready', () => viewReadyFn(window, plugin));
|
|
// 修复请求跨域问题
|
|
view.webContents.session.webRequest.onBeforeSendHeaders(
|
|
(details, callback) => {
|
|
callback({
|
|
requestHeaders: { referer: '*', ...details.requestHeaders },
|
|
});
|
|
}
|
|
);
|
|
|
|
view.webContents.session.webRequest.onHeadersReceived(
|
|
(details, callback) => {
|
|
callback({
|
|
responseHeaders: {
|
|
'Access-Control-Allow-Origin': ['*'],
|
|
...details.responseHeaders,
|
|
},
|
|
});
|
|
}
|
|
);
|
|
};
|
|
|
|
const removeView = (window: BrowserWindow) => {
|
|
if (!view) return;
|
|
window.removeBrowserView(view);
|
|
// window.setSize(800, 60);
|
|
executeHooks('PluginOut', null);
|
|
window.webContents?.executeJavaScript(`window.initRubick()`);
|
|
view = undefined;
|
|
};
|
|
|
|
const getView = () => view;
|
|
|
|
const executeHooks = (hook, data) => {
|
|
setTimeout(() => {
|
|
if (!view) return;
|
|
const evalJs = `if(window.rubick && window.rubick.hooks && typeof window.rubick.hooks.on${hook} === 'function' ) {
|
|
try {
|
|
window.rubick.hooks.on${hook}(${data ? JSON.stringify(data) : ''});
|
|
} catch(e) {}
|
|
}
|
|
`;
|
|
view.webContents?.executeJavaScript(evalJs);
|
|
}, 300);
|
|
};
|
|
|
|
return {
|
|
init,
|
|
getView,
|
|
removeView,
|
|
executeHooks,
|
|
};
|
|
};
|