@inpageedit/core 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +9 -2
  2. package/dist/PluginPrefSync-COidewzp.js +258 -0
  3. package/dist/PluginPrefSync-COidewzp.js.map +1 -0
  4. package/dist/__test__/utils/constants.d.ts +3 -2
  5. package/dist/components/index.js +69 -51
  6. package/dist/components/index.js.map +1 -1
  7. package/dist/constants/endpoints.d.ts +1 -1
  8. package/dist/{index-BR6gK_ki.js → index-BNDyaWnI.js} +44 -38
  9. package/dist/index-BNDyaWnI.js.map +1 -0
  10. package/dist/{index-BnAhw94L.js → index-BQzuJxBO.js} +2 -2
  11. package/dist/{index-BnAhw94L.js.map → index-BQzuJxBO.js.map} +1 -1
  12. package/dist/{index-Z-_kjibx.js → index-BUI2IX49.js} +763 -699
  13. package/dist/index-BUI2IX49.js.map +1 -0
  14. package/dist/{index-Cx-YiN1j.js → index-CBszdxJJ.js} +22 -21
  15. package/dist/index-CBszdxJJ.js.map +1 -0
  16. package/dist/index-CfgnJ51A.js +185 -0
  17. package/dist/index-CfgnJ51A.js.map +1 -0
  18. package/dist/index-Cx4qgCJK.js +4914 -0
  19. package/dist/{index-DqJUIV2e.js.map → index-Cx4qgCJK.js.map} +1 -1
  20. package/dist/index-D5J7RU5I.js +211 -0
  21. package/dist/index-D5J7RU5I.js.map +1 -0
  22. package/dist/{index-ByzgI28q.js → index-MhNAv9Vf.js} +6 -2
  23. package/dist/index-MhNAv9Vf.js.map +1 -0
  24. package/dist/{index-ByJfEsN8.js → index-U2RPZk8N.js} +148 -110
  25. package/dist/index-U2RPZk8N.js.map +1 -0
  26. package/dist/{index-CAiGct8U.js → index-VnRKIVau.js} +42 -42
  27. package/dist/index-VnRKIVau.js.map +1 -0
  28. package/dist/{index-eOIVMf9E.js → index-etJXONAj.js} +46 -35
  29. package/dist/index-etJXONAj.js.map +1 -0
  30. package/dist/index.js +1 -1
  31. package/dist/models/WikiTitle/index.d.ts +2 -2
  32. package/dist/plugins/analytics/index.d.ts +41 -0
  33. package/dist/plugins/in-article-links/index.d.ts +14 -0
  34. package/dist/plugins/preferences-ui/PluginPrefSync.d.ts +2 -0
  35. package/dist/plugins/preferences-ui/index.d.ts +3 -1
  36. package/dist/plugins/quick-delete/index.d.ts +3 -0
  37. package/dist/plugins/quick-diff/index.d.ts +17 -0
  38. package/dist/plugins/quick-edit/index.d.ts +8 -0
  39. package/dist/plugins/quick-move/index.d.ts +16 -0
  40. package/dist/plugins/quick-redirect/index.d.ts +15 -0
  41. package/dist/plugins/toolbox/index.d.ts +9 -0
  42. package/dist/services/PreferencesService.d.ts +9 -2
  43. package/dist/services/WikiMetadataService.d.ts +23 -23
  44. package/dist/style.css +1 -1
  45. package/dist/types/WikiMetadata.d.ts +6 -8
  46. package/lib/index.umd.js +24 -24
  47. package/lib/index.umd.js.map +1 -1
  48. package/lib/style.css +1 -1
  49. package/package.json +3 -3
  50. package/dist/ActionButton-BgbTKTg7.js +0 -24
  51. package/dist/ActionButton-BgbTKTg7.js.map +0 -1
  52. package/dist/PluginPrefSync-CNCU2DJU.js +0 -171
  53. package/dist/PluginPrefSync-CNCU2DJU.js.map +0 -1
  54. package/dist/index-2mNdeL-V.js +0 -193
  55. package/dist/index-2mNdeL-V.js.map +0 -1
  56. package/dist/index-BR6gK_ki.js.map +0 -1
  57. package/dist/index-ByJfEsN8.js.map +0 -1
  58. package/dist/index-ByzgI28q.js.map +0 -1
  59. package/dist/index-CAiGct8U.js.map +0 -1
  60. package/dist/index-Cx-YiN1j.js.map +0 -1
  61. package/dist/index-DqJUIV2e.js +0 -4861
  62. package/dist/index-Z-_kjibx.js.map +0 -1
  63. package/dist/index-eOIVMf9E.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { j as e, P as c } from "./index-CvhkVj_L.js";
