enable plugin

This commit is contained in:
Vanessa 2023-05-16 10:31:01 +08:00
parent f3d1acd166
commit 85496345ef
4 changed files with 105 additions and 41 deletions

View file

@ -16,6 +16,7 @@ import {Plugin} from "../plugin";
import {App} from "../index";
import {escapeAttr} from "../util/escape";
import {uninstall} from "../plugin/uninstall";
import {loadPlugin} from "../plugin/loader";
export const bazaar = {
element: undefined as Element,
@ -635,19 +636,16 @@ export const bazaar = {
event.stopPropagation();
break;
} else if (type === "plugin-enable") {
const itemElement = hasClosestByClassName(target, "b3-card");
if (itemElement) {
if (!target.getAttribute("disabled")) {
target.setAttribute("disabled", "disabled");
const enabled = (target as HTMLInputElement).checked;
fetchPost("/api/petal/setPetalEnabled", {
packageName: dataObj.name,
enabled,
}, () => {
}, (response) => {
target.removeAttribute("disabled");
if (enabled) {
exportLayout({
reload: true,
onlyData: false,
errorExit: false,
});
loadPlugin(app, response.data);
} else {
uninstall(app, dataObj.name);
}

View file

@ -549,7 +549,9 @@ export class Dock {
this.toggleModel(key, false, true, true);
this.element.querySelector(`[data-type="${key}"]`).remove();
const custom = this.data[key] as Custom;
custom.parent.parent.removeTab(custom.parent.id);
if (custom.parent) {
custom.parent.parent.removeTab(custom.parent.id);
}
delete this.data[key];
}
@ -603,7 +605,7 @@ export class Dock {
return max;
}
private genButton(data: IDockTab[], index: number) {
public genButton(data: IDockTab[], index: number, append = false) {
let html = "";
data.forEach(item => {
html += `<span data-height="${item.size.height}" data-width="${item.size.width}" data-type="${item.type}" data-index="${index}" data-hotkey="${item.hotkey || ""}" data-hotkeyLangId="${item.hotkeyLangId || ""}" data-title="${item.title}" class="dock__item${item.show ? " dock__item--active" : ""} b3-tooltips b3-tooltips__${this.getClassDirect(index)}" aria-label="${item.title} ${item.hotkey ? updateHotkeyTip(item.hotkey) : ""}${window.siyuan.languages.dockTip}">
@ -612,11 +614,19 @@ export class Dock {
this.data[item.type] = true;
});
if (index === 0) {
this.element.firstElementChild.innerHTML = `${html}<span class="dock__item dock__item--pin b3-tooltips b3-tooltips__${this.getClassDirect(index)}" aria-label="${this.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}">
if (append) {
this.element.firstElementChild.lastElementChild.insertAdjacentHTML("beforebegin", html);
} else {
this.element.firstElementChild.innerHTML = `${html}<span class="dock__item dock__item--pin b3-tooltips b3-tooltips__${this.getClassDirect(index)}" aria-label="${this.pin ? window.siyuan.languages.unpin : window.siyuan.languages.pin}">
<svg><use xlink:href="#iconPin"></use></svg>
</span>`;
}
} else {
this.element.lastElementChild.innerHTML = html;
if (append) {
this.element.lastElementChild.insertAdjacentHTML("beforeend", html);
} else {
this.element.lastElementChild.innerHTML = html;
}
}
}
}

View file

@ -2,6 +2,7 @@ import {fetchPost} from "../util/fetch";
import {App} from "../index";
import {Plugin} from "./index";
import {API} from "./API";
import {exportLayout} from "../layout/util";
const getObject = (key: string) => {
const api = {
@ -18,35 +19,8 @@ const runCode = (code: string, sourceURL: string) => {
export const loadPlugins = (app: App) => {
fetchPost("/api/petal/loadPetals", {}, response => {
let css = "";
response.data.forEach((item: { name: string, js: string, css: string, i18n: IObject }) => {
const exportsObj: { [key: string]: any } = {};
const moduleObj = {exports: exportsObj};
try {
runCode(item.js, "plugin:" + encodeURIComponent(item.name))(getObject, moduleObj, exportsObj);
} catch (e) {
console.error(`eval plugin ${item.name} error:`, e);
return;
}
const pluginClass = (moduleObj.exports || exportsObj).default || moduleObj.exports;
if (typeof pluginClass !== "function") {
console.error(`plugin ${item.name} has no export`);
return;
}
if (!(pluginClass.prototype instanceof Plugin)) {
console.error(`plugin ${item.name} does not extends Plugin`);
return;
}
const plugin = new pluginClass({
app,
name: item.name,
i18n: item.i18n
});
app.plugins.push(plugin);
try {
plugin.onload();
} catch (e) {
console.error(`plugin ${item.name} load error:`, e);
}
response.data.forEach((item: IPluginData) => {
loadPluginJS(app, item);
css += item.css || "" + "\n";
});
const styleElement = document.createElement("style");
@ -54,3 +28,78 @@ export const loadPlugins = (app: App) => {
document.head.append(styleElement);
});
};
const loadPluginJS = (app: App, item: IPluginData) => {
const exportsObj: { [key: string]: any } = {};
const moduleObj = {exports: exportsObj};
try {
runCode(item.js, "plugin:" + encodeURIComponent(item.name))(getObject, moduleObj, exportsObj);
} catch (e) {
console.error(`eval plugin ${item.name} error:`, e);
return;
}
const pluginClass = (moduleObj.exports || exportsObj).default || moduleObj.exports;
if (typeof pluginClass !== "function") {
console.error(`plugin ${item.name} has no export`);
return;
}
if (!(pluginClass.prototype instanceof Plugin)) {
console.error(`plugin ${item.name} does not extends Plugin`);
return;
}
const plugin = new pluginClass({
app,
name: item.name,
i18n: item.i18n
});
app.plugins.push(plugin);
try {
plugin.onload();
} catch (e) {
console.error(`plugin ${item.name} load error:`, e);
}
return plugin;
}
export const loadPlugin = (app: App, item: IPluginData) => {
const plugin = loadPluginJS(app, item);
Object.keys(plugin.docks).forEach(key => {
const dock = plugin.docks[key];
if (dock.config.position.startsWith("Left")) {
window.siyuan.layout.leftDock.genButton([{
type: key,
size: dock.config.size,
show: false,
icon: dock.config.icon,
title: dock.config.title,
hotkey: dock.config.hotkey
}], dock.config.position === "LeftBottom" ? 1 : 0, true)
} else if (dock.config.position.startsWith("Bottom")) {
window.siyuan.layout.bottomDock.genButton([{
type: key,
size: dock.config.size,
show: false,
icon: dock.config.icon,
title: dock.config.title,
hotkey: dock.config.hotkey
}], dock.config.position === "BottomRight" ? 1 : 0, true)
} else if (dock.config.position.startsWith("Right")) {
window.siyuan.layout.rightDock.genButton([{
type: key,
size: dock.config.size,
show: false,
icon: dock.config.icon,
title: dock.config.title,
hotkey: dock.config.hotkey
}], dock.config.position === "RightBottom" ? 1 : 0, true)
}
});
const styleElement = document.createElement("style");
styleElement.textContent = item.css;
document.head.append(styleElement);
exportLayout({
reload: false,
onlyData: false,
errorExit: false
});
};

View file

@ -298,6 +298,13 @@ declare interface IDockTab {
hotkeyLangId?: string // 常量中无法存变量
}
declare interface IPluginData {
name: string,
js: string,
css: string,
i18n: IObject
}
declare interface IPluginDockTab {
position: TPluginDockPosition,
size: { width: number, height: number },