@inpageedit/core 0.12.0 → 0.13.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/dist/BasePlugin-Bf2UuIHF.js +64 -0
- package/dist/BasePlugin-Bf2UuIHF.js.map +1 -0
- package/dist/IconQuickEdit-CMCQncyj.js.map +1 -1
- package/dist/InputBox-nQKtiWtZ.js +30 -0
- package/dist/InputBox-nQKtiWtZ.js.map +1 -0
- package/dist/PluginPrefSync-Dn1Xsiqz.js +341 -0
- package/dist/PluginPrefSync-Dn1Xsiqz.js.map +1 -0
- package/dist/PluginStoreApp-CpOLArL7.js +452 -0
- package/dist/PluginStoreApp-CpOLArL7.js.map +1 -0
- package/dist/Preferences-DS4-CFWe.js.map +1 -1
- package/dist/WatchlistAction-BbNAyryN.js +5 -0
- package/dist/WatchlistAction-BbNAyryN.js.map +1 -0
- package/dist/components/index.js +6 -7
- package/dist/components/index.js.map +1 -1
- package/dist/endpoints-DgyuoRZd.js +1507 -0
- package/dist/endpoints-DgyuoRZd.js.map +1 -0
- package/dist/{index-B5DtUqkK.js → index-2RfILgXm.js} +11 -11
- package/dist/{index-B5DtUqkK.js.map → index-2RfILgXm.js.map} +1 -1
- package/dist/{index-hSl8LzNb.js → index-BCdABp0e.js} +24 -24
- package/dist/index-BCdABp0e.js.map +1 -0
- package/dist/{index-Ckozkp6W.js → index-BJ7_Q1mB.js} +8 -7
- package/dist/{index-Ckozkp6W.js.map → index-BJ7_Q1mB.js.map} +1 -1
- package/dist/{index-CJFePavo.js → index-BNh95-x2.js} +37 -49
- package/dist/index-BNh95-x2.js.map +1 -0
- package/dist/{index-CYc6LH26.js → index-BQ-cHWkJ.js} +15 -16
- package/dist/{index-CYc6LH26.js.map → index-BQ-cHWkJ.js.map} +1 -1
- package/dist/index-BwdWyHLe.js +362 -0
- package/dist/index-BwdWyHLe.js.map +1 -0
- package/dist/{index-D4uwfUZL.js → index-CCRMmnwk.js} +10 -9
- package/dist/index-CCRMmnwk.js.map +1 -0
- package/dist/index-CG38LlAh.js.map +1 -1
- package/dist/index-CM_6yF2v.js.map +1 -1
- package/dist/{index-CZXxH2-9.js → index-CnIpUF9x.js} +4 -4
- package/dist/{index-CZXxH2-9.js.map → index-CnIpUF9x.js.map} +1 -1
- package/dist/{index-CPoUaSMw.js → index-CyG7_IYz.js} +14 -13
- package/dist/index-CyG7_IYz.js.map +1 -0
- package/dist/index-DD5CVCfD.js.map +1 -1
- package/dist/index-DdTiZqwt.js +3744 -0
- package/dist/index-DdTiZqwt.js.map +1 -0
- package/dist/{index-Bv7Dw5eO.js → index-eSlbrNqF.js} +6 -6
- package/dist/{index-Bv7Dw5eO.js.map → index-eSlbrNqF.js.map} +1 -1
- package/dist/index.d.ts +1723 -31
- package/dist/index.js +73 -9
- package/dist/index.js.map +1 -1
- package/dist/makeCallable-LDU0xZMJ.js.map +1 -1
- package/dist/models/index.js +486 -0
- package/dist/models/index.js.map +1 -0
- package/dist/noop-ClDc6zv4.js.map +1 -1
- package/dist/plugins/index.js +23 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/services/index.js +16 -0
- package/dist/services/index.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/{vueHooks-D0uVqbO-.js → vueHooks-l04s8cIl.js} +1112 -1080
- package/dist/{vueHooks-D0uVqbO-.js.map → vueHooks-l04s8cIl.js.map} +1 -1
- package/lib/index.umd.js +15 -11
- package/lib/index.umd.js.map +1 -1
- package/lib/style.css +1 -1
- package/package.json +22 -25
- package/dist/CheckBox-Bc79KBEB.js +0 -13
- package/dist/CheckBox-Bc79KBEB.js.map +0 -1
- package/dist/InPageEdit.d.ts +0 -42
- package/dist/InputBox-DZAdyZ4B.js +0 -22
- package/dist/InputBox-DZAdyZ4B.js.map +0 -1
- package/dist/PluginPrefSync-BPQkNtX8.js +0 -292
- package/dist/PluginPrefSync-BPQkNtX8.js.map +0 -1
- package/dist/PluginStoreApp-Cxspe6t8.js +0 -158
- package/dist/PluginStoreApp-Cxspe6t8.js.map +0 -1
- package/dist/__test__/utils/constants.d.ts +0 -3
- package/dist/components/ActionButton.d.ts +0 -6
- package/dist/components/CheckBox.d.ts +0 -10
- package/dist/components/Icon/IconEdit.d.ts +0 -2
- package/dist/components/Icon/IconQuickEdit.d.ts +0 -2
- package/dist/components/InputBox.d.ts +0 -11
- package/dist/components/MBox/index.d.ts +0 -14
- package/dist/components/MwUserLinks.d.ts +0 -6
- package/dist/components/ProgressBar/index.d.ts +0 -7
- package/dist/components/RadioBox.d.ts +0 -10
- package/dist/components/TabView/index.d.ts +0 -19
- package/dist/components/TwinSwapInput/index.d.ts +0 -19
- package/dist/components/index.d.ts +0 -8
- package/dist/components/utils.d.ts +0 -4
- package/dist/constants/endpoints.d.ts +0 -8
- package/dist/decorators/Preferences.d.ts +0 -35
- package/dist/index-BXaiDKnr.js +0 -5828
- package/dist/index-BXaiDKnr.js.map +0 -1
- package/dist/index-CB7TltEb.js +0 -297
- package/dist/index-CB7TltEb.js.map +0 -1
- package/dist/index-CJFePavo.js.map +0 -1
- package/dist/index-CPoUaSMw.js.map +0 -1
- package/dist/index-D4uwfUZL.js.map +0 -1
- package/dist/index-DEav9Ptt.js +0 -365
- package/dist/index-DEav9Ptt.js.map +0 -1
- package/dist/index-hSl8LzNb.js.map +0 -1
- package/dist/models/MemoryStorage.d.ts +0 -10
- package/dist/models/WikiPage/index.d.ts +0 -72
- package/dist/models/WikiPage/types/PageInfo.d.ts +0 -58
- package/dist/models/WikiPage/types/PageParseData.d.ts +0 -17
- package/dist/models/WikiPage/types/WatchlistAction.d.ts +0 -6
- package/dist/models/WikiTitle/index.d.ts +0 -89
- package/dist/models/WikiTitle/index.spec.d.ts +0 -1
- package/dist/plugins/BasePlugin.d.ts +0 -25
- package/dist/plugins/_debug/index.d.ts +0 -8
- package/dist/plugins/analytics/index.d.ts +0 -41
- package/dist/plugins/in-article-links/index.d.ts +0 -44
- package/dist/plugins/plugin-store/index.d.ts +0 -59
- package/dist/plugins/plugin-store/schema.d.ts +0 -41
- package/dist/plugins/preferences-ui/PluginPrefSync.d.ts +0 -28
- package/dist/plugins/preferences-ui/index.d.ts +0 -48
- package/dist/plugins/quick-delete/index.d.ts +0 -55
- package/dist/plugins/quick-diff/components/DiffTable.d.ts +0 -23
- package/dist/plugins/quick-diff/index.d.ts +0 -85
- package/dist/plugins/quick-edit/index.d.ts +0 -79
- package/dist/plugins/quick-move/index.d.ts +0 -47
- package/dist/plugins/quick-preview/index.d.ts +0 -37
- package/dist/plugins/quick-redirect/index.d.ts +0 -48
- package/dist/plugins/toolbox/index.d.ts +0 -65
- package/dist/polyfills/Promise.withResolvers.d.ts +0 -5
- package/dist/polyfills/index.d.ts +0 -0
- package/dist/services/ApiService.d.ts +0 -14
- package/dist/services/CurrentPageService.d.ts +0 -28
- package/dist/services/ModalService.d.ts +0 -27
- package/dist/services/PreferencesService.d.ts +0 -94
- package/dist/services/ResourceLoaderService.d.ts +0 -17
- package/dist/services/WikiMetadataService.d.ts +0 -108
- package/dist/services/WikiPageService.d.ts +0 -20
- package/dist/services/WikiTitleService.d.ts +0 -70
- package/dist/services/storage/index.d.ts +0 -40
- package/dist/services/storage/managers/IDBStorageManager.d.ts +0 -28
- package/dist/services/storage/managers/LocalStorageManager.d.ts +0 -27
- package/dist/types/WikiMetadata.d.ts +0 -131
- package/dist/utils/computeable.d.ts +0 -2
- package/dist/utils/defineAsyncPlugin.d.ts +0 -2
- package/dist/utils/interpolate.d.ts +0 -20
- package/dist/utils/interpolate.spec.d.ts +0 -1
- package/dist/utils/makeCallable.d.ts +0 -3
- package/dist/utils/noop.d.ts +0 -1
- package/dist/utils/sleep.d.ts +0 -1
- package/dist/utils/string.d.ts +0 -7
- package/dist/utils/url.d.ts +0 -24
- package/dist/utils/vueHooks.d.ts +0 -6
- package/dist/utils/vueReactivity.d.ts +0 -2
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { j as i } from "./index-CM_6yF2v.js";
|
|
2
|
-
import { B as I, W as U, I as k } from "./index-BXaiDKnr.js";
|
|
3
|
-
import { A as p } from "./ActionButton-CRjo_l3y.js";
|
|
4
|
-
var E = Object.create, m = Object.defineProperty, L = Object.getOwnPropertyDescriptor, w = (a, e) => (e = Symbol[a]) ? e : Symbol.for("Symbol." + a), x = (a) => {
|
|
5
|
-
throw TypeError(a);
|
|
6
|
-
}, F = (a, e, r) => e in a ? m(a, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : a[e] = r, C = (a, e) => m(a, "name", { value: e, configurable: !0 }), T = (a) => [, , , E(a?.[w("metadata")] ?? null)], j = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], S = (a) => a !== void 0 && typeof a != "function" ? x("Function expected") : a, D = (a, e, r, n, t) => ({ kind: j[a], name: e, metadata: n, addInitializer: (o) => r._ ? x("Already initialized") : t.push(S(o || null)) }), O = (a, e) => F(e, w("metadata"), a[3]), R = (a, e, r, n) => {
|
|
7
|
-
for (var t = 0, o = a[e >> 1], s = o && o.length; t < s; t++) o[t].call(r);
|
|
8
|
-
return n;
|
|
9
|
-
}, N = (a, e, r, n, t, o) => {
|
|
10
|
-
var s, l, c, d = e & 7, f = !1, v = 0, b = a[v] || (a[v] = []), u = d && (t = t.prototype, d < 5 && (d > 3 || !f) && L(t, r));
|
|
11
|
-
C(t, r);
|
|
12
|
-
for (var g = n.length - 1; g >= 0; g--)
|
|
13
|
-
c = D(d, r, l = {}, a[3], b), s = (0, n[g])(t, c), l._ = 1, S(s) && (t = s);
|
|
14
|
-
return O(a, t), u && m(t, r, u), f ? d ^ 4 ? o : u : t;
|
|
15
|
-
}, _, y, P;
|
|
16
|
-
_ = [k(["preferences", "wikiPage", "wikiTitle", "modal", "preferencesUI"])];
|
|
17
|
-
class h extends (P = I) {
|
|
18
|
-
constructor(e) {
|
|
19
|
-
super(e, {}, "pref-sync"), this.ctx = e, e.set("prefSync", this);
|
|
20
|
-
}
|
|
21
|
-
start() {
|
|
22
|
-
const e = this.ctx;
|
|
23
|
-
e.preferences.defineCategory({
|
|
24
|
-
name: "pref-sync",
|
|
25
|
-
label: "Sync",
|
|
26
|
-
description: "Import and export preferences",
|
|
27
|
-
index: 98,
|
|
28
|
-
customRenderer: () => {
|
|
29
|
-
const r = this.getUserPrefsPageTitle();
|
|
30
|
-
return /* @__PURE__ */ i("div", { className: "theme-ipe-prose", children: [
|
|
31
|
-
/* @__PURE__ */ i("section", { children: [
|
|
32
|
-
/* @__PURE__ */ i("h3", { children: "Backup your preferences via user page" }),
|
|
33
|
-
r && /* @__PURE__ */ i("p", { children: /* @__PURE__ */ i("a", { href: r?.getURL().toString(), target: "_blank", children: [
|
|
34
|
-
r?.getPrefixedText(),
|
|
35
|
-
" →"
|
|
36
|
-
] }) }),
|
|
37
|
-
/* @__PURE__ */ i("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
38
|
-
/* @__PURE__ */ i(
|
|
39
|
-
p,
|
|
40
|
-
{
|
|
41
|
-
type: "primary",
|
|
42
|
-
onClick: (n) => {
|
|
43
|
-
n.preventDefault();
|
|
44
|
-
const t = e.preferencesUI.getCurrentModal(), o = n.target;
|
|
45
|
-
o.disabled = !0, t?.setLoadingState(!0), this.importFromUserPage().then((s) => {
|
|
46
|
-
this.notifyImportSuccess(s);
|
|
47
|
-
}).finally(() => {
|
|
48
|
-
o.disabled = !1, t?.setLoadingState(!1);
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
children: "Import"
|
|
52
|
-
}
|
|
53
|
-
),
|
|
54
|
-
/* @__PURE__ */ i(
|
|
55
|
-
p,
|
|
56
|
-
{
|
|
57
|
-
type: "primary",
|
|
58
|
-
onClick: (n) => {
|
|
59
|
-
n.preventDefault();
|
|
60
|
-
const t = n.target;
|
|
61
|
-
t.disabled = !0;
|
|
62
|
-
const o = e.preferencesUI.getCurrentModal();
|
|
63
|
-
o?.setLoadingState(!0), this.exportToUserPage().then((s) => {
|
|
64
|
-
e.modal.notify("success", {
|
|
65
|
-
title: "Preferences Exported",
|
|
66
|
-
content: /* @__PURE__ */ i("p", { children: [
|
|
67
|
-
"Your preferences have been exported to",
|
|
68
|
-
" ",
|
|
69
|
-
/* @__PURE__ */ i("a", { href: s.getURL().toString(), target: "_blank", children: s.getPrefixedText() }),
|
|
70
|
-
"."
|
|
71
|
-
] })
|
|
72
|
-
});
|
|
73
|
-
}).finally(() => {
|
|
74
|
-
t.disabled = !1, o?.setLoadingState(!1);
|
|
75
|
-
});
|
|
76
|
-
},
|
|
77
|
-
children: "Export"
|
|
78
|
-
}
|
|
79
|
-
)
|
|
80
|
-
] })
|
|
81
|
-
] }),
|
|
82
|
-
/* @__PURE__ */ i("section", { children: [
|
|
83
|
-
/* @__PURE__ */ i("h3", { children: "Import and export preferences" }),
|
|
84
|
-
/* @__PURE__ */ i("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
85
|
-
/* @__PURE__ */ i(
|
|
86
|
-
p,
|
|
87
|
-
{
|
|
88
|
-
onClick: (n) => {
|
|
89
|
-
n.preventDefault();
|
|
90
|
-
const t = e.preferencesUI.getCurrentModal();
|
|
91
|
-
t?.setLoadingState(!0);
|
|
92
|
-
const o = document.createElement("input");
|
|
93
|
-
o.type = "file", o.accept = "application/json";
|
|
94
|
-
let s = !1;
|
|
95
|
-
const l = () => {
|
|
96
|
-
s || t?.setLoadingState(!1), window.removeEventListener("focus", l);
|
|
97
|
-
};
|
|
98
|
-
window.addEventListener("focus", l, { once: !0 }), o.addEventListener("change", async (c) => {
|
|
99
|
-
s = !0;
|
|
100
|
-
try {
|
|
101
|
-
const d = c.target.files?.[0];
|
|
102
|
-
if (!d)
|
|
103
|
-
return;
|
|
104
|
-
const f = await this.importFromFile(d);
|
|
105
|
-
this.notifyImportSuccess(f);
|
|
106
|
-
} catch (d) {
|
|
107
|
-
e.modal.notify("error", {
|
|
108
|
-
title: "Import failed",
|
|
109
|
-
content: d instanceof Error ? d.message : String(d)
|
|
110
|
-
});
|
|
111
|
-
} finally {
|
|
112
|
-
t?.setLoadingState(!1);
|
|
113
|
-
}
|
|
114
|
-
}), o.click();
|
|
115
|
-
},
|
|
116
|
-
children: "Import from file"
|
|
117
|
-
}
|
|
118
|
-
),
|
|
119
|
-
/* @__PURE__ */ i(
|
|
120
|
-
p,
|
|
121
|
-
{
|
|
122
|
-
onClick: (n) => {
|
|
123
|
-
n.preventDefault();
|
|
124
|
-
const t = /* @__PURE__ */ i("input", { type: "url" }), o = e.preferencesUI.getCurrentModal();
|
|
125
|
-
e.modal.confirm(
|
|
126
|
-
{
|
|
127
|
-
title: "Import Preferences from URL",
|
|
128
|
-
content: /* @__PURE__ */ i("div", { children: [
|
|
129
|
-
/* @__PURE__ */ i("label", { htmlFor: "url-input", children: "Enter the URL of the preferences JSON file:" }),
|
|
130
|
-
t
|
|
131
|
-
] })
|
|
132
|
-
},
|
|
133
|
-
async (s) => {
|
|
134
|
-
const l = t.value.trim();
|
|
135
|
-
if (!(!s || !l))
|
|
136
|
-
try {
|
|
137
|
-
o?.setLoadingState(!0);
|
|
138
|
-
const c = await this.importFromUrl(l);
|
|
139
|
-
this.notifyImportSuccess(c);
|
|
140
|
-
} catch (c) {
|
|
141
|
-
e.modal.notify("error", {
|
|
142
|
-
title: "Import failed",
|
|
143
|
-
content: c instanceof Error ? c.message : String(c)
|
|
144
|
-
});
|
|
145
|
-
} finally {
|
|
146
|
-
o?.setLoadingState(!1);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
);
|
|
150
|
-
},
|
|
151
|
-
children: "Import from URL"
|
|
152
|
-
}
|
|
153
|
-
),
|
|
154
|
-
/* @__PURE__ */ i(
|
|
155
|
-
p,
|
|
156
|
-
{
|
|
157
|
-
onClick: async (n) => {
|
|
158
|
-
n.preventDefault(), await e.preferencesUI.dispatchFormSave();
|
|
159
|
-
const t = await e.preferences.getExportableRecord(), o = JSON.stringify(t, null, 2);
|
|
160
|
-
e.modal.dialog(
|
|
161
|
-
{
|
|
162
|
-
title: "Save to file",
|
|
163
|
-
content: /* @__PURE__ */ i("div", { children: [
|
|
164
|
-
/* @__PURE__ */ i("label", { htmlFor: "data", children: "Your InPageEdit preferences:" }),
|
|
165
|
-
/* @__PURE__ */ i(
|
|
166
|
-
"textarea",
|
|
167
|
-
{
|
|
168
|
-
name: "data",
|
|
169
|
-
id: "data",
|
|
170
|
-
rows: 10,
|
|
171
|
-
value: o,
|
|
172
|
-
readOnly: !0,
|
|
173
|
-
style: { width: "100%" }
|
|
174
|
-
}
|
|
175
|
-
)
|
|
176
|
-
] }),
|
|
177
|
-
buttons: [
|
|
178
|
-
{
|
|
179
|
-
label: "Copy",
|
|
180
|
-
method: (s, l) => {
|
|
181
|
-
navigator.clipboard.writeText(o), e.modal.notify("success", {
|
|
182
|
-
content: "Copied to clipboard"
|
|
183
|
-
}), l.close();
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
label: "Download",
|
|
188
|
-
method: (s, l) => {
|
|
189
|
-
const c = document.createElement("a");
|
|
190
|
-
c.href = `data:text/json;charset=utf-8,${encodeURIComponent(o)}`, c.download = `ipe-prefs-${(/* @__PURE__ */ new Date()).toISOString()}.json`, c.click(), l.close();
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
]
|
|
194
|
-
},
|
|
195
|
-
() => {
|
|
196
|
-
}
|
|
197
|
-
);
|
|
198
|
-
},
|
|
199
|
-
children: "Save as file"
|
|
200
|
-
}
|
|
201
|
-
)
|
|
202
|
-
] })
|
|
203
|
-
] })
|
|
204
|
-
] });
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
stop() {
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* 获取用户页配置文件的标题
|
|
212
|
-
*/
|
|
213
|
-
getUserPrefsPageTitle() {
|
|
214
|
-
try {
|
|
215
|
-
const e = this.ctx.wiki?.userInfo?.name;
|
|
216
|
-
return e ? this.ctx.wikiTitle.newTitle(`User:${e}/ipe-prefs.json`, 2) : null;
|
|
217
|
-
} catch {
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* 从用户页加载配置
|
|
223
|
-
*/
|
|
224
|
-
async importFromUserPage() {
|
|
225
|
-
const e = this.getUserPrefsPageTitle();
|
|
226
|
-
if (!e)
|
|
227
|
-
return this.logger.debug("Cannot get user page title, skipping load"), {};
|
|
228
|
-
try {
|
|
229
|
-
const r = e.getURL({ action: "raw", ctype: "application/json" }), n = await this.importFromUrl(r.toString());
|
|
230
|
-
return this.logger.info("Loaded preferences from user page:", e), n;
|
|
231
|
-
} catch (r) {
|
|
232
|
-
return this.logger.error("Failed to load preferences from user page:", r), {};
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* 导出配置到用户页
|
|
237
|
-
*/
|
|
238
|
-
async exportToUserPage() {
|
|
239
|
-
const e = this.ctx, r = this.getUserPrefsPageTitle();
|
|
240
|
-
if (!r)
|
|
241
|
-
throw new Error("Cannot get user page title");
|
|
242
|
-
await e.preferencesUI.dispatchFormSave();
|
|
243
|
-
const n = await e.preferences.getExportableRecord(), t = JSON.stringify(n, null, 2);
|
|
244
|
-
try {
|
|
245
|
-
return await this.ctx.wikiPage.newBlankPage({
|
|
246
|
-
title: r.toString(),
|
|
247
|
-
ns: 2
|
|
248
|
-
// User namespace
|
|
249
|
-
}).edit({
|
|
250
|
-
text: t,
|
|
251
|
-
summary: "Update InPageEdit preferences",
|
|
252
|
-
watchlist: U.nochange
|
|
253
|
-
}), this.logger.info("Exported preferences to user page:", r), r;
|
|
254
|
-
} catch (o) {
|
|
255
|
-
throw this.logger.error("Failed to export preferences to user page:", o), o;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
async importFromUrl(e) {
|
|
259
|
-
const r = await fetch(e);
|
|
260
|
-
if (!r.ok)
|
|
261
|
-
throw new Error(`HTTP ${r.status}: ${r.statusText}`);
|
|
262
|
-
const n = await r.blob();
|
|
263
|
-
return await this.importFromFile(n);
|
|
264
|
-
}
|
|
265
|
-
async importFromFile(e) {
|
|
266
|
-
const r = await e.text(), n = JSON.parse(r);
|
|
267
|
-
return await this.ctx.preferences.setMany(n);
|
|
268
|
-
}
|
|
269
|
-
notifyImportSuccess(e) {
|
|
270
|
-
const r = Object.keys(e ?? {}), n = r.length;
|
|
271
|
-
return this.ctx.modal.notify("success", {
|
|
272
|
-
title: "Preferences Imported",
|
|
273
|
-
content: /* @__PURE__ */ i("section", { children: [
|
|
274
|
-
/* @__PURE__ */ i("p", { children: [
|
|
275
|
-
"Successfully imported ",
|
|
276
|
-
n || "",
|
|
277
|
-
" ",
|
|
278
|
-
n !== 1 ? "settings" : "setting",
|
|
279
|
-
":"
|
|
280
|
-
] }),
|
|
281
|
-
/* @__PURE__ */ i("ol", { style: { listStyle: "auto", paddingLeft: "1em" }, children: r.map((t) => /* @__PURE__ */ i("li", { children: t }, t)) })
|
|
282
|
-
] })
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
y = T(P);
|
|
287
|
-
h = N(y, 0, "PluginPrefSync", _, h);
|
|
288
|
-
R(y, 1, h);
|
|
289
|
-
export {
|
|
290
|
-
h as PluginPrefSync
|
|
291
|
-
};
|
|
292
|
-
//# sourceMappingURL=PluginPrefSync-BPQkNtX8.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PluginPrefSync-BPQkNtX8.js","sources":["../src/plugins/preferences-ui/PluginPrefSync.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit.js'\nimport { WatchlistAction } from '@/models/WikiPage/types/WatchlistAction.js'\nimport { IWikiTitle } from '@/models/WikiTitle/index.js'\n\ndeclare module '@/InPageEdit' {\n export interface InPageEdit {\n prefSync: PluginPrefSync\n }\n}\n\n@Inject(['preferences', 'wikiPage', 'wikiTitle', 'modal', 'preferencesUI'])\nexport class PluginPrefSync extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'pref-sync')\n ctx.set('prefSync', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n ctx.preferences.defineCategory({\n name: 'pref-sync',\n label: 'Sync',\n description: 'Import and export preferences',\n index: 98,\n customRenderer: () => {\n const userPageTitle = this.getUserPrefsPageTitle()\n return (\n <div className=\"theme-ipe-prose\">\n <section>\n <h3>Backup your preferences via user page</h3>\n {userPageTitle && (\n <p>\n <a href={userPageTitle?.getURL().toString()} target=\"_blank\">\n {userPageTitle?.getPrefixedText()} →\n </a>\n </p>\n )}\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <ActionButton\n type=\"primary\"\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getCurrentModal()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n modal?.setLoadingState(true)\n this.importFromUserPage()\n .then((record) => {\n this.notifyImportSuccess(record)\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n Import\n </ActionButton>\n <ActionButton\n type=\"primary\"\n onClick={(e) => {\n e.preventDefault()\n const btn = e.target as HTMLButtonElement\n btn.disabled = true\n const modal = ctx.preferencesUI.getCurrentModal()\n modal?.setLoadingState(true)\n this.exportToUserPage()\n .then((title) => {\n ctx.modal.notify('success', {\n title: 'Preferences Exported',\n content: (\n <p>\n Your preferences have been exported to{' '}\n <a href={title.getURL().toString()} target=\"_blank\">\n {title.getPrefixedText()}\n </a>\n .\n </p>\n ),\n })\n })\n .finally(() => {\n btn.disabled = false\n modal?.setLoadingState(false)\n })\n }}\n >\n Export\n </ActionButton>\n </div>\n </section>\n <section>\n <h3>Import and export preferences</h3>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const modal = ctx.preferencesUI.getCurrentModal()\n modal?.setLoadingState(true)\n const input = document.createElement('input')\n input.type = 'file'\n input.accept = 'application/json'\n // Mobile Safari (and some older browsers) do not fire a 'cancel' event when\n // the file picker is dismissed without selecting a file. We use a\n // window 'focus' listener as a heuristic: once the picker closes\n // the window regains focus; if no file was chosen we treat it as cancel.\n // Fuck you Apple\n let handled = false\n const onDialogClose = () => {\n // If change handler did not run, treat as cancel\n if (!handled) {\n modal?.setLoadingState(false)\n }\n window.removeEventListener('focus', onDialogClose)\n }\n window.addEventListener('focus', onDialogClose, { once: true })\n\n input.addEventListener('change', async (e) => {\n handled = true\n try {\n const file = (e.target as HTMLInputElement).files?.[0]\n if (!file) {\n return\n }\n const record = await this.importFromFile(file)\n this.notifyImportSuccess(record)\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n })\n input.click()\n }}\n >\n Import from file\n </ActionButton>\n <ActionButton\n onClick={(e) => {\n e.preventDefault()\n const input = (<input type=\"url\"></input>) as HTMLInputElement\n const modal = ctx.preferencesUI.getCurrentModal()\n ctx.modal.confirm(\n {\n title: 'Import Preferences from URL',\n content: (\n <div>\n <label htmlFor=\"url-input\">\n Enter the URL of the preferences JSON file:\n </label>\n {input}\n </div>\n ),\n },\n async (result) => {\n const url = input.value.trim()\n if (!result || !url) {\n return\n }\n try {\n modal?.setLoadingState(true)\n const record = await this.importFromUrl(url)\n this.notifyImportSuccess(record)\n } catch (e) {\n ctx.modal.notify('error', {\n title: 'Import failed',\n content: e instanceof Error ? e.message : String(e),\n })\n } finally {\n modal?.setLoadingState(false)\n }\n }\n )\n }}\n >\n Import from URL\n </ActionButton>\n <ActionButton\n onClick={async (e) => {\n e.preventDefault()\n // 首先尝试保存当前的表单内容\n await ctx.preferencesUI.dispatchFormSave()\n const data = await ctx.preferences.getExportableRecord()\n const json = JSON.stringify(data, null, 2)\n ctx.modal.dialog(\n {\n title: 'Save to file',\n content: (\n <div>\n <label htmlFor=\"data\">Your InPageEdit preferences:</label>\n <textarea\n name=\"data\"\n id=\"data\"\n rows={10}\n value={json}\n readOnly\n style={{ width: '100%' }}\n ></textarea>\n </div>\n ),\n buttons: [\n {\n label: 'Copy',\n method: (_, m) => {\n navigator.clipboard.writeText(json)\n ctx.modal.notify('success', {\n content: 'Copied to clipboard',\n })\n m.close()\n },\n },\n {\n label: 'Download',\n method: (_, m) => {\n const a = document.createElement('a')\n a.href = `data:text/json;charset=utf-8,${encodeURIComponent(json)}`\n a.download = `ipe-prefs-${new Date().toISOString()}.json`\n a.click()\n m.close()\n },\n },\n ],\n },\n () => {}\n )\n }}\n >\n Save as file\n </ActionButton>\n </div>\n </section>\n </div>\n )\n },\n })\n }\n\n protected stop(): Promise<void> | void {}\n\n /**\n * 获取用户页配置文件的标题\n */\n private getUserPrefsPageTitle(): IWikiTitle | null {\n try {\n const userName = this.ctx.wiki?.userInfo?.name\n if (!userName) {\n return null\n }\n // 使用 User: 命名空间\n return this.ctx.wikiTitle.newTitle(`User:${userName}/ipe-prefs.json`, 2)\n } catch {\n return null\n }\n }\n\n /**\n * 从用户页加载配置\n */\n async importFromUserPage(): Promise<Record<string, unknown>> {\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n this.logger.debug('Cannot get user page title, skipping load')\n return {}\n }\n\n try {\n // 使用 raw action 获取 JSON 内容\n const rawUrl = title.getURL({ action: 'raw', ctype: 'application/json' })\n const changed = await this.importFromUrl(rawUrl.toString())\n this.logger.info('Loaded preferences from user page:', title)\n return changed\n } catch (error) {\n this.logger.error('Failed to load preferences from user page:', error)\n return {}\n }\n }\n\n /**\n * 导出配置到用户页\n */\n async exportToUserPage(): Promise<IWikiTitle> {\n const ctx = this.ctx\n const title = this.getUserPrefsPageTitle()\n if (!title) {\n throw new Error('Cannot get user page title')\n }\n\n // 首先尝试保存当前的表单内容\n await ctx.preferencesUI.dispatchFormSave()\n\n const json = await ctx.preferences.getExportableRecord()\n const text = JSON.stringify(json, null, 2)\n\n try {\n const page = this.ctx.wikiPage.newBlankPage({\n title: title.toString(),\n ns: 2, // User namespace\n })\n await page.edit({\n text,\n summary: 'Update InPageEdit preferences',\n watchlist: WatchlistAction.nochange,\n })\n\n this.logger.info('Exported preferences to user page:', title)\n return title\n } catch (error) {\n this.logger.error('Failed to export preferences to user page:', error)\n throw error\n }\n }\n\n async importFromUrl(input: string): Promise<Record<string, unknown>> {\n const response = await fetch(input)\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n }\n const blob = await response.blob()\n const changed = await this.importFromFile(blob)\n return changed\n }\n\n async importFromFile(input: Blob): Promise<Record<string, unknown>> {\n const text = await input.text()\n const data = JSON.parse(text)\n const changed = await this.ctx.preferences.setMany(data)\n return changed\n }\n\n private notifyImportSuccess(configs?: Record<string, unknown>) {\n const keys = Object.keys(configs ?? {})\n const count = keys.length\n return this.ctx.modal.notify('success', {\n title: 'Preferences Imported',\n content: (\n <section>\n <p>\n Successfully imported {count || ''} {count !== 1 ? 'settings' : 'setting'}:\n </p>\n <ol style={{ listStyle: 'auto', paddingLeft: '1em' }}>\n {keys.map((key) => (\n <li key={key}>{key}</li>\n ))}\n </ol>\n </section>\n ),\n })\n }\n}\n"],"names":["_PluginPrefSync_decorators","_init","_a","Inject","PluginPrefSync","BasePlugin","ctx","userPageTitle","jsxs","jsx","ActionButton","e","modal","btn","record","title","input","handled","onDialogClose","file","result","url","data","json","_","m","a","userName","rawUrl","changed","error","text","WatchlistAction","response","blob","configs","keys","count","key","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { a as R, k as $, r as h, f as y, l as L, g as I, e as a, h as n, q as r, C as U, D as A, y as _, z as i, F as B, x as D, v as u } from "./vueHooks-D0uVqbO-.js";
|
|
2
|
-
import { _ as F } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
3
|
-
const M = { id: "ipe-plugin-store-app" }, N = { class: "sotre-header" }, V = { class: "store-search-wrapper" }, q = ["disabled"], z = ["disabled"], E = { class: "refresh-text" }, H = {
|
|
4
|
-
key: 0,
|
|
5
|
-
class: "store-loading"
|
|
6
|
-
}, T = {
|
|
7
|
-
key: 1,
|
|
8
|
-
class: "store-plugins"
|
|
9
|
-
}, j = { class: "plugin-info" }, G = { class: "plugin-header" }, J = { class: "name" }, K = {
|
|
10
|
-
key: 0,
|
|
11
|
-
class: "status-badge"
|
|
12
|
-
}, O = ["href"], Q = { class: "plugin-id" }, W = {
|
|
13
|
-
key: 0,
|
|
14
|
-
class: "plugin-desc"
|
|
15
|
-
}, X = { class: "plugin-meta" }, Y = {
|
|
16
|
-
key: 0,
|
|
17
|
-
class: "version"
|
|
18
|
-
}, Z = {
|
|
19
|
-
key: 1,
|
|
20
|
-
class: "author"
|
|
21
|
-
}, ee = {
|
|
22
|
-
key: 2,
|
|
23
|
-
class: "license"
|
|
24
|
-
}, se = ["onClick"], te = {
|
|
25
|
-
key: 2,
|
|
26
|
-
class: "plugin-empty"
|
|
27
|
-
}, re = /* @__PURE__ */ R({
|
|
28
|
-
__name: "PluginStoreApp",
|
|
29
|
-
setup(ae) {
|
|
30
|
-
const o = $(), c = h([]), v = h([]), f = h(""), l = h(!1);
|
|
31
|
-
y(async () => {
|
|
32
|
-
await m();
|
|
33
|
-
});
|
|
34
|
-
const m = async () => {
|
|
35
|
-
const t = await o.store.ctx.preferences.get("pluginStore.registries") || [], s = await Promise.allSettled(
|
|
36
|
-
t.map(async (e) => ({ ...await o.store.getRegistryInfo(e), registryUrl: e }))
|
|
37
|
-
);
|
|
38
|
-
c.value = s.filter((e) => e.status === "fulfilled").map((e) => e.value);
|
|
39
|
-
}, d = (t, s) => v.value.includes(`${t}:${s}`), k = (t) => {
|
|
40
|
-
try {
|
|
41
|
-
return new URL(t).hostname;
|
|
42
|
-
} catch {
|
|
43
|
-
return t;
|
|
44
|
-
}
|
|
45
|
-
}, p = L(() => {
|
|
46
|
-
const t = c.value.flatMap(
|
|
47
|
-
(e) => (e.packages || []).map((g) => ({
|
|
48
|
-
...g,
|
|
49
|
-
registry: e.registryUrl,
|
|
50
|
-
// 使用完整的 registry URL (index.json 地址)
|
|
51
|
-
registryHomepage: e.homepage
|
|
52
|
-
}))
|
|
53
|
-
);
|
|
54
|
-
if (!f.value.trim()) return t;
|
|
55
|
-
const s = f.value.toLowerCase();
|
|
56
|
-
return t.filter((e) => e.name?.toLowerCase().includes(s) || e.id?.toLowerCase().includes(s) || e.description?.toLowerCase().includes(s) || e.author?.toLowerCase().includes(s));
|
|
57
|
-
}), w = async (t, s) => {
|
|
58
|
-
o.store.installAndSetPreference(t, s);
|
|
59
|
-
}, C = async (t, s) => {
|
|
60
|
-
o.store.uninstallAndRemovePreference(t, s);
|
|
61
|
-
}, P = (t, s) => {
|
|
62
|
-
d(t, s) ? C(t, s) : w(t, s);
|
|
63
|
-
}, x = async () => {
|
|
64
|
-
if (!l.value) {
|
|
65
|
-
l.value = !0;
|
|
66
|
-
try {
|
|
67
|
-
const t = await o.store.ctx.preferences.get("pluginStore.registries") || [], s = await Promise.allSettled(
|
|
68
|
-
t.map(async (e) => ({ ...await o.store.refreshRegistryCache(e), registryUrl: e }))
|
|
69
|
-
);
|
|
70
|
-
c.value = s.filter((e) => e.status === "fulfilled").map((e) => e.value), o.modal.notify("success", {
|
|
71
|
-
content: `${t.length} registries refreshed successfully`
|
|
72
|
-
});
|
|
73
|
-
} catch {
|
|
74
|
-
o.modal.notify("error", {
|
|
75
|
-
content: "Failed to refresh registries"
|
|
76
|
-
});
|
|
77
|
-
} finally {
|
|
78
|
-
setTimeout(() => {
|
|
79
|
-
l.value = !1;
|
|
80
|
-
}, 3e3);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}, b = async () => {
|
|
84
|
-
const t = await o.store.ctx.preferences.get("pluginStore.plugins") || [];
|
|
85
|
-
v.value = t.map((s) => `${s.registry}:${s.id}`);
|
|
86
|
-
};
|
|
87
|
-
function S(t) {
|
|
88
|
-
const s = t.changes["pluginStore.plugins"];
|
|
89
|
-
s && Array.isArray(s) && (v.value = s.map((e) => `${e.registry}:${e.id}`));
|
|
90
|
-
}
|
|
91
|
-
return y(() => {
|
|
92
|
-
b(), o.on("preferences/changed", S);
|
|
93
|
-
}), y(() => {
|
|
94
|
-
}), I(() => {
|
|
95
|
-
}), (t, s) => (n(), a("div", M, [
|
|
96
|
-
r("div", N, [
|
|
97
|
-
r("div", V, [
|
|
98
|
-
U(r("input", {
|
|
99
|
-
class: "store-search-input",
|
|
100
|
-
"onUpdate:modelValue": s[0] || (s[0] = (e) => f.value = e),
|
|
101
|
-
type: "text",
|
|
102
|
-
placeholder: "Search plugins...",
|
|
103
|
-
disabled: c.value.length === 0
|
|
104
|
-
}, null, 8, q), [
|
|
105
|
-
[A, f.value]
|
|
106
|
-
]),
|
|
107
|
-
s[1] || (s[1] = r("div", { class: "store-search-icon" }, "🔍", -1))
|
|
108
|
-
]),
|
|
109
|
-
r("button", {
|
|
110
|
-
class: _(["store-refresh-btn", { refreshing: l.value }]),
|
|
111
|
-
onClick: x,
|
|
112
|
-
disabled: l.value
|
|
113
|
-
}, [
|
|
114
|
-
r("span", E, i(l.value ? "Refreshing..." : "Refresh"), 1)
|
|
115
|
-
], 10, z)
|
|
116
|
-
]),
|
|
117
|
-
c.value.length === 0 ? (n(), a("div", H, [...s[2] || (s[2] = [
|
|
118
|
-
r("div", { class: "loading-spinner" }, null, -1),
|
|
119
|
-
r("div", { class: "loading-text" }, "Loading...", -1)
|
|
120
|
-
])])) : p.value.length > 0 ? (n(), a("div", T, [
|
|
121
|
-
(n(!0), a(B, null, D(p.value, (e) => (n(), a("div", {
|
|
122
|
-
class: _(["plugin-item", { installed: d(e.registry, e.id) }]),
|
|
123
|
-
key: `${e.registry}:${e.id}`
|
|
124
|
-
}, [
|
|
125
|
-
r("div", j, [
|
|
126
|
-
r("div", G, [
|
|
127
|
-
r("div", J, i(e.name), 1),
|
|
128
|
-
d(e.registry, e.id) ? (n(), a("div", K, "✓")) : u("", !0)
|
|
129
|
-
]),
|
|
130
|
-
r("a", {
|
|
131
|
-
class: "registry-tag",
|
|
132
|
-
href: e.registryHomepage,
|
|
133
|
-
target: "_blank"
|
|
134
|
-
}, i(k(e.registry)), 9, O),
|
|
135
|
-
r("div", Q, i(e.id), 1),
|
|
136
|
-
e.description ? (n(), a("div", W, i(e.description), 1)) : u("", !0),
|
|
137
|
-
r("div", X, [
|
|
138
|
-
e.version ? (n(), a("span", Y, "v" + i(e.version), 1)) : u("", !0),
|
|
139
|
-
e.author ? (n(), a("span", Z, "👤 " + i(e.author), 1)) : u("", !0),
|
|
140
|
-
e.license ? (n(), a("span", ee, "📜 " + i(e.license), 1)) : u("", !0)
|
|
141
|
-
])
|
|
142
|
-
]),
|
|
143
|
-
r("button", {
|
|
144
|
-
class: _({ active: d(e.registry, e.id) }),
|
|
145
|
-
onClick: (g) => P(e.registry, e.id)
|
|
146
|
-
}, i(d(e.registry, e.id) ? "Remove" : "Install"), 11, se)
|
|
147
|
-
], 2))), 128))
|
|
148
|
-
])) : (n(), a("div", te, [...s[3] || (s[3] = [
|
|
149
|
-
r("div", { class: "plugin-empty-icon" }, "📦", -1),
|
|
150
|
-
r("div", { class: "plugin-empty-text" }, "No matching plugins found", -1)
|
|
151
|
-
])]))
|
|
152
|
-
]));
|
|
153
|
-
}
|
|
154
|
-
}), ie = /* @__PURE__ */ F(re, [["__scopeId", "data-v-6fcc9e77"]]);
|
|
155
|
-
export {
|
|
156
|
-
ie as default
|
|
157
|
-
};
|
|
158
|
-
//# sourceMappingURL=PluginStoreApp-Cxspe6t8.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PluginStoreApp-Cxspe6t8.js","sources":["../src/plugins/plugin-store/components/PluginStoreApp.vue"],"sourcesContent":["<template lang=\"pug\">\n#ipe-plugin-store-app\n .sotre-header\n .store-search-wrapper\n input.store-search-input(\n v-model='searchInput',\n type='text',\n placeholder='Search plugins...',\n :disabled='registryInfos.length === 0'\n )\n .store-search-icon 🔍\n button.store-refresh-btn(\n @click='refreshRegistries',\n :disabled='isRefreshing',\n :class='{ refreshing: isRefreshing }'\n )\n span.refresh-text {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n\n .store-loading(v-if='registryInfos.length === 0')\n .loading-spinner\n .loading-text Loading...\n\n .store-plugins(v-else-if='filteredPlugins.length > 0')\n .plugin-item(\n v-for='plugin in filteredPlugins',\n :key='`${plugin.registry}:${plugin.id}`',\n :class='{ installed: isInstalled(plugin.registry, plugin.id) }'\n )\n .plugin-info\n .plugin-header\n .name {{ plugin.name }}\n .status-badge(v-if='isInstalled(plugin.registry, plugin.id)') ✓\n a.registry-tag(:href='plugin.registryHomepage', target='_blank') {{ getRegistryLabel(plugin.registry) }}\n .plugin-id {{ plugin.id }}\n .plugin-desc(v-if='plugin.description') {{ plugin.description }}\n .plugin-meta\n span.version(v-if='plugin.version') v{{ plugin.version }}\n span.author(v-if='plugin.author') 👤 {{ plugin.author }}\n span.license(v-if='plugin.license') 📜 {{ plugin.license }}\n button(\n :class='{ active: isInstalled(plugin.registry, plugin.id) }',\n @click='togglePlugin(plugin.registry, plugin.id)'\n ) {{ isInstalled(plugin.registry, plugin.id) ? 'Remove' : 'Install' }}\n\n .plugin-empty(v-else)\n .plugin-empty-icon 📦\n .plugin-empty-text No matching plugins found\n</template>\n\n<script setup lang=\"ts\" vapor>\nimport { computed, onBeforeUnmount, onMounted, ref } from 'vue'\nimport type { PluginStoreRegistry } from '../schema.js'\n\ninterface RegistryWithUrl extends PluginStoreRegistry {\n registryUrl: string\n}\n\nconst ctx = useIPE()\nconst registryInfos = ref<RegistryWithUrl[]>([])\nconst installedPlugins = ref<string[]>([])\nconst searchInput = ref('')\nconst isRefreshing = ref(false)\n\nonMounted(async () => {\n await initRegistries()\n})\n\nconst initRegistries = async () => {\n const registryUrls = (await ctx.store.ctx.preferences.get('pluginStore.registries')) || []\n\n const results = await Promise.allSettled(\n registryUrls.map(async (url) => {\n const info = await ctx.store.getRegistryInfo(url)\n return { ...info, registryUrl: url }\n })\n )\n\n registryInfos.value = results\n .filter((r) => r.status === 'fulfilled')\n .map((r) => (r as PromiseFulfilledResult<RegistryWithUrl>).value)\n}\n\nconst isInstalled = (registry: string, id: string) => {\n return installedPlugins.value.includes(`${registry}:${id}`)\n}\n\n// 获取仓库标签显示名称\nconst getRegistryLabel = (registryUrl: string) => {\n try {\n const url = new URL(registryUrl)\n return url.hostname\n } catch {\n return registryUrl\n }\n}\n\n// 搜索过滤 - 合并所有仓库的插件\nconst filteredPlugins = computed(() => {\n // 合并所有仓库的packages,并添加registry信息(使用完整的registryUrl)\n const allPlugins = registryInfos.value.flatMap((registry) =>\n (registry.packages || []).map((pkg) => ({\n ...pkg,\n registry: registry.registryUrl, // 使用完整的 registry URL (index.json 地址)\n registryHomepage: registry.homepage,\n }))\n )\n\n if (!searchInput.value.trim()) return allPlugins\n\n const query = searchInput.value.toLowerCase()\n return allPlugins.filter((plugin) => {\n return (\n plugin.name?.toLowerCase().includes(query) ||\n plugin.id?.toLowerCase().includes(query) ||\n plugin.description?.toLowerCase().includes(query) ||\n plugin.author?.toLowerCase().includes(query)\n )\n })\n})\n\nconst enablePlugin = async (registry: string, id: string) => {\n ctx.store.installAndSetPreference(registry, id)\n}\nconst disablePlugin = async (registry: string, id: string) => {\n ctx.store.uninstallAndRemovePreference(registry, id)\n}\n\n// 切换插件状态\nconst togglePlugin = (registry: string, id: string) => {\n if (isInstalled(registry, id)) {\n disablePlugin(registry, id)\n } else {\n enablePlugin(registry, id)\n }\n}\n\n// 刷新所有 registry 缓存\nconst refreshRegistries = async () => {\n if (isRefreshing.value) return\n\n isRefreshing.value = true\n try {\n const registryUrls = (await ctx.store.ctx.preferences.get('pluginStore.registries')) || []\n\n const results = await Promise.allSettled(\n registryUrls.map(async (url) => {\n const info = await ctx.store.refreshRegistryCache(url)\n return { ...info, registryUrl: url }\n })\n )\n\n registryInfos.value = results\n .filter((r) => r.status === 'fulfilled')\n .map((r) => (r as PromiseFulfilledResult<RegistryWithUrl>).value)\n\n ctx.modal.notify('success', {\n content: `${registryUrls.length} registries refreshed successfully`,\n })\n } catch (error) {\n ctx.modal.notify('error', {\n content: 'Failed to refresh registries',\n })\n } finally {\n setTimeout(() => {\n isRefreshing.value = false\n }, 3000)\n }\n}\n\n// init plugin states\nconst initInstalStatus = async () => {\n const prefs = (await ctx.store.ctx.preferences.get('pluginStore.plugins')) || []\n installedPlugins.value = prefs.map((p) => `${p.registry}:${p.id}`)\n}\nfunction onPreferencesChanged(payload: { changes: Record<string, unknown> }) {\n const plugins = payload.changes['pluginStore.plugins'] as {\n registry: string\n id: string\n }[]\n if (plugins && Array.isArray(plugins)) {\n installedPlugins.value = plugins.map((p) => `${p.registry}:${p.id}`)\n }\n}\nonMounted(() => {\n initInstalStatus()\n ctx.on('preferences/changed', onPreferencesChanged)\n})\n\nonMounted(() => {\n console.info('mount plugin store app', ctx)\n})\nonBeforeUnmount(() => {\n console.info('unmount plugin store app', ctx)\n})\n</script>\n\n<style scoped lang=\"scss\">\n#ipe-plugin-store-app {\n padding: var(--ipe-modal-spacing);\n font-size: 0.875rem;\n color: var(--ipe-modal-text);\n}\n\n.sotre-header {\n margin-bottom: 1.25rem;\n display: flex;\n align-items: center;\n gap: var(--ipe-modal-spacing);\n\n h2 {\n margin: 0;\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--ipe-modal-text);\n }\n\n .store-search-wrapper {\n flex: 1;\n position: relative;\n\n .store-search-input {\n width: 100%;\n height: 2.5rem;\n padding: 0 0.875rem 0 2.5rem;\n border: 1.5px solid var(--ipe-modal-border-color);\n border-radius: var(--ipe-modal-button-radius);\n font-size: 0.875rem;\n outline: none;\n background: var(--ipe-modal-bg);\n color: var(--ipe-modal-text);\n transition: all 0.2s ease;\n line-height: 1.5;\n\n &:focus {\n border-color: var(--ipe-modal-accent);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--ipe-modal-accent) 10%, transparent);\n }\n\n &::placeholder {\n color: var(--ipe-modal-muted);\n }\n }\n\n .store-search-icon {\n position: absolute;\n left: 0.75rem;\n top: 50%;\n transform: translateY(-50%);\n pointer-events: none;\n opacity: 0.5;\n }\n }\n\n .store-refresh-btn {\n height: 2.5rem;\n padding: 0 1rem;\n border: 1.5px solid var(--ipe-modal-border-color);\n border-radius: var(--ipe-modal-button-radius);\n background: var(--ipe-modal-bg);\n color: var(--ipe-modal-text);\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 500;\n white-space: nowrap;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 0.375rem;\n\n &:hover:not(:disabled) {\n background: var(--ipe-modal-secondary-bg);\n border-color: var(--ipe-modal-accent);\n transform: translateY(-1px);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--ipe-modal-text) 10%, transparent);\n }\n\n &:active:not(:disabled) {\n transform: translateY(0);\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n }\n}\n\n.store-loading {\n padding: 10rem 1.25rem;\n text-align: center;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.75rem;\n\n .loading-spinner {\n width: 2rem;\n height: 2rem;\n border: 3px solid var(--ipe-modal-border-color);\n border-top-color: var(--ipe-modal-accent);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n }\n\n .loading-text {\n color: var(--ipe-modal-muted);\n font-size: 0.875rem;\n }\n}\n\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n\n.store-plugins {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.plugin-item {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 0.875rem;\n border: 1.5px solid var(--ipe-modal-border-color);\n border-radius: calc(var(--ipe-modal-button-radius) + 2px);\n background: var(--ipe-modal-secondary-bg);\n position: relative;\n transition: all 0.2s ease;\n\n &:hover {\n background: var(--ipe-modal-divider-color);\n border-color: color-mix(in srgb, var(--ipe-modal-accent) 30%, var(--ipe-modal-border-color));\n box-shadow: 0 2px 8px color-mix(in srgb, var(--ipe-modal-text) 5%, transparent);\n }\n\n &.installed {\n background: color-mix(in srgb, var(--ipe-modal-success) 5%, var(--ipe-modal-secondary-bg));\n border-color: color-mix(in srgb, var(--ipe-modal-success) 50%, var(--ipe-modal-border-color));\n\n &:hover {\n background: color-mix(in srgb, var(--ipe-modal-success) 8%, var(--ipe-modal-secondary-bg));\n border-color: var(--ipe-modal-success);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--ipe-modal-success) 15%, transparent);\n }\n }\n\n .plugin-info {\n flex: 1;\n min-width: 0;\n\n .plugin-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin-bottom: 0.25rem;\n\n .name {\n font-weight: 600;\n font-size: 1rem;\n color: var(--ipe-modal-text);\n line-height: 1.2;\n }\n\n .status-badge {\n font-size: 0.6875rem;\n color: var(--ipe-modal-success);\n font-weight: 600;\n background: color-mix(in srgb, var(--ipe-modal-success) 15%, transparent);\n padding: 0.125rem 0.375rem;\n border-radius: calc(var(--ipe-modal-button-radius) - 2px);\n line-height: 1;\n }\n }\n\n .plugin-id {\n font-size: 0.75rem;\n color: var(--ipe-modal-muted);\n font-family: monospace;\n margin-bottom: 0.375rem;\n background: color-mix(in srgb, var(--ipe-modal-muted) 5%, transparent);\n padding: 0.125rem 0.375rem;\n border-radius: 3px;\n display: inline-block;\n margin-left: 0.375rem;\n }\n\n .registry-tag {\n font-size: 0.6875rem;\n color: var(--ipe-modal-accent);\n font-family: monospace;\n margin-bottom: 0.375rem;\n background: color-mix(in srgb, var(--ipe-modal-accent) 10%, transparent);\n padding: 0.125rem 0.375rem;\n border-radius: 3px;\n display: inline-block;\n border: 1px solid color-mix(in srgb, var(--ipe-modal-accent) 20%, transparent);\n }\n\n .plugin-desc {\n font-size: 0.8125rem;\n color: var(--ipe-modal-muted);\n margin-bottom: 0.375rem;\n line-height: 1.5;\n }\n\n .plugin-meta {\n font-size: 0.75rem;\n color: var(--ipe-modal-muted);\n display: flex;\n gap: 1rem;\n\n .version {\n font-family: monospace;\n font-weight: 500;\n }\n\n .author {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n }\n }\n\n button {\n padding: 0.5rem 1.25rem;\n border: 1.5px solid var(--ipe-modal-accent);\n border-radius: var(--ipe-modal-button-radius);\n background: var(--ipe-modal-bg);\n color: var(--ipe-modal-accent);\n cursor: pointer;\n font-size: 0.8125rem;\n font-weight: 500;\n white-space: nowrap;\n transition: all 0.2s ease;\n\n &:hover {\n background: var(--ipe-modal-accent);\n color: var(--ipe-modal-bg);\n transform: translateY(-1px);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--ipe-modal-accent) 25%, transparent);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &.active {\n border-color: var(--ipe-modal-danger);\n color: var(--ipe-modal-danger);\n\n &:hover {\n background: var(--ipe-modal-danger);\n color: var(--ipe-modal-bg);\n box-shadow: 0 2px 6px color-mix(in srgb, var(--ipe-modal-danger) 25%, transparent);\n }\n }\n }\n}\n\n.plugin-empty {\n padding: 3rem 1.25rem;\n text-align: center;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.75rem;\n\n .plugin-empty-icon {\n font-size: 3rem;\n opacity: 0.3;\n }\n\n .plugin-empty-text {\n color: var(--ipe-modal-muted);\n font-size: 0.9375rem;\n }\n}\n</style>\n"],"names":["ctx","useIPE","registryInfos","ref","installedPlugins","searchInput","isRefreshing","onMounted","initRegistries","registryUrls","results","url","r","isInstalled","registry","id","getRegistryLabel","registryUrl","filteredPlugins","computed","allPlugins","pkg","query","plugin","enablePlugin","disablePlugin","togglePlugin","refreshRegistries","initInstalStatus","prefs","p","onPreferencesChanged","payload","plugins","onBeforeUnmount"],"mappings":"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"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { JSX } from 'jsx-dom';
|
|
2
|
-
export interface ActionButtonProps {
|
|
3
|
-
type?: 'primary' | 'secondary' | 'danger' | 'default';
|
|
4
|
-
tag?: 'a' | 'button' | 'div';
|
|
5
|
-
}
|
|
6
|
-
export declare const ActionButton: ({ type, tag, href, target, children, ...rest }: ActionButtonProps & Omit<JSX.IntrinsicElements["button"], "type"> & JSX.IntrinsicElements["a"]) => HTMLAnchorElement;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { JSX } from 'jsx-dom';
|
|
2
|
-
export type CheckBoxProps = {
|
|
3
|
-
id?: string;
|
|
4
|
-
name: string;
|
|
5
|
-
label?: string | HTMLElement;
|
|
6
|
-
checked?: boolean;
|
|
7
|
-
inputProps?: JSX.IntrinsicElements['input'];
|
|
8
|
-
labelProps?: JSX.IntrinsicElements['span'];
|
|
9
|
-
} & JSX.IntrinsicElements['label'];
|
|
10
|
-
export declare const CheckBox: (props: CheckBoxProps) => import('jsx-dom').ReactElement;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { JSX } from 'jsx-dom';
|
|
2
|
-
export type InputBoxProps = {
|
|
3
|
-
label: string;
|
|
4
|
-
id?: string;
|
|
5
|
-
name: string;
|
|
6
|
-
value?: string;
|
|
7
|
-
disabled?: boolean;
|
|
8
|
-
labelProps?: JSX.IntrinsicElements['label'];
|
|
9
|
-
inputProps?: JSX.IntrinsicElements['input'];
|
|
10
|
-
} & JSX.IntrinsicElements['div'];
|
|
11
|
-
export declare const InputBox: (props: InputBoxProps) => import('jsx-dom').ReactElement;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'jsx-dom';
|
|
2
|
-
import { JSX } from 'jsx-dom/jsx-runtime';
|
|
3
|
-
export type MBoxProps = {
|
|
4
|
-
type?: '' | 'default' | 'note' | 'info' | 'tip' | 'success' | 'important' | 'done' | 'warning' | 'caution' | 'error';
|
|
5
|
-
title?: ReactNode;
|
|
6
|
-
content?: ReactNode;
|
|
7
|
-
closeable?: boolean;
|
|
8
|
-
titleProps?: JSX.IntrinsicElements['div'];
|
|
9
|
-
contentProps?: JSX.IntrinsicElements['div'];
|
|
10
|
-
} & JSX.IntrinsicElements['div'];
|
|
11
|
-
export type MBoxElement = HTMLElement & {
|
|
12
|
-
close: () => Promise<void>;
|
|
13
|
-
};
|
|
14
|
-
export declare const MBox: (props: MBoxProps) => MBoxElement;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { JSX } from 'jsx-dom';
|
|
2
|
-
export type RadioBoxProps = {
|
|
3
|
-
id?: string;
|
|
4
|
-
name: string;
|
|
5
|
-
value: string;
|
|
6
|
-
label?: string | HTMLElement;
|
|
7
|
-
inputProps?: JSX.IntrinsicElements['input'];
|
|
8
|
-
labelProps?: JSX.IntrinsicElements['span'];
|
|
9
|
-
} & JSX.IntrinsicElements['label'];
|
|
10
|
-
export declare const RadioBox: (props: RadioBoxProps) => import('jsx-dom').ReactElement;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'jsx-dom';
|
|
2
|
-
export interface TabViewLabelOptions {
|
|
3
|
-
name: string;
|
|
4
|
-
children: ReactNode;
|
|
5
|
-
}
|
|
6
|
-
export declare function TabView({ tabs, defaultActiveIndex, }: {
|
|
7
|
-
tabs: (TabViewLabelOptions & {
|
|
8
|
-
content: ReactNode;
|
|
9
|
-
})[];
|
|
10
|
-
defaultActiveIndex?: number;
|
|
11
|
-
}): import('jsx-dom').ReactElement;
|
|
12
|
-
export declare function TabLabel({ name, children }: {
|
|
13
|
-
name: string;
|
|
14
|
-
children: ReactNode;
|
|
15
|
-
}): import('jsx-dom').ReactElement;
|
|
16
|
-
export declare function TabContent({ name, children }: {
|
|
17
|
-
name: string;
|
|
18
|
-
children: ReactNode;
|
|
19
|
-
}): import('jsx-dom').ReactElement;
|