@inpageedit/core 0.14.2 → 0.14.4
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/{BasePlugin-YOi2_vUo.js → BasePlugin-DD7l-5Xw.js} +2 -2
- package/dist/{BasePlugin-YOi2_vUo.js.map → BasePlugin-DD7l-5Xw.js.map} +1 -1
- package/dist/{PluginPrefSync-jTNlRQE-.js → PluginPrefSync-CbFuuC19.js} +3 -3
- package/dist/{PluginPrefSync-jTNlRQE-.js.map → PluginPrefSync-CbFuuC19.js.map} +1 -1
- package/dist/{PluginStoreApp-CGNxKXAN.js → PluginStoreApp-MbC3G9tu.js} +89 -85
- package/dist/PluginStoreApp-MbC3G9tu.js.map +1 -0
- package/dist/Preferences-C10tZMl1.js +2701 -0
- package/dist/Preferences-C10tZMl1.js.map +1 -0
- package/dist/{index-QtEF2mzS.js → index-B3jld2sl.js} +4 -4
- package/dist/{index-QtEF2mzS.js.map → index-B3jld2sl.js.map} +1 -1
- package/dist/{index-3NZkG2a3.js → index-BXNyXvre.js} +3 -3
- package/dist/{index-3NZkG2a3.js.map → index-BXNyXvre.js.map} +1 -1
- package/dist/{index-Dclp60EO.js → index-BanevHQ2.js} +3 -3
- package/dist/{index-Dclp60EO.js.map → index-BanevHQ2.js.map} +1 -1
- package/dist/index-BdHmr8jw.js +3090 -0
- package/dist/index-BdHmr8jw.js.map +1 -0
- package/dist/index-BjDTD66_.js +491 -0
- package/dist/index-BjDTD66_.js.map +1 -0
- package/dist/{index-D97lUU3h.js → index-BpQ6VGMz.js} +55 -55
- package/dist/index-BpQ6VGMz.js.map +1 -0
- package/dist/{index-D-fW3ESK.js → index-CnR6CqkM.js} +2 -2
- package/dist/{index-D-fW3ESK.js.map → index-CnR6CqkM.js.map} +1 -1
- package/dist/{index-DELHsLHS.js → index-DKCZDN-Q.js} +4 -4
- package/dist/{index-DELHsLHS.js.map → index-DKCZDN-Q.js.map} +1 -1
- package/dist/{index-BBNseJXG.js → index-DVOc6fB6.js} +3 -3
- package/dist/{index-BBNseJXG.js.map → index-DVOc6fB6.js.map} +1 -1
- package/dist/{index-D6zFqL2u.js → index-De25v1_Q.js} +3 -3
- package/dist/{index-D6zFqL2u.js.map → index-De25v1_Q.js.map} +1 -1
- package/dist/{index-BrYKe18j.js → index-DensW9qt.js} +3 -3
- package/dist/{index-BrYKe18j.js.map → index-DensW9qt.js.map} +1 -1
- package/dist/{index-DmLoihN1.js → index-WfXtYVMt.js} +134 -131
- package/dist/index-WfXtYVMt.js.map +1 -0
- package/dist/index.d.ts +21 -14
- package/dist/index.js +5 -5
- package/dist/models/index.js +7 -503
- package/dist/models/index.js.map +1 -1
- package/dist/plugins/index.js +10 -10
- package/dist/services/index.js +1 -1
- package/dist/style.css +1 -1
- package/lib/index.umd.js +11 -11
- package/lib/index.umd.js.map +1 -1
- package/lib/style.css +1 -1
- package/package.json +1 -1
- package/dist/PluginStoreApp-CGNxKXAN.js.map +0 -1
- package/dist/Preferences-BF2fcXrn.js +0 -1539
- package/dist/Preferences-BF2fcXrn.js.map +0 -1
- package/dist/index-C3m6ng6b.js +0 -4245
- package/dist/index-C3m6ng6b.js.map +0 -1
- package/dist/index-D97lUU3h.js.map +0 -1
- package/dist/index-DmLoihN1.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as n } from "./Preferences-
|
|
1
|
+
import { f as n } from "./Preferences-C10tZMl1.js";
|
|
2
2
|
class l {
|
|
3
3
|
constructor(e, t = void 0, h) {
|
|
4
4
|
this.ctx = e, this.disposeHandlers = [], this.name = h || "", this.config = t || {};
|
|
@@ -52,4 +52,4 @@ class l {
|
|
|
52
52
|
export {
|
|
53
53
|
l as B
|
|
54
54
|
};
|
|
55
|
-
//# sourceMappingURL=BasePlugin-
|
|
55
|
+
//# sourceMappingURL=BasePlugin-DD7l-5Xw.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BasePlugin-
|
|
1
|
+
{"version":3,"file":"BasePlugin-DD7l-5Xw.js","sources":["../src/plugins/BasePlugin.ts"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport type { Logger } from '@inpageedit/logger'\nimport { snakeCase } from '@/utils/string'\n\ninterface DisposeHandler {\n (ctx: InPageEdit): Promise<void> | void\n}\n\nexport default class BasePlugin<ConfigType extends unknown = any> {\n #name!: string\n public config: ConfigType\n private disposeHandlers: DisposeHandler[] = []\n /** 依赖注入 */\n static inject?: Inject = []\n /** 可重用? */\n static reusable = false\n /** 插件的偏好设置模式 */\n static PreferencesSchema?: Schema\n\n constructor(\n public ctx: InPageEdit,\n config: ConfigType = undefined as unknown as ConfigType,\n name?: string\n ) {\n this.name = name || ''\n this.config = config || ({} as ConfigType)\n const { promise, resolve, reject } = Promise.withResolvers<void>()\n queueMicrotask(() => {\n if (!this.name) {\n this.name = this.constructor.name\n }\n try {\n const ret = this.start()\n if (ret && typeof (ret as Promise<unknown>).then === 'function') {\n ;(ret as Promise<unknown>)\n .then(() => resolve())\n .catch((err) => {\n this.logger.error('start() returns a rejected promise', err)\n reject(err)\n })\n } else {\n resolve()\n }\n } catch (err) {\n this.logger.error('start() threw synchronously', err)\n reject(err)\n }\n\n promise.then(() => {\n this.logger.debug('started')\n })\n promise.catch((e) => {\n this.logger.error('start failed', e)\n this.ctx.scope.dispose()\n })\n })\n this.ctx.once('dispose', () => {\n this.disposeHandlers.forEach((fn) => fn(this.ctx))\n this.stop()\n this.logger.debug('disposed')\n })\n }\n\n protected start(): Promise<void> | void {}\n protected stop(): Promise<void> | void {}\n protected addDisposeHandler(fn: DisposeHandler): void {\n this.disposeHandlers.push(fn)\n }\n protected removeDisposeHandler(fn: DisposeHandler): void {\n this.disposeHandlers = this.disposeHandlers.filter((f) => f !== fn)\n }\n\n set name(name: string) {\n this.#name = snakeCase(name).toUpperCase()\n }\n get name(): string {\n return this.#name\n }\n\n get logger(): Logger {\n return this.ctx.logger(this.name)\n }\n}\n"],"names":["BasePlugin","ctx","config","name","promise","resolve","reject","ret","err","e","fn","#name","f","snakeCase"],"mappings":";AAQA,MAAqBA,EAA6C;AAAA,EAWhE,YACSC,GACPC,IAAqB,QACrBC,GACA;AAHO,SAAA,MAAAF,GATT,KAAQ,kBAAoC,CAAA,GAa1C,KAAK,OAAOE,KAAQ,IACpB,KAAK,SAASD,KAAW,CAAA;AACzB,UAAM,EAAE,SAAAE,GAAS,SAAAC,GAAS,QAAAC,EAAA,IAAW,QAAQ,cAAA;AAC7C,mBAAe,MAAM;AACnB,MAAK,KAAK,SACR,KAAK,OAAO,KAAK,YAAY;AAE/B,UAAI;AACF,cAAMC,IAAM,KAAK,MAAA;AACjB,QAAIA,KAAO,OAAQA,EAAyB,QAAS,aACjDA,EACC,KAAK,MAAMF,EAAA,CAAS,EACpB,MAAM,CAACG,MAAQ;AACd,eAAK,OAAO,MAAM,sCAAsCA,CAAG,GAC3DF,EAAOE,CAAG;AAAA,QACZ,CAAC,IAEHH,EAAA;AAAA,MAEJ,SAASG,GAAK;AACZ,aAAK,OAAO,MAAM,+BAA+BA,CAAG,GACpDF,EAAOE,CAAG;AAAA,MACZ;AAEA,MAAAJ,EAAQ,KAAK,MAAM;AACjB,aAAK,OAAO,MAAM,SAAS;AAAA,MAC7B,CAAC,GACDA,EAAQ,MAAM,CAACK,MAAM;AACnB,aAAK,OAAO,MAAM,gBAAgBA,CAAC,GACnC,KAAK,IAAI,MAAM,QAAA;AAAA,MACjB,CAAC;AAAA,IACH,CAAC,GACD,KAAK,IAAI,KAAK,WAAW,MAAM;AAC7B,WAAK,gBAAgB,QAAQ,CAACC,MAAOA,EAAG,KAAK,GAAG,CAAC,GACjD,KAAK,KAAA,GACL,KAAK,OAAO,MAAM,UAAU;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA,EApDAC;AAAA,EAIA,OAAA;AAAA,SAAO,SAAkB,CAAA;AAAA,EAAC;AAAA,EAE1B,OAAA;AAAA,SAAO,WAAW;AAAA,EAAA;AAAA,EAgDR,QAA8B;AAAA,EAAC;AAAA,EAC/B,OAA6B;AAAA,EAAC;AAAA,EAC9B,kBAAkBD,GAA0B;AACpD,SAAK,gBAAgB,KAAKA,CAAE;AAAA,EAC9B;AAAA,EACU,qBAAqBA,GAA0B;AACvD,SAAK,kBAAkB,KAAK,gBAAgB,OAAO,CAACE,MAAMA,MAAMF,CAAE;AAAA,EACpE;AAAA,EAEA,IAAI,KAAKP,GAAc;AACrB,SAAKQ,KAAQE,EAAUV,CAAI,EAAE,YAAA;AAAA,EAC/B;AAAA,EACA,IAAI,OAAe;AACjB,WAAO,KAAKQ;AAAA,EACd;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK,IAAI,OAAO,KAAK,IAAI;AAAA,EAClC;AACF;"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { j as r } from "./index-CM_6yF2v.js";
|
|
2
2
|
import { W as k } from "./WatchlistAction-BbNAyryN.js";
|
|
3
|
-
import { B as I } from "./BasePlugin-
|
|
3
|
+
import { B as I } from "./BasePlugin-DD7l-5Xw.js";
|
|
4
4
|
import { A as f } from "./ActionButton-CRjo_l3y.js";
|
|
5
|
-
import { I as U } from "./Preferences-
|
|
5
|
+
import { I as U } from "./Preferences-C10tZMl1.js";
|
|
6
6
|
var L = Object.create, w = Object.defineProperty, C = Object.getOwnPropertyDescriptor, v = (i, e) => (e = Symbol[i]) ? e : Symbol.for("Symbol." + i), x = (i) => {
|
|
7
7
|
throw TypeError(i);
|
|
8
8
|
}, E = (i, e, t) => e in i ? w(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, F = (i, e) => w(i, "name", { value: e, configurable: !0 }), T = (i) => [, , , L(i?.[v("metadata")] ?? null)], j = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], S = (i) => i !== void 0 && typeof i != "function" ? x("Function expected") : i, M = (i, e, t, s, n) => ({ kind: j[i], name: e, metadata: s, addInitializer: (o) => t._ ? x("Already initialized") : n.push(S(o || null)) }), D = (i, e) => E(e, v("metadata"), i[3]), O = (i, e, t, s) => {
|
|
@@ -334,4 +334,4 @@ O(y, 1, m);
|
|
|
334
334
|
export {
|
|
335
335
|
m as PluginPrefSync
|
|
336
336
|
};
|
|
337
|
-
//# sourceMappingURL=PluginPrefSync-
|
|
337
|
+
//# sourceMappingURL=PluginPrefSync-CbFuuC19.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginPrefSync-jTNlRQE-.js","sources":["../src/plugins/preferences-ui/PluginPrefSync.tsx"],"sourcesContent":["import { Inject, InPageEdit } 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', 'wiki', '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 const $ = 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 = (\n <input type=\"url\" style={{ width: '100%' }}></input>\n ) as HTMLInputElement\n const modal = ctx.preferencesUI.getCurrentModal()\n ctx.modal.confirm(\n {\n title: $`Import from URL`,\n content: (\n <div className=\"ipe-input-box\">\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 $ = this.ctx.$\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 {$({\n count,\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":";;;;;;;;;;;;;;;;GAAAA,GAAAC,GAAAC;AAUAF,IAAA,CAACG,EAAO,CAAC,eAAe,QAAQ,YAAY,aAAa,SAAS,iBAAiB,GAAG,CAAC,CAAA;AAChF,MAAMC,WAAuBF,IAAAG,GAAW;AAAA,EAC7C,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,WAAW,GADT,KAAA,MAAAA,GAEjBA,EAAI,IAAI,YAAY,IAAI;AAAA,EAC1B;AAAA,EAEU,QAA8B;AACtC,UAAMA,IAAM,KAAK,KACXC,IAAID,EAAI;AACd,IAAAA,EAAI,YAAY,eAAe;AAAA,MAC7B,MAAM;AAAA,MACN,OAAOC;AAAA,MACP,aAAaA;AAAA,MACb,OAAO;AAAA,MACP,gBAAgB,MAAM;AACpB,cAAMC,IAAgB,KAAK,sBAAA;AAC3B,eACEC,gBAAAA,EAAC,OAAA,EAAI,WAAU,mBACZ,UAAA;AAAA,UAAAD,uBACE,WAAA,EACC,UAAA;AAAA,YAAA,gBAAAE,EAAC,QAAI,UAAAH,yCAAA,CAAyC;AAAA,YAC9C,gBAAAG,EAAC,KAAA,EACC,UAAAD,gBAAAA,EAAC,KAAA,EAAE,MAAMD,GAAe,OAAA,EAAS,SAAA,GAAY,QAAO,UACjD,UAAA;AAAA,cAAAA,GAAe,gBAAA;AAAA,cAAkB;AAAA,YAAA,EAAA,CACpC,EAAA,CACF;AAAA,YACAC,gBAAAA,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,OAAA,GAC3D,UAAA;AAAA,cAAAA,gBAAAA;AAAAA,gBAACE;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,CAACC,MAAM;AACd,oBAAAA,EAAE,eAAA;AACF,0BAAMC,IAAMD,EAAE;AACd,oBAAAC,EAAI,WAAW;AACf,0BAAMC,IAAQR,EAAI,cAAc,gBAAA;AAChC,oBAAAQ,GAAO,gBAAgB,EAAI,GAC3B,KAAK,iBAAA,EACF,KAAK,CAACC,MAAU;AACf,sBAAAT,EAAI,MAAM,OAAO,WAAW;AAAA,wBAC1B,OAAOC;AAAA,wBACP,2BACG,KAAA,EAAE,UAAA;AAAA,0BAAA;AAAA,0BACsC;AAAA,0BACvC,gBAAAG,EAAC,KAAA,EAAE,MAAMK,EAAM,OAAA,EAAS,YAAY,QAAO,UACxC,UAAAA,EAAM,gBAAA,EAAgB,CACzB;AAAA,0BAAI;AAAA,wBAAA,EAAA,CAEN;AAAA,sBAAA,CAEH;AAAA,oBACH,CAAC,EACA,QAAQ,MAAM;AACb,sBAAAF,EAAI,WAAW,IACfC,GAAO,gBAAgB,EAAK;AAAA,oBAC9B,CAAC;AAAA,kBACL;AAAA,kBAEA,UAAA;AAAA,oBAAAL,gBAAAA;AAAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,OAAM;AAAA,wBACN,OAAM;AAAA,wBACN,QAAO;AAAA,wBACP,SAAQ;AAAA,wBACR,MAAK;AAAA,wBACL,QAAO;AAAA,wBACP,gBAAa;AAAA,wBACb,kBAAe;AAAA,wBACf,mBAAgB;AAAA,wBAChB,OAAM;AAAA,wBAEN,UAAA;AAAA,0BAAA,gBAAAC,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,0BAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,sOAAA,CAAsO;AAAA,0BAC9O,gBAAAA,EAAC,QAAA,EAAK,GAAE,YAAA,CAAY;AAAA,0BACpB,gBAAAA,EAAC,QAAA,EAAK,GAAE,oBAAA,CAAoB;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBACvB;AAAA,oBACNH;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEHE,gBAAAA;AAAAA,gBAACE;AAAA,gBAAA;AAAA,kBACC,SAAS,CAACC,MAAM;AACd,oBAAAA,EAAE,eAAA;AACF,0BAAME,IAAQR,EAAI,cAAc,gBAAA,GAC1BO,IAAMD,EAAE;AACd,oBAAAC,EAAI,WAAW,IACfC,GAAO,gBAAgB,EAAI,GAC3B,KAAK,mBAAA,EACF,KAAK,CAACE,MAAW;AAChB,2BAAK,oBAAoBA,CAAM;AAAA,oBACjC,CAAC,EACA,QAAQ,MAAM;AACb,sBAAAH,EAAI,WAAW,IACfC,GAAO,gBAAgB,EAAK;AAAA,oBAC9B,CAAC;AAAA,kBACL;AAAA,kBAEA,UAAA;AAAA,oBAAAL,gBAAAA;AAAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,OAAM;AAAA,wBACN,OAAM;AAAA,wBACN,QAAO;AAAA,wBACP,SAAQ;AAAA,wBACR,MAAK;AAAA,wBACL,QAAO;AAAA,wBACP,gBAAa;AAAA,wBACb,kBAAe;AAAA,wBACf,mBAAgB;AAAA,wBAChB,OAAM;AAAA,wBAEN,UAAA;AAAA,0BAAA,gBAAAC,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,0BAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,qOAAA,CAAqO;AAAA,0BAC7O,gBAAAA,EAAC,QAAA,EAAK,GAAE,WAAA,CAAW;AAAA,0BACnB,gBAAAA,EAAC,QAAA,EAAK,GAAE,oBAAA,CAAoB;AAAA,wBAAA;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBACvB;AAAA,oBACNH;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH,EAAA,CACF;AAAA,UAAA,GACF;AAAA,4BAED,WAAA,EACC,UAAA;AAAA,YAAA,gBAAAG,EAAC,QAAI,UAAAH,iCAAA,CAAiC;AAAA,YACtCE,gBAAAA,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,OAAA,GAC3D,UAAA;AAAA,cAAA,gBAAAC;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAACC,MAAM;AACd,oBAAAA,EAAE,eAAA;AACF,0BAAME,IAAQR,EAAI,cAAc,gBAAA;AAChC,oBAAAQ,GAAO,gBAAgB,EAAI;AAC3B,0BAAMG,IAAQ,SAAS,cAAc,OAAO;AAC5C,oBAAAA,EAAM,OAAO,QACbA,EAAM,SAAS;AAMf,wBAAIC,IAAU;AACd,0BAAMC,IAAgB,MAAM;AAE1B,sBAAKD,KACHJ,GAAO,gBAAgB,EAAK,GAE9B,OAAO,oBAAoB,SAASK,CAAa;AAAA,oBACnD;AACA,2BAAO,iBAAiB,SAASA,GAAe,EAAE,MAAM,IAAM,GAE9DF,EAAM,iBAAiB,UAAU,OAAOL,MAAM;AAC5C,sBAAAM,IAAU;AACV,0BAAI;AACF,8BAAME,IAAQR,EAAE,OAA4B,QAAQ,CAAC;AACrD,4BAAI,CAACQ;AACH;AAEF,8BAAMJ,IAAS,MAAM,KAAK,eAAeI,CAAI;AAC7C,6BAAK,oBAAoBJ,CAAM;AAAA,sBACjC,SAASJ,GAAG;AACV,wBAAAN,EAAI,MAAM,OAAO,SAAS;AAAA,0BACxB,OAAO;AAAA,0BACP,SAASM,aAAa,QAAQA,EAAE,UAAU,OAAOA,CAAC;AAAA,wBAAA,CACnD;AAAA,sBACH,UAAA;AACE,wBAAAE,GAAO,gBAAgB,EAAK;AAAA,sBAC9B;AAAA,oBACF,CAAC,GACDG,EAAM,MAAA;AAAA,kBACR;AAAA,kBAEC,UAAAV;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEH,gBAAAG;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBACC,SAAS,CAACC,MAAM;AACd,oBAAAA,EAAE,eAAA;AACF,0BAAMK,sBACH,SAAA,EAAM,MAAK,OAAM,OAAO,EAAE,OAAO,OAAA,GAAU,GAExCH,IAAQR,EAAI,cAAc,gBAAA;AAChC,oBAAAA,EAAI,MAAM;AAAA,sBACR;AAAA,wBACE,OAAOC;AAAA,wBACP,SACEE,gBAAAA,EAAC,OAAA,EAAI,WAAU,iBACb,UAAA;AAAA,0BAAA,gBAAAC,EAAC,SAAA,EAAM,SAAQ,aACZ,UAAAH,gDACH;AAAA,0BACCU;AAAA,wBAAA,EAAA,CACH;AAAA,sBAAA;AAAA,sBAGJ,OAAOI,MAAW;AAChB,8BAAMC,IAAML,EAAM,MAAM,KAAA;AACxB,4BAAI,GAACI,KAAU,CAACC;AAGhB,8BAAI;AACF,4BAAAR,GAAO,gBAAgB,EAAI;AAC3B,kCAAME,IAAS,MAAM,KAAK,cAAcM,CAAG;AAC3C,iCAAK,oBAAoBN,CAAM;AAAA,0BACjC,SAASJ,GAAG;AACV,4BAAAN,EAAI,MAAM,OAAO,SAAS;AAAA,8BACxB,OAAO;AAAA,8BACP,SAASM,aAAa,QAAQA,EAAE,UAAU,OAAOA,CAAC;AAAA,4BAAA,CACnD;AAAA,0BACH,UAAA;AACE,4BAAAE,GAAO,gBAAgB,EAAK;AAAA,0BAC9B;AAAA,sBACF;AAAA,oBAAA;AAAA,kBAEJ;AAAA,kBAEC,UAAAP;AAAA,gBAAA;AAAA,cAAA;AAAA,cAEH,gBAAAG;AAAA,gBAACC;AAAA,gBAAA;AAAA,kBACC,SAAS,OAAOC,MAAM;AACpB,oBAAAA,EAAE,eAAA,GAEF,MAAMN,EAAI,cAAc,iBAAA;AACxB,0BAAMiB,IAAO,MAAMjB,EAAI,YAAY,oBAAA,GAC7BkB,IAAO,KAAK,UAAUD,GAAM,MAAM,CAAC;AACzC,oBAAAjB,EAAI,MAAM;AAAA,sBACR;AAAA,wBACE,OAAOC;AAAA,wBACP,2BACG,OAAA,EACC,UAAA;AAAA,0BAAA,gBAAAG,EAAC,SAAA,EAAM,SAAQ,QAAQ,UAAAH,iCAAgC;AAAA,0BACvD,gBAAAG;AAAA,4BAAC;AAAA,4BAAA;AAAA,8BACC,MAAK;AAAA,8BACL,IAAG;AAAA,8BACH,MAAM;AAAA,8BACN,OAAOc;AAAA,8BACP,UAAQ;AAAA,8BACR,OAAO,EAAE,OAAO,OAAA;AAAA,4BAAO;AAAA,0BAAA;AAAA,wBACxB,GACH;AAAA,wBAEF,SAAS;AAAA,0BACP;AAAA,4BACE,OAAO;AAAA,4BACP,QAAQ,CAACC,GAAGC,MAAM;AAChB,wCAAU,UAAU,UAAUF,CAAI,GAClClB,EAAI,MAAM,OAAO,WAAW;AAAA,gCAC1B,SAASC;AAAA,8BAAA,CACV,GACDmB,EAAE,MAAA;AAAA,4BACJ;AAAA,0BAAA;AAAA,0BAEF;AAAA,4BACE,OAAOnB;AAAA,4BACP,QAAQ,CAACkB,GAAGC,MAAM;AAChB,oCAAMC,IAAI,SAAS,cAAc,GAAG;AACpC,8BAAAA,EAAE,OAAO,gCAAgC,mBAAmBH,CAAI,CAAC,IACjEG,EAAE,WAAW,cAAa,oBAAI,QAAO,aAAa,SAClDA,EAAE,MAAA,GACFD,EAAE,MAAA;AAAA,4BACJ;AAAA,0BAAA;AAAA,wBACF;AAAA,sBACF;AAAA,sBAEF,MAAM;AAAA,sBAAC;AAAA,oBAAA;AAAA,kBAEX;AAAA,kBAEC,UAAAnB;AAAA,gBAAA;AAAA,cAAA;AAAA,YACH,EAAA,CACF;AAAA,UAAA,EAAA,CACF;AAAA,QAAA,GACF;AAAA,MAEJ;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEU,OAA6B;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAKhC,wBAA2C;AACjD,QAAI;AACF,YAAMqB,IAAW,KAAK,IAAI,MAAM,UAAU;AAC1C,aAAKA,IAIE,KAAK,IAAI,UAAU,SAAS,QAAQA,CAAQ,mBAAmB,CAAC,IAH9D;AAAA,IAIX,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,qBAAuD;AAC3D,UAAMb,IAAQ,KAAK,sBAAA;AACnB,QAAI,CAACA;AACH,kBAAK,OAAO,MAAM,2CAA2C,GACtD,CAAA;AAGT,QAAI;AAEF,YAAMc,IAASd,EAAM,OAAO,EAAE,QAAQ,OAAO,OAAO,oBAAoB,GAClEe,IAAU,MAAM,KAAK,cAAcD,EAAO,UAAU;AAC1D,kBAAK,OAAO,KAAK,sCAAsCd,CAAK,GACrDe;AAAA,IACT,SAASC,GAAO;AACd,kBAAK,OAAO,MAAM,8CAA8CA,CAAK,GAC9D,CAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBAAwC;AAC5C,UAAMzB,IAAM,KAAK,KACXS,IAAQ,KAAK,sBAAA;AACnB,QAAI,CAACA;AACH,YAAM,IAAI,MAAM,4BAA4B;AAI9C,UAAMT,EAAI,cAAc,iBAAA;AAExB,UAAMkB,IAAO,MAAMlB,EAAI,YAAY,oBAAA,GAC7B0B,IAAO,KAAK,UAAUR,GAAM,MAAM,CAAC;AAEzC,QAAI;AAKF,mBAJa,KAAK,IAAI,SAAS,aAAa;AAAA,QAC1C,OAAOT,EAAM,SAAA;AAAA,QACb,IAAI;AAAA;AAAA,MAAA,CACL,EACU,KAAK;AAAA,QACd,MAAAiB;AAAA,QACA,SAAS;AAAA,QACT,WAAWC,EAAgB;AAAA,MAAA,CAC5B,GAED,KAAK,OAAO,KAAK,sCAAsClB,CAAK,GACrDA;AAAA,IACT,SAASgB,GAAO;AACd,iBAAK,OAAO,MAAM,8CAA8CA,CAAK,GAC/DA;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,cAAcd,GAAiD;AACnE,UAAMiB,IAAW,MAAM,MAAMjB,CAAK;AAClC,QAAI,CAACiB,EAAS;AACZ,YAAM,IAAI,MAAM,QAAQA,EAAS,MAAM,KAAKA,EAAS,UAAU,EAAE;AAEnE,UAAMC,IAAO,MAAMD,EAAS,KAAA;AAE5B,WADgB,MAAM,KAAK,eAAeC,CAAI;AAAA,EAEhD;AAAA,EAEA,MAAM,eAAelB,GAA+C;AAClE,UAAMe,IAAO,MAAMf,EAAM,KAAA,GACnBM,IAAO,KAAK,MAAMS,CAAI;AAE5B,WADgB,MAAM,KAAK,IAAI,YAAY,QAAQT,CAAI;AAAA,EAEzD;AAAA,EAEQ,oBAAoBa,GAAmC;AAC7D,UAAM7B,IAAI,KAAK,IAAI,GACb8B,IAAO,OAAO,KAAKD,KAAW,CAAA,CAAE,GAChCE,IAAQD,EAAK;AACnB,WAAO,KAAK,IAAI,MAAM,OAAO,WAAW;AAAA,MACtC,OAAO9B;AAAA,MACP,2BACG,WAAA,EACC,UAAA;AAAA,QAAA,gBAAAG,EAAC,OACE,UAAAH,EAAE;AAAA,UACD,OAAA+B;AAAA,QAAA,CACD,gFACH;AAAA,0BACC,MAAA,EAAG,OAAO,EAAE,WAAW,QAAQ,aAAa,MAAA,GAC1C,UAAAD,EAAK,IAAI,CAACE,MACT,gBAAA7B,EAAC,QAAc,UAAA6B,EAAA,GAANA,CAAU,CACpB,EAAA,CACH;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,CAEH;AAAA,EACH;AACF;AA3XOtC,IAAAuC,EAAAtC,CAAA;AAAME,IAANqC,0BADPzC,GACaI,CAAA;AAANsC,EAAAzC,GAAA,GAAMG,CAAA;"}
|
|
1
|
+
{"version":3,"file":"PluginPrefSync-CbFuuC19.js","sources":["../src/plugins/preferences-ui/PluginPrefSync.tsx"],"sourcesContent":["import { Inject, InPageEdit } 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', 'wiki', '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 const $ = 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 = (\n <input type=\"url\" style={{ width: '100%' }}></input>\n ) as HTMLInputElement\n const modal = ctx.preferencesUI.getCurrentModal()\n ctx.modal.confirm(\n {\n title: $`Import from URL`,\n content: (\n <div className=\"ipe-input-box\">\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 $ = this.ctx.$\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 {$({\n count,\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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"}
|