@inpageedit/core 0.11.1 → 0.12.1
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/dist/ActionButton-CRjo_l3y.js +24 -0
- package/dist/ActionButton-CRjo_l3y.js.map +1 -0
- package/dist/{IconQuickEdit-CAL1HXIb.js → IconQuickEdit-CMCQncyj.js} +2 -2
- package/dist/{IconQuickEdit-CAL1HXIb.js.map → IconQuickEdit-CMCQncyj.js.map} +1 -1
- package/dist/InPageEdit.d.ts +5 -1
- package/dist/InputBox-nQKtiWtZ.js +30 -0
- package/dist/InputBox-nQKtiWtZ.js.map +1 -0
- package/dist/PluginPrefSync-Ziogy_o-.js +339 -0
- package/dist/PluginPrefSync-Ziogy_o-.js.map +1 -0
- package/dist/PluginStoreApp-Bnvyl-Oc.js +452 -0
- package/dist/PluginStoreApp-Bnvyl-Oc.js.map +1 -0
- package/dist/{RadioBox-nJqWsxW2.js → RadioBox-0UuxlcWZ.js} +2 -2
- package/dist/{RadioBox-nJqWsxW2.js.map → RadioBox-0UuxlcWZ.js.map} +1 -1
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js +10 -0
- package/dist/_plugin-vue_export-helper-CHgC5LLL.js.map +1 -0
- package/dist/components/index.js +50 -69
- package/dist/components/index.js.map +1 -1
- package/dist/constants/endpoints.d.ts +2 -1
- package/dist/{index-CfgnJ51A.js → index-B3FUDhxl.js} +53 -43
- package/dist/index-B3FUDhxl.js.map +1 -0
- package/dist/index-B3YJdjxo.js +361 -0
- package/dist/index-B3YJdjxo.js.map +1 -0
- package/dist/{index-BNDyaWnI.js → index-BRjEc8b8.js} +10 -9
- package/dist/index-BRjEc8b8.js.map +1 -0
- package/dist/index-Bd70aDMT.js +172 -0
- package/dist/index-Bd70aDMT.js.map +1 -0
- package/dist/index-BvuaLEFc.js +179 -0
- package/dist/index-BvuaLEFc.js.map +1 -0
- package/dist/{index-lZkYoUca.js → index-CG38LlAh.js} +2 -2
- package/dist/{index-lZkYoUca.js.map → index-CG38LlAh.js.map} +1 -1
- package/dist/{index-CvhkVj_L.js → index-CM_6yF2v.js} +3 -3
- package/dist/{index-CvhkVj_L.js.map → index-CM_6yF2v.js.map} +1 -1
- package/dist/{index-etJXONAj.js → index-Ccr3YhkP.js} +6 -6
- package/dist/index-Ccr3YhkP.js.map +1 -0
- package/dist/{index-U2RPZk8N.js → index-D5zX93bn.js} +43 -44
- package/dist/index-D5zX93bn.js.map +1 -0
- package/dist/{index-Bh70Udzi.js → index-DD5CVCfD.js} +2 -2
- package/dist/{index-Bh70Udzi.js.map → index-DD5CVCfD.js.map} +1 -1
- package/dist/{index-BUI2IX49.js → index-DgQNTfPR.js} +2314 -2316
- package/dist/index-DgQNTfPR.js.map +1 -0
- package/dist/{index-BQzuJxBO.js → index-Dnmv-xDn.js} +4 -4
- package/dist/index-Dnmv-xDn.js.map +1 -0
- package/dist/index-eARjMi7f.js +1168 -0
- package/dist/index-eARjMi7f.js.map +1 -0
- package/dist/{index-D5J7RU5I.js → index-zHTGCjfF.js} +5 -7
- package/dist/index-zHTGCjfF.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/models/MemoryStorage.d.ts +10 -0
- package/dist/models/WikiPage/index.d.ts +19 -1
- package/dist/plugins/in-article-links/index.d.ts +5 -0
- package/dist/plugins/plugin-store/index.d.ts +56 -0
- package/dist/plugins/plugin-store/schema.d.ts +41 -0
- package/dist/plugins/preferences-ui/PluginPrefSync.d.ts +1 -0
- package/dist/plugins/preferences-ui/index.d.ts +34 -5
- package/dist/plugins/quick-diff/index.d.ts +3 -0
- package/dist/plugins/quick-edit/index.d.ts +8 -0
- package/dist/plugins/quick-move/index.d.ts +5 -3
- package/dist/plugins/quick-preview/index.d.ts +4 -0
- package/dist/plugins/quick-redirect/index.d.ts +11 -4
- package/dist/plugins/toolbox/index.d.ts +3 -0
- package/dist/services/PreferencesService.d.ts +53 -11
- package/dist/services/ResourceLoaderService.d.ts +3 -0
- package/dist/services/WikiMetadataService.d.ts +1 -1
- package/dist/services/storage/index.d.ts +18 -8
- package/dist/services/storage/{IPEStorageManager.d.ts → managers/IDBStorageManager.d.ts} +9 -6
- package/dist/services/storage/managers/LocalStorageManager.d.ts +27 -0
- package/dist/style.css +1 -1
- package/dist/vueHooks-l04s8cIl.js +4064 -0
- package/dist/vueHooks-l04s8cIl.js.map +1 -0
- package/lib/index.umd.js +12 -112
- package/lib/index.umd.js.map +1 -1
- package/lib/style.css +1 -1
- package/package.json +14 -14
- package/dist/CheckBox-D3rHnX7I.js +0 -13
- package/dist/CheckBox-D3rHnX7I.js.map +0 -1
- package/dist/InputBox-BV4m05Xs.js +0 -22
- package/dist/InputBox-BV4m05Xs.js.map +0 -1
- package/dist/PluginPrefSync-COidewzp.js +0 -258
- package/dist/PluginPrefSync-COidewzp.js.map +0 -1
- package/dist/index-BNDyaWnI.js.map +0 -1
- package/dist/index-BQzuJxBO.js.map +0 -1
- package/dist/index-BUI2IX49.js.map +0 -1
- package/dist/index-CBszdxJJ.js +0 -159
- package/dist/index-CBszdxJJ.js.map +0 -1
- package/dist/index-CfgnJ51A.js.map +0 -1
- package/dist/index-Cx4qgCJK.js +0 -4914
- package/dist/index-Cx4qgCJK.js.map +0 -1
- package/dist/index-D5J7RU5I.js.map +0 -1
- package/dist/index-MhNAv9Vf.js +0 -302
- package/dist/index-MhNAv9Vf.js.map +0 -1
- package/dist/index-U2RPZk8N.js.map +0 -1
- package/dist/index-VnRKIVau.js +0 -167
- package/dist/index-VnRKIVau.js.map +0 -1
- package/dist/index-etJXONAj.js.map +0 -1
- package/dist/plugins/quick-delete/index.d.ts +0 -52
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { c as s } from "./index-CM_6yF2v.js";
|
|
2
|
+
const d = window?.location?.origin, p = ({
|
|
3
|
+
type: n,
|
|
4
|
+
tag: t,
|
|
5
|
+
href: i,
|
|
6
|
+
target: o,
|
|
7
|
+
children: a,
|
|
8
|
+
...e
|
|
9
|
+
}) => (t = t || (i ? "a" : "button"), typeof o > "u" && i && i.startsWith("http") && !i.startsWith(d) && (o = "_blank"), s(
|
|
10
|
+
t,
|
|
11
|
+
{
|
|
12
|
+
className: `theme-ipe ipe-action-button ipe-modal-btn is-${n || "default"}`,
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
href: t === "a" ? i : void 0,
|
|
15
|
+
target: t === "a" ? o : void 0,
|
|
16
|
+
"data-href": t !== "a" ? i : void 0,
|
|
17
|
+
...e
|
|
18
|
+
},
|
|
19
|
+
a
|
|
20
|
+
));
|
|
21
|
+
export {
|
|
22
|
+
p as A
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=ActionButton-CRjo_l3y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionButton-CRjo_l3y.js","sources":["../src/components/ActionButton.tsx"],"sourcesContent":["import { h, JSX } from 'jsx-dom'\n\nexport interface ActionButtonProps {\n type?: 'primary' | 'secondary' | 'danger' | 'default'\n tag?: 'a' | 'button' | 'div'\n}\n\nconst origin = window?.location?.origin\n\nexport const ActionButton = ({\n type,\n tag,\n href,\n target,\n children,\n ...rest\n}: ActionButtonProps &\n Omit<JSX.IntrinsicElements['button'], 'type'> &\n JSX.IntrinsicElements['a']) => {\n tag = tag || (href ? 'a' : 'button')\n if (\n typeof target === 'undefined' &&\n href &&\n href.startsWith('http') &&\n !href.startsWith(origin)\n ) {\n target = '_blank'\n }\n return h(\n tag,\n {\n className: `theme-ipe ipe-action-button ipe-modal-btn is-${type || 'default'}`,\n // @ts-ignore\n href: tag === 'a' ? href : undefined,\n target: tag === 'a' ? target : undefined,\n 'data-href': tag !== 'a' ? href : undefined,\n ...rest,\n },\n children\n )\n}\n"],"names":["origin","ActionButton","type","tag","href","target","children","rest","h"],"mappings":";AAOA,MAAMA,IAAS,QAAQ,UAAU,QAEpBC,IAAe,CAAC;AAAA,EAC3B,MAAAC;AAAA,EACA,KAAAC;AAAA,EACA,MAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,OAGEJ,IAAMA,MAAQC,IAAO,MAAM,WAEzB,OAAOC,IAAW,OAClBD,KACAA,EAAK,WAAW,MAAM,KACtB,CAACA,EAAK,WAAWJ,CAAM,MAEvBK,IAAS,WAEJG;AAAAA,EACLL;AAAA,EACA;AAAA,IACE,WAAW,gDAAgDD,KAAQ,SAAS;AAAA;AAAA,IAE5E,MAAMC,MAAQ,MAAMC,IAAO;AAAA,IAC3B,QAAQD,MAAQ,MAAME,IAAS;AAAA,IAC/B,aAAaF,MAAQ,MAAMC,IAAO;AAAA,IAClC,GAAGG;AAAA,EAAA;AAAA,EAELD;AAAA;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { j as o } from "./index-
|
|
1
|
+
import { j as o } from "./index-CM_6yF2v.js";
|
|
2
2
|
const n = (t) => /* @__PURE__ */ o(
|
|
3
3
|
"svg",
|
|
4
4
|
{
|
|
@@ -24,4 +24,4 @@ const n = (t) => /* @__PURE__ */ o(
|
|
|
24
24
|
export {
|
|
25
25
|
n as I
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=IconQuickEdit-
|
|
27
|
+
//# sourceMappingURL=IconQuickEdit-CMCQncyj.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconQuickEdit-
|
|
1
|
+
{"version":3,"file":"IconQuickEdit-CMCQncyj.js","sources":["../src/components/Icon/IconQuickEdit.tsx"],"sourcesContent":["import { SVGProps } from 'jsx-dom'\n\nexport const IconQuickEdit = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n {...props}\n class={`icon icon-tabler icons-tabler-outline icon-tabler-pencil-bolt ${props.className || ''}`}\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4\" />\n <path d=\"M13.5 6.5l4 4\" />\n <path d=\"M19 16l-2 3h4l-2 3\" />\n </svg>\n)\n"],"names":["IconQuickEdit","props","jsxs","jsx"],"mappings":";AAEO,MAAMA,IAAgB,CAACC,MAC5BC,gBAAAA;AAAAA,EAAC;AAAA,EAAA;AAAA,IACC,OAAM;AAAA,IACN,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,gBAAa;AAAA,IACb,kBAAe;AAAA,IACf,mBAAgB;AAAA,IACf,GAAGD;AAAA,IACJ,OAAO,iEAAiEA,EAAM,aAAa,EAAE;AAAA,IAE7F,UAAA;AAAA,MAAA,gBAAAE,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,MAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,0DAAA,CAA0D;AAAA,MAClE,gBAAAA,EAAC,QAAA,EAAK,GAAE,gBAAA,CAAgB;AAAA,MACxB,gBAAAA,EAAC,QAAA,EAAK,GAAE,qBAAA,CAAqB;AAAA,IAAA;AAAA,EAAA;AAC/B;"}
|
package/dist/InPageEdit.d.ts
CHANGED
|
@@ -5,7 +5,9 @@ export interface InPageEditCoreConfig {
|
|
|
5
5
|
apiConfigs: Partial<FexiosConfigs>;
|
|
6
6
|
legacyPreferences: Record<string, any>;
|
|
7
7
|
logLevel: number;
|
|
8
|
+
storageNamespace: string;
|
|
8
9
|
autoloadStyles: boolean;
|
|
10
|
+
autoInstallCorePlugins: boolean;
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* ✏️ InPageEdit NEXT
|
|
@@ -26,10 +28,12 @@ export declare class InPageEdit extends Context {
|
|
|
26
28
|
readonly schema: Schemastery.Static;
|
|
27
29
|
readonly logger: Logger;
|
|
28
30
|
constructor(config?: Partial<InPageEditCoreConfig>);
|
|
29
|
-
|
|
31
|
+
withInject(inject: Inject): Promise<this>;
|
|
30
32
|
}
|
|
31
33
|
export { default as Schema } from 'schemastery';
|
|
32
34
|
export * from '@inpageedit/logger';
|
|
35
|
+
export interface PreferencesMap {
|
|
36
|
+
}
|
|
33
37
|
export { Inject, Service } from '@cordisjs/core';
|
|
34
38
|
export interface Events<C extends InPageEdit = InPageEdit> extends CordisEvents<C> {
|
|
35
39
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { j as e } from "./index-CM_6yF2v.js";
|
|
2
|
+
const h = (s) => {
|
|
3
|
+
const { id: t, name: l, label: a, checked: c, inputProps: i, labelProps: n, children: p, ...o } = s;
|
|
4
|
+
return /* @__PURE__ */ e("label", { className: "theme-ipe ipe-checkbox", ...o, children: [
|
|
5
|
+
/* @__PURE__ */ e("input", { type: "checkbox", id: t, name: l, checked: c, ...i }),
|
|
6
|
+
/* @__PURE__ */ e("span", { className: "ipe-checkbox-box" }),
|
|
7
|
+
/* @__PURE__ */ e("span", { ...n, children: a || p })
|
|
8
|
+
] });
|
|
9
|
+
}, b = (s) => {
|
|
10
|
+
const { label: t, id: l, name: a, value: c, disabled: i, labelProps: n, inputProps: p, ...o } = s;
|
|
11
|
+
return /* @__PURE__ */ e("div", { className: "theme-ipe ipe-input-box", ...o, children: [
|
|
12
|
+
/* @__PURE__ */ e("label", { htmlFor: l, style: { display: "block" }, ...n, children: t }),
|
|
13
|
+
/* @__PURE__ */ e(
|
|
14
|
+
"input",
|
|
15
|
+
{
|
|
16
|
+
id: l,
|
|
17
|
+
name: a,
|
|
18
|
+
value: c,
|
|
19
|
+
disabled: i,
|
|
20
|
+
style: { width: "100%" },
|
|
21
|
+
...p
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
] });
|
|
25
|
+
};
|
|
26
|
+
export {
|
|
27
|
+
h as C,
|
|
28
|
+
b as I
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=InputBox-nQKtiWtZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputBox-nQKtiWtZ.js","sources":["../src/components/CheckBox.tsx","../src/components/InputBox.tsx"],"sourcesContent":["import { JSX } from 'jsx-dom'\n\nexport type CheckBoxProps = {\n id?: string\n name: string\n label?: string | HTMLElement\n checked?: boolean\n inputProps?: JSX.IntrinsicElements['input']\n labelProps?: JSX.IntrinsicElements['span']\n} & JSX.IntrinsicElements['label']\n\nexport const CheckBox = (props: CheckBoxProps) => {\n const { id, name, label, checked, inputProps, labelProps, children, ...rest } = props\n return (\n <label className=\"theme-ipe ipe-checkbox\" {...rest}>\n <input type=\"checkbox\" id={id} name={name} checked={checked} {...inputProps} />\n <span className=\"ipe-checkbox-box\"></span>\n <span {...labelProps}>{label || children}</span>\n </label>\n )\n}\n","import { JSX } from 'jsx-dom'\n\nexport type InputBoxProps = {\n label: string\n id?: string\n name: string\n value?: string\n disabled?: boolean\n labelProps?: JSX.IntrinsicElements['label']\n inputProps?: JSX.IntrinsicElements['input']\n} & JSX.IntrinsicElements['div']\n\nexport const InputBox = (props: InputBoxProps) => {\n const { label, id, name, value, disabled, labelProps, inputProps, ...rest } = props\n return (\n <div className=\"theme-ipe ipe-input-box\" {...rest}>\n <label htmlFor={id} style={{ display: 'block' }} {...labelProps}>\n {label}\n </label>\n <input\n id={id}\n name={name}\n value={value}\n disabled={disabled}\n style={{ width: '100%' }}\n {...inputProps}\n />\n </div>\n )\n}\n"],"names":["CheckBox","props","id","name","label","checked","inputProps","labelProps","children","rest","jsxs","jsx","InputBox","value","disabled"],"mappings":";AAWO,MAAMA,IAAW,CAACC,MAAyB;AAChD,QAAM,EAAE,IAAAC,GAAI,MAAAC,GAAM,OAAAC,GAAO,SAAAC,GAAS,YAAAC,GAAY,YAAAC,GAAY,UAAAC,GAAU,GAAGC,EAAA,IAASR;AAChF,SACES,gBAAAA,EAAC,SAAA,EAAM,WAAU,0BAA0B,GAAGD,GAC5C,UAAA;AAAA,IAAA,gBAAAE,EAAC,WAAM,MAAK,YAAW,IAAAT,GAAQ,MAAAC,GAAY,SAAAE,GAAmB,GAAGC,GAAY;AAAA,IAC7E,gBAAAK,EAAC,QAAA,EAAK,WAAU,mBAAA,CAAmB;AAAA,IACnC,gBAAAA,EAAC,QAAA,EAAM,GAAGJ,GAAa,eAASC,EAAA,CAAS;AAAA,EAAA,GAC3C;AAEJ,GCRaI,IAAW,CAACX,MAAyB;AAChD,QAAM,EAAE,OAAAG,GAAO,IAAAF,GAAI,MAAAC,GAAM,OAAAU,GAAO,UAAAC,GAAU,YAAAP,GAAY,YAAAD,GAAY,GAAGG,EAAA,IAASR;AAC9E,SACES,gBAAAA,EAAC,OAAA,EAAI,WAAU,2BAA2B,GAAGD,GAC3C,UAAA;AAAA,IAAA,gBAAAE,EAAC,SAAA,EAAM,SAAST,GAAI,OAAO,EAAE,SAAS,QAAA,GAAY,GAAGK,GAClD,UAAAH,EAAA,CACH;AAAA,IACA,gBAAAO;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAAT;AAAA,QACA,MAAAC;AAAA,QACA,OAAAU;AAAA,QACA,UAAAC;AAAA,QACA,OAAO,EAAE,OAAO,OAAA;AAAA,QACf,GAAGR;AAAA,MAAA;AAAA,IAAA;AAAA,EACN,GACF;AAEJ;"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { j as r } from "./index-CM_6yF2v.js";
|
|
2
|
+
import { B as k, W as I, I as U } from "./index-DgQNTfPR.js";
|
|
3
|
+
import { A as p } from "./ActionButton-CRjo_l3y.js";
|
|
4
|
+
var L = Object.create, m = Object.defineProperty, C = Object.getOwnPropertyDescriptor, v = (a, e) => (e = Symbol[a]) ? e : Symbol.for("Symbol." + a), x = (a) => {
|
|
5
|
+
throw TypeError(a);
|
|
6
|
+
}, E = (a, e, n) => e in a ? m(a, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : a[e] = n, F = (a, e) => m(a, "name", { value: e, configurable: !0 }), T = (a) => [, , , L(a?.[v("metadata")] ?? null)], j = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], S = (a) => a !== void 0 && typeof a != "function" ? x("Function expected") : a, M = (a, e, n, o, t) => ({ kind: j[a], name: e, metadata: o, addInitializer: (i) => n._ ? x("Already initialized") : t.push(S(i || null)) }), D = (a, e) => E(e, v("metadata"), a[3]), O = (a, e, n, o) => {
|
|
7
|
+
for (var t = 0, i = a[e >> 1], s = i && i.length; t < s; t++) i[t].call(n);
|
|
8
|
+
return o;
|
|
9
|
+
}, R = (a, e, n, o, t, i) => {
|
|
10
|
+
var s, l, c, d = e & 7, f = !1, w = 0, P = a[w] || (a[w] = []), h = d && (t = t.prototype, d < 5 && (d > 3 || !f) && C(t, n));
|
|
11
|
+
F(t, n);
|
|
12
|
+
for (var u = o.length - 1; u >= 0; u--)
|
|
13
|
+
c = M(d, n, l = {}, a[3], P), s = (0, o[u])(t, c), l._ = 1, S(s) && (t = s);
|
|
14
|
+
return D(a, t), h && m(t, n, h), f ? d ^ 4 ? i : h : t;
|
|
15
|
+
}, b, y, _;
|
|
16
|
+
b = [U(["preferences", "wikiPage", "wikiTitle", "modal", "preferencesUI"])];
|
|
17
|
+
class g extends (_ = k) {
|
|
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 n = this.getUserPrefsPageTitle();
|
|
30
|
+
return /* @__PURE__ */ r("div", { className: "theme-ipe-prose", children: [
|
|
31
|
+
n && /* @__PURE__ */ r("section", { children: [
|
|
32
|
+
/* @__PURE__ */ r("h3", { children: "Backup your preferences via user page" }),
|
|
33
|
+
/* @__PURE__ */ r("p", { children: /* @__PURE__ */ r("a", { href: n?.getURL().toString(), target: "_blank", children: [
|
|
34
|
+
n?.getPrefixedText(),
|
|
35
|
+
" →"
|
|
36
|
+
] }) }),
|
|
37
|
+
/* @__PURE__ */ r("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
38
|
+
/* @__PURE__ */ r(
|
|
39
|
+
p,
|
|
40
|
+
{
|
|
41
|
+
type: "primary",
|
|
42
|
+
onClick: (o) => {
|
|
43
|
+
o.preventDefault();
|
|
44
|
+
const t = o.target;
|
|
45
|
+
t.disabled = !0;
|
|
46
|
+
const i = e.preferencesUI.getCurrentModal();
|
|
47
|
+
i?.setLoadingState(!0), this.exportToUserPage().then((s) => {
|
|
48
|
+
e.modal.notify("success", {
|
|
49
|
+
title: "Preferences Exported",
|
|
50
|
+
content: /* @__PURE__ */ r("p", { children: [
|
|
51
|
+
"Your preferences have been exported to",
|
|
52
|
+
" ",
|
|
53
|
+
/* @__PURE__ */ r("a", { href: s.getURL().toString(), target: "_blank", children: s.getPrefixedText() }),
|
|
54
|
+
"."
|
|
55
|
+
] })
|
|
56
|
+
});
|
|
57
|
+
}).finally(() => {
|
|
58
|
+
t.disabled = !1, i?.setLoadingState(!1);
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ r(
|
|
63
|
+
"svg",
|
|
64
|
+
{
|
|
65
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
66
|
+
width: "24",
|
|
67
|
+
height: "24",
|
|
68
|
+
viewBox: "0 0 24 24",
|
|
69
|
+
fill: "none",
|
|
70
|
+
stroke: "currentColor",
|
|
71
|
+
"stroke-width": "2",
|
|
72
|
+
"stroke-linecap": "round",
|
|
73
|
+
"stroke-linejoin": "round",
|
|
74
|
+
class: "icon icon-tabler icons-tabler-outline icon-tabler-cloud-up",
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ r("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
|
|
77
|
+
/* @__PURE__ */ r("path", { d: "M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.57 .811 3.128 1.986" }),
|
|
78
|
+
/* @__PURE__ */ r("path", { d: "M19 22v-6" }),
|
|
79
|
+
/* @__PURE__ */ r("path", { d: "M22 19l-3 -3l-3 3" })
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
" ",
|
|
84
|
+
"Backup"
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
/* @__PURE__ */ r(
|
|
89
|
+
p,
|
|
90
|
+
{
|
|
91
|
+
onClick: (o) => {
|
|
92
|
+
o.preventDefault();
|
|
93
|
+
const t = e.preferencesUI.getCurrentModal(), i = o.target;
|
|
94
|
+
i.disabled = !0, t?.setLoadingState(!0), this.importFromUserPage().then((s) => {
|
|
95
|
+
this.notifyImportSuccess(s);
|
|
96
|
+
}).finally(() => {
|
|
97
|
+
i.disabled = !1, t?.setLoadingState(!1);
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
children: [
|
|
101
|
+
/* @__PURE__ */ r(
|
|
102
|
+
"svg",
|
|
103
|
+
{
|
|
104
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
105
|
+
width: "24",
|
|
106
|
+
height: "24",
|
|
107
|
+
viewBox: "0 0 24 24",
|
|
108
|
+
fill: "none",
|
|
109
|
+
stroke: "currentColor",
|
|
110
|
+
"stroke-width": "2",
|
|
111
|
+
"stroke-linecap": "round",
|
|
112
|
+
"stroke-linejoin": "round",
|
|
113
|
+
class: "icon icon-tabler icons-tabler-outline icon-tabler-cloud-down",
|
|
114
|
+
children: [
|
|
115
|
+
/* @__PURE__ */ r("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
|
|
116
|
+
/* @__PURE__ */ r("path", { d: "M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.573 .813 3.13 1.99" }),
|
|
117
|
+
/* @__PURE__ */ r("path", { d: "M19 16v6" }),
|
|
118
|
+
/* @__PURE__ */ r("path", { d: "M22 19l-3 3l-3 -3" })
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
" ",
|
|
123
|
+
"Restore"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
] })
|
|
128
|
+
] }),
|
|
129
|
+
/* @__PURE__ */ r("section", { children: [
|
|
130
|
+
/* @__PURE__ */ r("h3", { children: "Import and export preferences" }),
|
|
131
|
+
/* @__PURE__ */ r("div", { style: { display: "flex", flexDirection: "column", gap: "1rem" }, children: [
|
|
132
|
+
/* @__PURE__ */ r(
|
|
133
|
+
p,
|
|
134
|
+
{
|
|
135
|
+
onClick: (o) => {
|
|
136
|
+
o.preventDefault();
|
|
137
|
+
const t = e.preferencesUI.getCurrentModal();
|
|
138
|
+
t?.setLoadingState(!0);
|
|
139
|
+
const i = document.createElement("input");
|
|
140
|
+
i.type = "file", i.accept = "application/json";
|
|
141
|
+
let s = !1;
|
|
142
|
+
const l = () => {
|
|
143
|
+
s || t?.setLoadingState(!1), window.removeEventListener("focus", l);
|
|
144
|
+
};
|
|
145
|
+
window.addEventListener("focus", l, { once: !0 }), i.addEventListener("change", async (c) => {
|
|
146
|
+
s = !0;
|
|
147
|
+
try {
|
|
148
|
+
const d = c.target.files?.[0];
|
|
149
|
+
if (!d)
|
|
150
|
+
return;
|
|
151
|
+
const f = await this.importFromFile(d);
|
|
152
|
+
this.notifyImportSuccess(f);
|
|
153
|
+
} catch (d) {
|
|
154
|
+
e.modal.notify("error", {
|
|
155
|
+
title: "Import failed",
|
|
156
|
+
content: d instanceof Error ? d.message : String(d)
|
|
157
|
+
});
|
|
158
|
+
} finally {
|
|
159
|
+
t?.setLoadingState(!1);
|
|
160
|
+
}
|
|
161
|
+
}), i.click();
|
|
162
|
+
},
|
|
163
|
+
children: "Import from file"
|
|
164
|
+
}
|
|
165
|
+
),
|
|
166
|
+
/* @__PURE__ */ r(
|
|
167
|
+
p,
|
|
168
|
+
{
|
|
169
|
+
onClick: (o) => {
|
|
170
|
+
o.preventDefault();
|
|
171
|
+
const t = /* @__PURE__ */ r("input", { type: "url" }), i = e.preferencesUI.getCurrentModal();
|
|
172
|
+
e.modal.confirm(
|
|
173
|
+
{
|
|
174
|
+
title: "Import Preferences from URL",
|
|
175
|
+
content: /* @__PURE__ */ r("div", { children: [
|
|
176
|
+
/* @__PURE__ */ r("label", { htmlFor: "url-input", children: "Enter the URL of the preferences JSON file:" }),
|
|
177
|
+
t
|
|
178
|
+
] })
|
|
179
|
+
},
|
|
180
|
+
async (s) => {
|
|
181
|
+
const l = t.value.trim();
|
|
182
|
+
if (!(!s || !l))
|
|
183
|
+
try {
|
|
184
|
+
i?.setLoadingState(!0);
|
|
185
|
+
const c = await this.importFromUrl(l);
|
|
186
|
+
this.notifyImportSuccess(c);
|
|
187
|
+
} catch (c) {
|
|
188
|
+
e.modal.notify("error", {
|
|
189
|
+
title: "Import failed",
|
|
190
|
+
content: c instanceof Error ? c.message : String(c)
|
|
191
|
+
});
|
|
192
|
+
} finally {
|
|
193
|
+
i?.setLoadingState(!1);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
},
|
|
198
|
+
children: "Import from URL"
|
|
199
|
+
}
|
|
200
|
+
),
|
|
201
|
+
/* @__PURE__ */ r(
|
|
202
|
+
p,
|
|
203
|
+
{
|
|
204
|
+
onClick: async (o) => {
|
|
205
|
+
o.preventDefault(), await e.preferencesUI.dispatchFormSave();
|
|
206
|
+
const t = await e.preferences.getExportableRecord(), i = JSON.stringify(t, null, 2);
|
|
207
|
+
e.modal.dialog(
|
|
208
|
+
{
|
|
209
|
+
title: "Save to file",
|
|
210
|
+
content: /* @__PURE__ */ r("div", { children: [
|
|
211
|
+
/* @__PURE__ */ r("label", { htmlFor: "data", children: "Your InPageEdit preferences:" }),
|
|
212
|
+
/* @__PURE__ */ r(
|
|
213
|
+
"textarea",
|
|
214
|
+
{
|
|
215
|
+
name: "data",
|
|
216
|
+
id: "data",
|
|
217
|
+
rows: 10,
|
|
218
|
+
value: i,
|
|
219
|
+
readOnly: !0,
|
|
220
|
+
style: { width: "100%" }
|
|
221
|
+
}
|
|
222
|
+
)
|
|
223
|
+
] }),
|
|
224
|
+
buttons: [
|
|
225
|
+
{
|
|
226
|
+
label: "Copy",
|
|
227
|
+
method: (s, l) => {
|
|
228
|
+
navigator.clipboard.writeText(i), e.modal.notify("success", {
|
|
229
|
+
content: "Copied to clipboard"
|
|
230
|
+
}), l.close();
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
label: "Download",
|
|
235
|
+
method: (s, l) => {
|
|
236
|
+
const c = document.createElement("a");
|
|
237
|
+
c.href = `data:text/json;charset=utf-8,${encodeURIComponent(i)}`, c.download = `ipe-prefs-${(/* @__PURE__ */ new Date()).toISOString()}.json`, c.click(), l.close();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
() => {
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
},
|
|
246
|
+
children: "Save as file"
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
] })
|
|
250
|
+
] })
|
|
251
|
+
] });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
stop() {
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* 获取用户页配置文件的标题
|
|
259
|
+
*/
|
|
260
|
+
getUserPrefsPageTitle() {
|
|
261
|
+
try {
|
|
262
|
+
const e = this.ctx.wiki?.userInfo?.name;
|
|
263
|
+
return e ? this.ctx.wikiTitle.newTitle(`User:${e}/ipe-prefs.json`, 2) : null;
|
|
264
|
+
} catch {
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 从用户页加载配置
|
|
270
|
+
*/
|
|
271
|
+
async importFromUserPage() {
|
|
272
|
+
const e = this.getUserPrefsPageTitle();
|
|
273
|
+
if (!e)
|
|
274
|
+
return this.logger.debug("Cannot get user page title, skipping load"), {};
|
|
275
|
+
try {
|
|
276
|
+
const n = e.getURL({ action: "raw", ctype: "application/json" }), o = await this.importFromUrl(n.toString());
|
|
277
|
+
return this.logger.info("Loaded preferences from user page:", e), o;
|
|
278
|
+
} catch (n) {
|
|
279
|
+
return this.logger.error("Failed to load preferences from user page:", n), {};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* 导出配置到用户页
|
|
284
|
+
*/
|
|
285
|
+
async exportToUserPage() {
|
|
286
|
+
const e = this.ctx, n = this.getUserPrefsPageTitle();
|
|
287
|
+
if (!n)
|
|
288
|
+
throw new Error("Cannot get user page title");
|
|
289
|
+
await e.preferencesUI.dispatchFormSave();
|
|
290
|
+
const o = await e.preferences.getExportableRecord(), t = JSON.stringify(o, null, 2);
|
|
291
|
+
try {
|
|
292
|
+
return await this.ctx.wikiPage.newBlankPage({
|
|
293
|
+
title: n.toString(),
|
|
294
|
+
ns: 2
|
|
295
|
+
// User namespace
|
|
296
|
+
}).edit({
|
|
297
|
+
text: t,
|
|
298
|
+
summary: "Update InPageEdit preferences",
|
|
299
|
+
watchlist: I.nochange
|
|
300
|
+
}), this.logger.info("Exported preferences to user page:", n), n;
|
|
301
|
+
} catch (i) {
|
|
302
|
+
throw this.logger.error("Failed to export preferences to user page:", i), i;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async importFromUrl(e) {
|
|
306
|
+
const n = await fetch(e);
|
|
307
|
+
if (!n.ok)
|
|
308
|
+
throw new Error(`HTTP ${n.status}: ${n.statusText}`);
|
|
309
|
+
const o = await n.blob();
|
|
310
|
+
return await this.importFromFile(o);
|
|
311
|
+
}
|
|
312
|
+
async importFromFile(e) {
|
|
313
|
+
const n = await e.text(), o = JSON.parse(n);
|
|
314
|
+
return await this.ctx.preferences.setMany(o);
|
|
315
|
+
}
|
|
316
|
+
notifyImportSuccess(e) {
|
|
317
|
+
const n = Object.keys(e ?? {}), o = n.length;
|
|
318
|
+
return this.ctx.modal.notify("success", {
|
|
319
|
+
title: "Preferences Imported",
|
|
320
|
+
content: /* @__PURE__ */ r("section", { children: [
|
|
321
|
+
/* @__PURE__ */ r("p", { children: [
|
|
322
|
+
"Successfully imported ",
|
|
323
|
+
o || "",
|
|
324
|
+
" ",
|
|
325
|
+
o !== 1 ? "settings" : "setting",
|
|
326
|
+
":"
|
|
327
|
+
] }),
|
|
328
|
+
/* @__PURE__ */ r("ol", { style: { listStyle: "auto", paddingLeft: "1em" }, children: n.map((t) => /* @__PURE__ */ r("li", { children: t }, t)) })
|
|
329
|
+
] })
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
y = T(_);
|
|
334
|
+
g = R(y, 0, "PluginPrefSync", b, g);
|
|
335
|
+
O(y, 1, g);
|
|
336
|
+
export {
|
|
337
|
+
g as PluginPrefSync
|
|
338
|
+
};
|
|
339
|
+
//# sourceMappingURL=PluginPrefSync-Ziogy_o-.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginPrefSync-Ziogy_o-.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 {userPageTitle && (\n <section>\n <h3>Backup your preferences via user page</h3>\n <p>\n <a href={userPageTitle?.getURL().toString()} target=\"_blank\">\n {userPageTitle?.getPrefixedText()} →\n </a>\n </p>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\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 <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud-up\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.57 .811 3.128 1.986\" />\n <path d=\"M19 22v-6\" />\n <path d=\"M22 19l-3 -3l-3 3\" />\n </svg>{' '}\n Backup\n </ActionButton>\n <ActionButton\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 <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"icon icon-tabler icons-tabler-outline icon-tabler-cloud-down\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99c1.38 0 2.573 .813 3.13 1.99\" />\n <path d=\"M19 16v6\" />\n <path d=\"M22 19l-3 3l-3 -3\" />\n </svg>{' '}\n Restore\n </ActionButton>\n </div>\n </section>\n )}\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","btn","modal","title","record","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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"}
|