@inpageedit/core 0.14.0 → 0.14.2

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.
Files changed (46) hide show
  1. package/README.md +18 -8
  2. package/dist/{BasePlugin-CU8beLYu.js → BasePlugin-YOi2_vUo.js} +2 -2
  3. package/dist/{BasePlugin-CU8beLYu.js.map → BasePlugin-YOi2_vUo.js.map} +1 -1
  4. package/dist/{PluginPrefSync-B-gPsC2n.js → PluginPrefSync-jTNlRQE-.js} +3 -3
  5. package/dist/{PluginPrefSync-B-gPsC2n.js.map → PluginPrefSync-jTNlRQE-.js.map} +1 -1
  6. package/dist/{PluginStoreApp-CDteVCBG.js → PluginStoreApp-CGNxKXAN.js} +2 -2
  7. package/dist/{PluginStoreApp-CDteVCBG.js.map → PluginStoreApp-CGNxKXAN.js.map} +1 -1
  8. package/dist/{Preferences-85Q9FAmb.js → Preferences-BF2fcXrn.js} +140 -132
  9. package/dist/Preferences-BF2fcXrn.js.map +1 -0
  10. package/dist/{index-DjPpAyfE.js → index-3NZkG2a3.js} +3 -3
  11. package/dist/{index-DjPpAyfE.js.map → index-3NZkG2a3.js.map} +1 -1
  12. package/dist/{index-DGtq21uW.js → index-BBNseJXG.js} +3 -3
  13. package/dist/{index-DGtq21uW.js.map → index-BBNseJXG.js.map} +1 -1
  14. package/dist/{index-Ci82vLXg.js → index-BrYKe18j.js} +4 -4
  15. package/dist/index-BrYKe18j.js.map +1 -0
  16. package/dist/{index-19CgGBI0.js → index-C3m6ng6b.js} +234 -231
  17. package/dist/index-C3m6ng6b.js.map +1 -0
  18. package/dist/index-D-fW3ESK.js +195 -0
  19. package/dist/index-D-fW3ESK.js.map +1 -0
  20. package/dist/{index-CQr1DJ8n.js → index-D6zFqL2u.js} +4 -4
  21. package/dist/index-D6zFqL2u.js.map +1 -0
  22. package/dist/{index-BrtFJ-M0.js → index-D97lUU3h.js} +3 -3
  23. package/dist/{index-BrtFJ-M0.js.map → index-D97lUU3h.js.map} +1 -1
  24. package/dist/{index-BKIf3i0I.js → index-DELHsLHS.js} +5 -5
  25. package/dist/{index-BKIf3i0I.js.map → index-DELHsLHS.js.map} +1 -1
  26. package/dist/{index-CVTBg5O9.js → index-Dclp60EO.js} +21 -17
  27. package/dist/index-Dclp60EO.js.map +1 -0
  28. package/dist/{index-DXL7teb0.js → index-DmLoihN1.js} +4 -4
  29. package/dist/{index-DXL7teb0.js.map → index-DmLoihN1.js.map} +1 -1
  30. package/dist/{index-D3iZhRMJ.js → index-QtEF2mzS.js} +156 -127
  31. package/dist/index-QtEF2mzS.js.map +1 -0
  32. package/dist/index.d.ts +73 -22
  33. package/dist/index.js +5 -5
  34. package/dist/plugins/index.js +10 -10
  35. package/dist/services/index.js +1 -1
  36. package/lib/index.umd.js +10 -10
  37. package/lib/index.umd.js.map +1 -1
  38. package/package.json +5 -5
  39. package/dist/Preferences-85Q9FAmb.js.map +0 -1
  40. package/dist/index-19CgGBI0.js.map +0 -1
  41. package/dist/index-CQr1DJ8n.js.map +0 -1
  42. package/dist/index-CVTBg5O9.js.map +0 -1
  43. package/dist/index-Ci82vLXg.js.map +0 -1
  44. package/dist/index-D3iZhRMJ.js.map +0 -1
  45. package/dist/index-rpiO9fpc.js +0 -145
  46. package/dist/index-rpiO9fpc.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CQr1DJ8n.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":";;;;;AA4BO,MAAMA,UAA4BC,EAAW;AAAA,EAQlD,YAAmBC,GAAiB;AAClC,UAAMA,GAAK,CAAA,GAAI,gBAAgB,GADd,KAAA,MAAAA;AAAA,EAEnB;AAAA,EATA,OAAA;AAAA,SAAgB,SAAS,CAAC,OAAO,YAAY,SAAS,GAAG;AAAA,EAAA;AAAA,EACzD,OAAA;AAAA,SAAgB,oBAAoBC,EAAO,OAAO;AAAA,MAChD,wBAAwBA,EAAO,OAAA,EAAS,QAAQ,2BAA2B;AAAA,IAAA,CAC5E,EACE,YAAY,wBAAwB,EACpC,MAAM,YAAY,QAAQ;AAAA,EAAA;AAAA,EAMnB,QAA8B;AACtC,SAAK,IAAI,IAAI,iBAAiB,IAAI;AAClC,UAAMC,IAAI,KAAK,IAAI,GAEbC,IAAc,OAAO,IAAI,OAAO,IAAI,YAAY,KAAK,IACrDC,IAAU,OAAO,IAAI,OAAO,IAAI,sBAAsB;AAC5D,SAAK,IAAI,OAAO,CAAC,SAAS,GAAG,CAACJ,MAAQ;AACpC,WAAK,MAAMA,GACXA,EAAI,QAAQ,UAAU;AAAA,QACpB,IAAI;AAAA,QACJ,MACEK,gBAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAM;AAAA,YACN,OAAM;AAAA,YACN,QAAO;AAAA,YACP,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,QAAO;AAAA,YACP,gBAAa;AAAA,YACb,kBAAe;AAAA,YACf,mBAAgB;AAAA,YAChB,OAAM;AAAA,YAEN,UAAA;AAAA,cAAA,gBAAAC,EAAC,UAAK,QAAO,QAAO,GAAE,iBAAgB,MAAK,QAAO;AAAA,cAClD,gBAAAA,EAAC,QAAA,EAAK,GAAE,4BAAA,CAA4B;AAAA,cACpC,gBAAAA,EAAC,QAAA,EAAK,GAAE,mBAAA,CAAmB;AAAA,cAC3B,gBAAAA,EAAC,QAAA,EAAK,GAAE,0BAAA,CAA0B;AAAA,cAClC,gBAAAA,EAAC,QAAA,EAAK,GAAE,uDAAA,CAAuD;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,QAGnE,SAASJ;AAAA,QACT,OAAO;AAAA,QACP,OAAO;AAAA,QACP,SAAS,MAAM;AACb,eAAK;AAAA,YACHE,IACI;AAAA,cACE,IAAID;AAAA,YAAA,IAEN,CAAA;AAAA,UAAC;AAAA,QAET;AAAA,MAAA,CACD,GACD,KAAK,kBAAkB,CAACH,MAAQ;AAC9BA,QAAAA,EAAI,QAAQ,aAAa,gBAAgB;AAAA,MAC3C,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEU,OAA6B;AAAA,EAAC;AAAA,EAExC,MAAM,UAAUO,GAAyC;AACvD,UAAML,IAAI,KAAK,IAAI,GACbM,IAAS,MAAM,KAAK,IAAI,YAAY,IAAI,sBAAsB;AACpE,IAAKD,MACHA,IAAU,CAAA,IAEZ,KAAK,IAAI,KAAK,+BAA+B,EAAE,KAAK,KAAK,KAAK,SAAAA,GAAS;AACvE,UAAME,IAAQ,KAAK,IAAI,MACpB,aAAa;AAAA,MACZ,OAAOP;AAAA,MACP,2BAAWQ,GAAA,EAAY;AAAA,MACvB,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA,CACT,EACA,KAAA;AAEH,QAAIC,IAAkC;AACtC,WAAAF,EAAM;AAAA,MAEFJ,gBAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK,CAACO,MAAQD,IAAUC;AAAA,UACxB,OAAO;AAAA,YACL,SAAS;AAAA,YACT,eAAe;AAAA,YACf,KAAK;AAAA,UAAA;AAAA,UAEP,UAAU,CAACC,MAAM;AAGf,gBAFAA,EAAE,eAAA,GACFF,GAAS,cAAA,GACL,CAACA,GAAS;AACZ;AAEF,kBAAMG,IAAW,IAAI,SAASH,CAAQ,GAChCJ,IAAU;AAAA,cACd,MAAMO,EAAS,IAAI,MAAM,GAAG,SAAA,EAAW,KAAA;AAAA,cACvC,IAAIA,EAAS,IAAI,IAAI,GAAG,SAAA,EAAW,KAAA;AAAA,cACnC,QAASA,EAAS,IAAI,QAAQ,KAAgB;AAAA,cAC9C,WAAWA,EAAS,IAAI,WAAW,MAAM;AAAA,YAAA;AAE3C,gBAAI,CAACP,EAAQ,QAAQ,CAACA,EAAQ,IAAI;AAChC,mBAAK,IAAI,MAAM,OAAO,SAAS;AAAA,gBAC7B,OAAOL;AAAA,gBACP,SAASA;AAAA,cAAA,CACV;AACD;AAAA,YACF;AACA,iBAAK,IAAI,KAAK,yBAAyB,EAAE,KAAK,KAAK,KAAK,SAASK,GAAS,GAC1EE,EAAM,gBAAgB,EAAI,GAC1B,KAAK,aAAaF,CAAO,EACtB,KAAK,CAACQ,MAAQ;AACb,cAAAN,EAAM,MAAA,GACN,KAAK,IAAI,MAAM,OAAO,WAAW;AAAA,gBAC/B,OAAOP;AAAA,gBACP,SAASA;AAAA,cAAA,CACV;AAAA,YACH,CAAC,EACA,MAAM,CAACc,MAAU;AAChB,cAAAP,EAAM,gBAAgB,EAAK,GAC3B,KAAK,IAAI,MAAM,OAAO,SAAS;AAAA,gBAC7B,OAAOP;AAAA,gBACP,SAASc,aAAiB,QAAQA,EAAM,UAAU,OAAOA,CAAK;AAAA,cAAA,CAC/D;AAAA,YACH,CAAC;AAAA,UACL;AAAA,UAEA,UAAA;AAAA,YAAA,gBAAAV;AAAA,cAACW;AAAA,cAAA;AAAA,gBACC,QAAQ;AAAA,kBACN;AAAA,oBACE,OAAOf;AAAA,oBACP,MAAM;AAAA,oBACN,OAAOK,GAAS;AAAA,oBAChB,UAAU;AAAA,kBAAA;AAAA,kBAEZ;AAAA,oBACE,OAAOL;AAAA,oBACP,MAAM;AAAA,oBACN,OAAOK,GAAS;AAAA,oBAChB,UAAU;AAAA,kBAAA;AAAA,gBACZ;AAAA,cACF;AAAA,YAAA;AAAA,YAEF,gBAAAD;AAAA,cAACY;AAAA,cAAA;AAAA,gBACC,OAAOhB;AAAA,gBACP,IAAG;AAAA,gBACH,MAAK;AAAA,gBACL,OAAOK,GAAS,UAAUC,KAAU;AAAA,cAAA;AAAA,YAAA;AAAA,YAEtC,gBAAAF,EAAC,OAAA,EACC,UAAA,gBAAAA,EAACa,GAAA,EAAS,MAAK,aAAY,IAAG,aAAY,SAASZ,GAAS,WACzD,UAAAL,8DAAA,CACH,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACF,GAGJO,EAAM,WAAW;AAAA,MACf;AAAA,QACE,OAAOP;AAAA,QACP,WAAW;AAAA,QACX,QAAQ,MAAM;AACZ,UAAAS,GAAS,cAAc,IAAI,MAAM,QAAQ,CAAC;AAAA,QAC5C;AAAA,MAAA;AAAA,IACF,CACD,GAED,KAAK,IAAI,KAAK,6BAA6B,EAAE,KAAK,KAAK,KAAK,OAAAF,GAAO,GAE5DA,EAAM,KAAA;AAAA,EACf;AAAA,EAEA,MAAM,aAAaF,GAA8B;AAC/C,UAAM,EAAE,MAAAa,GAAM,IAAAC,GAAI,QAAAb,IAAS,IAAI,WAAAc,IAAY,OAAUf,GAC/CgB,IAAW,MAAM,KAAK,IAAI,SAAS,aAAa;AAAA,MACpD,OAAOH;AAAA,IAAA,CACR,GACKI,IAAU,gBAAgBH,CAAE;AAClC,WAAOE,EAAS;AAAA,MACd;AAAA,QACE,MAAMC;AAAA,QACN,SAAShB;AAAA,MAAA;AAAA,MAEX;AAAA,QACE,YAAY,CAACc;AAAA,MAAA;AAAA,IACf;AAAA,EAEJ;AACF;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-CVTBg5O9.js","sources":["../src/plugins/analytics/index.tsx"],"sourcesContent":["import { Endpoints } from '@/constants/endpoints.js'\nimport { Inject, InPageEdit, Schema } from '@/InPageEdit'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n analytics: PluginAnalytics\n }\n}\n\nexport interface IPEBeaconPayload {\n siteApi: string\n siteName?: string\n userId: number\n userName: string\n version?: string\n usages: IPEBeaconUsage[]\n}\n\nexport interface IPEBeaconUsage {\n ts: number\n feature: string\n subtype?: string\n page?: string\n}\n\n@Inject(['wiki', 'preferences', '$'])\nexport class PluginAnalytics extends BasePlugin {\n private _usages: IPEBeaconUsage[] = []\n private _timer: ReturnType<typeof setInterval> | null = null\n private readonly MAX_QUEUE_SIZE = 50\n private readonly INTERVAL_MS = 60 * 1000 // 1分钟\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'analytics')\n this._setupTimer()\n this._registerUnloadHandler()\n this._showConfirmNotify()\n this._initPluginListeners()\n ctx.set('analytics', this)\n }\n\n protected start(): Promise<void> | void {\n const ctx = this.ctx\n const $ = ctx.$\n ctx.preferences.registerCustomConfig(\n 'analytics',\n Schema.object({\n 'analytics._intro': Schema.const(\n <section>\n <h3>{$`InPageEdit Analytics`}</h3>\n <p>\n {$`InPageEdit Analytics is the companion analytics platform for the InPageEdit NEXT project. By collecting and displaying usage data from around the world, it helps developers and the community better understand how the tool is used, optimize feature design, and enhance user experience.`}\n </p>\n <h4>{$`What data will be collected?`}</h4>\n <ol style={{ listStyle: 'number', paddingLeft: '1em' }}>\n <li>\n <strong>{$`Usage data`}</strong>:{' '}\n {$`When and which features you use, what pages you edit, etc.`}\n </li>\n <li>\n <strong>{$`User information`}</strong>: {$`Your user name and user ID.`}\n </li>\n <li>\n <strong>{$`Site information`}</strong>: {$`This wiki's url and site name.`}\n </li>\n </ol>\n <p>\n <strong>{$`NO sensitive data will be collected.`}</strong>\n </p>\n <div style={{ display: 'grid', gap: '0.5rem' }}>\n <a href={this.analyticsDashUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n <button className=\"btn\" style={{ width: '100%' }}>\n {$`Analytics Platform`}\n </button>\n </a>\n <a\n href={`${this.analyticsDashUrl}/_redirect/user?${new URLSearchParams({\n siteApi: this.ctx.wiki.getSciprtUrl('api'),\n mwUserId: this.ctx.wiki.userInfo.id.toString(),\n }).toString()}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <button className=\"btn\" style={{ width: '100%' }}>\n {$`View My Data`}\n </button>\n </a>\n </div>\n </section>\n ).role('raw-html'),\n 'analytics.enabled': Schema.boolean()\n .description($`prefs.analytics.enabled`)\n .default(false),\n }).description($`prefs.analytics.$`),\n 'general'\n )\n }\n\n private get analyticsDashUrl() {\n return import.meta.env.PROD ? Endpoints.ANALYTICS_DASH_URL : 'http://localhost:20105'\n }\n private get analyticsApiBase() {\n return import.meta.env.PROD ? Endpoints.ANALYTICS_API_BASE : 'http://localhost:20105/api/v6'\n }\n\n private _setupTimer() {\n this._timer = setInterval(() => {\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }, this.INTERVAL_MS)\n }\n\n private _registerUnloadHandler() {\n const handleUnload = () => {\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }\n\n window.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden') {\n handleUnload()\n }\n })\n\n window.addEventListener('pagehide', handleUnload)\n window.addEventListener('beforeunload', handleUnload)\n }\n\n private async _showConfirmNotify() {\n const $ = this.ctx.$\n this.ctx.inject(['modal', 'storage'], async (ctx) => {\n const key = 'analytics/confirm-shown'\n const shown = await ctx.storage.simpleKV.get(key)\n const enabled = await ctx.preferences.get('analytics.enabled')\n if (shown || enabled) {\n return\n }\n ctx.modal.notify(\n 'confirm',\n {\n title: $`Enable Analytics`,\n content: (\n <div>\n <p>{$`Help us improve InPageEdit by sharing your usage data with us.`}</p>\n <p>{$`What data will be collected?`}</p>\n <ul style={{ listStyle: 'auto', paddingLeft: '1.5em' }}>\n <li>\n {$`Usage data`}: {$`When and which features you use, what pages you edit, etc.`}\n </li>\n <li>\n {$`User information`}: {$`Your user name and user ID.`}\n </li>\n <li>\n {$`Site information`}: {$`This wiki's url and site name.`}\n </li>\n </ul>\n <p>\n <strong>{$`NO sensitive data will be collected.`}</strong>\n </p>\n </div>\n ),\n okBtn: {\n label: $`Enable`,\n },\n cancelBtn: {\n label: $`Disable`,\n },\n closeAfter: 0,\n onClose: () => {\n this.ctx.storage.simpleKV.set(key, 1)\n },\n },\n (result) => {\n ctx.preferences.set('analytics.enabled', result)\n if (result) {\n this.addEvent('analytics', 'enabled')\n }\n }\n )\n })\n }\n\n private _initPluginListeners() {\n const ctx = this.ctx\n ctx.on('in-article-links/anchor-clicked', (payload) => {\n this.addEvent('in-article-links', paramCase(payload.action))\n })\n ctx.on('quick-diff/loaded', (payload) => {\n this.addEvent('quick-diff', 'loaded', payload.compare.fromtitle)\n })\n ctx.on('quick-redirect/submit', (payload) => {\n this.addEvent('quick-redirect', 'submit', payload.payload.to || undefined)\n })\n ctx.on('quick-preview/loaded', (payload) => {\n this.addEvent('quick-preview', 'loaded', payload.wikiPage.title)\n })\n ctx.on('quick-edit/wiki-page', (payload) => {\n this.addEvent('quick-edit', undefined, payload.wikiPage.title)\n })\n ctx.on('quick-edit/submit', (payload) => {\n this.addEvent('quick-edit', 'submit', payload.wikiPage.title)\n })\n ctx.on('quick-move/submit', (payload) => {\n this.addEvent('quick-move', 'submit')\n })\n ctx.on('toolbox/button-clicked', (payload) => {\n this.addEvent('toolbox', `button-clicked#${payload.id || 'unknown'}`)\n })\n }\n\n public addEvent(feature: string, subtype?: string, page?: string) {\n const usage: IPEBeaconUsage = {\n ts: Date.now(),\n feature,\n subtype,\n page,\n }\n this._usages.push(usage)\n\n // 如果usages数组超过50个,立即发送\n if (this._usages.length >= this.MAX_QUEUE_SIZE) {\n this.sendBeacon()\n }\n\n return this\n }\n\n private async sendBeacon() {\n if (this._usages.length === 0) {\n return true\n }\n\n const enabled = await this.ctx.preferences.get<boolean>('analytics.enabled', false)\n if (!enabled) {\n this.logger.debug('Analytics disabled, skipping')\n return true\n }\n\n const usages = this._usages.splice(0, this._usages.length)\n const payload: IPEBeaconPayload = {\n siteApi: this.ctx.wiki.getSciprtUrl('api'),\n siteName: this.ctx.wiki.siteInfo.general.sitename,\n userId: this.ctx.wiki.userInfo.id,\n userName: this.ctx.wiki.userInfo.name,\n version: this.ctx.version.split('-')[0],\n usages,\n }\n const body = JSON.stringify(payload)\n\n const endpoint = `${this.analyticsApiBase}/submit`\n\n const beaconOK = navigator?.sendBeacon?.(endpoint, body)\n if (beaconOK) {\n this.logger.debug('Beacon sent successfully', payload)\n return true\n } else {\n this.logger.debug('Beacon failed, sending via XMLHttpRequest')\n const { promise, resolve, reject } = promiseWithResolvers<boolean>()\n try {\n const xhr = new XMLHttpRequest()\n xhr.open('POST', endpoint, true)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(body)\n xhr.onload = () => {\n this.logger.debug('Beacon sent successfully via XMLHttpRequest', payload)\n resolve(xhr.status >= 200 && xhr.status < 300)\n }\n xhr.onerror = () => {\n reject(new Error('Failed to send beacon'))\n }\n } catch (error) {\n reject(error)\n }\n return promise\n }\n }\n\n /**\n * 清理资源\n */\n protected stop() {\n if (this._timer !== null) {\n clearInterval(this._timer)\n this._timer = null\n }\n // 在销毁前发送剩余的数据\n if (this._usages.length > 0) {\n this.sendBeacon()\n }\n }\n}\n"],"names":["_PluginAnalytics_decorators","_init","_a","Inject","PluginAnalytics","BasePlugin","ctx","$","Schema","jsx","jsxs","Endpoints","handleUnload","key","shown","enabled","result","payload","paramCase","feature","subtype","page","usage","usages","body","endpoint","promise","resolve","reject","promiseWithResolvers","xhr","error","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-Ci82vLXg.js","sources":["../src/plugins/quick-move/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema } from '@/InPageEdit'\nimport { IPEModal } from '@inpageedit/modal'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickMove: PluginQuickMove\n }\n interface Events {\n 'quick-move/init-options'(payload: {\n ctx: InPageEdit\n options: Partial<QuickMoveOptions>\n }): void\n 'quick-move/show-modal'(payload: { ctx: InPageEdit; modal: IPEModal }): void\n 'quick-move/submit'(payload: {\n ctx: InPageEdit\n modal: IPEModal\n payload: MovePageOptions\n }): void\n }\n interface PreferencesMap {\n 'quickMove.reason': string\n }\n}\n\nexport interface MovePageOptions {\n from: string\n to: string\n reason?: string\n movetalk?: boolean\n movesubpages?: boolean\n noredirect?: boolean\n}\nexport interface QuickMoveOptions extends Partial<MovePageOptions> {\n lockFromField?: boolean\n lockToField?: boolean\n}\n\n@RegisterPreferences(\n Schema.object({\n 'quickMove.reason': Schema.string().default('[IPE-NEXT] Quick move'),\n })\n .description('Quick move options')\n .extra('category', 'editor')\n)\n@Inject(['modal', 'wiki', '$'])\nexport class PluginQuickMove extends BasePlugin {\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-move')\n ctx.set('quickMove', this)\n }\n\n protected start(): Promise<void> | void {\n this.ctx.inject(['toolbox'], (ctx) => {\n this.injectToolbox(ctx)\n })\n }\n\n private injectToolbox(ctx: InPageEdit) {\n const $ = ctx.$\n const curPageName = window.mw?.config.get('wgPageName') || ''\n const canEdit = window.mw?.config.get('wgIsProbablyEditable')\n ctx.toolbox.addButton({\n id: 'quick-move',\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-forms\"\n >\n <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M12 3a3 3 0 0 0 -3 3v12a3 3 0 0 0 3 3\" />\n <path d=\"M6 3a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3\" />\n <path d=\"M13 7h7a1 1 0 0 1 1 1v8a1 1 0 0 1 -1 1h-7\" />\n <path d=\"M5 7h-1a1 1 0 0 0 -1 1v8a1 1 0 0 0 1 1h1\" />\n <path d=\"M17 12h.01\" />\n <path d=\"M13 12h.01\" />\n </svg>\n ),\n tooltip: $`Quick Move`,\n group: 'group1',\n index: 1,\n onClick: () => {\n this.showModal(\n canEdit\n ? {\n lockFromField: true,\n from: curPageName,\n }\n : {}\n )\n },\n })\n }\n\n async showModal(options?: Partial<QuickMoveOptions>) {\n const $ = this.ctx.$\n const reason = await this.ctx.preferences.get('quickMove.reason')\n const modal = this.ctx.modal\n .createObject({\n title: $`Quick Move`,\n content: (<ProgressBar />) as HTMLElement,\n className: 'quick-move 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 movetalk: formData.get('movetalk') === 'on',\n movesubpages: formData.get('movesubpages') === 'on',\n noredirect: formData.get('noredirect') === 'on',\n }\n if (!options.from || !options.to) {\n this.ctx.modal.notify('error', {\n title: $`Failed to move`,\n content: 'From and to are required.',\n })\n return\n }\n this.ctx.emit('quick-move/submit', { ctx: this.ctx, modal, payload: options })\n modal.setLoadingState(true)\n this.movePage(options)\n .then(() => {\n location.reload()\n })\n .catch((error) => {\n modal.setLoadingState(false)\n this.ctx.modal.notify('error', {\n title: $`Failed to move`,\n content: error instanceof Error ? error.message : String(error),\n })\n })\n }}\n >\n <TwinSwapInput\n inputs={[\n {\n label: $`Move from`,\n name: 'from',\n value: options?.from,\n required: true,\n },\n {\n label: $`Move to`,\n name: 'to',\n value: options?.to,\n required: true,\n },\n ]}\n />\n <div>\n <CheckBox name=\"movetalk\" id=\"movetalk\" checked={options?.movetalk}>\n {$`Move talk page`}\n </CheckBox>\n </div>\n <div>\n <CheckBox name=\"movesubpages\" id=\"movesubpages\" checked={options?.movesubpages}>\n {$`Move subpages (up to 100)`}\n </CheckBox>\n </div>\n {this.ctx.wiki.hasRight('suppressredirect') && (\n <div>\n <CheckBox name=\"noredirect\" id=\"noredirect\" checked={options?.noredirect}>\n {$`Move without leaving a redirect`}\n </CheckBox>\n </div>\n )}\n <InputBox\n label={$`Reason`}\n id=\"reason\"\n name=\"reason\"\n value={options?.reason ?? reason ?? ''}\n />\n </form>\n ) as HTMLElement\n )\n\n modal.setButtons([\n {\n label: $`Move`,\n className: 'is-primary is-ghost',\n method: () => {\n formRef?.dispatchEvent(new Event('submit'))\n },\n },\n ])\n\n return modal.show()\n }\n\n async movePage(options: MovePageOptions) {\n const { from, to, reason = '', ...rest } = options\n\n if (!from || !to) {\n throw new Error('From and to titles are required.')\n }\n if (from === to) {\n throw new Error('From and to titles cannot be the same.')\n }\n\n const wikiPage = await this.ctx.wikiPage.newFromTitle(from)\n return wikiPage.moveTo(to, reason, rest)\n }\n}\n"],"names":["_PluginQuickMove_decorators","_init","_a","RegisterPreferences","Schema","Inject","PluginQuickMove","BasePlugin","ctx","$","curPageName","canEdit","jsxs","jsx","options","reason","modal","ProgressBar","formRef","el","e","formData","error","TwinSwapInput","CheckBox","InputBox","from","to","rest","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-D3iZhRMJ.js","sources":["../src/plugins/plugin-store/schema.ts","../src/plugins/plugin-store/index.tsx"],"sourcesContent":["import Schema from 'schemastery'\n\nexport const PLUGIN_STORE_REGISTRY_MANIFEST_VERSION = 1\n\nexport interface PluginStoreRegistry {\n manifest_version: number\n name: string\n base_url: string\n homepage?: string\n maintainers?: PluginStoreRegistryMaintainer[]\n repository?: PluginStoreRegistryRepository\n packages: PluginStorePackage[]\n}\n\nexport interface PluginStoreRegistryMaintainer {\n name: string\n email?: string\n}\n\nexport interface PluginStoreRegistryRepository {\n type: 'git'\n url: string\n}\n\nexport interface PluginStorePackage {\n id: string\n name: string\n version: string\n description?: string\n author?: string\n license?: string\n loader: PluginStorePackageLoader\n}\n\nexport interface PluginStorePackageLoader {\n kind: 'autoload' | 'module' | 'umd' | 'styles'\n entry?: string\n styles?: string[]\n main_export?: string\n}\n\nexport namespace PluginStoreSchemas {\n export const PackageLoader = new Schema<PluginStorePackageLoader>(\n Schema.object({\n kind: Schema.union(['autoload', 'module', 'umd', 'styles']).required().default('autoload'),\n entry: Schema.string(),\n styles: Schema.array(Schema.string()),\n main_export: Schema.string(),\n })\n )\n\n export const Package = new Schema<PluginStorePackage>(\n Schema.object({\n id: Schema.string().required(),\n name: Schema.string().required(),\n version: Schema.string().required(),\n description: Schema.string(),\n author: Schema.string(),\n license: Schema.string(),\n loader: PackageLoader.required(),\n })\n )\n\n export const RegistryMaintainer = new Schema<PluginStoreRegistryMaintainer>(\n Schema.object({\n name: Schema.string().required(),\n email: Schema.string(),\n })\n )\n\n export const RegistryRepository = new Schema<PluginStoreRegistryRepository>(\n Schema.object({\n type: Schema.union(['git']).required().default('git'),\n url: Schema.string().required(),\n })\n )\n\n export const Registry = new Schema<PluginStoreRegistry>(\n Schema.object({\n manifest_version: Schema.number().min(PLUGIN_STORE_REGISTRY_MANIFEST_VERSION).required(),\n name: Schema.string().required(),\n base_url: Schema.string().required(),\n homepage: Schema.string(),\n maintainers: Schema.array(RegistryMaintainer),\n repository: RegistryRepository,\n packages: Schema.array(Package).required(),\n })\n )\n}\n","import { InPageEdit, Schema } from '@/InPageEdit'\nimport { ForkScope, Inject } from '@cordisjs/core'\nimport { defineAsyncComponent, type App as VueApp } from 'vue'\nimport { PluginStoreRegistry, PluginStoreSchemas } from './schema'\nimport { AbstractIPEStorageManager } from '@/services/storage/index.js'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n store: PluginPluginStore\n }\n interface PreferencesMap {\n 'pluginStore.registries': string[]\n 'pluginStore.plugins': { source?: 'online_manifest' | 'npm'; registry: string; id: string }[]\n 'pluginStore.cdnForNpm': string\n }\n}\n\nexport type PluginStoreRegistrySource = 'online_manifest' | 'npm'\n\nconst tryGetGlobalPlugin = (main_export: string) => {\n if (!main_export) return null\n try {\n return main_export\n .split('.')\n .reduce<any>((acc, key) => (acc == null ? acc : acc[key]), globalThis as any)\n } catch {\n return null\n }\n}\n\n/**\n * 解析资源URL\n * @param resourcePath - entry或style路径,可能是相对路径或完整URL\n * @param baseUrl - registry中的base_url,可能是完整URL或相对路径\n * @param registryUrl - registry的URL(必须是绝对URL,作为相对baseUrl时的基准)\n * @returns 解析后的完整URL\n */\nconst resolveResourceUrl = (resourcePath: string, baseUrl: string, registryUrl: string): string => {\n // 完整URL:直接返回\n if (/^https?:\\/\\//i.test(resourcePath)) return resourcePath\n\n // 兜底:规范化一个“带尾斜杠”的 helper\n const ensureSlash = (s: string) => (s.endsWith('/') ? s : s + '/')\n\n // 如果 baseUrl 是完整URL:直接用它当基准(并确保目录语义)\n if (/^https?:\\/\\//i.test(baseUrl)) {\n const normalizedBase = ensureSlash(baseUrl)\n return new URL(resourcePath, normalizedBase).href\n }\n\n // baseUrl 是相对路径(如 './' 或 '/plugins')\n // 先把 baseUrl 相对于 registryUrl 解析成绝对URL\n // 注意:当 baseUrl 是 '/plugins' 这种根相对路径时,new URL 会以 registryUrl 的 origin 作为根。\n const registryAbs = (() => {\n try {\n return new URL(registryUrl).href\n } catch {\n // 极端情况(开发环境传了相对 registry),用页面 origin 兜底\n return new URL(registryUrl, location.origin).href\n }\n })()\n\n const resolvedBaseUrl = new URL(ensureSlash(baseUrl), registryAbs).href\n return new URL(resourcePath, resolvedBaseUrl).href\n}\n\n@Inject(['storage', 'preferences', 'resourceLoader', '$'])\nexport class PluginPluginStore extends BasePlugin {\n // re-export for external usage\n static readonly PluginStoreSchemas = PluginStoreSchemas\n static REGISTRY_INFO_CACHE_TTL = 1000 * 60 * 60 * 24 // 1 day\n static REGISTRY_INFO_STORAGE_NAME = 'plugin-store-registry'\n static REGISTRY_ETAG_STORAGE_NAME = 'psreg-etag'\n private regInfoDB: AbstractIPEStorageManager<PluginStoreRegistry>\n\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'plugin-store')\n ctx.set('store', this)\n this.regInfoDB = ctx.storage.createDatabase<PluginStoreRegistry>(\n PluginPluginStore.REGISTRY_INFO_STORAGE_NAME,\n PluginPluginStore.REGISTRY_INFO_CACHE_TTL,\n 1,\n 'indexedDB'\n )\n }\n\n protected async start() {\n this._installUserPlugins()\n this._injectPreferenceUI()\n }\n\n private async _installUserPlugins() {\n const prefs = await this.ctx.preferences.get('pluginStore.plugins', [])\n if (!prefs?.length) {\n return\n }\n for (const pref of prefs) {\n this.install(pref.registry, pref.id, pref.source)\n }\n }\n\n private async _createManagementApp() {\n const ctx = await this.ctx.withInject(['store'])\n const PluginStoreApp = defineAsyncComponent(() => import('./components/PluginStoreApp.vue'))\n const app = createVueAppWithIPE(ctx, PluginStoreApp)\n return app\n }\n\n private async _injectPreferenceUI() {\n const ctx = this.ctx\n const $ = ctx.$\n\n ctx.preferences.defineCategory({\n name: 'plugin-store',\n label: $`Plugin Store`,\n description: $`Plugin Store`,\n index: 90,\n autoGenerateForm: false,\n customRenderer: async ({ onUnmount }) => {\n const container = <div id=\"ipe-plugin-store-preferences-vue\"></div>\n const app = await this._createManagementApp()\n app.mount(container)\n\n onUnmount(() => {\n app.unmount()\n this.ctx.logger.debug('Plugin Store preferences app unmounted')\n })\n\n return (\n <section>\n {container}\n {/* <div className=\"theme-ipe-prose\">\n <hr />\n <div style={{ textAlign: 'center', marginBottom: '1em', fontSize: '0.8em' }}>\n 🚫 DO NOT edit fields below manually 🚫\n </div>\n </div> */}\n </section>\n )\n },\n })\n\n ctx.preferences.registerCustomConfig(\n 'plugin-store',\n Schema.object({\n 'pluginStore.registries': Schema.array(Schema.string())\n .default([\n import.meta.env.PROD\n ? Endpoints.PLUGIN_REGISTRY_URL\n : import.meta.resolve('/src/__mock__/plugin-registry/index.json'),\n ])\n .description($`Registry URLs`)\n .hidden(),\n 'pluginStore.cdnForNpm': Schema.string()\n .description($`CDN to install packages from npm`)\n .default('https://cdn.jsdelivr.net/npm/{{ package }}{{ version ? \"@\" + version : \"\" }}')\n .hidden(),\n 'pluginStore.plugins': Schema.array(\n Schema.object({\n source: Schema.union(['online_manifest', 'npm']).default('online_manifest'),\n registry: Schema.string().required(),\n id: Schema.string().required(),\n })\n )\n .description($`Installed plugins`)\n .default([])\n .hidden(),\n }),\n 'plugin-store'\n )\n }\n\n async showModal() {\n const modal = this.ctx.modal.show({\n title: $`Plugin Store`,\n sizeClass: 'small',\n })\n const container = <section id=\"ipe-plugin-store-vue\"></section>\n modal.setContent(container)\n const app = await this._createManagementApp()\n app.mount(container)\n modal.on(modal.Event.Close, () => {\n app.unmount()\n })\n return modal\n }\n\n private _installedPlugins = new Map<string, Promise<ForkScope<InPageEdit> | null>>()\n async install(\n registry: string,\n id: string,\n source: PluginStoreRegistrySource = 'online_manifest'\n ): Promise<ForkScope<InPageEdit> | null> {\n const registryInfo = await this.getRegistryInfo(registry, source)\n if (!registryInfo) {\n this.ctx.logger.warn(`Registry ${registry} not found`)\n return null\n }\n const key = `${registry}#${id}`\n if (this._installedPlugins.has(key)) {\n return (await this._installedPlugins.get(key)) ?? null\n }\n // 2) 把 registry 原始 URL 传进去,供 URL 解析使用\n const scope = this._installOneByRegistryInfo(registry, registryInfo, id)\n this._installedPlugins.set(key, scope)\n return await scope\n }\n async uninstall(registry: string, id: string): Promise<boolean> {\n const promise = this._installedPlugins.get(`${registry}#${id}`)\n if (promise === void 0) {\n return true // not installed or already uninstalled\n }\n this._installedPlugins.delete(`${registry}#${id}`)\n const scope = await promise\n if (scope) {\n return scope.dispose?.() ?? true // disposed successfully\n }\n return true // not a plugin, just removed from the list\n }\n\n async addToPreferences(registry: string, id: string) {\n let prefs =\n (await this.ctx.preferences.get<{ registry: string; id: string }[]>('pluginStore.plugins')) ||\n []\n const existed = prefs.some((p) => p.registry === registry && p.id === id)\n if (existed) {\n return true\n }\n prefs.push({ registry, id })\n await this.ctx.preferences.set('pluginStore.plugins', prefs)\n return true\n }\n async removeFromPreferences(registry: string, id: string) {\n let prefs =\n (await this.ctx.preferences.get<{ registry: string; id: string }[]>('pluginStore.plugins')) ||\n []\n prefs = prefs.filter((p) => p.registry !== registry || p.id !== id)\n await this.ctx.preferences.set('pluginStore.plugins', prefs)\n return true\n }\n\n async installAndSetPreference(registry: string, id: string) {\n await this.addToPreferences(registry, id)\n return this.install(registry, id)\n }\n async uninstallAndRemovePreference(registry: string, id: string) {\n await this.removeFromPreferences(registry, id)\n return this.uninstall(registry, id)\n }\n\n // 3) 增加 registryUrl 参数\n private async _installOneByRegistryInfo(\n registryUrl: string,\n registryInfo: PluginStoreRegistry,\n id: string\n ): Promise<ForkScope<InPageEdit> | null> {\n const baseUrl = registryInfo.base_url\n const pkg = registryInfo.packages.find((p) => p.id === id)\n if (!pkg) {\n this.ctx.logger.warn(`Package ${id} not found in registry ${registryUrl}`)\n return null\n }\n\n const loader = pkg.loader\n const { kind, entry = 'index.js', styles = [], main_export = null } = loader\n\n // 4) 统一用 resolveResourceUrl 解析入口\n let entryUrl: string | null = null\n if (kind !== 'styles') {\n if (!entry) {\n this.ctx.logger.warn(`Entry url missing for ${id}`, loader)\n return null\n }\n try {\n entryUrl = resolveResourceUrl(entry, baseUrl, registryUrl)\n } catch (e) {\n this.ctx.logger.warn(\n `Failed to resolve entry \"${entry}\" with base \"${baseUrl}\" and registry \"${registryUrl}\"`,\n e\n )\n return null\n }\n }\n\n const datasets = {\n 'data-plugin-registry': registryUrl,\n 'data-plugin-id': id,\n }\n\n let fork: ForkScope<InPageEdit> | null = null\n\n switch (kind) {\n case 'autoload': {\n fork = this.ctx.plugin({\n inject: ['resourceLoader'],\n name: `plugin-store-${registryUrl}-${id}`,\n apply: (ctx) => {\n if (!entryUrl) return\n ctx.resourceLoader.loadScript(entryUrl, { ...datasets })\n },\n })\n break\n }\n case 'module': {\n if (!entryUrl) {\n this.ctx.logger.warn(`Entry url missing for module kind, package ${id}`)\n return null\n }\n const apply = await import(/* @vite-ignore */ entryUrl).then(\n (m) => (main_export ? m[main_export] : m.default) ?? m\n )\n if (!apply) {\n this.ctx.logger.warn(`Main export ${main_export} not found in module ${entryUrl}`)\n return null\n }\n fork = this.ctx.plugin(apply)\n break\n }\n case 'umd': {\n let apply = tryGetGlobalPlugin(main_export!)\n if (!apply) {\n if (!entryUrl) {\n this.ctx.logger.warn(`Entry url missing for umd kind, package ${id}`)\n return null\n }\n await this.ctx.resourceLoader.loadScript(entryUrl, { ...datasets })\n apply = tryGetGlobalPlugin(main_export!)\n }\n if (!apply) {\n this.ctx.logger.warn(\n `Main export ${main_export} not found on globalThis after loading ${entryUrl}`\n )\n return null\n }\n fork = this.ctx.plugin(apply)\n break\n }\n case 'styles': {\n // 没有脚本,仅样式。下面统一样式注入逻辑会覆盖\n break\n }\n }\n\n // 5) 统一解析并注入样式(兼容绝对URL与相对 + base_url 的组合)\n if (styles && styles.length > 0) {\n let urls: string[] = []\n try {\n urls = styles.map((u) => resolveResourceUrl(u, baseUrl, registryUrl)).filter(Boolean)\n } catch (e) {\n this.ctx.logger.warn(`Failed to resolve styles for ${id}`, styles, e)\n }\n\n // 确保存在父 fork\n fork ||= this.ctx.plugin({ name: `plugin-store-${registryUrl}-${id}`, apply() {} })\n\n // 在子插件里加载样式,并在卸载时清理\n fork.ctx.plugin({\n inject: ['resourceLoader'],\n name: `plugin-store-${registryUrl}-${id}-styles`,\n apply: (ctx) => {\n urls.forEach((u) => ctx.resourceLoader.loadStyle(u, { ...datasets }))\n ctx.on('dispose', () => {\n try {\n urls.forEach((u) => ctx.resourceLoader.removeStyle(u))\n } catch (e) {\n console.info('styles cleanup failed', e)\n }\n })\n },\n })\n }\n\n return fork\n }\n\n validateRegistry(data: any): PluginStoreRegistry {\n return PluginStoreSchemas.Registry(data)\n }\n\n async getRegistryInfo(\n registry: string,\n source: PluginStoreRegistrySource = 'online_manifest',\n noCache = false\n ): Promise<PluginStoreRegistry> {\n try {\n let info: PluginStoreRegistry\n switch (source) {\n case 'online_manifest': {\n info = await this._fetchOnlineRegistryInfo(registry, noCache)\n this.logger.debug('Fetched registry info from online manifest', info)\n this.setRegistryCache(registry, info)\n break\n }\n default: {\n throw new Error(`Unsupported registry source: ${source}`)\n }\n }\n\n return info\n } catch (e) {\n this.ctx.logger.warn('Failed to fetch registry info', e)\n }\n\n const info = await this.getRegistryCache(registry)\n if (!info) {\n throw new Error(`Failed to fetch registry info: ${registry}`)\n }\n return info\n }\n\n private _onlineRegistryQueries = new Map<string, Promise<PluginStoreRegistry>>()\n private async _fetchOnlineRegistryInfo(\n registry: string,\n noCache = false\n ): Promise<PluginStoreRegistry> {\n if (!noCache && this._onlineRegistryQueries.has(registry)) {\n return await this._onlineRegistryQueries.get(registry)!\n }\n const task = async () => {\n const payload: RequestInit = {\n method: 'GET',\n }\n if (noCache) {\n payload.cache = 'no-store'\n }\n const response = await fetch(registry, payload)\n const data = await response.json()\n const validated = this.validateRegistry(data)\n return validated\n }\n const promise = task()\n this._onlineRegistryQueries.set(registry, promise)\n return await promise\n }\n\n private async getRegistryCache(registry: string) {\n const data = await this.regInfoDB.get(registry)\n if (data) {\n try {\n const validated = this.validateRegistry(data)\n return validated\n } catch (e) {\n this.ctx.logger.warn('Invalid cached registry', e, data)\n this.regInfoDB.delete(registry)\n }\n }\n return null\n }\n private async setRegistryCache(registry: string, data: PluginStoreRegistry) {\n return this.regInfoDB.set(registry, data)\n }\n private async deleteRegistryCache(registry: string) {\n await this.regInfoDB.delete(registry)\n }\n async clearAllRegistryCaches() {\n await this.regInfoDB.clear()\n this.ctx.logger.debug('All registry caches cleared')\n }\n\n /**\n * 刷新指定 registry 的缓存(重新从网络获取)\n */\n async refreshRegistryCache(registry: string): Promise<PluginStoreRegistry> {\n const data = await this.getRegistryInfo(registry, 'online_manifest', true)\n if (!data) {\n throw new Error(`Failed to refresh registry cache: ${registry}`)\n }\n this.ctx.logger.debug('Registry cache refreshed:', registry)\n return data\n }\n\n /**\n * 刷新所有已配置的 registry 缓存\n */\n async refreshAllRegistryCaches(): Promise<Record<string, PluginStoreRegistry | null>> {\n const registryUrls = (await this.ctx.preferences.get('pluginStore.registries')) || []\n const responses = await Promise.allSettled(\n registryUrls.map((url) => this.refreshRegistryCache(url))\n )\n const results: Record<string, PluginStoreRegistry | null> = {}\n for (const [index, response] of responses.entries()) {\n if (response.status === 'fulfilled') {\n results[registryUrls[index]] = response.value\n } else {\n results[registryUrls[index]] = null\n }\n }\n return results\n }\n}\n"],"names":["PLUGIN_STORE_REGISTRY_MANIFEST_VERSION","PluginStoreSchemas","Schema","_PluginPluginStore_decorators","_init","_a","tryGetGlobalPlugin","main_export","acc","key","resolveResourceUrl","resourcePath","baseUrl","registryUrl","ensureSlash","s","normalizedBase","registryAbs","resolvedBaseUrl","Inject","_PluginPluginStore","BasePlugin","ctx","prefs","pref","PluginStoreApp","defineAsyncComponent","createVueAppWithIPE","$","onUnmount","container","jsx","app","Endpoints","modal","registry","id","source","registryInfo","scope","promise","p","pkg","loader","kind","entry","styles","entryUrl","e","datasets","fork","apply","m","urls","u","data","noCache","info","payload","registryUrls","responses","url","results","index","response","__decoratorStart","__decorateElement","__runInitializers","PluginPluginStore"],"mappings":"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"}
@@ -1,145 +0,0 @@
1
- import { j as c } from "./index-CM_6yF2v.js";
2
- import { c as D, R as C, I as E, S as f } from "./Preferences-85Q9FAmb.js";
3
- var I = Object.create, v = Object.defineProperty, T = Object.getOwnPropertyDescriptor, y = (e, t) => (t = Symbol[e]) ? t : Symbol.for("Symbol." + e), _ = (e) => {
4
- throw TypeError(e);
5
- }, z = (e, t, o) => t in e ? v(e, t, { enumerable: !0, configurable: !0, writable: !0, value: o }) : e[t] = o, q = (e, t) => v(e, "name", { value: t, configurable: !0 }), $ = (e) => [, , , I(e?.[y("metadata")] ?? null)], O = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], w = (e) => e !== void 0 && typeof e != "function" ? _("Function expected") : e, j = (e, t, o, n, r) => ({ kind: O[e], name: t, metadata: n, addInitializer: (i) => o._ ? _("Already initialized") : r.push(w(i || null)) }), k = (e, t) => z(t, y("metadata"), e[3]), A = (e, t, o, n) => {
6
- for (var r = 0, i = e[t >> 1], a = i && i.length; r < a; r++) i[r].call(o);
7
- return n;
8
- }, M = (e, t, o, n, r, i) => {
9
- var a, h, g, l = t & 7, b = !1, s = 0, u = e[s] || (e[s] = []), d = l && (r = r.prototype, l < 5 && (l > 3 || !b) && T(r, o));
10
- q(r, o);
11
- for (var p = n.length - 1; p >= 0; p--)
12
- g = j(l, o, h = {}, e[3], u), a = (0, n[p])(r, g), h._ = 1, w(a) && (r = a);
13
- return k(e, r), d && v(r, o, d), b ? l ^ 4 ? i : d : r;
14
- }, S, m, P;
15
- S = [C(
16
- f.object({
17
- toolboxAlwaysShow: f.boolean().description("Make the toolbox opened by default").default(!1)
18
- }).description("Toolbox preferences")
19
- ), E(["preferences"])];
20
- class x extends (P = D) {
21
- constructor(t) {
22
- super(t, "toolbox", !1), this.ctx = t, this.container = void 0;
23
- }
24
- async start() {
25
- this.container = this.createToolbox(), this.ctx.preferences.get("toolboxAlwaysShow").then((t) => {
26
- t && this.container.classList.add("is-persistent");
27
- }), this.setupHoverLogic(), document.body.appendChild(this.container), this.updateButtonDelays();
28
- }
29
- stop() {
30
- this.container?.remove();
31
- }
32
- get isPersistent() {
33
- return this.container.classList.contains("is-persistent");
34
- }
35
- setupHoverLogic() {
36
- let t = null;
37
- this.container.addEventListener("mouseenter", () => {
38
- t && (clearTimeout(t), t = null), this.isPersistent || this.container.classList.add("is-hovered");
39
- }), this.container.addEventListener("mouseleave", () => {
40
- this.isPersistent || (t = window.setTimeout(() => {
41
- this.container.classList.remove("is-hovered");
42
- }, 150));
43
- });
44
- }
45
- /**
46
- * 计算按钮动画延迟
47
- * @param index 按钮索引(从0开始)
48
- * @param totalCount 总按钮数量
49
- * @returns 延迟时间(秒)
50
- */
51
- calculateButtonDelay(t, o) {
52
- if (o <= 1) return 0;
53
- const n = 0.15, r = t / (o - 1), i = n * Math.sqrt(r);
54
- return Math.round(i * 1e3) / 1e3;
55
- }
56
- /**
57
- * 更新按钮组的动画延迟
58
- */
59
- updateButtonDelays() {
60
- this.container.querySelectorAll(".btn-group").forEach((o) => {
61
- const n = o.querySelectorAll(".btn-tip-group"), r = n.length;
62
- n.forEach((i, a) => {
63
- const h = this.calculateButtonDelay(a, r);
64
- i.style.setProperty("--transition-delay", `${h}s`), i.style.setProperty("--max-transition-delay", "0.15s");
65
- });
66
- });
67
- }
68
- createToolbox() {
69
- return /* @__PURE__ */ c("div", { id: "ipe-edit-toolbox", children: [
70
- /* @__PURE__ */ c("ul", { className: "btn-group group1", style: { display: "flex", flexDirection: "column" } }),
71
- /* @__PURE__ */ c("ul", { className: "btn-group group2", style: { display: "flex", flexDirection: "row" } }),
72
- /* @__PURE__ */ c(
73
- "button",
74
- {
75
- className: "ipe-toolbox-btn",
76
- id: "toolbox-toggler",
77
- onClick: () => {
78
- this.toggle();
79
- },
80
- children: /* @__PURE__ */ c("svg", { xmlns: "http://www.w3.org/2000/svg", width: "448", height: "512", viewBox: "0 0 448 512", children: [
81
- /* @__PURE__ */ c("rect", { width: "448", height: "512", fill: "none" }),
82
- /* @__PURE__ */ c(
83
- "path",
84
- {
85
- fill: "currentColor",
86
- 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"
87
- }
88
- )
89
- ] })
90
- }
91
- )
92
- ] });
93
- }
94
- normalizeButtonId(t) {
95
- return t || (t = Math.random().toString(36).substring(2, 8)), `ipe-toolbox__${t.trim()}`.replace(/\s\.#/g, "-");
96
- }
97
- addButton(t) {
98
- let { id: o, group: n, icon: r, tooltip: i, itemProps: a, buttonProps: h, onClick: g, index: l } = t;
99
- o = this.normalizeButtonId(o);
100
- const b = this.container.querySelector(`#${o}`);
101
- b && (this.ctx.logger("toolbox").warn(`Button with id ${o} already exists, replacing it.`), b.remove());
102
- let s = null;
103
- if (typeof n > "u" || n === "auto") {
104
- const d = this.container.querySelector(".btn-group.group1"), p = this.container.querySelector(".btn-group.group2"), B = d?.children.length || 0, L = p?.children.length || 0;
105
- s = B <= L ? d : p;
106
- } else
107
- s = this.container.querySelector(`.btn-group.${n}`);
108
- if (!s) throw new Error(`Button group ${n} not found`);
109
- const u = /* @__PURE__ */ c("li", { class: "btn-tip-group", id: o, onClick: g, ...a, children: [
110
- /* @__PURE__ */ c("div", { class: "btn-tip", children: i }),
111
- /* @__PURE__ */ c("button", { id: `${o}-btn`, "data-id": t.id, class: "ipe-toolbox-btn", ...h, children: r })
112
- ] });
113
- return u.addEventListener("click", (d) => {
114
- this.ctx.emit("toolbox/button-clicked", {
115
- ctx: this.ctx,
116
- button: d.target,
117
- id: t.id
118
- });
119
- }), typeof l == "number" ? l <= 0 ? s.prepend(u) : l >= s.children.length ? s.appendChild(u) : s.children[l]?.before(u) : s.appendChild(u), this.ctx.emit("toolbox/button-added", {
120
- ctx: this.ctx,
121
- button: u
122
- }), this.updateButtonDelays(), u;
123
- }
124
- removeButton(t) {
125
- const o = this.normalizeButtonId(t);
126
- this.container.querySelector(`#${o}`)?.remove(), this.ctx.emit("toolbox/button-removed", { ctx: this.ctx, id: t }), this.updateButtonDelays();
127
- }
128
- getContainer() {
129
- return this.container;
130
- }
131
- get isOpened() {
132
- return this.container.classList.contains("is-persistent") || this.container.classList.contains("is-hovered");
133
- }
134
- toggle(t) {
135
- const o = this.isPersistent, n = typeof t == "boolean" ? t : !o;
136
- this.container.classList.toggle("is-persistent", n), this.container.classList.remove("is-hovered"), this.ctx.preferences.set("toolboxAlwaysShow", n), this.ctx.emit("toolbox/toggle", { ctx: this.ctx, opened: this.isOpened });
137
- }
138
- }
139
- m = $(P);
140
- x = M(m, 0, "PluginToolbox", S, x);
141
- A(m, 1, x);
142
- export {
143
- x as PluginToolbox
144
- };
145
- //# sourceMappingURL=index-rpiO9fpc.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-rpiO9fpc.js","sources":["../src/plugins/toolbox/index.tsx"],"sourcesContent":["import { Inject, InPageEdit, Schema, Service } from '@/InPageEdit'\nimport { JSX, ReactElement } from 'jsx-dom'\nimport './styles.scss'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n toolbox: PluginToolbox\n }\n interface Events {\n 'toolbox/button-added'(payload: { ctx: InPageEdit; button: HTMLElement }): void\n 'toolbox/button-removed'(payload: { ctx: InPageEdit; id: string }): void\n 'toolbox/button-clicked'(payload: { ctx: InPageEdit; button: HTMLElement; id: string }): void\n 'toolbox/toggle'(payload: { ctx: InPageEdit; opened: boolean }): void\n }\n interface PreferencesMap {\n toolboxAlwaysShow: boolean\n }\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 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.updateButtonDelays()\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 return `ipe-toolbox__${id.trim()}`.replace(/\\s\\.#/g, '-')\n }\n\n addButton(payload: {\n id: string\n group?: 'auto' | 'group1' | 'group2'\n icon: string | HTMLElement | SVGElement | ReactElement\n tooltip?: string | HTMLElement\n itemProps?: JSX.IntrinsicElements['li']\n buttonProps?: JSX.IntrinsicElements['button']\n onClick?: (event: MouseEvent) => void\n index?: number\n }) {\n let { id, group, icon, tooltip, itemProps, buttonProps, onClick, index } = payload\n id = this.normalizeButtonId(id)\n\n const existingButton = this.container.querySelector(`#${id}`)\n if (existingButton) {\n this.ctx.logger('toolbox').warn(`Button with id ${id} already exists, replacing it.`)\n existingButton.remove()\n }\n\n let groupEl: HTMLElement | null = null\n if (typeof group === 'undefined' || group === 'auto') {\n // 选择按钮最少的那一组,一样多就选第一组\n const group1 = this.container.querySelector('.btn-group.group1') as HTMLElement\n const group2 = this.container.querySelector('.btn-group.group2') as HTMLElement\n const group1Count = group1?.children.length || 0\n const group2Count = group2?.children.length || 0\n groupEl = group1Count <= group2Count ? group1 : group2\n } else {\n groupEl = this.container.querySelector(`.btn-group.${group}`)\n }\n if (!groupEl) throw new Error(`Button group ${group} not found`)\n\n const button = (\n <li class=\"btn-tip-group\" id={id} onClick={onClick} {...itemProps}>\n <div class=\"btn-tip\">{tooltip}</div>\n <button id={`${id}-btn`} data-id={payload.id} class=\"ipe-toolbox-btn\" {...buttonProps}>\n {icon}\n </button>\n </li>\n )\n\n button.addEventListener('click', (e) => {\n this.ctx.emit('toolbox/button-clicked', {\n ctx: this.ctx,\n button: e.target as HTMLElement,\n id: payload.id,\n })\n })\n\n if (typeof index === 'number') {\n if (index <= 0) {\n groupEl.prepend(button)\n } else if (index >= groupEl.children.length) {\n groupEl.appendChild(button)\n } else {\n groupEl.children[index]?.before(button)\n }\n } else {\n groupEl.appendChild(button)\n }\n\n this.ctx.emit('toolbox/button-added', {\n ctx: this.ctx,\n button: button as HTMLElement,\n })\n\n // 更新按钮延迟\n this.updateButtonDelays()\n\n return button as HTMLElement\n }\n\n removeButton(id: string) {\n const normalizedId = this.normalizeButtonId(id)\n const button = this.container.querySelector(`#${normalizedId}`)\n button?.remove()\n this.ctx.emit('toolbox/button-removed', { ctx: this.ctx, id })\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","val","hoverTimeout","index","totalCount","totalDuration","normalizedIndex","delay","group","buttons","button","jsxs","jsx","id","payload","icon","tooltip","itemProps","buttonProps","onClick","existingButton","groupEl","group1","group2","group1Count","group2Count","e","normalizedId","force","isPersistent","newPersistent","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}