diff --git a/package.json b/package.json index 5e96d1f..f788b67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubick", - "version": "2.0.8", + "version": "2.0.9", "author": "muwoo <2424880409@qq.com>", "private": true, "scripts": { diff --git a/public/preload.js b/public/preload.js index 059a403..4f6b20d 100644 --- a/public/preload.js +++ b/public/preload.js @@ -1,19 +1,19 @@ -const { ipcRenderer, shell } = require("electron"); -const os = require("os"); +const { ipcRenderer, shell } = require('electron'); +const os = require('os'); const ipcSendSync = (type, data) => { - const returnValue = ipcRenderer.sendSync("msg-trigger", { + const returnValue = ipcRenderer.sendSync('msg-trigger', { type, - data + data, }); if (returnValue instanceof Error) throw returnValue; return returnValue; }; const ipcSend = (type, data) => { - ipcRenderer.send("msg-trigger", { + ipcRenderer.send('msg-trigger', { type, - data + data, }); }; @@ -22,99 +22,99 @@ window.rubick = { // 事件 onPluginEnter(cb) { console.log(window.rubick.hooks); - typeof cb === "function" && (window.rubick.hooks.onPluginEnter = cb); + typeof cb === 'function' && (window.rubick.hooks.onPluginEnter = cb); }, onPluginReady(cb) { - typeof cb === "function" && (window.rubick.hooks.onPluginReady = cb); + typeof cb === 'function' && (window.rubick.hooks.onPluginReady = cb); }, onPluginOut(cb) { - typeof cb === "function" && (window.rubick.hooks.onPluginOut = cb); + typeof cb === 'function' && (window.rubick.hooks.onPluginOut = cb); }, openPlugin(plugin) { - ipcSendSync("loadPlugin", plugin); + ipcSendSync('loadPlugin', plugin); }, // 窗口交互 hideMainWindow() { - ipcSendSync("hideMainWindow"); + ipcSendSync('hideMainWindow'); }, showMainWindow() { - ipcSendSync("showMainWindow"); + ipcSendSync('showMainWindow'); }, showOpenDialog(options) { - ipcSendSync("showOpenDialog", options); + ipcSendSync('showOpenDialog', options); }, setExpendHeight(height) { - ipcSendSync("setExpendHeight", height); + ipcSendSync('setExpendHeight', height); }, - setSubInput(onChange, placeholder = "", isFocus) { - typeof onChange === "function" && + setSubInput(onChange, placeholder = '', isFocus) { + typeof onChange === 'function' && (window.rubick.hooks.onSubInputChange = onChange); - ipcSendSync("setSubInput", { + ipcSendSync('setSubInput', { placeholder, - isFocus + isFocus, }); }, removeSubInput() { delete window.rubick.hooks.onSubInputChange; - ipcSendSync("removeSubInput"); + ipcSendSync('removeSubInput'); }, setSubInputValue(text) { - ipcSendSync("setSubInputValue", { text }); + ipcSendSync('setSubInputValue', { text }); }, subInputBlur() { - ipcSendSync("subInputBlur"); + ipcSendSync('subInputBlur'); }, getPath(name) { - return ipcSendSync("getPath", { name }); + return ipcSendSync('getPath', { name }); }, showNotification(body, clickFeatureCode) { - ipcSend("showNotification", { body, clickFeatureCode }); + ipcSend('showNotification', { body, clickFeatureCode }); }, copyImage(img) { - return ipcSendSync("copyImage", { img }); + return ipcSendSync('copyImage', { img }); }, copyText(text) { - return ipcSendSync("copyText", { text }); + return ipcSendSync('copyText', { text }); }, - copyFile: file => { - return ipcSendSync("copyFile", { file }); + copyFile: (file) => { + return ipcSendSync('copyFile', { file }); }, db: { - put: data => ipcSendSync("dbPut", { data }), - get: id => ipcSendSync("dbGet", { id }), - remove: doc => ipcSendSync("dbRemove", { doc }), - bulkDocs: docs => ipcSendSync("dbBulkDocs", { docs }), - allDocs: key => ipcSendSync("dbAllDocs", { key }) + put: (data) => ipcSendSync('dbPut', { data }), + get: (id) => ipcSendSync('dbGet', { id }), + remove: (doc) => ipcSendSync('dbRemove', { doc }), + bulkDocs: (docs) => ipcSendSync('dbBulkDocs', { docs }), + allDocs: (key) => ipcSendSync('dbAllDocs', { key }), }, dbStorage: { setItem: (key, value) => { const target = { _id: String(key) }; - const result = ipcSendSync("dbGet", { id: target._id }); + const result = ipcSendSync('dbGet', { id: target._id }); result && (target._rev = result._rev); target.value = value; - const res = ipcSendSync("dbPut", { data: target }); + const res = ipcSendSync('dbPut', { data: target }); if (res.error) throw new Error(res.message); }, - getItem: key => { - const res = ipcSendSync("dbGet", { id: key }); - return res && "value" in res ? res.value : null; + getItem: (key) => { + const res = ipcSendSync('dbGet', { id: key }); + return res && 'value' in res ? res.value : null; + }, + removeItem: (key) => { + const res = ipcSendSync('dbGet', { id: key }); + res && ipcSendSync('dbRemove', { doc: res }); }, - removeItem: key => { - const res = ipcSendSync("dbGet", { id: key }); - res && ipcSendSync("dbRemove", { doc: res }); - } }, isDarkColors() { return false; }, getFeatures() { - return ipcSendSync("getFeatures"); + return ipcSendSync('getFeatures'); }, setFeature(feature) { - return ipcSendSync("setFeature", { feature }); + return ipcSendSync('setFeature', { feature }); }, removeFeature(code) { - return ipcSendSync("removeFeature", { code }); + return ipcSendSync('removeFeature', { code }); }, // 系统 @@ -123,29 +123,29 @@ window.rubick = { }, isMacOs() { - return os.type() === "Darwin"; + return os.type() === 'Darwin'; }, isWindows() { - return os.type() === "Windows_NT"; + return os.type() === 'Windows_NT'; }, isLinux() { - return os.type() === "Linux"; + return os.type() === 'Linux'; }, shellOpenPath(path) { shell.openPath(path); }, - getLocalId: () => ipcSendSync("getLocalId"), + getLocalId: () => ipcSendSync('getLocalId'), removePlugin() { - ipcSend("removePlugin"); + ipcSend('removePlugin'); }, - shellShowItemInFolder: path => { - ipcSend("shellShowItemInFolder", { path }); + shellShowItemInFolder: (path) => { + ipcSend('shellShowItemInFolder', { path }); }, redirect: (label, payload) => { @@ -153,6 +153,6 @@ window.rubick = { }, shellBeep: () => { - ipcSend("shellBeep") + ipcSend('shellBeep'); }, }; diff --git a/src/main/browsers/detach.ts b/src/main/browsers/detach.ts index 3e91191..24409f8 100644 --- a/src/main/browsers/detach.ts +++ b/src/main/browsers/detach.ts @@ -1,5 +1,5 @@ -import { app, BrowserWindow, protocol } from "electron"; -import path from "path"; +import { app, BrowserWindow, protocol } from 'electron'; +import path from 'path'; export default () => { let win: any; @@ -12,7 +12,7 @@ export default () => { height: viewInfo.height, width: viewInfo.width, autoHideMenuBar: true, - titleBarStyle: "hidden", + titleBarStyle: 'hidden', trafficLightPosition: { x: 12, y: 21 }, title: pluginInfo.pluginName, resizable: true, @@ -32,22 +32,34 @@ export default () => { }); if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode - win.loadURL("http://localhost:8082"); + win.loadURL('http://localhost:8082'); } else { - win.loadURL(`file://${path.join(__static, "./detach/index.html")}`); + win.loadURL(`file://${path.join(__static, './detach/index.html')}`); } - - win.on("closed", () => { + win.on('close', () => { + executeHooks('PluginOut', null); + }); + win.on('closed', () => { win = undefined; }); - win.once("ready-to-show", () => { + win.once('ready-to-show', () => { win.setBrowserView(view); win.webContents.executeJavaScript( `window.initDetach(${JSON.stringify(pluginInfo)})` ); win.show(); }); + const executeHooks = (hook, data) => { + if (!view) return; + const evalJs = `console.log(window.rubick);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) {console.log(e)} + } + `; + view.webContents.executeJavaScript(evalJs); + }; }; const getWindow = () => win; diff --git a/src/main/browsers/runner.ts b/src/main/browsers/runner.ts index f75ae9a..b3c5c22 100644 --- a/src/main/browsers/runner.ts +++ b/src/main/browsers/runner.ts @@ -1,19 +1,19 @@ -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 { 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'; const getRelativePath = (indexPath) => { return commonConst.windows() - ? indexPath.replace("file://", "") - : indexPath.replace("file:", ""); + ? 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") { + if (name === 'rubick-system-feature') { return path.resolve(__static, `../feature/public/preload.js`); } if (tplPath) { @@ -37,20 +37,29 @@ export default () => { }; const createView = (plugin, window: BrowserWindow) => { - let pluginIndexPath = plugin.tplPath || plugin.indexPath; + const { tplPath, indexPath, development, name, main, pluginSetting, ext } = + plugin; + let pluginIndexPath = tplPath || indexPath; + let preloadPath; + // 开发环境 + 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) { + if (plugin.name === 'rubick-system-feature' && !pluginIndexPath) { pluginIndexPath = commonConst.dev() - ? "http://localhost:8081/#/" + ? 'http://localhost:8081/#/' : `file://${__static}/feature/index.html`; } if (!pluginIndexPath) { - const pluginPath = path.resolve(baseDir, "node_modules", plugin.name); - pluginIndexPath = `file://${path.join(pluginPath, "./", plugin.main)}`; + const pluginPath = path.resolve(baseDir, 'node_modules', name); + pluginIndexPath = `file://${path.join(pluginPath, './', main)}`; } - const preload = getPreloadPath(plugin, pluginIndexPath); + const preload = getPreloadPath(plugin, preloadPath || pluginIndexPath); - const ses = session.fromPartition("<" + plugin.name + ">"); + const ses = session.fromPartition('<' + name + '>'); ses.setPreloads([`${__static}/preload.js`]); view = new BrowserView({ @@ -67,19 +76,20 @@ export default () => { }); window.setBrowserView(view); view.webContents.loadURL(pluginIndexPath); - view.webContents.once("dom-ready", () => { - window.setSize(800, 660); - view.setBounds({ x: 0, y: 60, width: 800, height: 600 }); + view.webContents.once('dom-ready', () => { + const height = pluginSetting && pluginSetting.height; + window.setSize(800, height || 660); + view.setBounds({ x: 0, y: 60, width: 800, height: height || 660 }); view.setAutoResize({ width: true }); - executeHooks("PluginEnter", plugin.ext); - executeHooks("PluginReady", plugin.ext); + executeHooks('PluginEnter', ext); + executeHooks('PluginReady', ext); window.webContents.executeJavaScript(`window.pluginLoaded()`); }); // 修复请求跨域问题 view.webContents.session.webRequest.onBeforeSendHeaders( (details, callback) => { callback({ - requestHeaders: { referer: "*", ...details.requestHeaders }, + requestHeaders: { referer: '*', ...details.requestHeaders }, }); } ); @@ -88,7 +98,7 @@ export default () => { (details, callback) => { callback({ responseHeaders: { - "Access-Control-Allow-Origin": ["*"], + 'Access-Control-Allow-Origin': ['*'], ...details.responseHeaders, }, }); @@ -100,7 +110,7 @@ export default () => { if (!view) return; window.removeBrowserView(view); window.setSize(800, 60); - executeHooks("PluginOut", null); + executeHooks('PluginOut', null); window.webContents.executeJavaScript(`window.initRubick()`); view = undefined; }; @@ -111,7 +121,7 @@ export default () => { 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) : ""}); + window.rubick.hooks.on${hook}(${data ? JSON.stringify(data) : ''}); } catch(e) {} } `; diff --git a/src/main/common/api.ts b/src/main/common/api.ts index f9315b2..3d72a6a 100644 --- a/src/main/common/api.ts +++ b/src/main/common/api.ts @@ -6,27 +6,27 @@ import { Notification, nativeImage, clipboard, - shell -} from "electron"; -import { runner, detach } from "../browsers"; -import fs from "fs"; -import { LocalDb } from "@/core"; -import plist from "plist"; -import { DECODE_KEY } from "@/common/constans/main"; -import mainInstance from "../index"; + shell, +} from 'electron'; +import { runner, detach } from '../browsers'; +import fs from 'fs'; +import { LocalDb } from '@/core'; +import plist from 'plist'; +import { DECODE_KEY } from '@/common/constans/main'; +import mainInstance from '../index'; const runnerInstance = runner(); const detachInstance = detach(); -const dbInstance = new LocalDb(app.getPath("userData")); +const dbInstance = new LocalDb(app.getPath('userData')); dbInstance.init(); class API { public currentPlugin: null | any = null; - private DBKEY = "RUBICK_DB_DEFAULT"; + private DBKEY = 'RUBICK_DB_DEFAULT'; init(mainWindow: BrowserWindow) { // 响应 preload.js 事件 - ipcMain.on("msg-trigger", async (event, arg) => { + ipcMain.on('msg-trigger', async (event, arg) => { const window = arg.winId ? BrowserWindow.fromId(arg.winId) : mainWindow; const data = await this[arg.type](arg, window, event); event.returnValue = data; @@ -41,9 +41,9 @@ class API { }; public __EscapeKeyDown = (event, input, window) => { - if (input.type !== "keyDown") return; + if (input.type !== 'keyDown') return; if (!(input.meta || input.control || input.shift || input.alt)) { - if (input.key === "Escape") { + if (input.key === 'Escape') { if (this.currentPlugin) { this.removePlugin(null, window); } else { @@ -70,17 +70,17 @@ class API { this.currentPlugin = plugin; window.webContents.executeJavaScript( `window.setCurrentPlugin(${JSON.stringify({ - currentPlugin: this.currentPlugin + currentPlugin: this.currentPlugin, })})` ); window.show(); // 按 ESC 退出插件 - window.webContents.on("before-input-event", (event, input) => + window.webContents.on('before-input-event', (event, input) => this.__EscapeKeyDown(event, input, window) ); runnerInstance .getView() - .webContents.on("before-input-event", (event, input) => + .webContents.on('before-input-event', (event, input) => this.__EscapeKeyDown(event, input, window) ); } @@ -91,7 +91,7 @@ class API { } public openPluginDevTools() { - runnerInstance.getView().webContents.openDevTools({ mode: "detach" }); + runnerInstance.getView().webContents.openDevTools({ mode: 'detach' }); } public hideMainWindow(arg, window) { @@ -118,7 +118,7 @@ class API { if (!originWindow) return; originWindow.webContents.executeJavaScript( `window.setSubInput(${JSON.stringify({ - placeholder: data.placeholder + placeholder: data.placeholder, })})` ); } @@ -128,7 +128,7 @@ class API { } public sendSubInputChangeEvent({ data }) { - runnerInstance.executeHooks("SubInputChange", data); + runnerInstance.executeHooks('SubInputChange', data); } public removeSubInput(data, window, e) { @@ -142,7 +142,7 @@ class API { if (!originWindow) return; originWindow.webContents.executeJavaScript( `window.setSubInputValue(${JSON.stringify({ - value: data.text + value: data.text, })})` ); } @@ -153,13 +153,13 @@ class API { public showNotification({ data: { body } }) { if (!Notification.isSupported()) return; - "string" != typeof body && (body = String(body)); + 'string' != typeof body && (body = String(body)); const plugin = this.currentPlugin; if (!plugin) return; const notify = new Notification({ title: plugin.pluginName, body, - icon: plugin.logo + icon: plugin.logo, }); notify.show(); } @@ -177,7 +177,7 @@ class API { public copyFile({ data }) { if (data.file && fs.existsSync(data.file)) { clipboard.writeBuffer( - "NSFilenamesPboardType", + 'NSFilenamesPboardType', Buffer.from(plist.build([data.file])) ); return true; @@ -214,7 +214,7 @@ class API { ...this.currentPlugin, features: (() => { let has = false; - this.currentPlugin.features.some(feature => { + this.currentPlugin.features.some((feature) => { has = feature.code === data.feature.code; return has; }); @@ -222,11 +222,11 @@ class API { return [...this.currentPlugin.features, data.feature]; } return this.currentPlugin.features; - })() + })(), }; window.webContents.executeJavaScript( `window.updatePlugin(${JSON.stringify({ - currentPlugin: this.currentPlugin + currentPlugin: this.currentPlugin, })})` ); return true; @@ -235,16 +235,16 @@ class API { public removeFeature({ data }, window) { this.currentPlugin = { ...this.currentPlugin, - features: this.currentPlugin.features.filter(feature => { + features: this.currentPlugin.features.filter((feature) => { if (data.code.type) { return feature.code.type !== data.code.type; } return feature.code !== data.code; - }) + }), }; window.webContents.executeJavaScript( `window.updatePlugin(${JSON.stringify({ - currentPlugin: this.currentPlugin + currentPlugin: this.currentPlugin, })})` ); return true; @@ -255,14 +255,14 @@ class API { if (!code || !runnerInstance.getView()) return; if (modifiers.length > 0) { runnerInstance.getView().webContents.sendInputEvent({ - type: "keyDown", + type: 'keyDown', modifiers, - keyCode: code + keyCode: code, }); } else { runnerInstance.getView().webContents.sendInputEvent({ - type: "keyDown", - keyCode: code + type: 'keyDown', + keyCode: code, }); } } @@ -273,11 +273,11 @@ class API { window.setBrowserView(null); window.webContents .executeJavaScript(`window.getMainInputInfo()`) - .then(res => { + .then((res) => { detachInstance.init( { ...this.currentPlugin, - subInput: res + subInput: res, }, window.getBounds(), view @@ -293,7 +293,7 @@ class API { } public getLocalId() { - return encodeURIComponent(app.getPath("home")); + return encodeURIComponent(app.getPath('home')); } public shellShowItemInFolder({ data }) {