@inpageedit/core 0.14.5 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ActionButton-CRjo_l3y.js → ActionButton-B6OUgtHx.js} +2 -2
- package/dist/{ActionButton-CRjo_l3y.js.map → ActionButton-B6OUgtHx.js.map} +1 -1
- package/dist/CheckBox-Dx3r3LQz.js +13 -0
- package/dist/CheckBox-Dx3r3LQz.js.map +1 -0
- package/dist/IconQuickDiff-BkbxyY-d.js +29 -0
- package/dist/IconQuickDiff-BkbxyY-d.js.map +1 -0
- package/dist/IconQuickEdit-BiRYADU_.js +68 -0
- package/dist/IconQuickEdit-BiRYADU_.js.map +1 -0
- package/dist/IconUpload-Bz4BW_nc.js +27 -0
- package/dist/IconUpload-Bz4BW_nc.js.map +1 -0
- package/dist/InPageEdit.js +20 -0
- package/dist/InPageEdit.js.map +1 -0
- package/dist/InputBox-D2ZRTMFP.js +42 -0
- package/dist/InputBox-D2ZRTMFP.js.map +1 -0
- package/dist/PluginImagesUsed-BVyvFA1_.js +90 -0
- package/dist/PluginImagesUsed-BVyvFA1_.js.map +1 -0
- package/dist/{PluginPrefSync-CbFuuC19.js → PluginPrefSync-CUKkx4Qk.js} +11 -11
- package/dist/{PluginPrefSync-CbFuuC19.js.map → PluginPrefSync-CUKkx4Qk.js.map} +1 -1
- package/dist/{PluginStoreApp-MbC3G9tu.js → PluginStoreApp-CoOAw1fr.js} +4 -4
- package/dist/{PluginStoreApp-MbC3G9tu.js.map → PluginStoreApp-CoOAw1fr.js.map} +1 -1
- package/dist/PluginTemplatesUsed-CdjT1wR4.js +76 -0
- package/dist/PluginTemplatesUsed-CdjT1wR4.js.map +1 -0
- package/dist/{index-CM_6yF2v.js → Promise.withResolvers-C4chhLB1.js} +17 -11
- package/dist/Promise.withResolvers-C4chhLB1.js.map +1 -0
- package/dist/{RadioBox-0UuxlcWZ.js → RadioBox-B0z9YHQg.js} +2 -2
- package/dist/{RadioBox-0UuxlcWZ.js.map → RadioBox-B0z9YHQg.js.map} +1 -1
- package/dist/components/index.js +75 -46
- package/dist/components/index.js.map +1 -1
- package/dist/{BasePlugin-DD7l-5Xw.js → core.js} +28 -10
- package/dist/core.js.map +1 -0
- package/dist/{index-De25v1_Q.js → index-1tsXE6ax.js} +11 -10
- package/dist/index-1tsXE6ax.js.map +1 -0
- package/dist/{index-WfXtYVMt.js → index-B32tFyLB.js} +132 -100
- package/dist/index-B32tFyLB.js.map +1 -0
- package/dist/index-BPTMltVf.js +170 -0
- package/dist/index-BPTMltVf.js.map +1 -0
- package/dist/{index-DKCZDN-Q.js → index-BYlcHc-O.js} +23 -25
- package/dist/index-BYlcHc-O.js.map +1 -0
- package/dist/{index-CnR6CqkM.js → index-C4qm_X_A.js} +11 -11
- package/dist/{index-CnR6CqkM.js.map → index-C4qm_X_A.js.map} +1 -1
- package/dist/index-CAtPo7xJ.js +793 -0
- package/dist/index-CAtPo7xJ.js.map +1 -0
- package/dist/{index-DensW9qt.js → index-CVCy0wPP.js} +9 -8
- package/dist/index-CVCy0wPP.js.map +1 -0
- package/dist/index-CYfkwXRf.js +1631 -0
- package/dist/index-CYfkwXRf.js.map +1 -0
- package/dist/index-DZa9mxN4.js +168 -0
- package/dist/index-DZa9mxN4.js.map +1 -0
- package/dist/{index-BpQ6VGMz.js → index-Dm2vgYkZ.js} +89 -67
- package/dist/index-Dm2vgYkZ.js.map +1 -0
- package/dist/{index-BanevHQ2.js → index-NWWeW3tX.js} +87 -84
- package/dist/index-NWWeW3tX.js.map +1 -0
- package/dist/index-QnWieXQc.js +4932 -0
- package/dist/index-QnWieXQc.js.map +1 -0
- package/dist/{index-B3jld2sl.js → index-bQ0CVu3l.js} +13 -17
- package/dist/{index-B3jld2sl.js.map → index-bQ0CVu3l.js.map} +1 -1
- package/dist/index-ygc4AMy4.js +44 -0
- package/dist/index-ygc4AMy4.js.map +1 -0
- package/dist/{index-DD5CVCfD.js → index-z_qDGCMT.js} +2 -2
- package/dist/{index-DD5CVCfD.js.map → index-z_qDGCMT.js.map} +1 -1
- package/dist/index.d.ts +411 -163
- package/dist/index.js +24 -26
- package/dist/index.js.map +1 -1
- package/dist/{makeCallable-LDU0xZMJ.js → makeCallable-Cg4zUG4c.js} +2 -2
- package/dist/{makeCallable-LDU0xZMJ.js.map → makeCallable-Cg4zUG4c.js.map} +1 -1
- package/dist/models/index.js +7 -7
- package/dist/models/index.js.map +1 -1
- package/dist/plugins/index.js +18 -14
- package/dist/plugins/index.js.map +1 -1
- package/dist/services/index.js +11 -9
- package/dist/style.css +1 -1
- package/dist/{vueHooks-l04s8cIl.js → vueHooks-Bs93iP61.js} +1519 -1492
- package/dist/vueHooks-Bs93iP61.js.map +1 -0
- package/lib/index.umd.js +19 -13
- package/lib/index.umd.js.map +1 -1
- package/lib/style.css +1 -1
- package/package.json +38 -27
- package/dist/BasePlugin-DD7l-5Xw.js.map +0 -1
- package/dist/IconQuickEdit-CMCQncyj.js +0 -27
- package/dist/IconQuickEdit-CMCQncyj.js.map +0 -1
- package/dist/InputBox-nQKtiWtZ.js +0 -30
- package/dist/InputBox-nQKtiWtZ.js.map +0 -1
- package/dist/Preferences-C10tZMl1.js +0 -2701
- package/dist/Preferences-C10tZMl1.js.map +0 -1
- package/dist/WatchlistAction-BbNAyryN.js +0 -5
- package/dist/WatchlistAction-BbNAyryN.js.map +0 -1
- package/dist/index-7R2LfhNn.js +0 -220
- package/dist/index-7R2LfhNn.js.map +0 -1
- package/dist/index-BXNyXvre.js +0 -116
- package/dist/index-BXNyXvre.js.map +0 -1
- package/dist/index-BanevHQ2.js.map +0 -1
- package/dist/index-BjDTD66_.js +0 -491
- package/dist/index-BjDTD66_.js.map +0 -1
- package/dist/index-BpQ6VGMz.js.map +0 -1
- package/dist/index-CG38LlAh.js +0 -46
- package/dist/index-CG38LlAh.js.map +0 -1
- package/dist/index-CM_6yF2v.js.map +0 -1
- package/dist/index-DKCZDN-Q.js.map +0 -1
- package/dist/index-De25v1_Q.js.map +0 -1
- package/dist/index-DensW9qt.js.map +0 -1
- package/dist/index-DxaqNWv4.js +0 -3090
- package/dist/index-DxaqNWv4.js.map +0 -1
- package/dist/index-WfXtYVMt.js.map +0 -1
- package/dist/vueHooks-l04s8cIl.js.map +0 -1
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { j as n } from "./
|
|
2
|
-
import { S as
|
|
3
|
-
import {
|
|
4
|
-
var
|
|
1
|
+
import { j as n, p as I } from "./Promise.withResolvers-C4chhLB1.js";
|
|
2
|
+
import { S as p, E as v, p as x, a as P } from "./index-QnWieXQc.js";
|
|
3
|
+
import { BasePlugin as U } from "./core.js";
|
|
4
|
+
var q = Object.create, f = Object.defineProperty, B = Object.getOwnPropertyDescriptor, b = (i, t) => (t = Symbol[i]) ? t : /* @__PURE__ */ Symbol.for("Symbol." + i), w = (i) => {
|
|
5
5
|
throw TypeError(i);
|
|
6
|
-
}, L = (i,
|
|
7
|
-
for (var s = 0, r = i[
|
|
6
|
+
}, L = (i, t, e) => t in i ? f(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e, N = (i, t) => f(i, "name", { value: t, configurable: !0 }), $ = (i) => [, , , q(i?.[b("metadata")] ?? null)], T = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"], E = (i) => i !== void 0 && typeof i != "function" ? w("Function expected") : i, D = (i, t, e, a, s) => ({ kind: T[i], name: t, metadata: a, addInitializer: (r) => e._ ? w("Already initialized") : s.push(E(r || null)) }), O = (i, t) => L(t, b("metadata"), i[3]), j = (i, t, e, a) => {
|
|
7
|
+
for (var s = 0, r = i[t >> 1], o = r && r.length; s < o; s++) r[s].call(e);
|
|
8
8
|
return a;
|
|
9
|
-
}, C = (i,
|
|
10
|
-
var o, c, h, d =
|
|
11
|
-
N(s,
|
|
12
|
-
for (var
|
|
13
|
-
h = D(d,
|
|
14
|
-
return O(i, s), u && f(s,
|
|
15
|
-
},
|
|
16
|
-
|
|
9
|
+
}, C = (i, t, e, a, s, r) => {
|
|
10
|
+
var o, c, h, d = t & 7, l = !1, y = 0, A = i[y] || (i[y] = []), u = d && (s = s.prototype, d < 5 && (d > 3 || !l) && B(s, e));
|
|
11
|
+
N(s, e);
|
|
12
|
+
for (var g = a.length - 1; g >= 0; g--)
|
|
13
|
+
h = D(d, e, c = {}, i[3], A), o = (0, a[g])(s, h), c._ = 1, E(o) && (s = o);
|
|
14
|
+
return O(i, s), u && f(s, e, u), l ? d ^ 4 ? r : u : s;
|
|
15
|
+
}, k, _, S;
|
|
16
|
+
k = [P(["wiki", "preferences", "$"])];
|
|
17
17
|
class m extends (S = U) {
|
|
18
18
|
// 1分钟
|
|
19
|
-
constructor(
|
|
20
|
-
super(
|
|
19
|
+
constructor(t) {
|
|
20
|
+
super(t, {}, "analytics"), this.ctx = t, this._usages = [], this._timer = null, this.MAX_QUEUE_SIZE = 50, this.INTERVAL_MS = 60 * 1e3, this._setupTimer(), this._registerUnloadHandler(), this._showConfirmNotify(), this._initPluginListeners(), t.set("analytics", this);
|
|
21
21
|
}
|
|
22
22
|
start() {
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const t = this.ctx, e = t.$;
|
|
24
|
+
t.preferences.registerCustomConfig(
|
|
25
25
|
"analytics",
|
|
26
|
-
|
|
27
|
-
"analytics._intro":
|
|
26
|
+
p.object({
|
|
27
|
+
"analytics._intro": p.const(
|
|
28
28
|
/* @__PURE__ */ n("section", { children: [
|
|
29
|
-
/* @__PURE__ */ n("h3", { children:
|
|
30
|
-
/* @__PURE__ */ n("p", { children:
|
|
31
|
-
/* @__PURE__ */ n("h4", { children:
|
|
29
|
+
/* @__PURE__ */ n("h3", { children: e`InPageEdit Analytics` }),
|
|
30
|
+
/* @__PURE__ */ n("p", { children: e`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.` }),
|
|
31
|
+
/* @__PURE__ */ n("h4", { children: e`What data will be collected?` }),
|
|
32
32
|
/* @__PURE__ */ n("ol", { style: { listStyle: "number", paddingLeft: "1em" }, children: [
|
|
33
33
|
/* @__PURE__ */ n("li", { children: [
|
|
34
|
-
/* @__PURE__ */ n("strong", { children:
|
|
34
|
+
/* @__PURE__ */ n("strong", { children: e`Usage data` }),
|
|
35
35
|
":",
|
|
36
36
|
" ",
|
|
37
|
-
|
|
37
|
+
e`When and which features you use, what pages you edit, etc.`
|
|
38
38
|
] }),
|
|
39
39
|
/* @__PURE__ */ n("li", { children: [
|
|
40
|
-
/* @__PURE__ */ n("strong", { children:
|
|
40
|
+
/* @__PURE__ */ n("strong", { children: e`User information` }),
|
|
41
41
|
": ",
|
|
42
|
-
|
|
42
|
+
e`Your user name and user ID.`
|
|
43
43
|
] }),
|
|
44
44
|
/* @__PURE__ */ n("li", { children: [
|
|
45
|
-
/* @__PURE__ */ n("strong", { children:
|
|
45
|
+
/* @__PURE__ */ n("strong", { children: e`Site information` }),
|
|
46
46
|
": ",
|
|
47
|
-
|
|
47
|
+
e`This wiki's url and site name.`
|
|
48
48
|
] })
|
|
49
49
|
] }),
|
|
50
|
-
/* @__PURE__ */ n("p", { children: /* @__PURE__ */ n("strong", { children:
|
|
50
|
+
/* @__PURE__ */ n("p", { children: /* @__PURE__ */ n("strong", { children: e`NO sensitive data will be collected.` }) }),
|
|
51
51
|
/* @__PURE__ */ n("div", { style: { display: "grid", gap: "0.5rem" }, children: [
|
|
52
|
-
/* @__PURE__ */ n("a", { href: this.analyticsDashUrl, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ n("button", { className: "btn", style: { width: "100%" }, children:
|
|
52
|
+
/* @__PURE__ */ n("a", { href: this.analyticsDashUrl, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ n("button", { className: "btn", style: { width: "100%" }, children: e`Analytics Platform` }) }),
|
|
53
53
|
/* @__PURE__ */ n(
|
|
54
54
|
"a",
|
|
55
55
|
{
|
|
@@ -59,22 +59,22 @@ class m extends (S = U) {
|
|
|
59
59
|
}).toString()}`,
|
|
60
60
|
target: "_blank",
|
|
61
61
|
rel: "noopener noreferrer",
|
|
62
|
-
children: /* @__PURE__ */ n("button", { className: "btn", style: { width: "100%" }, children:
|
|
62
|
+
children: /* @__PURE__ */ n("button", { className: "btn", style: { width: "100%" }, children: e`View My Data` })
|
|
63
63
|
}
|
|
64
64
|
)
|
|
65
65
|
] })
|
|
66
66
|
] })
|
|
67
67
|
).role("raw-html"),
|
|
68
|
-
"analytics.enabled":
|
|
69
|
-
}).description(
|
|
68
|
+
"analytics.enabled": p.boolean().description(e`prefs.analytics.enabled`).default(!1)
|
|
69
|
+
}).description(e`prefs.analytics.$`),
|
|
70
70
|
"general"
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
get analyticsDashUrl() {
|
|
74
|
-
return
|
|
74
|
+
return v.ANALYTICS_DASH_URL;
|
|
75
75
|
}
|
|
76
76
|
get analyticsApiBase() {
|
|
77
|
-
return
|
|
77
|
+
return v.ANALYTICS_API_BASE;
|
|
78
78
|
}
|
|
79
79
|
_setupTimer() {
|
|
80
80
|
this._timer = setInterval(() => {
|
|
@@ -82,48 +82,48 @@ class m extends (S = U) {
|
|
|
82
82
|
}, this.INTERVAL_MS);
|
|
83
83
|
}
|
|
84
84
|
_registerUnloadHandler() {
|
|
85
|
-
const
|
|
85
|
+
const t = () => {
|
|
86
86
|
this._usages.length > 0 && this.sendBeacon();
|
|
87
87
|
};
|
|
88
88
|
window.addEventListener("visibilitychange", () => {
|
|
89
|
-
document.visibilityState === "hidden" &&
|
|
90
|
-
}), window.addEventListener("pagehide",
|
|
89
|
+
document.visibilityState === "hidden" && t();
|
|
90
|
+
}), window.addEventListener("pagehide", t), window.addEventListener("beforeunload", t);
|
|
91
91
|
}
|
|
92
92
|
async _showConfirmNotify() {
|
|
93
|
-
const
|
|
94
|
-
this.ctx.inject(["modal", "storage"], async (
|
|
95
|
-
const a = "analytics/confirm-shown", s = await
|
|
96
|
-
s || r ||
|
|
93
|
+
const { $: t } = this.ctx;
|
|
94
|
+
this.ctx.inject(["modal", "storage"], async (e) => {
|
|
95
|
+
const a = "analytics/confirm-shown", s = await e.storage.simpleKV.get(a), r = await e.preferences.get("analytics.enabled");
|
|
96
|
+
s || r || e.modal.notify(
|
|
97
97
|
"confirm",
|
|
98
98
|
{
|
|
99
|
-
title:
|
|
99
|
+
title: t`Enable Analytics`,
|
|
100
100
|
content: /* @__PURE__ */ n("div", { children: [
|
|
101
|
-
/* @__PURE__ */ n("p", { children:
|
|
102
|
-
/* @__PURE__ */ n("p", { children:
|
|
101
|
+
/* @__PURE__ */ n("p", { children: t`Help us improve InPageEdit by sharing your usage data with us.` }),
|
|
102
|
+
/* @__PURE__ */ n("p", { children: t`What data will be collected?` }),
|
|
103
103
|
/* @__PURE__ */ n("ul", { style: { listStyle: "auto", paddingLeft: "1.5em" }, children: [
|
|
104
104
|
/* @__PURE__ */ n("li", { children: [
|
|
105
|
-
|
|
105
|
+
t`Usage data`,
|
|
106
106
|
": ",
|
|
107
|
-
|
|
107
|
+
t`When and which features you use, what pages you edit, etc.`
|
|
108
108
|
] }),
|
|
109
109
|
/* @__PURE__ */ n("li", { children: [
|
|
110
|
-
|
|
110
|
+
t`User information`,
|
|
111
111
|
": ",
|
|
112
|
-
|
|
112
|
+
t`Your user name and user ID.`
|
|
113
113
|
] }),
|
|
114
114
|
/* @__PURE__ */ n("li", { children: [
|
|
115
|
-
|
|
115
|
+
t`Site information`,
|
|
116
116
|
": ",
|
|
117
|
-
|
|
117
|
+
t`This wiki's url and site name.`
|
|
118
118
|
] })
|
|
119
119
|
] }),
|
|
120
|
-
/* @__PURE__ */ n("p", { children: /* @__PURE__ */ n("strong", { children:
|
|
120
|
+
/* @__PURE__ */ n("p", { children: /* @__PURE__ */ n("strong", { children: t`NO sensitive data will be collected.` }) })
|
|
121
121
|
] }),
|
|
122
122
|
okBtn: {
|
|
123
|
-
label:
|
|
123
|
+
label: t`Enable`
|
|
124
124
|
},
|
|
125
125
|
cancelBtn: {
|
|
126
|
-
label:
|
|
126
|
+
label: t`Disable`
|
|
127
127
|
},
|
|
128
128
|
closeAfter: 0,
|
|
129
129
|
onClose: () => {
|
|
@@ -131,40 +131,43 @@ class m extends (S = U) {
|
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
133
|
(o) => {
|
|
134
|
-
|
|
134
|
+
e.preferences.set("analytics.enabled", o), o && this.addEvent("analytics", "enabled");
|
|
135
135
|
}
|
|
136
136
|
);
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
139
|
_initPluginListeners() {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
this.addEvent(
|
|
143
|
-
}),
|
|
144
|
-
this.addEvent("
|
|
145
|
-
}),
|
|
146
|
-
this.addEvent("quick-
|
|
147
|
-
}),
|
|
148
|
-
this.addEvent("quick-
|
|
149
|
-
}),
|
|
150
|
-
this.addEvent("quick-
|
|
151
|
-
}),
|
|
152
|
-
this.addEvent("quick-edit",
|
|
153
|
-
}),
|
|
140
|
+
const t = this.ctx;
|
|
141
|
+
t.on("analytics/event", (e) => {
|
|
142
|
+
e && this.addEvent(e.feature, e.subtype, e.page);
|
|
143
|
+
}), t.on("in-article-links/anchor-clicked", (e) => {
|
|
144
|
+
this.addEvent("in-article-links", x(e.action));
|
|
145
|
+
}), t.on("quick-diff/loaded", (e) => {
|
|
146
|
+
this.addEvent("quick-diff", "loaded", e.compare.fromtitle);
|
|
147
|
+
}), t.on("quick-redirect/submit", (e) => {
|
|
148
|
+
this.addEvent("quick-redirect", "submit", e.payload.to || void 0);
|
|
149
|
+
}), t.on("quick-preview/loaded", (e) => {
|
|
150
|
+
this.addEvent("quick-preview", "loaded", e.wikiPage.title);
|
|
151
|
+
}), t.on("quick-edit/wiki-page", (e) => {
|
|
152
|
+
this.addEvent("quick-edit", void 0, e.wikiPage.title);
|
|
153
|
+
}), t.on("quick-edit/submit", (e) => {
|
|
154
|
+
this.addEvent("quick-edit", "submit", e.wikiPage.title);
|
|
155
|
+
}), t.on("quick-move/submit", () => {
|
|
154
156
|
this.addEvent("quick-move", "submit");
|
|
155
|
-
}),
|
|
156
|
-
this.addEvent("toolbox", `button-clicked#${
|
|
157
|
-
}),
|
|
158
|
-
s === "new-added" && this.addEvent("plugin-store", "plugin-installed", `${
|
|
159
|
-
}),
|
|
160
|
-
this.addEvent("plugin-store", "plugin-uninstalled", `${
|
|
157
|
+
}), t.on("toolbox/button-clicked", ({ payload: e }) => {
|
|
158
|
+
this.addEvent("toolbox", `button-clicked#${e.id || "unknown"}`);
|
|
159
|
+
}), t.on("plugin-store/plugin-installed", ({ registry: e, id: a, by: s }) => {
|
|
160
|
+
s === "new-added" && this.addEvent("plugin-store", "plugin-installed", `${a}@${e.name}`);
|
|
161
|
+
}), t.on("plugin-store/plugin-uninstalled", ({ registry: e, id: a }) => {
|
|
162
|
+
this.addEvent("plugin-store", "plugin-uninstalled", `${a}@${e.name}`);
|
|
161
163
|
});
|
|
162
164
|
}
|
|
163
|
-
addEvent(
|
|
165
|
+
addEvent(t, e, a) {
|
|
166
|
+
if (!t) return;
|
|
164
167
|
const s = {
|
|
165
168
|
ts: Date.now(),
|
|
166
|
-
feature:
|
|
167
|
-
subtype:
|
|
169
|
+
feature: t,
|
|
170
|
+
subtype: e,
|
|
168
171
|
page: a
|
|
169
172
|
};
|
|
170
173
|
return this._usages.push(s), this._usages.length >= this.MAX_QUEUE_SIZE && this.sendBeacon(), this;
|
|
@@ -174,19 +177,19 @@ class m extends (S = U) {
|
|
|
174
177
|
return !0;
|
|
175
178
|
if (!await this.ctx.preferences.get("analytics.enabled", !1))
|
|
176
179
|
return this.logger.debug("Analytics disabled, skipping"), !0;
|
|
177
|
-
const
|
|
180
|
+
const e = this._usages.splice(0, this._usages.length), a = {
|
|
178
181
|
siteApi: this.ctx.wiki.getSciprtUrl("api"),
|
|
179
182
|
siteName: this.ctx.wiki.siteInfo.general.sitename,
|
|
180
183
|
userId: this.ctx.wiki.userInfo.id,
|
|
181
184
|
userName: this.ctx.wiki.userInfo.name,
|
|
182
185
|
version: this.ctx.version.split("-")[0],
|
|
183
|
-
usages:
|
|
186
|
+
usages: e
|
|
184
187
|
}, s = JSON.stringify(a), r = `${this.analyticsApiBase}/submit`;
|
|
185
188
|
if (navigator?.sendBeacon?.(r, s))
|
|
186
189
|
return this.logger.debug("Beacon sent successfully", a), !0;
|
|
187
190
|
{
|
|
188
191
|
this.logger.debug("Beacon failed, sending via XMLHttpRequest");
|
|
189
|
-
const { promise: c, resolve: h, reject: d } =
|
|
192
|
+
const { promise: c, resolve: h, reject: d } = I();
|
|
190
193
|
try {
|
|
191
194
|
const l = new XMLHttpRequest();
|
|
192
195
|
l.open("POST", r, !0), l.setRequestHeader("Content-Type", "application/json"), l.send(s), l.onload = () => {
|
|
@@ -208,9 +211,9 @@ class m extends (S = U) {
|
|
|
208
211
|
}
|
|
209
212
|
}
|
|
210
213
|
_ = $(S);
|
|
211
|
-
m = C(_, 0, "PluginAnalytics",
|
|
214
|
+
m = C(_, 0, "PluginAnalytics", k, m);
|
|
212
215
|
j(_, 1, m);
|
|
213
216
|
export {
|
|
214
217
|
m as PluginAnalytics
|
|
215
218
|
};
|
|
216
|
-
//# sourceMappingURL=index-
|
|
219
|
+
//# sourceMappingURL=index-NWWeW3tX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-NWWeW3tX.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 interface Events {\n 'analytics/event'(payload: { feature: string; subtype?: string; page?: string }): void\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('analytics/event', (payload) => {\n if (!payload) return\n this.addEvent(payload.feature, payload.subtype, payload.page)\n })\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', () => {\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 ctx.on('plugin-store/plugin-installed', ({ registry, id, by }) => {\n if (by === 'new-added') {\n this.addEvent('plugin-store', 'plugin-installed', `${id}@${registry.name}`)\n }\n })\n ctx.on('plugin-store/plugin-uninstalled', ({ registry, id }) => {\n this.addEvent('plugin-store', 'plugin-uninstalled', `${id}@${registry.name}`)\n })\n }\n\n public addEvent(feature: string, subtype?: string, page?: string) {\n if (!feature) return\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","registry","id","by","feature","subtype","page","usage","usages","body","endpoint","promise","resolve","reject","promiseWithResolvers","xhr","error","__decoratorStart","__decorateElement","__runInitializers"],"mappings":"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"}
|