@inpageedit/core 0.17.3 → 0.17.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/InPageEdit.js +1 -1
- package/dist/{PluginImagesUsed-DWpe6M-r.js → PluginImagesUsed-DIsW4sQH.js} +2 -2
- package/dist/{PluginImagesUsed-DWpe6M-r.js.map → PluginImagesUsed-DIsW4sQH.js.map} +1 -1
- package/dist/{PluginPrefSync-CmVHL2wx.js → PluginPrefSync-BM1-tOBL.js} +2 -2
- package/dist/{PluginPrefSync-CmVHL2wx.js.map → PluginPrefSync-BM1-tOBL.js.map} +1 -1
- package/dist/{PluginStoreApp-CmLstT3F.js → PluginStoreApp-By2yV_Kl.js} +2 -2
- package/dist/{PluginStoreApp-CmLstT3F.js.map → PluginStoreApp-By2yV_Kl.js.map} +1 -1
- package/dist/{PluginTemplatesUsed-BjRYFXHz.js → PluginTemplatesUsed-BhNX1xSY.js} +2 -2
- package/dist/{PluginTemplatesUsed-BjRYFXHz.js.map → PluginTemplatesUsed-BhNX1xSY.js.map} +1 -1
- package/dist/core.js +2 -2
- package/dist/{index-CkSdNy0U.js → index-B5KNZ_9z.js} +2 -2
- package/dist/{index-CkSdNy0U.js.map → index-B5KNZ_9z.js.map} +1 -1
- package/dist/{index-DTU2DZU6.js → index-BAJiXDPz.js} +14 -14
- package/dist/{index-DTU2DZU6.js.map → index-BAJiXDPz.js.map} +1 -1
- package/dist/{index-BVMm7Dix.js → index-BFdMEvlW.js} +2 -2
- package/dist/{index-BVMm7Dix.js.map → index-BFdMEvlW.js.map} +1 -1
- package/dist/{index-JvsrhizC.js → index-Bd_cTayA.js} +3 -3
- package/dist/{index-JvsrhizC.js.map → index-Bd_cTayA.js.map} +1 -1
- package/dist/{index-BbvMbIgz.js → index-Bf8jOXlz.js} +3 -3
- package/dist/{index-BbvMbIgz.js.map → index-Bf8jOXlz.js.map} +1 -1
- package/dist/{index-CUDVeUEv.js → index-BoVgsh8u.js} +2 -2
- package/dist/{index-CUDVeUEv.js.map → index-BoVgsh8u.js.map} +1 -1
- package/dist/{index-BlVSMvH-.js → index-CZfEZBOj.js} +2 -2
- package/dist/{index-BlVSMvH-.js.map → index-CZfEZBOj.js.map} +1 -1
- package/dist/{index-Dfdy54gH.js → index-CoX1x5ls.js} +2 -2
- package/dist/{index-Dfdy54gH.js.map → index-CoX1x5ls.js.map} +1 -1
- package/dist/{index-DvFkW8lL.js → index-D8_-baBt.js} +2 -2
- package/dist/{index-DvFkW8lL.js.map → index-D8_-baBt.js.map} +1 -1
- package/dist/{index-LvMaeDQn.js → index-DHitL1S2.js} +2 -2
- package/dist/{index-LvMaeDQn.js.map → index-DHitL1S2.js.map} +1 -1
- package/dist/{index-D-8cyCdX.js → index-QZjXZBoj.js} +31 -27
- package/dist/index-QZjXZBoj.js.map +1 -0
- package/dist/{index-BYgh1HkH.js → index-S6Jhp39r.js} +2 -2
- package/dist/{index-BYgh1HkH.js.map → index-S6Jhp39r.js.map} +1 -1
- package/dist/{index-Ce-zc5RR.js → index-ruv3nAtX.js} +2 -2
- package/dist/{index-Ce-zc5RR.js.map → index-ruv3nAtX.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/plugins/index.js +12 -12
- package/dist/services/index.js +1 -1
- package/lib/index.umd.js +2 -2
- package/lib/index.umd.js.map +1 -1
- package/package.json +1 -1
- package/dist/index-D-8cyCdX.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-CUDVeUEv.js","sources":["../src/plugins/quick-preview/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport { type QuickEditEventPayload } from '@/plugins/quick-edit'\nimport { IWikiPage } from '@/models/WikiPage'\nimport { MwApiParams } from 'wiki-saikou'\nimport { PageParseData } from '@/models/WikiPage/types/PageParseData'\nimport { IPEModal, IPEModalOptions } from '@inpageedit/modal'\n\nimport './style.scss'\n\ninterface QuickPreviewEventPayload {\n ctx: InPageEdit\n modal: IPEModal\n wikiPage: IWikiPage\n text: string\n parseData: PageParseData\n}\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickPreview: PluginQuickPreview & {\n // for backward compatibility\n (\n ...args: Parameters<PluginQuickPreview['previewWikitext']>\n ): ReturnType<PluginQuickPreview['previewWikitext']>\n }\n }\n interface Events {\n 'quick-preview/show-modal'(payload: Omit<QuickPreviewEventPayload, 'parseData'>): void\n 'quick-preview/loaded'(payload: QuickPreviewEventPayload): void\n }\n interface PreferencesMap {\n 'quickPreview.keyshortcut.quickEdit': string\n 'quickPreview.keyshortcut.quickDelete': string\n }\n}\n\n@Inject(['api', 'wikiPage', 'modal', 'preferences', '$'])\n@RegisterPreferences(\n Schema.object({\n 'quickPreview.keyshortcut': Schema.string()\n .default('ctrl-i')\n .role('keyshortcut')\n .description('Key shortcut to open quick preview in quick edit modal'),\n })\n .extra('category', 'editor')\n .description('Quick preview options')\n)\nexport class PluginQuickPreview extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quickPreview')\n this.ctx.set('quickPreview', makeCallable(this, 'previewWikitext'))\n }\n\n protected start(): Promise<void> | void {\n this.ctx.on('quick-edit/wiki-page', this.injectQuickEdit.bind(this))\n }\n\n protected stop(): Promise<void> | void {}\n\n previewWikitext(\n text: string,\n params?: MwApiParams,\n wikiPage?: IWikiPage,\n modal?: IPEModal,\n modalOptions?: Partial<IPEModalOptions>\n ) {\n const { $ } = this.ctx\n\n wikiPage ||= this.ctx.wikiPage.newBlankPage({\n title: 'API',\n })\n\n if (!modal || modal.isDestroyed) {\n modal = this.ctx.modal\n .createObject({\n className: 'in-page-edit ipe-quickPreview',\n sizeClass: 'large',\n center: false,\n ...modalOptions,\n })\n .init()\n }\n\n modal.show()\n modal.setTitle($`Preview - Loading...`)\n modal.setContent(<ProgressBar />)\n modal.bringToFront()\n this.ctx.emit('quick-preview/show-modal', {\n ctx: this.ctx,\n text,\n modal,\n wikiPage,\n })\n\n wikiPage\n .preview(text, params)\n .then((ret) => {\n const {\n data: { parse },\n } = ret\n modal.setTitle($(parse.title)`Preview - {{ $1 }}`)\n let outputRef: HTMLElement | null = null\n modal.setContent(\n (\n <section>\n <div\n ref={(el) => (outputRef = el)}\n className=\"mw-parser-output\"\n innerHTML={parse.text}\n ></div>\n </section>\n ) as HTMLElement\n )\n if (window.mw?.hook && typeof jQuery === 'function') {\n window.mw.hook('wikipage.content').fire(jQuery(outputRef!))\n }\n this.ctx.emit('quick-preview/loaded', {\n ctx: this.ctx,\n modal,\n wikiPage,\n text,\n parseData: parse,\n })\n })\n .catch((error) => {\n modal.setTitle($`Preview - Failed`)\n modal.setContent(\n <>\n <p>{$`Failed to preview`}</p>\n <p>{error instanceof Error ? error.message : String(error)}</p>\n </>\n )\n })\n\n return modal\n }\n\n private async injectQuickEdit({ options, modal, wikiPage }: QuickEditEventPayload) {\n const { $ } = this.ctx\n let latestPreviewModal: IPEModal | undefined = undefined\n modal.addButton(\n {\n label: $`Preview`,\n side: 'left',\n className: 'btn btn-secondary',\n keyPress:\n (await this.ctx.preferences.get('quickPreview.keyshortcut.quickEdit')) || undefined,\n method: () => {\n let wikitext =\n (modal.get$content().querySelector<HTMLTextAreaElement>('textarea[name=\"text\"]')\n ?.value as string) || ''\n if (options.section === 'new') {\n const title = modal\n .get$content()\n .querySelector<HTMLInputElement>('input[name=\"summary\"]')?.value\n if (title) {\n wikitext = `==${title}==\\n${wikitext}`\n }\n }\n\n latestPreviewModal = this.previewWikitext(\n wikitext,\n undefined,\n wikiPage,\n latestPreviewModal,\n {\n backdrop: false,\n draggable: true,\n }\n )\n },\n },\n 1\n )\n modal.on(modal.Event.Close, () => {\n latestPreviewModal?.destroy()\n latestPreviewModal = undefined\n })\n }\n\n private _contentTypeCache = new Map<string, Promise<string>>()\n private fetchContentType(url: string) {\n const cached = this._contentTypeCache.get(url)\n if (cached) return cached\n const promise = fetch(url, { method: 'HEAD' })\n .then((res) => res.headers.get('content-type') || '')\n .catch(() => {\n this._contentTypeCache.delete(url)\n return ''\n })\n this._contentTypeCache.set(url, promise)\n return promise\n }\n async getPreviewType(fileOrUrl: File | string) {\n if (!fileOrUrl) return 'unknown'\n let contentType: string\n let ext: string\n if (fileOrUrl instanceof File) {\n contentType = fileOrUrl.type\n ext = fileOrUrl.name.split('.').pop()?.toLowerCase() || ''\n } else {\n const url = new URL(fileOrUrl, location.origin)\n if (url.protocol === 'data:' || url.protocol === 'blob:' || url.protocol.startsWith('http')) {\n contentType = await this.fetchContentType(url.href)\n } else {\n contentType = ''\n }\n ext = url.pathname.split('.').pop()?.toLowerCase() || ''\n }\n if (\n contentType.startsWith('image/') &&\n /** Windows provide PDFs as image/pdf */ !contentType.includes('pdf')\n ) {\n return 'image'\n }\n if (contentType.startsWith('video/')) return 'video'\n if (contentType.startsWith('audio/')) return 'audio'\n if (contentType.startsWith('text/html')) return 'html'\n if (ext === 'md') return 'markdown'\n if (contentType.startsWith('text/')) return 'text'\n // detect by file extension\n if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'ico', 'webp'].includes(ext)) return 'image'\n if (['mp4', 'webm', 'ogg', 'flv', 'avi', 'mov', 'wmv', 'mkv'].includes(ext)) return 'video'\n if (['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a', 'wma'].includes(ext)) return 'audio'\n if (['html', 'htm'].includes(ext)) return 'html'\n if (['json', 'yml', 'yaml', 'toml', 'py'].includes(ext)) return 'text'\n if (['pdf'].includes(ext)) return 'pdf'\n return 'unknown'\n }\n async previewFile(fileOrUrl: File | string, alt?: string) {\n const previewElement = await this.getPreviewElement(fileOrUrl, alt)\n if (!previewElement) return\n const modal = this.ctx.modal.dialog({\n className: 'in-page-edit ipe-quickPreview',\n sizeClass: 'mediumToLarge',\n center: true,\n title: alt ?? (fileOrUrl instanceof File ? fileOrUrl.name : fileOrUrl),\n content: <section className=\"ipe-quickPreview__content\">{previewElement}</section>,\n })\n return modal\n }\n private _objectUrls = new WeakMap<File, string>()\n private getObjectUrl(file: File) {\n if (!this._objectUrls.has(file)) {\n const objUrl = URL.createObjectURL(file)\n this._objectUrls.set(file, objUrl)\n }\n return this._objectUrls.get(file)!\n }\n async getPreviewElement(fileOrUrl: File | string, alt?: string) {\n const previewType = await this.getPreviewType(fileOrUrl)\n const url = fileOrUrl instanceof File ? this.getObjectUrl(fileOrUrl) : fileOrUrl\n switch (previewType) {\n case 'image':\n return (\n <img src={url} alt={alt ?? (fileOrUrl instanceof File ? fileOrUrl.name : fileOrUrl)} />\n )\n case 'video':\n return <video src={url} controls={true} aria-label={alt} />\n case 'audio':\n return <audio src={url} controls={true} aria-label={alt} />\n case 'pdf':\n return <embed type=\"application/pdf\" src={url} aria-label={alt} />\n }\n return null\n }\n\n previewWikiPage(title: string) {\n throw new Error('Not implemented')\n }\n}\n"],"names":["_PluginQuickPreview_decorators","_init","_a","Inject","RegisterPreferences","Schema","PluginQuickPreview","BasePlugin","ctx","makeCallable","text","params","wikiPage","modal","modalOptions","$","jsx","ProgressBar","ret","parse","outputRef","el","error","jsxs","Fragment","options","latestPreviewModal","wikitext","title","url","cached","promise","res","fileOrUrl","contentType","ext","alt","previewElement","file","objUrl","previewType","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-BoVgsh8u.js","sources":["../src/plugins/quick-preview/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport { type QuickEditEventPayload } from '@/plugins/quick-edit'\nimport { IWikiPage } from '@/models/WikiPage'\nimport { MwApiParams } from 'wiki-saikou'\nimport { PageParseData } from '@/models/WikiPage/types/PageParseData'\nimport { IPEModal, IPEModalOptions } from '@inpageedit/modal'\n\nimport './style.scss'\n\ninterface QuickPreviewEventPayload {\n ctx: InPageEdit\n modal: IPEModal\n wikiPage: IWikiPage\n text: string\n parseData: PageParseData\n}\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickPreview: PluginQuickPreview & {\n // for backward compatibility\n (\n ...args: Parameters<PluginQuickPreview['previewWikitext']>\n ): ReturnType<PluginQuickPreview['previewWikitext']>\n }\n }\n interface Events {\n 'quick-preview/show-modal'(payload: Omit<QuickPreviewEventPayload, 'parseData'>): void\n 'quick-preview/loaded'(payload: QuickPreviewEventPayload): void\n }\n interface PreferencesMap {\n 'quickPreview.keyshortcut.quickEdit': string\n 'quickPreview.keyshortcut.quickDelete': string\n }\n}\n\n@Inject(['api', 'wikiPage', 'modal', 'preferences', '$'])\n@RegisterPreferences(\n Schema.object({\n 'quickPreview.keyshortcut': Schema.string()\n .default('ctrl-i')\n .role('keyshortcut')\n .description('Key shortcut to open quick preview in quick edit modal'),\n })\n .extra('category', 'editor')\n .description('Quick preview options')\n)\nexport class PluginQuickPreview extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quickPreview')\n this.ctx.set('quickPreview', makeCallable(this, 'previewWikitext'))\n }\n\n protected start(): Promise<void> | void {\n this.ctx.on('quick-edit/wiki-page', this.injectQuickEdit.bind(this))\n }\n\n protected stop(): Promise<void> | void {}\n\n previewWikitext(\n text: string,\n params?: MwApiParams,\n wikiPage?: IWikiPage,\n modal?: IPEModal,\n modalOptions?: Partial<IPEModalOptions>\n ) {\n const { $ } = this.ctx\n\n wikiPage ||= this.ctx.wikiPage.newBlankPage({\n title: 'API',\n })\n\n if (!modal || modal.isDestroyed) {\n modal = this.ctx.modal\n .createObject({\n className: 'in-page-edit ipe-quickPreview',\n sizeClass: 'large',\n center: false,\n ...modalOptions,\n })\n .init()\n }\n\n modal.show()\n modal.setTitle($`Preview - Loading...`)\n modal.setContent(<ProgressBar />)\n modal.bringToFront()\n this.ctx.emit('quick-preview/show-modal', {\n ctx: this.ctx,\n text,\n modal,\n wikiPage,\n })\n\n wikiPage\n .preview(text, params)\n .then((ret) => {\n const {\n data: { parse },\n } = ret\n modal.setTitle($(parse.title)`Preview - {{ $1 }}`)\n let outputRef: HTMLElement | null = null\n modal.setContent(\n (\n <section>\n <div\n ref={(el) => (outputRef = el)}\n className=\"mw-parser-output\"\n innerHTML={parse.text}\n ></div>\n </section>\n ) as HTMLElement\n )\n if (window.mw?.hook && typeof jQuery === 'function') {\n window.mw.hook('wikipage.content').fire(jQuery(outputRef!))\n }\n this.ctx.emit('quick-preview/loaded', {\n ctx: this.ctx,\n modal,\n wikiPage,\n text,\n parseData: parse,\n })\n })\n .catch((error) => {\n modal.setTitle($`Preview - Failed`)\n modal.setContent(\n <>\n <p>{$`Failed to preview`}</p>\n <p>{error instanceof Error ? error.message : String(error)}</p>\n </>\n )\n })\n\n return modal\n }\n\n private async injectQuickEdit({ options, modal, wikiPage }: QuickEditEventPayload) {\n const { $ } = this.ctx\n let latestPreviewModal: IPEModal | undefined = undefined\n modal.addButton(\n {\n label: $`Preview`,\n side: 'left',\n className: 'btn btn-secondary',\n keyPress:\n (await this.ctx.preferences.get('quickPreview.keyshortcut.quickEdit')) || undefined,\n method: () => {\n let wikitext =\n (modal.get$content().querySelector<HTMLTextAreaElement>('textarea[name=\"text\"]')\n ?.value as string) || ''\n if (options.section === 'new') {\n const title = modal\n .get$content()\n .querySelector<HTMLInputElement>('input[name=\"summary\"]')?.value\n if (title) {\n wikitext = `==${title}==\\n${wikitext}`\n }\n }\n\n latestPreviewModal = this.previewWikitext(\n wikitext,\n undefined,\n wikiPage,\n latestPreviewModal,\n {\n backdrop: false,\n draggable: true,\n }\n )\n },\n },\n 1\n )\n modal.on(modal.Event.Close, () => {\n latestPreviewModal?.destroy()\n latestPreviewModal = undefined\n })\n }\n\n private _contentTypeCache = new Map<string, Promise<string>>()\n private fetchContentType(url: string) {\n const cached = this._contentTypeCache.get(url)\n if (cached) return cached\n const promise = fetch(url, { method: 'HEAD' })\n .then((res) => res.headers.get('content-type') || '')\n .catch(() => {\n this._contentTypeCache.delete(url)\n return ''\n })\n this._contentTypeCache.set(url, promise)\n return promise\n }\n async getPreviewType(fileOrUrl: File | string) {\n if (!fileOrUrl) return 'unknown'\n let contentType: string\n let ext: string\n if (fileOrUrl instanceof File) {\n contentType = fileOrUrl.type\n ext = fileOrUrl.name.split('.').pop()?.toLowerCase() || ''\n } else {\n const url = new URL(fileOrUrl, location.origin)\n if (url.protocol === 'data:' || url.protocol === 'blob:' || url.protocol.startsWith('http')) {\n contentType = await this.fetchContentType(url.href)\n } else {\n contentType = ''\n }\n ext = url.pathname.split('.').pop()?.toLowerCase() || ''\n }\n if (\n contentType.startsWith('image/') &&\n /** Windows provide PDFs as image/pdf */ !contentType.includes('pdf')\n ) {\n return 'image'\n }\n if (contentType.startsWith('video/')) return 'video'\n if (contentType.startsWith('audio/')) return 'audio'\n if (contentType.startsWith('text/html')) return 'html'\n if (ext === 'md') return 'markdown'\n if (contentType.startsWith('text/')) return 'text'\n // detect by file extension\n if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'ico', 'webp'].includes(ext)) return 'image'\n if (['mp4', 'webm', 'ogg', 'flv', 'avi', 'mov', 'wmv', 'mkv'].includes(ext)) return 'video'\n if (['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a', 'wma'].includes(ext)) return 'audio'\n if (['html', 'htm'].includes(ext)) return 'html'\n if (['json', 'yml', 'yaml', 'toml', 'py'].includes(ext)) return 'text'\n if (['pdf'].includes(ext)) return 'pdf'\n return 'unknown'\n }\n async previewFile(fileOrUrl: File | string, alt?: string) {\n const previewElement = await this.getPreviewElement(fileOrUrl, alt)\n if (!previewElement) return\n const modal = this.ctx.modal.dialog({\n className: 'in-page-edit ipe-quickPreview',\n sizeClass: 'mediumToLarge',\n center: true,\n title: alt ?? (fileOrUrl instanceof File ? fileOrUrl.name : fileOrUrl),\n content: <section className=\"ipe-quickPreview__content\">{previewElement}</section>,\n })\n return modal\n }\n private _objectUrls = new WeakMap<File, string>()\n private getObjectUrl(file: File) {\n if (!this._objectUrls.has(file)) {\n const objUrl = URL.createObjectURL(file)\n this._objectUrls.set(file, objUrl)\n }\n return this._objectUrls.get(file)!\n }\n async getPreviewElement(fileOrUrl: File | string, alt?: string) {\n const previewType = await this.getPreviewType(fileOrUrl)\n const url = fileOrUrl instanceof File ? this.getObjectUrl(fileOrUrl) : fileOrUrl\n switch (previewType) {\n case 'image':\n return (\n <img src={url} alt={alt ?? (fileOrUrl instanceof File ? fileOrUrl.name : fileOrUrl)} />\n )\n case 'video':\n return <video src={url} controls={true} aria-label={alt} />\n case 'audio':\n return <audio src={url} controls={true} aria-label={alt} />\n case 'pdf':\n return <embed type=\"application/pdf\" src={url} aria-label={alt} />\n }\n return null\n }\n\n previewWikiPage(title: string) {\n throw new Error('Not implemented')\n }\n}\n"],"names":["_PluginQuickPreview_decorators","_init","_a","Inject","RegisterPreferences","Schema","PluginQuickPreview","BasePlugin","ctx","makeCallable","text","params","wikiPage","modal","modalOptions","$","jsx","ProgressBar","ret","parse","outputRef","el","error","jsxs","Fragment","options","latestPreviewModal","wikitext","title","url","cached","promise","res","fileOrUrl","contentType","ext","alt","previewElement","file","objUrl","previewType","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as t } from "./Promise.withResolvers-C4chhLB1.js";
|
|
2
|
-
import { R as de, a as ce, S as z } from "./index-
|
|
2
|
+
import { R as de, a as ce, S as z } from "./index-BAJiXDPz.js";
|
|
3
3
|
import { BasePlugin as ue } from "./core.js";
|
|
4
4
|
import { C as pe } from "./CheckBox-Dx3r3LQz.js";
|
|
5
5
|
import { I as M } from "./IconUpload-Bz4BW_nc.js";
|
|
@@ -778,4 +778,4 @@ xe(B, 1, W);
|
|
|
778
778
|
export {
|
|
779
779
|
W as PluginQuickUpload
|
|
780
780
|
};
|
|
781
|
-
//# sourceMappingURL=index-
|
|
781
|
+
//# sourceMappingURL=index-CZfEZBOj.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-BlVSMvH-.js","sources":["../src/plugins/quick-upload/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\n\nimport './style.scss'\n\nimport BasePlugin from '@/plugins/BasePlugin'\nimport { RegisterPreferences } from '@/decorators/Preferences'\nimport { IconUpload } from '@/components/Icon'\nimport { CheckBox } from '@/components'\nimport type { UploadFileResult } from '@/services/WikiFileService'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickUpload: PluginQuickUpload\n }\n interface Preferences {\n 'quickUpload.summary': string\n }\n}\n\ntype UploadItem = {\n id: string\n file: File\n filename: string\n text: string\n status: 'queued' | 'uploading' | 'success' | 'warning' | 'error' | 'paused'\n message?: string\n retryable?: boolean\n fileUrl?: string\n result?: UploadFileResult\n}\n\nconst PreviewPlaceholderNA = ({ $ }: { $: (strings: TemplateStringsArray) => string }) => (\n <div className=\"ipe-quickUpload__preview-placeholder is-na\">\n <span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"icon icon-tabler icons-tabler-filled icon-tabler-file-unknown\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 2l.117 .007a1 1 0 0 1 .876 .876l.007 .117v4l.005 .15a2 2 0 0 0 1.838 1.844l.157 .006h4l.117 .007a1 1 0 0 1 .876 .876l.007 .117v9a3 3 0 0 1 -2.824 2.995l-.176 .005h-10a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-14a3 3 0 0 1 2.824 -2.995l.176 -.005zm0 15a1 1 0 0 0 -.993 .883l-.007 .127a1 1 0 0 0 1.993 .117l.007 -.127a1 1 0 0 0 -1 -1m1.136 -5.727a2.5 2.5 0 0 0 -3.037 .604a1 1 0 0 0 1.434 1.389l.088 -.09a.5 .5 0 1 1 .379 .824a1 1 0 0 0 -.002 2a2.5 2.5 0 0 0 1.137 -4.727\" />\n <path d=\"M19 7h-4l-.001 -4.001z\" />\n </svg>\n <p>{$`No preview available`}</p>\n </span>\n </div>\n)\n\n@RegisterPreferences(\n Schema.object({\n 'quickUpload.summary': Schema.string()\n .description('Default summary of the quick upload')\n .default('[IPE-NEXT] Quick upload'),\n })\n)\n@Inject(['modal', '$', 'wikiTitle', 'wikiFile', 'quickPreview', 'preferences'])\nexport class PluginQuickUpload extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-upload')\n }\n\n protected async start() {\n this.injectToolbox()\n this.ctx.set('quickUpload', this)\n }\n\n protected async stop() {}\n\n private injectToolbox() {\n const { $ } = this.ctx\n this.ctx.inject(['toolbox'], (ctx) => {\n ctx.toolbox.addButton({\n id: 'quick-upload',\n group: 'group2',\n index: 2,\n icon: <IconUpload />,\n tooltip: () => $`Quick Upload`,\n onClick: (e) => {\n e.preventDefault()\n this.showModal()\n },\n })\n ctx.on('dispose', () => {\n ctx.toolbox.removeButton('quick-upload')\n })\n })\n }\n\n private formatFileSize(size: number = 0) {\n size = Number(size)\n if (!Number.isFinite(size) || size < 0) return '0 B'\n\n const units = ['B', 'KB', 'MB', 'GB', 'TB']\n let index = 0\n while (size >= 1024 && index < units.length - 1) {\n size /= 1024\n index++\n }\n\n // 使用 Intl 来格式化数字(自动处理千分位、小数等)\n const formatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 })\n return `${formatter.format(size)} ${units[index]}`\n }\n\n private isFileAccepted(file: File, accept: string): boolean {\n if (!accept) return true\n const rules = accept\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n if (!rules.length) return true\n const fileType = file.type || ''\n const fileName = file.name || ''\n return rules.some((rule) => {\n // extension: .png .pdf\n if (rule.startsWith('.')) {\n return fileName.toLowerCase().endsWith(rule.toLowerCase())\n }\n // image/*, video/* ...\n if (rule.endsWith('/*')) {\n const prefix = rule.slice(0, -1) // keep the trailing slash\n return fileType.startsWith(prefix)\n }\n // exact mime\n return fileType === rule\n })\n }\n\n private getDefaultPreviewPlaceholder() {\n const { $ } = this.ctx\n return (\n <div className=\"ipe-quickUpload__preview-placeholder\">\n <span>\n <IconUpload />\n <p>{$`You can drag & drop files to this modal`}</p>\n </span>\n </div>\n )\n }\n\n private safeId() {\n return `mu_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`\n }\n\n async showModal() {\n const { $ } = this.ctx\n\n let isUploading = false\n let pauseRequested = false\n\n const showMessage = (type: 'success' | 'warning' | 'error', title: string, content: any) => {\n this.ctx.modal.notify(type, {\n title,\n content,\n closeAfter: type === 'success' ? 3000 : 8000,\n })\n }\n\n const modal = this.ctx.modal.show({\n className: 'ipe-quickUpload compact-buttons',\n sizeClass: 'mediumToLarge',\n center: false,\n title: $`Quick Upload`,\n content: $`Quick Upload`,\n outSideClose: false,\n beforeClose: () => {\n if (isUploading) {\n showMessage('warning', $`Upload in progress`, $`Please pause or wait for it to finish.`)\n return false\n }\n return true\n },\n })\n\n const defaultSummary = (await this.ctx.preferences.get('quickUpload.summary')) || ''\n const accept = 'image/*,video/*,audio/*,application/pdf'\n const confirmThreshold = 20\n\n let items: UploadItem[] = []\n let selectedId: string | null = null\n\n const ui = {\n fileInput: null as HTMLInputElement | null,\n listEl: null as HTMLElement | null,\n previewWrapper: null as HTMLElement | null,\n progressEl: null as HTMLElement | null,\n progressTextEl: null as HTMLElement | null,\n summaryInput: null as HTMLTextAreaElement | null,\n ignoreWarnings: null as HTMLInputElement | null,\n selectedCountEl: null as HTMLElement | null,\n readyCountEl: null as HTMLElement | null,\n }\n\n const updateItem = (id: string, patch: Partial<UploadItem>) => {\n items = items.map((x) => (x.id === id ? { ...x, ...patch } : x))\n }\n\n const removeItem = (id: string) => {\n items = items.filter((x) => x.id !== id)\n if (selectedId === id) {\n selectedId = items[0]?.id ?? null\n }\n }\n\n const updateMany = (ids: Set<string>, fn: (it: UploadItem) => UploadItem) => {\n items = items.map((x) => (ids.has(x.id) ? fn(x) : x))\n }\n\n const summarizeApiErrors = (e: any) => {\n const out: string[] = []\n const s = (v: any) => (v == null ? '' : String(v))\n if (e instanceof Error) {\n out.push(e.message)\n let cur: any = e\n while (cur?.cause) {\n cur = cur.cause\n if (cur instanceof Error) out.push(cur.message)\n else break\n }\n } else if (e?.data?.error?.info) {\n out.push(s(e.data.error.info))\n } else if (e?.error?.info) {\n out.push(s(e.error.info))\n } else if (e?.message) {\n out.push(s(e.message))\n }\n return out.filter(Boolean)\n }\n\n const formatUploadError = (e: any): { message: string; retryable: boolean } => {\n let reasons = summarizeApiErrors(e)\n if (reasons.length === 0) reasons = ['Upload failed with unknown error.']\n\n const combined = reasons.join('\\n')\n const lower = combined.toLowerCase()\n\n if (\n lower.includes('file is larger') ||\n lower.includes('files larger than') ||\n lower.includes('maximum upload size')\n ) {\n return { message: `File too large\\n${combined}`, retryable: false }\n }\n\n if (lower.includes('network') || lower.includes('timeout') || lower.includes('timed out')) {\n return { message: `Network issue\\n${combined}`, retryable: true }\n }\n\n return { message: combined, retryable: true }\n }\n\n const shouldRetryItem = (it: UploadItem) => {\n if (it.status === 'warning') return true\n if (it.status === 'error') return it.retryable !== false\n return false\n }\n\n type UploadMode = 'all' | 'resume' | 'retry'\n\n const getUploadCandidates = (mode: UploadMode, list: UploadItem[]) => {\n if (mode === 'retry') return list.filter((it) => shouldRetryItem(it))\n if (mode === 'resume') {\n return list.filter(\n (it) => (it.status === 'queued' || it.status === 'paused') && it.retryable !== false\n )\n }\n return list.filter((it) => it.status === 'queued' || it.status === 'paused')\n }\n\n const prepareRetryState = (candidates: UploadItem[]) => {\n const idset = new Set(candidates.map((c) => c.id))\n updateMany(idset, (x) =>\n x.retryable === false ? x : { ...x, status: 'queued', message: undefined }\n )\n }\n\n const getSelected = () => {\n return items.find((x) => x.id === selectedId) || null\n }\n\n const setSelected = (id: string | null) => {\n selectedId = id\n renderList()\n void renderPreview()\n }\n\n const countByStatus = () => {\n const out = { ok: 0, warn: 0, err: 0, paused: 0 }\n for (const it of items) {\n if (it.status === 'success') out.ok++\n else if (it.status === 'warning') out.warn++\n else if (it.status === 'error') out.err++\n else if (it.status === 'paused') out.paused++\n }\n return out\n }\n\n const setProgress = (done: number, total: number) => {\n const pct = total > 0 ? Math.floor((done / total) * 100) : 0\n if (ui.progressTextEl) ui.progressTextEl.textContent = `${done}/${total} (${pct}%)`\n if (ui.progressEl) ui.progressEl.style.width = `${Math.max(0, Math.min(100, pct))}%`\n }\n\n const sanitizeFilename = (name: string) => {\n return (name || '').replace(/\\s+/g, ' ').trim()\n }\n\n const resetAll = () => {\n items = []\n selectedId = null\n setProgress(0, 0)\n if (ui.summaryInput) ui.summaryInput.value = String(defaultSummary || '')\n if (ui.ignoreWarnings) ui.ignoreWarnings.checked = false\n renderList()\n void renderPreview()\n }\n\n const addFiles = (files: File[]) => {\n const accepted = files.filter((f) => this.isFileAccepted(f, String(accept || '')))\n if (!accepted.length) return\n\n const newItems: UploadItem[] = accepted.map((file) => ({\n id: this.safeId(),\n file,\n filename: file.name,\n text: '',\n status: 'queued',\n retryable: true,\n }))\n\n items = [...items, ...newItems]\n if (!selectedId && items.length) {\n selectedId = items[0].id\n }\n renderList()\n void renderPreview()\n }\n\n const buildUploadBody = (item: UploadItem) => {\n const body: Record<string, any> = {}\n\n body.filename = sanitizeFilename(item.filename || item.file.name)\n body.file = item.file\n\n const summary = (ui.summaryInput?.value || '').trim() || ''\n body.comment = summary\n\n body.text = item.text || ''\n\n if (ui.ignoreWarnings?.checked) {\n body.ignorewarnings = '1'\n }\n\n return body\n }\n\n const getStatusLabel = (status: UploadItem['status']) => {\n switch (status) {\n case 'queued':\n return 'Queued'\n case 'uploading':\n return 'Uploading'\n case 'success':\n return 'Uploaded'\n case 'warning':\n return 'Warning'\n case 'error':\n return 'Failed'\n case 'paused':\n return 'Paused'\n default:\n return status\n }\n }\n\n const renderList = () => {\n if (!ui.listEl) return\n ui.listEl.innerHTML = ''\n\n if (!isUploading) {\n setProgress(0, items.length)\n }\n\n if (!items.length) {\n ui.listEl.appendChild(\n <div style={{ opacity: 0.75, padding: '8px 0' }}>\n <p>No files selected.</p>\n </div>\n )\n updateFooter()\n return\n } else {\n const list = (\n <ul\n style={{\n listStyle: 'none',\n padding: 0,\n margin: 0,\n display: 'grid',\n gap: '6px',\n }}\n />\n ) as HTMLUListElement\n\n items.forEach((item) => {\n const isActive = item.id === selectedId\n const row = (\n <li\n style={{\n border: '1px solid var(--ipe-border-color, rgba(0,0,0,.12))',\n borderRadius: '8px',\n padding: '8px',\n cursor: 'pointer',\n background: isActive ? 'rgba(59,130,246,.08)' : 'transparent',\n minWidth: 0,\n }}\n onClick={() => setSelected(item.id)}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\n <div style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>\n <div\n style={{\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n wordBreak: 'break-word',\n fontSize: '13px',\n }}\n >\n <strong style={{ fontWeight: 600 }}>{item.filename}</strong>\n </div>\n <div style={{ fontSize: '12px', opacity: 0.75 }}>\n {getStatusLabel(item.status)}\n </div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>\n <button\n type=\"button\"\n className=\"ipe-btn is-text\"\n title={'Remove'}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n removeItem(item.id)\n renderList()\n void renderPreview()\n }}\n >\n ×\n </button>\n </div>\n </div>\n\n {item.message ? (\n <div\n style={{\n fontSize: '12px',\n opacity: 0.8,\n marginTop: '4px',\n whiteSpace: 'pre-wrap',\n }}\n >\n {item.message}\n </div>\n ) : null}\n </li>\n ) as HTMLLIElement\n\n list.appendChild(row)\n })\n\n ui.listEl.appendChild(list)\n }\n\n updateFooter()\n }\n\n const renderPreview = async () => {\n if (!ui.previewWrapper) return\n ui.previewWrapper.innerHTML = ''\n\n const item = getSelected()\n if (!item) {\n ui.previewWrapper.appendChild(this.getDefaultPreviewPlaceholder())\n return\n }\n\n const file = item.file\n\n const header = (\n <section style={{ display: 'grid', gap: '6px' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'baseline',\n justifyContent: 'space-between',\n gap: '12px',\n }}\n >\n <strong style={{ wordBreak: 'break-word' }}>{file.name}</strong>\n <span style={{ fontSize: '12px', opacity: 0.8 }}>{this.formatFileSize(file.size)}</span>\n </div>\n <div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' }}>\n <span style={{ fontSize: '12px', opacity: 0.8 }}>{file.type || $`Unknown type`}</span>\n {item.fileUrl ? (\n <a\n href={item.fileUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ fontSize: '12px' }}\n >\n {$`Open file page`}\n </a>\n ) : null}\n </div>\n </section>\n ) as HTMLElement\n\n const previewEl = (await this.ctx.quickPreview.getPreviewElement(file)) || (\n <PreviewPlaceholderNA $={$} />\n )\n\n const previewBox = (\n <div className=\"ipe-quickUpload__preview-content\" style={{ marginTop: '10px' }}>\n {previewEl}\n </div>\n ) as HTMLElement\n\n const isLocked = item.status === 'success'\n const filenameEditor = (\n <div\n className=\"ipe-input-box\"\n style={{\n marginTop: '8px',\n opacity: isLocked ? 0.55 : 1,\n filter: isLocked ? 'grayscale(1)' : undefined,\n pointerEvents: isLocked ? 'none' : undefined,\n }}\n >\n <label htmlFor=\"mu_filename\">{$`Target filename`}</label>\n <input\n id=\"mu_filename\"\n name=\"mu_filename\"\n type=\"text\"\n value={item.filename}\n disabled={isUploading || isLocked}\n onInput={(e: Event) => {\n const v = (e.target as HTMLInputElement).value\n updateItem(item.id, { filename: v })\n renderList()\n }}\n />\n </div>\n ) as HTMLElement\n\n const descEditor = (\n <div\n className=\"ipe-input-box\"\n style={{\n marginTop: '8px',\n opacity: isLocked ? 0.55 : 1,\n filter: isLocked ? 'grayscale(1)' : undefined,\n pointerEvents: isLocked ? 'none' : undefined,\n }}\n >\n <label htmlFor=\"mu_text\">File description</label>\n <textarea\n id=\"mu_text\"\n placeholder={'This file is for...\\n[[Category:XXX]]'}\n disabled={isUploading || isLocked}\n value={item.text || ''}\n onInput={(e: Event) => {\n const v = (e.target as HTMLTextAreaElement).value\n updateItem(item.id, { text: v })\n renderList()\n }}\n ></textarea>\n </div>\n ) as HTMLElement\n\n ui.previewWrapper.appendChild(header)\n ui.previewWrapper.appendChild(previewBox)\n ui.previewWrapper.appendChild(filenameEditor)\n ui.previewWrapper.appendChild(descEditor)\n }\n\n const uploadOne = async (item: UploadItem) => {\n updateItem(item.id, { status: 'uploading', message: undefined })\n renderList()\n await renderPreview()\n\n const body = buildUploadBody(item)\n\n this.ctx.emit('analytics/event', {\n feature: 'quick-upload',\n page: body.filename?.toString() || undefined,\n })\n\n try {\n const result = await this.ctx.wikiFile.upload(body)\n\n if (result.data?.upload?.result === 'Success') {\n const fileUrl = this.ctx.wikiFile.getFileUrl(`File:${result.data.upload.filename}`)\n updateItem(item.id, {\n status: 'success',\n fileUrl,\n result: result.data.upload as any,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n throw result\n } catch (e) {\n let reasons: string[] = []\n\n if ((e as any)?.data?.upload) {\n const uploadResult = (e as any).data.upload as UploadFileResult\n\n if (uploadResult.result === 'Success') {\n const fname = (uploadResult as any).filename || body.filename\n const fileUrl = this.ctx.wikiFile.getFileUrl(`File:${fname}`)\n updateItem(item.id, {\n status: 'success',\n fileUrl,\n result: uploadResult,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n if (\n Array.isArray(uploadResult.warnings?.duplicate) &&\n uploadResult.warnings.duplicate.length > 0\n ) {\n reasons.push(`Duplicate of: ${uploadResult.warnings.duplicate.join(', ')}`)\n updateItem(item.id, {\n status: 'warning',\n message: reasons.join('\\n'),\n result: uploadResult,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n if (uploadResult.warnings?.exists) {\n reasons.push('A file with the same name already exists.')\n updateItem(item.id, {\n status: 'warning',\n message: reasons.join('\\n'),\n result: uploadResult,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n const { message, retryable } = formatUploadError(e)\n updateItem(item.id, { status: 'error', message, retryable })\n renderList()\n await renderPreview()\n return\n }\n\n const { message, retryable } = formatUploadError(e)\n updateItem(item.id, { status: 'error', message, retryable })\n renderList()\n await renderPreview()\n }\n }\n\n const uploadAll = async (mode: UploadMode = 'all') => {\n if (isUploading) return\n\n let candidates = getUploadCandidates(mode, items)\n\n if (mode === 'retry') {\n if (candidates.length === 0) {\n showMessage(\n 'warning',\n 'Nothing to retry',\n <div>There are no retryable failed/warning items.</div>\n )\n return\n }\n } else if (mode === 'resume') {\n if (candidates.length === 0) {\n showMessage(\n 'warning',\n 'Nothing to resume',\n <div>There are no queued paused items to continue.</div>\n )\n return\n }\n } else {\n if (items.length === 0) {\n showMessage(\n 'warning',\n $`No files selected`,\n <div>{$`Please select one or more files.`}</div>\n )\n return\n }\n if (items.length > confirmThreshold) {\n this.ctx.modal.confirm(\n {\n title: $`Confirm bulk upload`,\n content: (\n <div>\n {$`You are about to upload`} <strong>{items.length}</strong>{' '}\n {$`files at once. Are you sure?`}\n </div>\n ),\n center: true,\n okBtn: { label: $`Upload`, className: 'is-primary is-ghost' },\n cancelBtn: { label: $`Cancel`, className: 'is-danger is-ghost' },\n },\n (confirmed) => {\n if (confirmed) {\n void uploadAll('all')\n }\n return true\n }\n )\n return\n }\n }\n\n if (mode === 'retry') {\n prepareRetryState(candidates)\n renderList()\n await renderPreview()\n candidates = getUploadCandidates('retry', items)\n }\n\n isUploading = true\n pauseRequested = false\n updateFooter()\n\n try {\n const total = candidates.length\n let done = 0\n setProgress(0, total)\n\n for (const item of candidates) {\n if (pauseRequested) {\n const remainingIds = new Set(candidates.slice(done).map((x) => x.id))\n updateMany(remainingIds, (x) =>\n x.status === 'queued' || x.status === 'uploading'\n ? { ...x, status: 'paused', message: 'Paused by user', retryable: true }\n : x\n )\n renderList()\n await renderPreview()\n break\n }\n\n const current = items.find((x) => x.id === item.id)\n if (!current) {\n done++\n setProgress(done, total)\n continue\n }\n\n await uploadOne(current)\n done++\n setProgress(done, total)\n }\n\n const { ok, warn, err, paused } = countByStatus()\n if (paused > 0) {\n showMessage(\n 'warning',\n 'Upload paused',\n <div>\n <div>\n Uploaded: <strong>{ok}</strong>\n </div>\n <div>\n Warnings: <strong>{warn}</strong>\n </div>\n <div>\n Errors: <strong>{err}</strong>\n </div>\n <div>\n Paused: <strong>{paused}</strong>\n </div>\n </div>\n )\n } else if (err === 0 && warn === 0) {\n showMessage(\n 'success',\n 'Upload completed',\n <div>\n <strong>All files uploaded successfully.</strong>\n <div>\n Uploaded: <strong>{ok}</strong>\n </div>\n </div>\n )\n } else {\n showMessage(\n 'warning',\n 'Upload completed with issues',\n <div>\n <div>\n Uploaded: <strong>{ok}</strong>\n </div>\n {warn ? (\n <div>\n Warnings: <strong>{warn}</strong>\n </div>\n ) : null}\n {err ? (\n <div>\n Errors: <strong>{err}</strong>\n </div>\n ) : null}\n </div>\n )\n }\n } finally {\n isUploading = false\n updateFooter()\n }\n }\n\n const handleDrop = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n const container = e.currentTarget as HTMLElement\n container?.classList.remove('is-dragover')\n\n const files = Array.from(e.dataTransfer?.files || [])\n if (!files.length) return\n addFiles(files)\n }\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n const container = e.currentTarget as HTMLElement\n if (e.dataTransfer) e.dataTransfer.dropEffect = 'copy'\n container?.classList.add('is-dragover')\n }\n\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n const container = e.currentTarget as HTMLElement\n container?.classList.remove('is-dragover')\n }\n\n const progressBar = (\n <div style={{ marginBottom: '10px' }}>\n <div\n style={{\n height: '8px',\n borderRadius: '999px',\n background: 'rgba(0,0,0,.08)',\n overflow: 'hidden',\n }}\n >\n <div\n ref={(el: any) => {\n ui.progressEl = el\n }}\n style={{\n height: '100%',\n width: '0%',\n background: 'var(--ipe-primary, #3b82f6)',\n transition: 'width .2s ease',\n }}\n />\n </div>\n <div\n style={{\n marginTop: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '10px',\n }}\n >\n <div\n ref={(el: any) => {\n ui.progressTextEl = el\n }}\n style={{ fontSize: '12px', opacity: 0.8 }}\n >\n 0/0 (0%)\n </div>\n </div>\n </div>\n ) as HTMLElement\n\n const leftPanel = (\n <section style={{ display: 'grid', gap: '10px', minWidth: 0 }}>\n <div className=\"ipe-input-box\">\n <label htmlFor=\"mu_files\">\n Files{' '}\n {items.length > 0 ? (\n <span style={{ opacity: 0.85 }}>({items.length} selected)</span>\n ) : null}\n </label>\n <input\n id=\"mu_files\"\n type=\"file\"\n multiple\n accept={String(accept || '')}\n disabled={isUploading}\n ref={(el: any) => {\n ui.fileInput = el\n }}\n onChange={(e: Event) => {\n const files = Array.from((e.target as HTMLInputElement).files || [])\n addFiles(files)\n ;(e.target as HTMLInputElement).value = ''\n }}\n />\n </div>\n\n <div\n ref={(el: any) => {\n ui.listEl = el\n }}\n />\n </section>\n ) as HTMLElement\n\n const rightPanel = (\n <section style={{ display: 'grid', gap: '10px' }}>\n <div\n className=\"ipe-quickUpload__preview\"\n ref={(el: any) => {\n ui.previewWrapper = el\n }}\n onClick={(e) => {\n const target = e.target\n if (\n target &&\n (target as HTMLElement).closest('img, .ipe-quickUpload__preview-placeholder')\n ) {\n e.preventDefault()\n ui.fileInput?.click()\n }\n }}\n style={{\n border: '1px solid var(--ipe-border-color, rgba(0,0,0,.12))',\n borderRadius: '8px',\n padding: '10px',\n minWidth: 0,\n }}\n />\n </section>\n ) as HTMLElement\n\n const containerEl = (\n <section\n className=\"ipe-quickUpload__container\"\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n style={{ display: 'grid', gap: '12px' }}\n >\n {progressBar}\n <div className=\"ipe-quickUpload__layout\">\n {leftPanel}\n {rightPanel}\n </div>\n\n <div\n style={{\n borderTop: '1px solid var(--ipe-border-color, rgba(0,0,0,.12))',\n paddingTop: '10px',\n display: 'grid',\n gap: '10px',\n }}\n >\n <div className=\"ipe-input-box\">\n <label htmlFor=\"mu_summary\">Summary (applies to all files)</label>\n <textarea\n id=\"mu_summary\"\n disabled={isUploading}\n ref={(el: any) => {\n ui.summaryInput = el\n }}\n onInput={() => {}}\n />\n </div>\n\n <CheckBox\n name=\"ignorewarnings\"\n label={$`Ignore warnings and upload anyway`}\n inputProps={{\n disabled: isUploading,\n ref: (el: any) => {\n ui.ignoreWarnings = el\n },\n }}\n />\n </div>\n </section>\n ) as HTMLElement\n\n modal.setContent(containerEl)\n\n if (ui.summaryInput) ui.summaryInput.value = String(defaultSummary || '')\n\n const updateFooter = () => {\n const { warn, err, paused } = countByStatus()\n const hasFailed = err > 0 || warn > 0\n const hasPaused = paused > 0\n\n let label = $`Upload`\n let action = () => void uploadAll('all')\n let className = 'is-primary is-text'\n\n if (isUploading) {\n label = pauseRequested ? 'Pausing...' : 'Pause after current'\n action = () => {\n pauseRequested = true\n updateFooter()\n }\n } else if (hasPaused) {\n label = 'Resume'\n action = () => void uploadAll('resume')\n } else if (hasFailed) {\n label = 'Retry failed/warnings'\n action = () => void uploadAll('retry')\n }\n\n modal.setButtons([\n {\n label: $`Cancel`,\n className: 'is-danger is-text',\n method: () => modal.close(),\n },\n {\n label: 'Reset',\n className: 'is-text',\n method: () => {\n if (isUploading) return\n resetAll()\n },\n },\n {\n label,\n className,\n method: action,\n },\n ])\n }\n\n renderList()\n await renderPreview()\n\n return modal\n }\n}\n"],"names":["_PluginQuickUpload_decorators","_init","_a","PreviewPlaceholderNA","$","jsxs","jsx","RegisterPreferences","Schema","Inject","PluginQuickUpload","BasePlugin","ctx","IconUpload","e","size","units","index","file","accept","rules","s","fileType","fileName","rule","prefix","isUploading","pauseRequested","showMessage","type","title","content","modal","defaultSummary","confirmThreshold","items","selectedId","ui","updateItem","id","patch","x","removeItem","updateMany","ids","fn","summarizeApiErrors","out","v","cur","formatUploadError","reasons","combined","lower","shouldRetryItem","it","getUploadCandidates","mode","list","prepareRetryState","candidates","idset","c","getSelected","setSelected","renderList","renderPreview","countByStatus","setProgress","done","total","pct","sanitizeFilename","name","resetAll","addFiles","files","accepted","f","newItems","buildUploadBody","item","body","summary","getStatusLabel","status","isActive","row","updateFooter","header","previewEl","previewBox","isLocked","filenameEditor","descEditor","uploadOne","result","fileUrl","uploadResult","fname","message","retryable","uploadAll","confirmed","remainingIds","current","ok","warn","err","paused","handleDrop","handleDragOver","container","handleDragLeave","progressBar","el","leftPanel","containerEl","target","CheckBox","hasFailed","hasPaused","label","action","className","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CZfEZBOj.js","sources":["../src/plugins/quick-upload/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\n\nimport './style.scss'\n\nimport BasePlugin from '@/plugins/BasePlugin'\nimport { RegisterPreferences } from '@/decorators/Preferences'\nimport { IconUpload } from '@/components/Icon'\nimport { CheckBox } from '@/components'\nimport type { UploadFileResult } from '@/services/WikiFileService'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickUpload: PluginQuickUpload\n }\n interface Preferences {\n 'quickUpload.summary': string\n }\n}\n\ntype UploadItem = {\n id: string\n file: File\n filename: string\n text: string\n status: 'queued' | 'uploading' | 'success' | 'warning' | 'error' | 'paused'\n message?: string\n retryable?: boolean\n fileUrl?: string\n result?: UploadFileResult\n}\n\nconst PreviewPlaceholderNA = ({ $ }: { $: (strings: TemplateStringsArray) => string }) => (\n <div className=\"ipe-quickUpload__preview-placeholder is-na\">\n <span>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"icon icon-tabler icons-tabler-filled icon-tabler-file-unknown\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 2l.117 .007a1 1 0 0 1 .876 .876l.007 .117v4l.005 .15a2 2 0 0 0 1.838 1.844l.157 .006h4l.117 .007a1 1 0 0 1 .876 .876l.007 .117v9a3 3 0 0 1 -2.824 2.995l-.176 .005h-10a3 3 0 0 1 -2.995 -2.824l-.005 -.176v-14a3 3 0 0 1 2.824 -2.995l.176 -.005zm0 15a1 1 0 0 0 -.993 .883l-.007 .127a1 1 0 0 0 1.993 .117l.007 -.127a1 1 0 0 0 -1 -1m1.136 -5.727a2.5 2.5 0 0 0 -3.037 .604a1 1 0 0 0 1.434 1.389l.088 -.09a.5 .5 0 1 1 .379 .824a1 1 0 0 0 -.002 2a2.5 2.5 0 0 0 1.137 -4.727\" />\n <path d=\"M19 7h-4l-.001 -4.001z\" />\n </svg>\n <p>{$`No preview available`}</p>\n </span>\n </div>\n)\n\n@RegisterPreferences(\n Schema.object({\n 'quickUpload.summary': Schema.string()\n .description('Default summary of the quick upload')\n .default('[IPE-NEXT] Quick upload'),\n })\n)\n@Inject(['modal', '$', 'wikiTitle', 'wikiFile', 'quickPreview', 'preferences'])\nexport class PluginQuickUpload extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-upload')\n }\n\n protected async start() {\n this.injectToolbox()\n this.ctx.set('quickUpload', this)\n }\n\n protected async stop() {}\n\n private injectToolbox() {\n const { $ } = this.ctx\n this.ctx.inject(['toolbox'], (ctx) => {\n ctx.toolbox.addButton({\n id: 'quick-upload',\n group: 'group2',\n index: 2,\n icon: <IconUpload />,\n tooltip: () => $`Quick Upload`,\n onClick: (e) => {\n e.preventDefault()\n this.showModal()\n },\n })\n ctx.on('dispose', () => {\n ctx.toolbox.removeButton('quick-upload')\n })\n })\n }\n\n private formatFileSize(size: number = 0) {\n size = Number(size)\n if (!Number.isFinite(size) || size < 0) return '0 B'\n\n const units = ['B', 'KB', 'MB', 'GB', 'TB']\n let index = 0\n while (size >= 1024 && index < units.length - 1) {\n size /= 1024\n index++\n }\n\n // 使用 Intl 来格式化数字(自动处理千分位、小数等)\n const formatter = new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 })\n return `${formatter.format(size)} ${units[index]}`\n }\n\n private isFileAccepted(file: File, accept: string): boolean {\n if (!accept) return true\n const rules = accept\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n if (!rules.length) return true\n const fileType = file.type || ''\n const fileName = file.name || ''\n return rules.some((rule) => {\n // extension: .png .pdf\n if (rule.startsWith('.')) {\n return fileName.toLowerCase().endsWith(rule.toLowerCase())\n }\n // image/*, video/* ...\n if (rule.endsWith('/*')) {\n const prefix = rule.slice(0, -1) // keep the trailing slash\n return fileType.startsWith(prefix)\n }\n // exact mime\n return fileType === rule\n })\n }\n\n private getDefaultPreviewPlaceholder() {\n const { $ } = this.ctx\n return (\n <div className=\"ipe-quickUpload__preview-placeholder\">\n <span>\n <IconUpload />\n <p>{$`You can drag & drop files to this modal`}</p>\n </span>\n </div>\n )\n }\n\n private safeId() {\n return `mu_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`\n }\n\n async showModal() {\n const { $ } = this.ctx\n\n let isUploading = false\n let pauseRequested = false\n\n const showMessage = (type: 'success' | 'warning' | 'error', title: string, content: any) => {\n this.ctx.modal.notify(type, {\n title,\n content,\n closeAfter: type === 'success' ? 3000 : 8000,\n })\n }\n\n const modal = this.ctx.modal.show({\n className: 'ipe-quickUpload compact-buttons',\n sizeClass: 'mediumToLarge',\n center: false,\n title: $`Quick Upload`,\n content: $`Quick Upload`,\n outSideClose: false,\n beforeClose: () => {\n if (isUploading) {\n showMessage('warning', $`Upload in progress`, $`Please pause or wait for it to finish.`)\n return false\n }\n return true\n },\n })\n\n const defaultSummary = (await this.ctx.preferences.get('quickUpload.summary')) || ''\n const accept = 'image/*,video/*,audio/*,application/pdf'\n const confirmThreshold = 20\n\n let items: UploadItem[] = []\n let selectedId: string | null = null\n\n const ui = {\n fileInput: null as HTMLInputElement | null,\n listEl: null as HTMLElement | null,\n previewWrapper: null as HTMLElement | null,\n progressEl: null as HTMLElement | null,\n progressTextEl: null as HTMLElement | null,\n summaryInput: null as HTMLTextAreaElement | null,\n ignoreWarnings: null as HTMLInputElement | null,\n selectedCountEl: null as HTMLElement | null,\n readyCountEl: null as HTMLElement | null,\n }\n\n const updateItem = (id: string, patch: Partial<UploadItem>) => {\n items = items.map((x) => (x.id === id ? { ...x, ...patch } : x))\n }\n\n const removeItem = (id: string) => {\n items = items.filter((x) => x.id !== id)\n if (selectedId === id) {\n selectedId = items[0]?.id ?? null\n }\n }\n\n const updateMany = (ids: Set<string>, fn: (it: UploadItem) => UploadItem) => {\n items = items.map((x) => (ids.has(x.id) ? fn(x) : x))\n }\n\n const summarizeApiErrors = (e: any) => {\n const out: string[] = []\n const s = (v: any) => (v == null ? '' : String(v))\n if (e instanceof Error) {\n out.push(e.message)\n let cur: any = e\n while (cur?.cause) {\n cur = cur.cause\n if (cur instanceof Error) out.push(cur.message)\n else break\n }\n } else if (e?.data?.error?.info) {\n out.push(s(e.data.error.info))\n } else if (e?.error?.info) {\n out.push(s(e.error.info))\n } else if (e?.message) {\n out.push(s(e.message))\n }\n return out.filter(Boolean)\n }\n\n const formatUploadError = (e: any): { message: string; retryable: boolean } => {\n let reasons = summarizeApiErrors(e)\n if (reasons.length === 0) reasons = ['Upload failed with unknown error.']\n\n const combined = reasons.join('\\n')\n const lower = combined.toLowerCase()\n\n if (\n lower.includes('file is larger') ||\n lower.includes('files larger than') ||\n lower.includes('maximum upload size')\n ) {\n return { message: `File too large\\n${combined}`, retryable: false }\n }\n\n if (lower.includes('network') || lower.includes('timeout') || lower.includes('timed out')) {\n return { message: `Network issue\\n${combined}`, retryable: true }\n }\n\n return { message: combined, retryable: true }\n }\n\n const shouldRetryItem = (it: UploadItem) => {\n if (it.status === 'warning') return true\n if (it.status === 'error') return it.retryable !== false\n return false\n }\n\n type UploadMode = 'all' | 'resume' | 'retry'\n\n const getUploadCandidates = (mode: UploadMode, list: UploadItem[]) => {\n if (mode === 'retry') return list.filter((it) => shouldRetryItem(it))\n if (mode === 'resume') {\n return list.filter(\n (it) => (it.status === 'queued' || it.status === 'paused') && it.retryable !== false\n )\n }\n return list.filter((it) => it.status === 'queued' || it.status === 'paused')\n }\n\n const prepareRetryState = (candidates: UploadItem[]) => {\n const idset = new Set(candidates.map((c) => c.id))\n updateMany(idset, (x) =>\n x.retryable === false ? x : { ...x, status: 'queued', message: undefined }\n )\n }\n\n const getSelected = () => {\n return items.find((x) => x.id === selectedId) || null\n }\n\n const setSelected = (id: string | null) => {\n selectedId = id\n renderList()\n void renderPreview()\n }\n\n const countByStatus = () => {\n const out = { ok: 0, warn: 0, err: 0, paused: 0 }\n for (const it of items) {\n if (it.status === 'success') out.ok++\n else if (it.status === 'warning') out.warn++\n else if (it.status === 'error') out.err++\n else if (it.status === 'paused') out.paused++\n }\n return out\n }\n\n const setProgress = (done: number, total: number) => {\n const pct = total > 0 ? Math.floor((done / total) * 100) : 0\n if (ui.progressTextEl) ui.progressTextEl.textContent = `${done}/${total} (${pct}%)`\n if (ui.progressEl) ui.progressEl.style.width = `${Math.max(0, Math.min(100, pct))}%`\n }\n\n const sanitizeFilename = (name: string) => {\n return (name || '').replace(/\\s+/g, ' ').trim()\n }\n\n const resetAll = () => {\n items = []\n selectedId = null\n setProgress(0, 0)\n if (ui.summaryInput) ui.summaryInput.value = String(defaultSummary || '')\n if (ui.ignoreWarnings) ui.ignoreWarnings.checked = false\n renderList()\n void renderPreview()\n }\n\n const addFiles = (files: File[]) => {\n const accepted = files.filter((f) => this.isFileAccepted(f, String(accept || '')))\n if (!accepted.length) return\n\n const newItems: UploadItem[] = accepted.map((file) => ({\n id: this.safeId(),\n file,\n filename: file.name,\n text: '',\n status: 'queued',\n retryable: true,\n }))\n\n items = [...items, ...newItems]\n if (!selectedId && items.length) {\n selectedId = items[0].id\n }\n renderList()\n void renderPreview()\n }\n\n const buildUploadBody = (item: UploadItem) => {\n const body: Record<string, any> = {}\n\n body.filename = sanitizeFilename(item.filename || item.file.name)\n body.file = item.file\n\n const summary = (ui.summaryInput?.value || '').trim() || ''\n body.comment = summary\n\n body.text = item.text || ''\n\n if (ui.ignoreWarnings?.checked) {\n body.ignorewarnings = '1'\n }\n\n return body\n }\n\n const getStatusLabel = (status: UploadItem['status']) => {\n switch (status) {\n case 'queued':\n return 'Queued'\n case 'uploading':\n return 'Uploading'\n case 'success':\n return 'Uploaded'\n case 'warning':\n return 'Warning'\n case 'error':\n return 'Failed'\n case 'paused':\n return 'Paused'\n default:\n return status\n }\n }\n\n const renderList = () => {\n if (!ui.listEl) return\n ui.listEl.innerHTML = ''\n\n if (!isUploading) {\n setProgress(0, items.length)\n }\n\n if (!items.length) {\n ui.listEl.appendChild(\n <div style={{ opacity: 0.75, padding: '8px 0' }}>\n <p>No files selected.</p>\n </div>\n )\n updateFooter()\n return\n } else {\n const list = (\n <ul\n style={{\n listStyle: 'none',\n padding: 0,\n margin: 0,\n display: 'grid',\n gap: '6px',\n }}\n />\n ) as HTMLUListElement\n\n items.forEach((item) => {\n const isActive = item.id === selectedId\n const row = (\n <li\n style={{\n border: '1px solid var(--ipe-border-color, rgba(0,0,0,.12))',\n borderRadius: '8px',\n padding: '8px',\n cursor: 'pointer',\n background: isActive ? 'rgba(59,130,246,.08)' : 'transparent',\n minWidth: 0,\n }}\n onClick={() => setSelected(item.id)}\n >\n <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>\n <div style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>\n <div\n style={{\n textOverflow: 'ellipsis',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n wordBreak: 'break-word',\n fontSize: '13px',\n }}\n >\n <strong style={{ fontWeight: 600 }}>{item.filename}</strong>\n </div>\n <div style={{ fontSize: '12px', opacity: 0.75 }}>\n {getStatusLabel(item.status)}\n </div>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>\n <button\n type=\"button\"\n className=\"ipe-btn is-text\"\n title={'Remove'}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n removeItem(item.id)\n renderList()\n void renderPreview()\n }}\n >\n ×\n </button>\n </div>\n </div>\n\n {item.message ? (\n <div\n style={{\n fontSize: '12px',\n opacity: 0.8,\n marginTop: '4px',\n whiteSpace: 'pre-wrap',\n }}\n >\n {item.message}\n </div>\n ) : null}\n </li>\n ) as HTMLLIElement\n\n list.appendChild(row)\n })\n\n ui.listEl.appendChild(list)\n }\n\n updateFooter()\n }\n\n const renderPreview = async () => {\n if (!ui.previewWrapper) return\n ui.previewWrapper.innerHTML = ''\n\n const item = getSelected()\n if (!item) {\n ui.previewWrapper.appendChild(this.getDefaultPreviewPlaceholder())\n return\n }\n\n const file = item.file\n\n const header = (\n <section style={{ display: 'grid', gap: '6px' }}>\n <div\n style={{\n display: 'flex',\n alignItems: 'baseline',\n justifyContent: 'space-between',\n gap: '12px',\n }}\n >\n <strong style={{ wordBreak: 'break-word' }}>{file.name}</strong>\n <span style={{ fontSize: '12px', opacity: 0.8 }}>{this.formatFileSize(file.size)}</span>\n </div>\n <div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' }}>\n <span style={{ fontSize: '12px', opacity: 0.8 }}>{file.type || $`Unknown type`}</span>\n {item.fileUrl ? (\n <a\n href={item.fileUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ fontSize: '12px' }}\n >\n {$`Open file page`}\n </a>\n ) : null}\n </div>\n </section>\n ) as HTMLElement\n\n const previewEl = (await this.ctx.quickPreview.getPreviewElement(file)) || (\n <PreviewPlaceholderNA $={$} />\n )\n\n const previewBox = (\n <div className=\"ipe-quickUpload__preview-content\" style={{ marginTop: '10px' }}>\n {previewEl}\n </div>\n ) as HTMLElement\n\n const isLocked = item.status === 'success'\n const filenameEditor = (\n <div\n className=\"ipe-input-box\"\n style={{\n marginTop: '8px',\n opacity: isLocked ? 0.55 : 1,\n filter: isLocked ? 'grayscale(1)' : undefined,\n pointerEvents: isLocked ? 'none' : undefined,\n }}\n >\n <label htmlFor=\"mu_filename\">{$`Target filename`}</label>\n <input\n id=\"mu_filename\"\n name=\"mu_filename\"\n type=\"text\"\n value={item.filename}\n disabled={isUploading || isLocked}\n onInput={(e: Event) => {\n const v = (e.target as HTMLInputElement).value\n updateItem(item.id, { filename: v })\n renderList()\n }}\n />\n </div>\n ) as HTMLElement\n\n const descEditor = (\n <div\n className=\"ipe-input-box\"\n style={{\n marginTop: '8px',\n opacity: isLocked ? 0.55 : 1,\n filter: isLocked ? 'grayscale(1)' : undefined,\n pointerEvents: isLocked ? 'none' : undefined,\n }}\n >\n <label htmlFor=\"mu_text\">File description</label>\n <textarea\n id=\"mu_text\"\n placeholder={'This file is for...\\n[[Category:XXX]]'}\n disabled={isUploading || isLocked}\n value={item.text || ''}\n onInput={(e: Event) => {\n const v = (e.target as HTMLTextAreaElement).value\n updateItem(item.id, { text: v })\n renderList()\n }}\n ></textarea>\n </div>\n ) as HTMLElement\n\n ui.previewWrapper.appendChild(header)\n ui.previewWrapper.appendChild(previewBox)\n ui.previewWrapper.appendChild(filenameEditor)\n ui.previewWrapper.appendChild(descEditor)\n }\n\n const uploadOne = async (item: UploadItem) => {\n updateItem(item.id, { status: 'uploading', message: undefined })\n renderList()\n await renderPreview()\n\n const body = buildUploadBody(item)\n\n this.ctx.emit('analytics/event', {\n feature: 'quick-upload',\n page: body.filename?.toString() || undefined,\n })\n\n try {\n const result = await this.ctx.wikiFile.upload(body)\n\n if (result.data?.upload?.result === 'Success') {\n const fileUrl = this.ctx.wikiFile.getFileUrl(`File:${result.data.upload.filename}`)\n updateItem(item.id, {\n status: 'success',\n fileUrl,\n result: result.data.upload as any,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n throw result\n } catch (e) {\n let reasons: string[] = []\n\n if ((e as any)?.data?.upload) {\n const uploadResult = (e as any).data.upload as UploadFileResult\n\n if (uploadResult.result === 'Success') {\n const fname = (uploadResult as any).filename || body.filename\n const fileUrl = this.ctx.wikiFile.getFileUrl(`File:${fname}`)\n updateItem(item.id, {\n status: 'success',\n fileUrl,\n result: uploadResult,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n if (\n Array.isArray(uploadResult.warnings?.duplicate) &&\n uploadResult.warnings.duplicate.length > 0\n ) {\n reasons.push(`Duplicate of: ${uploadResult.warnings.duplicate.join(', ')}`)\n updateItem(item.id, {\n status: 'warning',\n message: reasons.join('\\n'),\n result: uploadResult,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n if (uploadResult.warnings?.exists) {\n reasons.push('A file with the same name already exists.')\n updateItem(item.id, {\n status: 'warning',\n message: reasons.join('\\n'),\n result: uploadResult,\n retryable: true,\n })\n renderList()\n await renderPreview()\n return\n }\n\n const { message, retryable } = formatUploadError(e)\n updateItem(item.id, { status: 'error', message, retryable })\n renderList()\n await renderPreview()\n return\n }\n\n const { message, retryable } = formatUploadError(e)\n updateItem(item.id, { status: 'error', message, retryable })\n renderList()\n await renderPreview()\n }\n }\n\n const uploadAll = async (mode: UploadMode = 'all') => {\n if (isUploading) return\n\n let candidates = getUploadCandidates(mode, items)\n\n if (mode === 'retry') {\n if (candidates.length === 0) {\n showMessage(\n 'warning',\n 'Nothing to retry',\n <div>There are no retryable failed/warning items.</div>\n )\n return\n }\n } else if (mode === 'resume') {\n if (candidates.length === 0) {\n showMessage(\n 'warning',\n 'Nothing to resume',\n <div>There are no queued paused items to continue.</div>\n )\n return\n }\n } else {\n if (items.length === 0) {\n showMessage(\n 'warning',\n $`No files selected`,\n <div>{$`Please select one or more files.`}</div>\n )\n return\n }\n if (items.length > confirmThreshold) {\n this.ctx.modal.confirm(\n {\n title: $`Confirm bulk upload`,\n content: (\n <div>\n {$`You are about to upload`} <strong>{items.length}</strong>{' '}\n {$`files at once. Are you sure?`}\n </div>\n ),\n center: true,\n okBtn: { label: $`Upload`, className: 'is-primary is-ghost' },\n cancelBtn: { label: $`Cancel`, className: 'is-danger is-ghost' },\n },\n (confirmed) => {\n if (confirmed) {\n void uploadAll('all')\n }\n return true\n }\n )\n return\n }\n }\n\n if (mode === 'retry') {\n prepareRetryState(candidates)\n renderList()\n await renderPreview()\n candidates = getUploadCandidates('retry', items)\n }\n\n isUploading = true\n pauseRequested = false\n updateFooter()\n\n try {\n const total = candidates.length\n let done = 0\n setProgress(0, total)\n\n for (const item of candidates) {\n if (pauseRequested) {\n const remainingIds = new Set(candidates.slice(done).map((x) => x.id))\n updateMany(remainingIds, (x) =>\n x.status === 'queued' || x.status === 'uploading'\n ? { ...x, status: 'paused', message: 'Paused by user', retryable: true }\n : x\n )\n renderList()\n await renderPreview()\n break\n }\n\n const current = items.find((x) => x.id === item.id)\n if (!current) {\n done++\n setProgress(done, total)\n continue\n }\n\n await uploadOne(current)\n done++\n setProgress(done, total)\n }\n\n const { ok, warn, err, paused } = countByStatus()\n if (paused > 0) {\n showMessage(\n 'warning',\n 'Upload paused',\n <div>\n <div>\n Uploaded: <strong>{ok}</strong>\n </div>\n <div>\n Warnings: <strong>{warn}</strong>\n </div>\n <div>\n Errors: <strong>{err}</strong>\n </div>\n <div>\n Paused: <strong>{paused}</strong>\n </div>\n </div>\n )\n } else if (err === 0 && warn === 0) {\n showMessage(\n 'success',\n 'Upload completed',\n <div>\n <strong>All files uploaded successfully.</strong>\n <div>\n Uploaded: <strong>{ok}</strong>\n </div>\n </div>\n )\n } else {\n showMessage(\n 'warning',\n 'Upload completed with issues',\n <div>\n <div>\n Uploaded: <strong>{ok}</strong>\n </div>\n {warn ? (\n <div>\n Warnings: <strong>{warn}</strong>\n </div>\n ) : null}\n {err ? (\n <div>\n Errors: <strong>{err}</strong>\n </div>\n ) : null}\n </div>\n )\n }\n } finally {\n isUploading = false\n updateFooter()\n }\n }\n\n const handleDrop = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n const container = e.currentTarget as HTMLElement\n container?.classList.remove('is-dragover')\n\n const files = Array.from(e.dataTransfer?.files || [])\n if (!files.length) return\n addFiles(files)\n }\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n const container = e.currentTarget as HTMLElement\n if (e.dataTransfer) e.dataTransfer.dropEffect = 'copy'\n container?.classList.add('is-dragover')\n }\n\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n const container = e.currentTarget as HTMLElement\n container?.classList.remove('is-dragover')\n }\n\n const progressBar = (\n <div style={{ marginBottom: '10px' }}>\n <div\n style={{\n height: '8px',\n borderRadius: '999px',\n background: 'rgba(0,0,0,.08)',\n overflow: 'hidden',\n }}\n >\n <div\n ref={(el: any) => {\n ui.progressEl = el\n }}\n style={{\n height: '100%',\n width: '0%',\n background: 'var(--ipe-primary, #3b82f6)',\n transition: 'width .2s ease',\n }}\n />\n </div>\n <div\n style={{\n marginTop: '6px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '10px',\n }}\n >\n <div\n ref={(el: any) => {\n ui.progressTextEl = el\n }}\n style={{ fontSize: '12px', opacity: 0.8 }}\n >\n 0/0 (0%)\n </div>\n </div>\n </div>\n ) as HTMLElement\n\n const leftPanel = (\n <section style={{ display: 'grid', gap: '10px', minWidth: 0 }}>\n <div className=\"ipe-input-box\">\n <label htmlFor=\"mu_files\">\n Files{' '}\n {items.length > 0 ? (\n <span style={{ opacity: 0.85 }}>({items.length} selected)</span>\n ) : null}\n </label>\n <input\n id=\"mu_files\"\n type=\"file\"\n multiple\n accept={String(accept || '')}\n disabled={isUploading}\n ref={(el: any) => {\n ui.fileInput = el\n }}\n onChange={(e: Event) => {\n const files = Array.from((e.target as HTMLInputElement).files || [])\n addFiles(files)\n ;(e.target as HTMLInputElement).value = ''\n }}\n />\n </div>\n\n <div\n ref={(el: any) => {\n ui.listEl = el\n }}\n />\n </section>\n ) as HTMLElement\n\n const rightPanel = (\n <section style={{ display: 'grid', gap: '10px' }}>\n <div\n className=\"ipe-quickUpload__preview\"\n ref={(el: any) => {\n ui.previewWrapper = el\n }}\n onClick={(e) => {\n const target = e.target\n if (\n target &&\n (target as HTMLElement).closest('img, .ipe-quickUpload__preview-placeholder')\n ) {\n e.preventDefault()\n ui.fileInput?.click()\n }\n }}\n style={{\n border: '1px solid var(--ipe-border-color, rgba(0,0,0,.12))',\n borderRadius: '8px',\n padding: '10px',\n minWidth: 0,\n }}\n />\n </section>\n ) as HTMLElement\n\n const containerEl = (\n <section\n className=\"ipe-quickUpload__container\"\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n style={{ display: 'grid', gap: '12px' }}\n >\n {progressBar}\n <div className=\"ipe-quickUpload__layout\">\n {leftPanel}\n {rightPanel}\n </div>\n\n <div\n style={{\n borderTop: '1px solid var(--ipe-border-color, rgba(0,0,0,.12))',\n paddingTop: '10px',\n display: 'grid',\n gap: '10px',\n }}\n >\n <div className=\"ipe-input-box\">\n <label htmlFor=\"mu_summary\">Summary (applies to all files)</label>\n <textarea\n id=\"mu_summary\"\n disabled={isUploading}\n ref={(el: any) => {\n ui.summaryInput = el\n }}\n onInput={() => {}}\n />\n </div>\n\n <CheckBox\n name=\"ignorewarnings\"\n label={$`Ignore warnings and upload anyway`}\n inputProps={{\n disabled: isUploading,\n ref: (el: any) => {\n ui.ignoreWarnings = el\n },\n }}\n />\n </div>\n </section>\n ) as HTMLElement\n\n modal.setContent(containerEl)\n\n if (ui.summaryInput) ui.summaryInput.value = String(defaultSummary || '')\n\n const updateFooter = () => {\n const { warn, err, paused } = countByStatus()\n const hasFailed = err > 0 || warn > 0\n const hasPaused = paused > 0\n\n let label = $`Upload`\n let action = () => void uploadAll('all')\n let className = 'is-primary is-text'\n\n if (isUploading) {\n label = pauseRequested ? 'Pausing...' : 'Pause after current'\n action = () => {\n pauseRequested = true\n updateFooter()\n }\n } else if (hasPaused) {\n label = 'Resume'\n action = () => void uploadAll('resume')\n } else if (hasFailed) {\n label = 'Retry failed/warnings'\n action = () => void uploadAll('retry')\n }\n\n modal.setButtons([\n {\n label: $`Cancel`,\n className: 'is-danger is-text',\n method: () => modal.close(),\n },\n {\n label: 'Reset',\n className: 'is-text',\n method: () => {\n if (isUploading) return\n resetAll()\n },\n },\n {\n label,\n className,\n method: action,\n },\n ])\n }\n\n renderList()\n await renderPreview()\n\n return modal\n }\n}\n"],"names":["_PluginQuickUpload_decorators","_init","_a","PreviewPlaceholderNA","$","jsxs","jsx","RegisterPreferences","Schema","Inject","PluginQuickUpload","BasePlugin","ctx","IconUpload","e","size","units","index","file","accept","rules","s","fileType","fileName","rule","prefix","isUploading","pauseRequested","showMessage","type","title","content","modal","defaultSummary","confirmThreshold","items","selectedId","ui","updateItem","id","patch","x","removeItem","updateMany","ids","fn","summarizeApiErrors","out","v","cur","formatUploadError","reasons","combined","lower","shouldRetryItem","it","getUploadCandidates","mode","list","prepareRetryState","candidates","idset","c","getSelected","setSelected","renderList","renderPreview","countByStatus","setProgress","done","total","pct","sanitizeFilename","name","resetAll","addFiles","files","accepted","f","newItems","buildUploadBody","item","body","summary","getStatusLabel","status","isActive","row","updateFooter","header","previewEl","previewBox","isLocked","filenameEditor","descEditor","uploadOne","result","fileUrl","uploadResult","fname","message","retryable","uploadAll","confirmed","remainingIds","current","ok","warn","err","paused","handleDrop","handleDragOver","container","handleDragLeave","progressBar","el","leftPanel","containerEl","target","CheckBox","hasFailed","hasPaused","label","action","className","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as r, P as m } from "./Promise.withResolvers-C4chhLB1.js";
|
|
2
|
-
import { S as d } from "./index-
|
|
2
|
+
import { S as d } from "./index-BAJiXDPz.js";
|
|
3
3
|
import { BasePlugin as h } from "./core.js";
|
|
4
4
|
import { T as u } from "./index-z_qDGCMT.js";
|
|
5
5
|
import { I as f } from "./InputBox-D2ZRTMFP.js";
|
|
@@ -171,4 +171,4 @@ class P extends h {
|
|
|
171
171
|
export {
|
|
172
172
|
P as PluginQuickRedirect
|
|
173
173
|
};
|
|
174
|
-
//# sourceMappingURL=index-
|
|
174
|
+
//# sourceMappingURL=index-CoX1x5ls.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-Dfdy54gH.js","sources":["../src/plugins/quick-redirect/index.tsx"],"sourcesContent":["import { InPageEdit, Schema } from '@/InPageEdit'\nimport { IPEModal } from '@inpageedit/modal'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickRedirect: PluginQuickRedirect\n }\n interface Events {\n 'quick-redirect/init-options'(payload: {\n ctx: InPageEdit\n options: Partial<QuickRedirectOptions>\n }): void\n 'quick-redirect/show-modal'(payload: { ctx: InPageEdit; modal: IPEModal }): void\n 'quick-redirect/submit'(payload: { ctx: InPageEdit; payload: RedirectPageOptions }): void\n }\n interface PreferencesMap {\n 'quickRedirect.reason': string\n }\n}\n\nexport interface RedirectPageOptions {\n from: string\n to: string\n reason?: string\n overwrite?: boolean\n}\nexport interface QuickRedirectOptions extends Partial<RedirectPageOptions> {}\n\nexport class PluginQuickRedirect extends BasePlugin {\n static readonly inject = ['api', 'wikiPage', 'modal', '$']\n static readonly PreferencesSchema = Schema.object({\n 'quickRedirect.reason': Schema.string().default('[IPE-NEXT] Quick redirect'),\n })\n .description('Quick redirect options')\n .extra('category', 'editor')\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-redirect')\n }\n\n protected start(): Promise<void> | void {\n this.ctx.set('quickRedirect', this)\n const { $ } = this.ctx\n\n const curPageName = window.mw?.config.get('wgPageName') || ''\n const canEdit = window.mw?.config.get('wgIsProbablyEditable')\n this.ctx.inject(['toolbox'], (ctx) => {\n this.ctx = ctx\n ctx.toolbox.addButton({\n id: 'quick-redirect',\n icon: (\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-file-symlink\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 21v-4a3 3 0 0 1 3 -3h5\" />\n <path d=\"M9 17l3 -3l-3 -3\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M5 11v-6a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-9.5\" />\n </svg>\n ) as HTMLElement,\n tooltip: () => $`Quick Redirect`,\n group: 'group1',\n index: 2,\n onClick: () => {\n this.showModal(\n canEdit\n ? {\n to: curPageName,\n }\n : {}\n )\n },\n })\n this.addDisposeHandler((ctx) => {\n ctx.toolbox.removeButton('quick-redirect')\n })\n })\n }\n\n protected stop(): Promise<void> | void {}\n\n async showModal(options?: Partial<QuickRedirectOptions>) {\n const { $ } = this.ctx\n const reason = await this.ctx.preferences.get('quickRedirect.reason')\n if (!options) {\n options = {}\n }\n this.ctx.emit('quick-redirect/init-options', { ctx: this.ctx, options })\n const modal = this.ctx.modal\n .createObject({\n title: $`Quick Redirect`,\n content: (<ProgressBar />) as HTMLElement,\n className: 'quick-redirect compact-buttons',\n sizeClass: 'smallToMedium',\n center: true,\n })\n .init()\n\n let formRef: HTMLFormElement | null = null\n modal.setContent(\n (\n <form\n ref={(el) => (formRef = el)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n }}\n onSubmit={(e) => {\n e.preventDefault()\n formRef?.checkValidity()\n if (!formRef?.reportValidity()) {\n return\n }\n const formData = new FormData(formRef!)\n const options = {\n from: formData.get('from')?.toString().trim()!,\n to: formData.get('to')?.toString().trim()!,\n reason: (formData.get('reason') as string) || '',\n overwrite: formData.get('overwrite') === 'on',\n }\n if (!options.from || !options.to) {\n this.ctx.modal.notify('error', {\n title: $`Failed to redirect`,\n content: $`From and to are required.`,\n })\n return\n }\n this.ctx.emit('quick-redirect/submit', { ctx: this.ctx, payload: options })\n modal.setLoadingState(true)\n this.redirectPage(options)\n .then((res) => {\n modal.close()\n this.ctx.modal.notify('success', {\n title: $`Redirect successful`,\n content: $`The redirect has been created.`,\n })\n })\n .catch((error) => {\n modal.setLoadingState(false)\n this.ctx.modal.notify('error', {\n title: $`Failed to redirect`,\n content: error instanceof Error ? error.message : String(error),\n })\n })\n }}\n >\n <TwinSwapInput\n inputs={[\n {\n label: $`Redirect from`,\n name: 'from',\n value: options?.from,\n required: true,\n },\n {\n label: $`Redirect to`,\n name: 'to',\n value: options?.to,\n required: true,\n },\n ]}\n />\n <InputBox\n label={$`Reason`}\n id=\"reason\"\n name=\"reason\"\n value={options?.reason ?? reason ?? ''}\n />\n <div>\n <CheckBox name=\"overwrite\" id=\"overwrite\" checked={options?.overwrite}>\n {$`Force create redirect even if the from page already exists`}\n </CheckBox>\n </div>\n </form>\n ) as HTMLFormElement\n )\n modal.setButtons([\n {\n label: $`Create Redirect`,\n className: 'is-primary is-ghost',\n method: () => {\n formRef?.dispatchEvent(new Event('submit'))\n },\n },\n ])\n\n this.ctx.emit('quick-redirect/show-modal', { ctx: this.ctx, modal })\n\n return modal.show()\n }\n\n async redirectPage(options: RedirectPageOptions) {\n const { from, to, reason = '', overwrite = false } = options\n const wikiPage = await this.ctx.wikiPage.newBlankPage({\n title: from,\n })\n const content = `#REDIRECT [[:${to}]]`\n return wikiPage.edit(\n {\n text: content,\n summary: reason,\n },\n {\n createonly: !overwrite,\n }\n )\n }\n}\n"],"names":["PluginQuickRedirect","BasePlugin","ctx","Schema","$","curPageName","canEdit","jsxs","jsx","options","reason","modal","ProgressBar","formRef","el","e","formData","res","error","TwinSwapInput","InputBox","CheckBox","from","to","overwrite","wikiPage","content"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CoX1x5ls.js","sources":["../src/plugins/quick-redirect/index.tsx"],"sourcesContent":["import { InPageEdit, Schema } from '@/InPageEdit'\nimport { IPEModal } from '@inpageedit/modal'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickRedirect: PluginQuickRedirect\n }\n interface Events {\n 'quick-redirect/init-options'(payload: {\n ctx: InPageEdit\n options: Partial<QuickRedirectOptions>\n }): void\n 'quick-redirect/show-modal'(payload: { ctx: InPageEdit; modal: IPEModal }): void\n 'quick-redirect/submit'(payload: { ctx: InPageEdit; payload: RedirectPageOptions }): void\n }\n interface PreferencesMap {\n 'quickRedirect.reason': string\n }\n}\n\nexport interface RedirectPageOptions {\n from: string\n to: string\n reason?: string\n overwrite?: boolean\n}\nexport interface QuickRedirectOptions extends Partial<RedirectPageOptions> {}\n\nexport class PluginQuickRedirect extends BasePlugin {\n static readonly inject = ['api', 'wikiPage', 'modal', '$']\n static readonly PreferencesSchema = Schema.object({\n 'quickRedirect.reason': Schema.string().default('[IPE-NEXT] Quick redirect'),\n })\n .description('Quick redirect options')\n .extra('category', 'editor')\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-redirect')\n }\n\n protected start(): Promise<void> | void {\n this.ctx.set('quickRedirect', this)\n const { $ } = this.ctx\n\n const curPageName = window.mw?.config.get('wgPageName') || ''\n const canEdit = window.mw?.config.get('wgIsProbablyEditable')\n this.ctx.inject(['toolbox'], (ctx) => {\n this.ctx = ctx\n ctx.toolbox.addButton({\n id: 'quick-redirect',\n icon: (\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-file-symlink\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M4 21v-4a3 3 0 0 1 3 -3h5\" />\n <path d=\"M9 17l3 -3l-3 -3\" />\n <path d=\"M14 3v4a1 1 0 0 0 1 1h4\" />\n <path d=\"M5 11v-6a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-9.5\" />\n </svg>\n ) as HTMLElement,\n tooltip: () => $`Quick Redirect`,\n group: 'group1',\n index: 2,\n onClick: () => {\n this.showModal(\n canEdit\n ? {\n to: curPageName,\n }\n : {}\n )\n },\n })\n this.addDisposeHandler((ctx) => {\n ctx.toolbox.removeButton('quick-redirect')\n })\n })\n }\n\n protected stop(): Promise<void> | void {}\n\n async showModal(options?: Partial<QuickRedirectOptions>) {\n const { $ } = this.ctx\n const reason = await this.ctx.preferences.get('quickRedirect.reason')\n if (!options) {\n options = {}\n }\n this.ctx.emit('quick-redirect/init-options', { ctx: this.ctx, options })\n const modal = this.ctx.modal\n .createObject({\n title: $`Quick Redirect`,\n content: (<ProgressBar />) as HTMLElement,\n className: 'quick-redirect compact-buttons',\n sizeClass: 'smallToMedium',\n center: true,\n })\n .init()\n\n let formRef: HTMLFormElement | null = null\n modal.setContent(\n (\n <form\n ref={(el) => (formRef = el)}\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '1rem',\n }}\n onSubmit={(e) => {\n e.preventDefault()\n formRef?.checkValidity()\n if (!formRef?.reportValidity()) {\n return\n }\n const formData = new FormData(formRef!)\n const options = {\n from: formData.get('from')?.toString().trim()!,\n to: formData.get('to')?.toString().trim()!,\n reason: (formData.get('reason') as string) || '',\n overwrite: formData.get('overwrite') === 'on',\n }\n if (!options.from || !options.to) {\n this.ctx.modal.notify('error', {\n title: $`Failed to redirect`,\n content: $`From and to are required.`,\n })\n return\n }\n this.ctx.emit('quick-redirect/submit', { ctx: this.ctx, payload: options })\n modal.setLoadingState(true)\n this.redirectPage(options)\n .then((res) => {\n modal.close()\n this.ctx.modal.notify('success', {\n title: $`Redirect successful`,\n content: $`The redirect has been created.`,\n })\n })\n .catch((error) => {\n modal.setLoadingState(false)\n this.ctx.modal.notify('error', {\n title: $`Failed to redirect`,\n content: error instanceof Error ? error.message : String(error),\n })\n })\n }}\n >\n <TwinSwapInput\n inputs={[\n {\n label: $`Redirect from`,\n name: 'from',\n value: options?.from,\n required: true,\n },\n {\n label: $`Redirect to`,\n name: 'to',\n value: options?.to,\n required: true,\n },\n ]}\n />\n <InputBox\n label={$`Reason`}\n id=\"reason\"\n name=\"reason\"\n value={options?.reason ?? reason ?? ''}\n />\n <div>\n <CheckBox name=\"overwrite\" id=\"overwrite\" checked={options?.overwrite}>\n {$`Force create redirect even if the from page already exists`}\n </CheckBox>\n </div>\n </form>\n ) as HTMLFormElement\n )\n modal.setButtons([\n {\n label: $`Create Redirect`,\n className: 'is-primary is-ghost',\n method: () => {\n formRef?.dispatchEvent(new Event('submit'))\n },\n },\n ])\n\n this.ctx.emit('quick-redirect/show-modal', { ctx: this.ctx, modal })\n\n return modal.show()\n }\n\n async redirectPage(options: RedirectPageOptions) {\n const { from, to, reason = '', overwrite = false } = options\n const wikiPage = await this.ctx.wikiPage.newBlankPage({\n title: from,\n })\n const content = `#REDIRECT [[:${to}]]`\n return wikiPage.edit(\n {\n text: content,\n summary: reason,\n },\n {\n createonly: !overwrite,\n }\n )\n }\n}\n"],"names":["PluginQuickRedirect","BasePlugin","ctx","Schema","$","curPageName","canEdit","jsxs","jsx","options","reason","modal","ProgressBar","formRef","el","e","formData","res","error","TwinSwapInput","InputBox","CheckBox","from","to","overwrite","wikiPage","content"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as l } from "./Promise.withResolvers-C4chhLB1.js";
|
|
2
|
-
import { d as M, g as f, R as L, a as I, S as v } from "./index-
|
|
2
|
+
import { d as M, g as f, R as L, a as I, S as v } from "./index-BAJiXDPz.js";
|
|
3
3
|
var N = Object.create, x = Object.defineProperty, q = Object.getOwnPropertyDescriptor, _ = (i, t) => (t = Symbol[i]) ? t : /* @__PURE__ */ Symbol.for("Symbol." + i), w = (i) => {
|
|
4
4
|
throw TypeError(i);
|
|
5
5
|
}, A = (i, t, e) => t in i ? x(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e, T = (i, t) => x(i, "name", { value: t, configurable: !0 }), C = (i) => [, , , N(i?.[_("metadata")] ?? null)], E = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], P = (i) => i !== void 0 && typeof i != "function" ? w("Function expected") : i, k = (i, t, e, n, o) => ({ kind: E[i], name: t, metadata: n, addInitializer: (r) => e._ ? w("Already initialized") : o.push(P(r || null)) }), D = (i, t) => A(t, _("metadata"), i[3]), z = (i, t, e, n) => {
|
|
@@ -192,4 +192,4 @@ z(m, 1, b);
|
|
|
192
192
|
export {
|
|
193
193
|
b as PluginToolbox
|
|
194
194
|
};
|
|
195
|
-
//# sourceMappingURL=index-
|
|
195
|
+
//# sourceMappingURL=index-D8_-baBt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-DvFkW8lL.js","sources":["../src/plugins/toolbox/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema, Service } from '@/InPageEdit'\nimport { JSX, ReactElement } from 'jsx-dom'\nimport './styles.scss'\nimport { ComputeAbleSync } from '@/utils/computeable.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n toolbox: PluginToolbox\n }\n interface Events {\n 'toolbox/button-added'(payload: { ctx: InPageEdit; payload: ToolboxButton }): void\n 'toolbox/button-removed'(payload: { ctx: InPageEdit; payload: ToolboxButton }): void\n 'toolbox/button-clicked'(payload: {\n ctx: InPageEdit\n event: MouseEvent\n payload: ToolboxButton\n }): void\n 'toolbox/toggle'(payload: { ctx: InPageEdit; opened: boolean }): void\n }\n interface PreferencesMap {\n toolboxAlwaysShow: boolean\n }\n}\n\ninterface ToolboxButton {\n id: string\n group?: 'auto' | 'group1' | 'group2'\n icon: ComputeAbleSync<string | HTMLElement | SVGElement | ReactElement>\n tooltip?: ComputeAbleSync<string | HTMLElement>\n itemProps?: JSX.IntrinsicElements['li']\n buttonProps?: JSX.IntrinsicElements['button']\n onClick?: (event: MouseEvent) => void\n index?: number // 任意数值均可:负数靠前、正数靠后、Infinity 末尾、未传时按插入顺序\n}\n\n@RegisterPreferences(\n Schema.object({\n toolboxAlwaysShow: Schema.boolean()\n .description('Make the toolbox opened by default')\n .default(false),\n }).description('Toolbox preferences')\n)\n@Inject(['preferences'])\nexport class PluginToolbox extends Service {\n container!: HTMLElement\n\n // ==== 内部状态 ====\n private buttons: ToolboxButton[] = []\n\n // 插入顺序序列号:用于当 index 未给时保持“自然顺序”\n private seqCounter = 0\n private seqMap = new Map<string, number>() // id -> seq\n\n constructor(public ctx: InPageEdit) {\n super(ctx, 'toolbox', false)\n }\n\n protected async start(): Promise<void> {\n this.container = this.createToolbox()\n this.ctx.preferences.get('toolboxAlwaysShow').then((val) => {\n if (val) {\n this.container.classList.add('is-persistent')\n }\n })\n this.setupHoverLogic()\n document.body.appendChild(this.container)\n\n // 国际化变化时重新渲染\n this.ctx.on('i18n/changed', () => {\n console.info('i18n/changed', this.buttons)\n this.renderAll()\n })\n }\n\n protected stop(): void | Promise<void> {\n this.container?.remove()\n }\n\n private get isPersistent() {\n return this.container.classList.contains('is-persistent')\n }\n\n private setupHoverLogic() {\n let hoverTimeout: number | null = null\n\n // 鼠标进入时暂时展开\n this.container.addEventListener('mouseenter', () => {\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n hoverTimeout = null\n }\n\n // 如果不在持久化状态,则添加hover展开效果\n if (!this.isPersistent) {\n this.container.classList.add('is-hovered')\n }\n })\n\n // 鼠标离开时收起(如果不是持久化状态)\n this.container.addEventListener('mouseleave', () => {\n if (!this.isPersistent) {\n hoverTimeout = window.setTimeout(() => {\n this.container.classList.remove('is-hovered')\n }, 150) // 延迟150ms收起,避免快速移动鼠标时闪烁\n }\n })\n }\n\n /**\n * 计算按钮动画延迟\n * @param index 按钮索引(从0开始)\n * @param totalCount 总按钮数量\n * @returns 延迟时间(秒)\n */\n private calculateButtonDelay(index: number, totalCount: number): number {\n if (totalCount <= 1) return 0\n\n // 总动画时长150ms = 0.15s\n const totalDuration = 0.15\n // 使用平方根函数创建非线性延迟,差值逐渐缩小\n const normalizedIndex = index / (totalCount - 1)\n const delay = totalDuration * Math.sqrt(normalizedIndex)\n\n return Math.round(delay * 1000) / 1000 // 保留3位小数\n }\n\n /**\n * 更新按钮组的动画延迟\n */\n private updateButtonDelays() {\n const btnGroups = this.container.querySelectorAll('.btn-group')\n\n btnGroups.forEach((group) => {\n const buttons = group.querySelectorAll('.btn-tip-group')\n const totalCount = buttons.length\n\n buttons.forEach((button, index) => {\n const delay = this.calculateButtonDelay(index, totalCount)\n ;(button as HTMLElement).style.setProperty('--transition-delay', `${delay}s`)\n ;(button as HTMLElement).style.setProperty('--max-transition-delay', '0.15s')\n })\n })\n }\n\n private createToolbox() {\n const toggler = (\n <button\n className=\"ipe-toolbox-btn\"\n id=\"toolbox-toggler\"\n onClick={() => {\n this.toggle()\n }}\n >\n {/* Font Awesome 5 Solid: Plus */}\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"448\" height=\"512\" viewBox=\"0 0 448 512\">\n <rect width=\"448\" height=\"512\" fill=\"none\" />\n <path\n fill=\"currentColor\"\n d=\"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32\"\n />\n </svg>\n </button>\n )\n const element = (\n <div id=\"ipe-edit-toolbox\">\n <ul className=\"btn-group group1\" style={{ display: 'flex', flexDirection: 'column' }}></ul>\n <ul className=\"btn-group group2\" style={{ display: 'flex', flexDirection: 'row' }}></ul>\n {toggler}\n </div>\n )\n\n return element as HTMLElement\n }\n\n private normalizeButtonId(id: string) {\n if (!id) {\n id = Math.random().toString(36).substring(2, 8)\n }\n // 修复:正确替换空白/点/井号(保留语义,修正正则)\n return `ipe-toolbox__${id.trim()}`.replace(/[\\s.#]+/g, '-')\n }\n\n // ====== 排序与分组 ======\n private chooseAutoGroup(): 'group1' | 'group2' {\n const g1 = this.buttons.filter((b) => b.group === 'group1').length\n const g2 = this.buttons.filter((b) => b.group === 'group2').length\n return g1 <= g2 ? 'group1' : 'group2'\n }\n\n // 归一化排序键:\n // 1) 若 index 是有限数值 => 直接使用(允许负数/小数/很大数);\n // 2) 若为 Infinity / -Infinity => 自然比较;\n // 3) 若 NaN / 未提供 => 返回 null,后续用插入顺序(seq)比较。\n private orderKey(btn: ToolboxButton): number | null {\n const idx = (btn as any).index\n if (typeof idx === 'number') {\n if (Number.isNaN(idx)) return null\n return idx // 包含 Infinity 与 -Infinity\n }\n return null\n }\n\n private compareButtons = (a: ToolboxButton, b: ToolboxButton) => {\n const ak = this.orderKey(a) // number | null\n const bk = this.orderKey(b)\n\n const va = ak ?? 0\n const vb = bk ?? 0\n\n if (va < vb) return -1\n if (va > vb) return 1\n\n // 有效值相等时的细化:\n const sa = this.seqMap.get(a.id) ?? 0\n const sb = this.seqMap.get(b.id) ?? 0\n\n if (ak === null && bk === null) {\n if (sa !== sb) return sa - sb\n return 0 // 不以 id 再兜底,保持稳定排序\n }\n\n if (ak === null && bk !== null) return -1 // 无 index(按0) 优先于 数值 index=0\n if (ak !== null && bk === null) return 1\n\n // 双方都有 index 且值相等,退化到 seq;仍然相等时返回 0\n if (sa !== sb) return sa - sb\n return 0\n }\n\n // ====== 对外 API:新增/替换/删除 ======\n addButton(payload: ToolboxButton) {\n // 统一化 id(保留原意:若缺失则补)\n payload.id = (payload.id || '').trim()\n if (!payload.id) {\n this.ctx.logger('toolbox').warn('Button id is empty, generating a random one.')\n payload.id = Math.random().toString(36).slice(2, 10)\n }\n\n const existingIndex = this.buttons.findIndex((button) => button.id === payload.id)\n\n // 分组:新增时 auto,替换时默认保留原组,除非明确指定\n const nextGroup: 'group1' | 'group2' = (() => {\n if (existingIndex !== -1) {\n const old = this.buttons[existingIndex]\n return !payload.group || payload.group === 'auto' ? (old.group as any) : payload.group\n }\n return !payload.group || payload.group === 'auto' ? this.chooseAutoGroup() : payload.group\n })()\n\n // 序列号:用于 index 未提供时,保持插入顺序\n if (!this.seqMap.has(payload.id)) {\n this.seqMap.set(payload.id, this.seqCounter++)\n }\n\n if (existingIndex !== -1) {\n // 替换:保留旧的 seq,不动;index 未传则沿用旧值\n const old = this.buttons[existingIndex]\n const incomingIndex =\n typeof payload.index === 'number' && !Number.isNaN(payload.index)\n ? payload.index\n : old.index\n const merged: ToolboxButton = { ...old, ...payload, group: nextGroup, index: incomingIndex }\n\n this.buttons.splice(existingIndex, 1, merged)\n } else {\n // 新增:按给定 index 或留空;只设置组\n const incomingIndex =\n typeof payload.index === 'number' && !Number.isNaN(payload.index)\n ? payload.index\n : undefined\n const fresh: ToolboxButton = { ...payload, group: nextGroup, index: incomingIndex }\n this.buttons.push(fresh)\n }\n\n this.ctx.emit('toolbox/button-added', { ctx: this.ctx, payload })\n this.renderAll()\n }\n\n removeButton(id: string) {\n const index = this.buttons.findIndex((button) => button.id === id)\n if (index !== -1) {\n const payload = this.buttons[index]\n this.buttons.splice(index, 1)\n // 可选择是否保留 seq,使得将来同 id 重加时仍按旧顺序;这里删除时保留更合理\n this.ctx.emit('toolbox/button-removed', { ctx: this.ctx, payload })\n this.renderAll()\n }\n }\n\n // ====== 渲染 ======\n private renderButton(payload: ToolboxButton) {\n let { id, icon, index, tooltip, itemProps, buttonProps, onClick } = payload\n const normalizedId = this.normalizeButtonId(id)\n\n // 结构尽量保持,避免在 <li> 上绑定 click 造成双触发\n const element = (\n <li class=\"btn-tip-group\" id={normalizedId} data-id={id} data-index={index} {...itemProps}>\n <div class=\"btn-tip\">{computeFallbackSync(tooltip)}</div>\n <button\n id={`${normalizedId}-btn`}\n data-id={payload.id}\n class=\"ipe-toolbox-btn\"\n onClick={(e: any) => {\n onClick?.(e as MouseEvent)\n this.ctx.emit('toolbox/button-clicked', {\n ctx: this.ctx,\n event: e as MouseEvent,\n payload,\n })\n }}\n {...buttonProps}\n >\n {computeFallbackSync(icon)}\n </button>\n </li>\n )\n\n return element as HTMLElement\n }\n\n private renderAll() {\n const group1 = this.buttons\n .filter((b) => b.group === 'group1')\n .slice()\n .sort(this.compareButtons)\n const group2 = this.buttons\n .filter((b) => b.group === 'group2')\n .slice()\n .sort(this.compareButtons)\n\n const group1El = this.container.querySelector('.btn-group.group1') as HTMLElement\n const group2El = this.container.querySelector('.btn-group.group2') as HTMLElement\n\n group1El.innerHTML = ''\n group2El.innerHTML = ''\n\n group1.forEach((button) => {\n group1El.appendChild(this.renderButton(button))\n })\n group2.forEach((button) => {\n group2El.appendChild(this.renderButton(button))\n })\n\n // 统一更新动画延迟\n this.updateButtonDelays()\n }\n\n getContainer() {\n return this.container\n }\n\n get isOpened() {\n return (\n this.container.classList.contains('is-persistent') ||\n this.container.classList.contains('is-hovered')\n )\n }\n\n toggle(force?: boolean) {\n const isPersistent = this.isPersistent\n const newPersistent = typeof force === 'boolean' ? force : !isPersistent\n this.container.classList.toggle('is-persistent', newPersistent)\n this.container.classList.remove('is-hovered')\n this.ctx.preferences.set('toolboxAlwaysShow', newPersistent)\n this.ctx.emit('toolbox/toggle', { ctx: this.ctx, opened: this.isOpened })\n }\n}\n"],"names":["_PluginToolbox_decorators","_init","_a","RegisterPreferences","Schema","Inject","PluginToolbox","Service","ctx","a","b","ak","bk","va","vb","sa","sb","val","hoverTimeout","index","totalCount","totalDuration","normalizedIndex","delay","group","buttons","button","jsxs","jsx","id","g1","g2","btn","idx","payload","existingIndex","nextGroup","old","incomingIndex","merged","fresh","icon","tooltip","itemProps","buttonProps","onClick","normalizedId","computeFallbackSync","e","group1","group2","group1El","group2El","force","isPersistent","newPersistent","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-D8_-baBt.js","sources":["../src/plugins/toolbox/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema, Service } from '@/InPageEdit'\nimport { JSX, ReactElement } from 'jsx-dom'\nimport './styles.scss'\nimport { ComputeAbleSync } from '@/utils/computeable.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n toolbox: PluginToolbox\n }\n interface Events {\n 'toolbox/button-added'(payload: { ctx: InPageEdit; payload: ToolboxButton }): void\n 'toolbox/button-removed'(payload: { ctx: InPageEdit; payload: ToolboxButton }): void\n 'toolbox/button-clicked'(payload: {\n ctx: InPageEdit\n event: MouseEvent\n payload: ToolboxButton\n }): void\n 'toolbox/toggle'(payload: { ctx: InPageEdit; opened: boolean }): void\n }\n interface PreferencesMap {\n toolboxAlwaysShow: boolean\n }\n}\n\ninterface ToolboxButton {\n id: string\n group?: 'auto' | 'group1' | 'group2'\n icon: ComputeAbleSync<string | HTMLElement | SVGElement | ReactElement>\n tooltip?: ComputeAbleSync<string | HTMLElement>\n itemProps?: JSX.IntrinsicElements['li']\n buttonProps?: JSX.IntrinsicElements['button']\n onClick?: (event: MouseEvent) => void\n index?: number // 任意数值均可:负数靠前、正数靠后、Infinity 末尾、未传时按插入顺序\n}\n\n@RegisterPreferences(\n Schema.object({\n toolboxAlwaysShow: Schema.boolean()\n .description('Make the toolbox opened by default')\n .default(false),\n }).description('Toolbox preferences')\n)\n@Inject(['preferences'])\nexport class PluginToolbox extends Service {\n container!: HTMLElement\n\n // ==== 内部状态 ====\n private buttons: ToolboxButton[] = []\n\n // 插入顺序序列号:用于当 index 未给时保持“自然顺序”\n private seqCounter = 0\n private seqMap = new Map<string, number>() // id -> seq\n\n constructor(public ctx: InPageEdit) {\n super(ctx, 'toolbox', false)\n }\n\n protected async start(): Promise<void> {\n this.container = this.createToolbox()\n this.ctx.preferences.get('toolboxAlwaysShow').then((val) => {\n if (val) {\n this.container.classList.add('is-persistent')\n }\n })\n this.setupHoverLogic()\n document.body.appendChild(this.container)\n\n // 国际化变化时重新渲染\n this.ctx.on('i18n/changed', () => {\n console.info('i18n/changed', this.buttons)\n this.renderAll()\n })\n }\n\n protected stop(): void | Promise<void> {\n this.container?.remove()\n }\n\n private get isPersistent() {\n return this.container.classList.contains('is-persistent')\n }\n\n private setupHoverLogic() {\n let hoverTimeout: number | null = null\n\n // 鼠标进入时暂时展开\n this.container.addEventListener('mouseenter', () => {\n if (hoverTimeout) {\n clearTimeout(hoverTimeout)\n hoverTimeout = null\n }\n\n // 如果不在持久化状态,则添加hover展开效果\n if (!this.isPersistent) {\n this.container.classList.add('is-hovered')\n }\n })\n\n // 鼠标离开时收起(如果不是持久化状态)\n this.container.addEventListener('mouseleave', () => {\n if (!this.isPersistent) {\n hoverTimeout = window.setTimeout(() => {\n this.container.classList.remove('is-hovered')\n }, 150) // 延迟150ms收起,避免快速移动鼠标时闪烁\n }\n })\n }\n\n /**\n * 计算按钮动画延迟\n * @param index 按钮索引(从0开始)\n * @param totalCount 总按钮数量\n * @returns 延迟时间(秒)\n */\n private calculateButtonDelay(index: number, totalCount: number): number {\n if (totalCount <= 1) return 0\n\n // 总动画时长150ms = 0.15s\n const totalDuration = 0.15\n // 使用平方根函数创建非线性延迟,差值逐渐缩小\n const normalizedIndex = index / (totalCount - 1)\n const delay = totalDuration * Math.sqrt(normalizedIndex)\n\n return Math.round(delay * 1000) / 1000 // 保留3位小数\n }\n\n /**\n * 更新按钮组的动画延迟\n */\n private updateButtonDelays() {\n const btnGroups = this.container.querySelectorAll('.btn-group')\n\n btnGroups.forEach((group) => {\n const buttons = group.querySelectorAll('.btn-tip-group')\n const totalCount = buttons.length\n\n buttons.forEach((button, index) => {\n const delay = this.calculateButtonDelay(index, totalCount)\n ;(button as HTMLElement).style.setProperty('--transition-delay', `${delay}s`)\n ;(button as HTMLElement).style.setProperty('--max-transition-delay', '0.15s')\n })\n })\n }\n\n private createToolbox() {\n const toggler = (\n <button\n className=\"ipe-toolbox-btn\"\n id=\"toolbox-toggler\"\n onClick={() => {\n this.toggle()\n }}\n >\n {/* Font Awesome 5 Solid: Plus */}\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"448\" height=\"512\" viewBox=\"0 0 448 512\">\n <rect width=\"448\" height=\"512\" fill=\"none\" />\n <path\n fill=\"currentColor\"\n d=\"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32\"\n />\n </svg>\n </button>\n )\n const element = (\n <div id=\"ipe-edit-toolbox\">\n <ul className=\"btn-group group1\" style={{ display: 'flex', flexDirection: 'column' }}></ul>\n <ul className=\"btn-group group2\" style={{ display: 'flex', flexDirection: 'row' }}></ul>\n {toggler}\n </div>\n )\n\n return element as HTMLElement\n }\n\n private normalizeButtonId(id: string) {\n if (!id) {\n id = Math.random().toString(36).substring(2, 8)\n }\n // 修复:正确替换空白/点/井号(保留语义,修正正则)\n return `ipe-toolbox__${id.trim()}`.replace(/[\\s.#]+/g, '-')\n }\n\n // ====== 排序与分组 ======\n private chooseAutoGroup(): 'group1' | 'group2' {\n const g1 = this.buttons.filter((b) => b.group === 'group1').length\n const g2 = this.buttons.filter((b) => b.group === 'group2').length\n return g1 <= g2 ? 'group1' : 'group2'\n }\n\n // 归一化排序键:\n // 1) 若 index 是有限数值 => 直接使用(允许负数/小数/很大数);\n // 2) 若为 Infinity / -Infinity => 自然比较;\n // 3) 若 NaN / 未提供 => 返回 null,后续用插入顺序(seq)比较。\n private orderKey(btn: ToolboxButton): number | null {\n const idx = (btn as any).index\n if (typeof idx === 'number') {\n if (Number.isNaN(idx)) return null\n return idx // 包含 Infinity 与 -Infinity\n }\n return null\n }\n\n private compareButtons = (a: ToolboxButton, b: ToolboxButton) => {\n const ak = this.orderKey(a) // number | null\n const bk = this.orderKey(b)\n\n const va = ak ?? 0\n const vb = bk ?? 0\n\n if (va < vb) return -1\n if (va > vb) return 1\n\n // 有效值相等时的细化:\n const sa = this.seqMap.get(a.id) ?? 0\n const sb = this.seqMap.get(b.id) ?? 0\n\n if (ak === null && bk === null) {\n if (sa !== sb) return sa - sb\n return 0 // 不以 id 再兜底,保持稳定排序\n }\n\n if (ak === null && bk !== null) return -1 // 无 index(按0) 优先于 数值 index=0\n if (ak !== null && bk === null) return 1\n\n // 双方都有 index 且值相等,退化到 seq;仍然相等时返回 0\n if (sa !== sb) return sa - sb\n return 0\n }\n\n // ====== 对外 API:新增/替换/删除 ======\n addButton(payload: ToolboxButton) {\n // 统一化 id(保留原意:若缺失则补)\n payload.id = (payload.id || '').trim()\n if (!payload.id) {\n this.ctx.logger('toolbox').warn('Button id is empty, generating a random one.')\n payload.id = Math.random().toString(36).slice(2, 10)\n }\n\n const existingIndex = this.buttons.findIndex((button) => button.id === payload.id)\n\n // 分组:新增时 auto,替换时默认保留原组,除非明确指定\n const nextGroup: 'group1' | 'group2' = (() => {\n if (existingIndex !== -1) {\n const old = this.buttons[existingIndex]\n return !payload.group || payload.group === 'auto' ? (old.group as any) : payload.group\n }\n return !payload.group || payload.group === 'auto' ? this.chooseAutoGroup() : payload.group\n })()\n\n // 序列号:用于 index 未提供时,保持插入顺序\n if (!this.seqMap.has(payload.id)) {\n this.seqMap.set(payload.id, this.seqCounter++)\n }\n\n if (existingIndex !== -1) {\n // 替换:保留旧的 seq,不动;index 未传则沿用旧值\n const old = this.buttons[existingIndex]\n const incomingIndex =\n typeof payload.index === 'number' && !Number.isNaN(payload.index)\n ? payload.index\n : old.index\n const merged: ToolboxButton = { ...old, ...payload, group: nextGroup, index: incomingIndex }\n\n this.buttons.splice(existingIndex, 1, merged)\n } else {\n // 新增:按给定 index 或留空;只设置组\n const incomingIndex =\n typeof payload.index === 'number' && !Number.isNaN(payload.index)\n ? payload.index\n : undefined\n const fresh: ToolboxButton = { ...payload, group: nextGroup, index: incomingIndex }\n this.buttons.push(fresh)\n }\n\n this.ctx.emit('toolbox/button-added', { ctx: this.ctx, payload })\n this.renderAll()\n }\n\n removeButton(id: string) {\n const index = this.buttons.findIndex((button) => button.id === id)\n if (index !== -1) {\n const payload = this.buttons[index]\n this.buttons.splice(index, 1)\n // 可选择是否保留 seq,使得将来同 id 重加时仍按旧顺序;这里删除时保留更合理\n this.ctx.emit('toolbox/button-removed', { ctx: this.ctx, payload })\n this.renderAll()\n }\n }\n\n // ====== 渲染 ======\n private renderButton(payload: ToolboxButton) {\n let { id, icon, index, tooltip, itemProps, buttonProps, onClick } = payload\n const normalizedId = this.normalizeButtonId(id)\n\n // 结构尽量保持,避免在 <li> 上绑定 click 造成双触发\n const element = (\n <li class=\"btn-tip-group\" id={normalizedId} data-id={id} data-index={index} {...itemProps}>\n <div class=\"btn-tip\">{computeFallbackSync(tooltip)}</div>\n <button\n id={`${normalizedId}-btn`}\n data-id={payload.id}\n class=\"ipe-toolbox-btn\"\n onClick={(e: any) => {\n onClick?.(e as MouseEvent)\n this.ctx.emit('toolbox/button-clicked', {\n ctx: this.ctx,\n event: e as MouseEvent,\n payload,\n })\n }}\n {...buttonProps}\n >\n {computeFallbackSync(icon)}\n </button>\n </li>\n )\n\n return element as HTMLElement\n }\n\n private renderAll() {\n const group1 = this.buttons\n .filter((b) => b.group === 'group1')\n .slice()\n .sort(this.compareButtons)\n const group2 = this.buttons\n .filter((b) => b.group === 'group2')\n .slice()\n .sort(this.compareButtons)\n\n const group1El = this.container.querySelector('.btn-group.group1') as HTMLElement\n const group2El = this.container.querySelector('.btn-group.group2') as HTMLElement\n\n group1El.innerHTML = ''\n group2El.innerHTML = ''\n\n group1.forEach((button) => {\n group1El.appendChild(this.renderButton(button))\n })\n group2.forEach((button) => {\n group2El.appendChild(this.renderButton(button))\n })\n\n // 统一更新动画延迟\n this.updateButtonDelays()\n }\n\n getContainer() {\n return this.container\n }\n\n get isOpened() {\n return (\n this.container.classList.contains('is-persistent') ||\n this.container.classList.contains('is-hovered')\n )\n }\n\n toggle(force?: boolean) {\n const isPersistent = this.isPersistent\n const newPersistent = typeof force === 'boolean' ? force : !isPersistent\n this.container.classList.toggle('is-persistent', newPersistent)\n this.container.classList.remove('is-hovered')\n this.ctx.preferences.set('toolboxAlwaysShow', newPersistent)\n this.ctx.emit('toolbox/toggle', { ctx: this.ctx, opened: this.isOpened })\n }\n}\n"],"names":["_PluginToolbox_decorators","_init","_a","RegisterPreferences","Schema","Inject","PluginToolbox","Service","ctx","a","b","ak","bk","va","vb","sa","sb","val","hoverTimeout","index","totalCount","totalDuration","normalizedIndex","delay","group","buttons","button","jsxs","jsx","id","g1","g2","btn","idx","payload","existingIndex","nextGroup","old","incomingIndex","merged","fresh","icon","tooltip","itemProps","buttonProps","onClick","normalizedId","computeFallbackSync","e","group1","group2","group1El","group2El","force","isPersistent","newPersistent","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as a, P as S } from "./Promise.withResolvers-C4chhLB1.js";
|
|
2
|
-
import { R as E, a as j, S as k } from "./index-
|
|
2
|
+
import { R as E, a as j, S as k } from "./index-BAJiXDPz.js";
|
|
3
3
|
import { BasePlugin as q } from "./core.js";
|
|
4
4
|
import { T as F } from "./index-z_qDGCMT.js";
|
|
5
5
|
import { C as v } from "./CheckBox-Dx3r3LQz.js";
|
|
@@ -177,4 +177,4 @@ R(g, 1, h);
|
|
|
177
177
|
export {
|
|
178
178
|
h as PluginQuickMove
|
|
179
179
|
};
|
|
180
|
-
//# sourceMappingURL=index-
|
|
180
|
+
//# sourceMappingURL=index-DHitL1S2.js.map
|