2
- import { B as l } from "./index-Z-_kjibx.js";
1
+ import { j as e, P as n } from "./index-CvhkVj_L.js";
2
+ import { B as l } from "./index-BUI2IX49.js";
3
3
  import { T as d } from "./index-Bh70Udzi.js";
4
4
  import { I as m } from "./InputBox-BV4m05Xs.js";
5
5
  import { C as u } from "./CheckBox-D3rHnX7I.js";
6
- class v extends l {
6
+ class k extends l {
7
7
  constructor(t) {
8
8
  super(t, {}, "quick-redirect"), this.ctx = t;
9
9
  }
@@ -56,9 +56,10 @@ class v extends l {
56
56
  stop() {
57
57
  }
58
58
  quickRedirect(t) {
59
+ t || (t = {}), this.ctx.emit("quick-redirect/init-options", { ctx: this.ctx, options: t });
59
60
  const i = this.ctx.modal.createObject({
60
61
  title: "Quick Redirect",
61
- content: /* @__PURE__ */ e(c, {}),
62
+ content: /* @__PURE__ */ e(n, {}),
62
63
  className: "quick-redirect compact-buttons",
63
64
  sizeClass: "smallToMedium",
64
65
  center: !0
@@ -77,28 +78,28 @@ class v extends l {
77
78
  onSubmit: (o) => {
78
79
  if (o.preventDefault(), r?.checkValidity(), !r?.reportValidity())
79
80
  return;
80
- const a = new FormData(r), s = {
81
- from: a.get("from")?.toString().trim(),
82
- to: a.get("to")?.toString().trim(),
83
- reason: a.get("reason") || "",
84
- overwrite: a.get("overwrite") === "on"
81
+ const c = new FormData(r), a = {
82
+ from: c.get("from")?.toString().trim(),
83
+ to: c.get("to")?.toString().trim(),
84
+ reason: c.get("reason") || "",
85
+ overwrite: c.get("overwrite") === "on"
85
86
  };
86
- if (!s.from || !s.to) {
87
+ if (!a.from || !a.to) {
87
88
  this.ctx.modal.notify("error", {
88
89
  title: "Failed to redirect",
89
90
  content: "From and to are required."
90
91
  });
91
92
  return;
92
93
  }
93
- i.setLoadingState(!0), this.redirectPage(s).then((n) => {
94
+ this.ctx.emit("quick-redirect/submit", { ctx: this.ctx, payload: a }), i.setLoadingState(!0), this.redirectPage(a).then((s) => {
94
95
  i.close(), this.ctx.modal.notify("success", {
95
96
  title: "Redirect successful",
96
97
  content: "The redirect has been created."
97
98
  });
98
- }).catch((n) => {
99
+ }).catch((s) => {
99
100
  i.setLoadingState(!1), this.ctx.modal.notify("error", {
100
101
  title: "Failed to redirect",
101
- content: n instanceof Error ? n.message : String(n)
102
+ content: s instanceof Error ? s.message : String(s)
102
103
  });
103
104
  });
104
105
  },
@@ -135,24 +136,24 @@ class v extends l {
135
136
  r?.dispatchEvent(new Event("submit"));
136
137
  }
137
138
  }
138
- ]), i.show();
139
+ ]), this.ctx.emit("quick-redirect/show-modal", { ctx: this.ctx, modal: i }), i.show();
139
140
  }
140
141
  async redirectPage(t) {
141
- const { from: i, to: r, reason: o = "", overwrite: a = !1 } = t, s = await this.ctx.wikiPage.newBlankPage({
142
+ const { from: i, to: r, reason: o = "", overwrite: c = !1 } = t, a = await this.ctx.wikiPage.newBlankPage({
142
143
  title: i
143
- }), n = `#REDIRECT [[:${r}]]`;
144
- return s.edit(
144
+ }), s = `#REDIRECT [[:${r}]]`;
145
+ return a.edit(
145
146
  {
146
- text: n,
147
+ text: s,
147
148
  summary: o
148
149
  },
149
150
  {
150
- createonly: !a
151
+ createonly: !c
151
152
  }
152
153
  );
153
154
  }
154
155
  }
155
156
  export {
156
- v as PluginQuickRedirect
157
+ k as PluginQuickRedirect
157
158
  };
158
- //# sourceMappingURL=index-Cx-YiN1j.js.map
159
+ //# sourceMappingURL=index-CBszdxJJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CBszdxJJ.js","sources":["../src/plugins/quick-redirect/index.tsx"],"sourcesContent":["import { InPageEdit } from '@/InPageEdit'\nimport { IPEModal } from '@inpageedit/modal'\n\ndeclare module '@/InPageEdit' {\n interface InPageEdit {\n quickRedirect: PluginQuickRedirect['quickRedirect']\n redirectPage: PluginQuickRedirect['redirectPage']\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}\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\n constructor(public ctx: InPageEdit) {\n super(ctx, {}, 'quick-redirect')\n }\n\n protected start(): Promise<void> | void {\n this.ctx.set('quickRedirect', this.quickRedirect.bind(this))\n this.ctx.set('redirectPage', this.redirectPage.bind(this))\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.quickRedirect(\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 quickRedirect(options?: Partial<QuickRedirectOptions>) {\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: 'From',\n name: 'from',\n value: options?.from,\n required: true,\n },\n {\n label: 'To',\n name: 'to',\n value: options?.to,\n required: true,\n },\n ]}\n />\n <InputBox label=\"Reason\" id=\"reason\" name=\"reason\" value={options?.reason} />\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","curPageName","canEdit","jsxs","jsx","options","modal","ProgressBar","formRef","el","e","formData","res","error","TwinSwapInput","InputBox","CheckBox","from","to","reason","overwrite","wikiPage","content"],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import { j as n } from "./index-CvhkVj_L.js";
2
+ import { B as A, S as p, E as v, p as P, a as x, I as U } from "./index-BUI2IX49.js";
3
+ var q = Object.create, f = Object.defineProperty, B = Object.getOwnPropertyDescriptor, b = (i, e) => (e = Symbol[i]) ? e : Symbol.for("Symbol." + i), w = (i) => {
4
+ throw TypeError(i);
5
+ }, L = (i, e, t) => e in i ? f(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t, N = (i, e) => f(i, "name", { value: e, configurable: !0 }), T = (i) => [, , , q(i?.[b("metadata")] ?? null)], D = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], k = (i) => i !== void 0 && typeof i != "function" ? w("Function expected") : i, O = (i, e, t, a, s) => ({ kind: D[i], name: e, metadata: a, addInitializer: (l) => t._ ? w("Already initialized") : s.push(k(l || null)) }), j = (i, e) => L(e, b("metadata"), i[3]), C = (i, e, t, a) => {
6
+ for (var s = 0, l = i[e >> 1], c = l && l.length; s < c; s++) l[s].call(t);
7
+ return a;
8
+ }, M = (i, e, t, a, s, l) => {
9
+ var c, d, h, o = e & 7, r = !1, y = 0, I = i[y] || (i[y] = []), u = o && (s = s.prototype, o < 5 && (o > 3 || !r) && B(s, t));
10
+ N(s, t);
11
+ for (var g = a.length - 1; g >= 0; g--)
12
+ h = O(o, t, d = {}, i[3], I), c = (0, a[g])(s, h), d._ = 1, k(c) && (s = c);
13
+ return j(i, s), u && f(s, t, u), r ? o ^ 4 ? l : u : s;
14
+ }, E, _, S;
15
+ E = [U(["wiki", "preferences"])];
16
+ class m extends (S = A) {
17
+ // 1分钟
18
+ constructor(e) {
19
+ super(e, {}, "analytics"), this.ctx = e, this._usages = [], this._timer = null, this.MAX_QUEUE_SIZE = 50, this.INTERVAL_MS = 60 * 1e3, this._setupTimer(), this._registerUnloadHandler(), this._showConfirmNotify(), this._initPluginListeners(), e.set("analytics", this);
20
+ }
21
+ start() {
22
+ this.ctx.preferences.registerCustomConfig(
23
+ "analytics",
24
+ p.object({
25
+ "analytics._intro": p.const(
26
+ /* @__PURE__ */ n("section", { children: [
27
+ /* @__PURE__ */ n("h3", { children: "InPageEdit Analytics" }),
28
+ /* @__PURE__ */ n("p", { children: "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." }),
29
+ /* @__PURE__ */ n("h4", { children: "What data will be collected?" }),
30
+ /* @__PURE__ */ n("ul", { style: { listStyle: "auto", paddingLeft: "1.5em" }, children: [
31
+ /* @__PURE__ */ n("li", { children: "Usage data: What features you use, what pages you edit, etc." }),
32
+ /* @__PURE__ */ n("li", { children: "User information: Your username, user ID." }),
33
+ /* @__PURE__ */ n("li", { children: "Site information: The wiki you are editing." })
34
+ ] }),
35
+ /* @__PURE__ */ n("p", { children: /* @__PURE__ */ n("strong", { children: "NO sensitive data will be collected." }) }),
36
+ /* @__PURE__ */ n("ul", { style: { listStyle: "auto", paddingLeft: "1.5em" }, children: [
37
+ /* @__PURE__ */ n("li", { children: /* @__PURE__ */ n("a", { href: this.analyticsDashUrl, target: "_blank", rel: "noopener noreferrer", children: "Analytics Platform →" }) }),
38
+ /* @__PURE__ */ n("li", { children: /* @__PURE__ */ n(
39
+ "a",
40
+ {
41
+ href: `${this.analyticsDashUrl}/_redirect/user?${new URLSearchParams({
42
+ siteApi: this.ctx.wiki.getSciprtUrl("api"),
43
+ mwUserId: this.ctx.wiki.userInfo.id.toString()
44
+ }).toString()}`,
45
+ target: "_blank",
46
+ rel: "noopener noreferrer",
47
+ children: "My Data →"
48
+ }
49
+ ) })
50
+ ] })
51
+ ] })
52
+ ).role("raw-html"),
53
+ "analytics.enabled": p.boolean().description("Share my usage data with the community.").default(!1)
54
+ }).description("Analytics settings"),
55
+ "general"
56
+ );
57
+ }
58
+ get analyticsDashUrl() {
59
+ return v.ANALYTICS_DASH_URL;
60
+ }
61
+ get analyticsApiBase() {
62
+ return v.ANALYTICS_API_BASE;
63
+ }
64
+ _setupTimer() {
65
+ this._timer = setInterval(() => {
66
+ this._usages.length > 0 && this.sendBeacon();
67
+ }, this.INTERVAL_MS);
68
+ }
69
+ _registerUnloadHandler() {
70
+ const e = () => {
71
+ this._usages.length > 0 && this.sendBeacon();
72
+ };
73
+ window.addEventListener("visibilitychange", () => {
74
+ document.visibilityState === "hidden" && e();
75
+ }), window.addEventListener("pagehide", e), window.addEventListener("beforeunload", e);
76
+ }
77
+ _showConfirmNotify() {
78
+ localStorage.getItem("IPE:analytics/confirm-shown") || this.ctx.inject(["modal"], (t) => {
79
+ t.modal.notify(
80
+ "confirm",
81
+ {
82
+ title: "Enable Analytics",
83
+ content: /* @__PURE__ */ n("div", { children: [
84
+ /* @__PURE__ */ n("p", { children: "Help us improve InPageEdit by sharing your usage data with us." }),
85
+ /* @__PURE__ */ n("p", { children: "What data will be collected?" }),
86
+ /* @__PURE__ */ n("ul", { style: { listStyle: "auto", paddingLeft: "1.5em" }, children: [
87
+ /* @__PURE__ */ n("li", { children: "Usage data: What features you use, what pages you edit, etc." }),
88
+ /* @__PURE__ */ n("li", { children: "User information: Your username, user ID." }),
89
+ /* @__PURE__ */ n("li", { children: "Site information: The wiki you are editing." })
90
+ ] }),
91
+ /* @__PURE__ */ n("p", { children: /* @__PURE__ */ n("strong", { children: "NO sensitive data will be collected." }) })
92
+ ] }),
93
+ okBtn: {
94
+ label: "Enable"
95
+ },
96
+ cancelBtn: {
97
+ label: "Disable"
98
+ },
99
+ closeAfter: 0,
100
+ onClose() {
101
+ localStorage.setItem("IPE:analytics/confirm-shown", "1");
102
+ }
103
+ },
104
+ (a) => {
105
+ t.preferences.set("analytics.enabled", a), a && this.addEvent("analytics", "enabled");
106
+ }
107
+ );
108
+ });
109
+ }
110
+ _initPluginListeners() {
111
+ const e = this.ctx;
112
+ e.on("in-article-links/anchor-clicked", (t) => {
113
+ this.addEvent("in-article-links", P(t.action));
114
+ }), e.on("quick-delete/submit", (t) => {
115
+ this.addEvent("quick-delete", "submit", t.wikiPage.title);
116
+ }), e.on("quick-diff/loaded", (t) => {
117
+ this.addEvent("quick-diff", "loaded", t.compare.fromtitle);
118
+ }), e.on("quick-redirect/submit", (t) => {
119
+ this.addEvent("quick-redirect", "submit", t.payload.to || void 0);
120
+ }), e.on("quick-preview/loaded", (t) => {
121
+ this.addEvent("quick-preview", "loaded", t.wikiPage.title);
122
+ }), e.on("quick-edit/wiki-page", (t) => {
123
+ this.addEvent("quick-edit", void 0, t.wikiPage.title);
124
+ }), e.on("quick-edit/submit", (t) => {
125
+ this.addEvent("quick-edit", "submit", t.wikiPage.title);
126
+ }), e.on("quick-move/submit", (t) => {
127
+ this.addEvent("quick-move", "submit");
128
+ }), e.on("toolbox/button-clicked", (t) => {
129
+ this.addEvent("toolbox", `button-clicked#${t.id || "unknown"}`);
130
+ });
131
+ }
132
+ addEvent(e, t, a) {
133
+ const s = {
134
+ ts: Date.now(),
135
+ feature: e,
136
+ subtype: t,
137
+ page: a
138
+ };
139
+ return this._usages.push(s), this._usages.length >= this.MAX_QUEUE_SIZE && this.sendBeacon(), this;
140
+ }
141
+ async sendBeacon() {
142
+ if (this._usages.length === 0)
143
+ return !0;
144
+ if (!await this.ctx.preferences.get("analytics.enabled", !1))
145
+ return this.logger.debug("Analytics disabled, skipping"), !0;
146
+ const t = this._usages.splice(0, this._usages.length), a = {
147
+ siteApi: this.ctx.wiki.getSciprtUrl("api"),
148
+ siteName: this.ctx.wiki.siteInfo.general.sitename,
149
+ userId: this.ctx.wiki.userInfo.id,
150
+ userName: this.ctx.wiki.userInfo.name,
151
+ version: this.ctx.version.split("-")[0],
152
+ usages: t
153
+ }, s = JSON.stringify(a), l = `${this.analyticsApiBase}/submit`;
154
+ if (navigator?.sendBeacon?.(l, s))
155
+ return this.logger.debug("Beacon sent successfully", a), !0;
156
+ {
157
+ this.logger.debug("Beacon failed, sending via XMLHttpRequest");
158
+ const { promise: d, resolve: h, reject: o } = x();
159
+ try {
160
+ const r = new XMLHttpRequest();
161
+ r.open("POST", l, !0), r.setRequestHeader("Content-Type", "application/json"), r.send(s), r.onload = () => {
162
+ this.logger.debug("Beacon sent successfully via XMLHttpRequest", a), h(r.status >= 200 && r.status < 300);
163
+ }, r.onerror = () => {
164
+ o(new Error("Failed to send beacon"));
165
+ };
166
+ } catch (r) {
167
+ o(r);
168
+ }
169
+ return d;
170
+ }
171
+ }
172
+ /**
173
+ * 清理资源
174
+ */
175
+ stop() {
176
+ this._timer !== null && (clearInterval(this._timer), this._timer = null), this._usages.length > 0 && this.sendBeacon();
177
+ }
178
+ }
179
+ _ = T(S);
180
+ m = M(_, 0, "PluginAnalytics", E, m);
181
+ C(_, 1, m);
182
+ export {
183
+ m as PluginAnalytics
184
+ };
185
+ //# sourceMappingURL=index-CfgnJ51A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CfgnJ51A.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 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\n project. By collecting and displaying usage data from around the world, it helps\n developers and the community better understand how the tool is used, optimize feature\n design, and enhance user experience.\n </p>\n <h4>What data will be collected?</h4>\n <ul style={{ listStyle: 'auto', paddingLeft: '1.5em' }}>\n <li>Usage data: What features you use, what pages you edit, etc.</li>\n <li>User information: Your username, user ID.</li>\n <li>Site information: The wiki you are editing.</li>\n </ul>\n <p>\n <strong>NO sensitive data will be collected.</strong>\n </p>\n <ul style={{ listStyle: 'auto', paddingLeft: '1.5em' }}>\n <li>\n <a href={this.analyticsDashUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n Analytics Platform →\n </a>\n </li>\n <li>\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 My Data →\n </a>\n </li>\n </ul>\n </section>\n ).role('raw-html'),\n 'analytics.enabled': Schema.boolean()\n .description('Share my usage data with the community.')\n .default(false),\n }).description('Analytics settings'),\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 _showConfirmNotify() {\n const shown = localStorage.getItem('IPE:analytics/confirm-shown')\n if (shown) {\n return\n }\n this.ctx.inject(['modal'], (ctx) => {\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>Usage data: What features you use, what pages you edit, etc.</li>\n <li>User information: Your username, user ID.</li>\n <li>Site information: The wiki you are editing.</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 localStorage.setItem('IPE:analytics/confirm-shown', '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-delete/submit', (payload) => {\n this.addEvent('quick-delete', 'submit', payload.wikiPage.title)\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","result","payload","paramCase","feature","subtype","page","usage","usages","body","endpoint","promise","resolve","reject","promiseWithResolvers","xhr","error","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}