dsh-plugin-update 0.5.8 → 0.7.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/CHANGELOG.md +16 -4
- package/README.md +46 -9
- package/dist/bilingual.d.ts +4 -4
- package/dist/bilingual.js +300 -1
- package/dist/changelog.d.ts +19 -13
- package/dist/changelog.js +60 -22
- package/dist/diag.d.ts +3 -0
- package/dist/diag.js +32 -20
- package/dist/entry-batch.d.ts +10 -2
- package/dist/entry-batch.js +21 -7
- package/dist/entry.d.ts +31 -2
- package/dist/entry.js +83 -27
- package/dist/host-batch.js +104 -13
- package/dist/http.d.ts +2 -2
- package/dist/http.js +1 -1
- package/dist/panel-batch.d.ts +53 -11
- package/dist/panel-batch.js +500 -153
- package/dist/panel.d.ts +84 -25
- package/dist/panel.js +618 -364
- package/dist/store.d.ts +42 -0
- package/dist/store.js +139 -0
- package/package.json +1 -1
package/dist/panel.js
CHANGED
|
@@ -10,92 +10,156 @@ import {
|
|
|
10
10
|
yankedBannerHTML
|
|
11
11
|
} from "./changelog.js";
|
|
12
12
|
import { LOG_EVENT_CALL, LOG_EVENT_CALL_FAIL, LOG_EVENT_INSTALL_EXEC } from "./log-events.js";
|
|
13
|
+
import { copyText } from "./bilingual.js";
|
|
14
|
+
import { normalizeLangTag, resolveLang, subscribeLang } from "./lang.js";
|
|
13
15
|
function normalizePanelTheme(value) {
|
|
14
|
-
return value === "archive"
|
|
16
|
+
return value === "archive" ? "archive" : "default";
|
|
15
17
|
}
|
|
16
|
-
const
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
18
|
+
const THEME_TOKEN_VARS = {
|
|
19
|
+
text: "--dsh-update-text",
|
|
20
|
+
textMuted: "--dsh-update-text-muted",
|
|
21
|
+
bg: "--dsh-update-bg",
|
|
22
|
+
bgSoft: "--dsh-update-bg-soft",
|
|
23
|
+
border: "--dsh-update-border",
|
|
24
|
+
borderStrong: "--dsh-update-border-strong",
|
|
25
|
+
buttonBg: "--dsh-update-button-bg",
|
|
26
|
+
primary: "--dsh-update-primary",
|
|
27
|
+
primaryDeep: "--dsh-update-primary-deep",
|
|
28
|
+
focus: "--dsh-update-focus",
|
|
29
|
+
okBg: "--dsh-update-ok-bg",
|
|
30
|
+
okBorder: "--dsh-update-ok-border",
|
|
31
|
+
okText: "--dsh-update-ok-text",
|
|
32
|
+
warnBg: "--dsh-update-warn-bg",
|
|
33
|
+
warnBorder: "--dsh-update-warn-border",
|
|
34
|
+
warnText: "--dsh-update-warn-text",
|
|
35
|
+
badBg: "--dsh-update-bad-bg",
|
|
36
|
+
badBorder: "--dsh-update-bad-border",
|
|
37
|
+
badText: "--dsh-update-bad-text",
|
|
38
|
+
busyBg: "--dsh-update-busy-bg",
|
|
39
|
+
busyBorder: "--dsh-update-busy-border",
|
|
40
|
+
busyText: "--dsh-update-busy-text",
|
|
41
|
+
fontSans: "--dsh-update-font-sans",
|
|
42
|
+
fontSerif: "--dsh-update-font-serif",
|
|
43
|
+
fontMono: "--dsh-update-font-mono",
|
|
44
|
+
shadow: "--dsh-update-shadow",
|
|
45
|
+
radiusPanel: "--dsh-update-radius-panel",
|
|
46
|
+
radiusButton: "--dsh-update-radius-button",
|
|
47
|
+
radiusBadge: "--dsh-update-radius-badge",
|
|
48
|
+
entryFontSize: "--dsh-update-entry-font-size",
|
|
49
|
+
entryPadding: "--dsh-update-entry-padding",
|
|
50
|
+
entryBorderRadius: "--dsh-update-entry-border-radius",
|
|
51
|
+
entryScale: "--dsh-update-entry-scale"
|
|
52
|
+
};
|
|
53
|
+
const THEME_TOKEN_COLOR_KEYS = /* @__PURE__ */ new Set([
|
|
54
|
+
"text",
|
|
55
|
+
"textMuted",
|
|
56
|
+
"bg",
|
|
57
|
+
"bgSoft",
|
|
58
|
+
"border",
|
|
59
|
+
"borderStrong",
|
|
60
|
+
"buttonBg",
|
|
61
|
+
"primary",
|
|
62
|
+
"primaryDeep",
|
|
63
|
+
"focus",
|
|
64
|
+
"okBg",
|
|
65
|
+
"okBorder",
|
|
66
|
+
"okText",
|
|
67
|
+
"warnBg",
|
|
68
|
+
"warnBorder",
|
|
69
|
+
"warnText",
|
|
70
|
+
"badBg",
|
|
71
|
+
"badBorder",
|
|
72
|
+
"badText",
|
|
73
|
+
"busyBg",
|
|
74
|
+
"busyBorder",
|
|
75
|
+
"busyText"
|
|
76
|
+
]);
|
|
77
|
+
function themeTokensError(raw) {
|
|
78
|
+
return new Error(`[dsh-plugin-update] \u4E3B\u9898\u53C2\u6570 themeTokens \u975E\u6CD5\uFF1A\u53EA\u6536\u5DF2\u77E5 token \u952E\uFF08\u989C\u8272\u7528 hex \u6216\u82F1\u6587\u540D\uFF0C\u5B57\u4F53/\u5706\u89D2/\u9634\u5F71/\u5C3A\u5BF8\u4E3A\u5B89\u5168 CSS \u503C\uFF0CentryScale \u4E3A\u5927\u4E8E 0 \u7684\u6709\u9650\u6570\uFF09\uFF08\u6536\u5230 ${JSON.stringify(raw ?? null)})`);
|
|
79
|
+
}
|
|
80
|
+
function isSafeThemeCssValue(value) {
|
|
81
|
+
const v = value.trim();
|
|
82
|
+
if (!v || v.length > 200) return false;
|
|
83
|
+
if (/[;"'<>\`{}!&]/.test(v)) return false;
|
|
84
|
+
if (/url\s*\(/i.test(v)) return false;
|
|
85
|
+
if (/expression\s*\(/i.test(v)) return false;
|
|
86
|
+
if (/javascript\s*:/i.test(v)) return false;
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
function isThemeColorValue(value) {
|
|
90
|
+
const v = value.trim();
|
|
91
|
+
if (!v || v.length > 100) return false;
|
|
92
|
+
return /^(?:#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6}|#[0-9a-fA-F]{8}|[a-zA-Z]+)$/.test(v);
|
|
93
|
+
}
|
|
94
|
+
function themeTokensStyleFor(tokens) {
|
|
95
|
+
if (tokens === void 0 || tokens === null) return "";
|
|
96
|
+
if (typeof tokens !== "object" || Array.isArray(tokens)) throw themeTokensError(tokens);
|
|
97
|
+
for (const key of Object.keys(tokens)) {
|
|
98
|
+
if (!Object.prototype.hasOwnProperty.call(THEME_TOKEN_VARS, key)) throw themeTokensError(tokens);
|
|
48
99
|
}
|
|
100
|
+
const parts = [];
|
|
101
|
+
for (const key of Object.keys(THEME_TOKEN_VARS)) {
|
|
102
|
+
const value = tokens[key];
|
|
103
|
+
if (value === void 0) continue;
|
|
104
|
+
if (key === "entryScale") {
|
|
105
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) throw themeTokensError(tokens);
|
|
106
|
+
parts.push(THEME_TOKEN_VARS[key] + ":" + String(value));
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (typeof value !== "string") throw themeTokensError(tokens);
|
|
110
|
+
const text = value.trim();
|
|
111
|
+
if (THEME_TOKEN_COLOR_KEYS.has(key)) {
|
|
112
|
+
if (!isThemeColorValue(text)) throw themeTokensError(tokens);
|
|
113
|
+
} else if (!isSafeThemeCssValue(text)) throw themeTokensError(tokens);
|
|
114
|
+
parts.push(THEME_TOKEN_VARS[key] + ":" + text);
|
|
115
|
+
}
|
|
116
|
+
return parts.join(";");
|
|
117
|
+
}
|
|
118
|
+
const BLOCKED_KEYS = {
|
|
119
|
+
"unknown-profile": { title: "panel.blocked.unknown-profile.title", action: "panel.blocked.unknown-profile.action" },
|
|
120
|
+
"source-install": { title: "panel.blocked.source-install.title", action: "panel.blocked.source-install.action" },
|
|
121
|
+
"invalid-installation": { title: "panel.blocked.invalid-installation.title", action: "panel.blocked.invalid-installation.action" },
|
|
122
|
+
"installation-changed": { title: "panel.blocked.installation-changed.title", action: "panel.blocked.installation-changed.action" },
|
|
123
|
+
"pending-restart": { title: "panel.blocked.pending-restart.title", action: "panel.blocked.pending-restart.action" },
|
|
124
|
+
"registry-conflict": { title: "panel.blocked.registry-conflict.title", action: "panel.blocked.registry-conflict.action" },
|
|
125
|
+
"incompatible-node": { title: "panel.blocked.incompatible-node.title", action: "panel.blocked.incompatible-node.action" },
|
|
126
|
+
"recovery-required": { title: "panel.blocked.recovery-required.title", action: "panel.blocked.recovery-required.action" }
|
|
49
127
|
};
|
|
50
|
-
function blockedCopy(reason) {
|
|
128
|
+
function blockedCopy(reason, lang) {
|
|
51
129
|
if (reason === null || reason === void 0) return null;
|
|
52
|
-
|
|
130
|
+
const keys = BLOCKED_KEYS[reason];
|
|
131
|
+
if (!keys) return null;
|
|
132
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
133
|
+
return { title: copyText(keys.title, l), action: copyText(keys.action, l) };
|
|
53
134
|
}
|
|
54
|
-
const
|
|
55
|
-
"check-failed": {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
act: "\u68C0\u67E5\u6E05\u5355\u6587\u4EF6\u91CC\u7684\u5305\u540D\u4E0E\u7248\u672C\u5199\u6CD5\uFF0C\u518D\u67E5\u4E00\u6B21"
|
|
62
|
-
},
|
|
63
|
-
"check-expired": {
|
|
64
|
-
zh: "\u51ED\u8BC1\u8FC7\u671F\u4E86\uFF0C\u5B89\u88C5\u8BF7\u6C42\u88AB\u62D2",
|
|
65
|
-
act: "\u91CD\u65B0\u67E5\u4E00\u6B21\u65B0\u7248\u518D\u70B9\u5B89\u88C5\uFF0C\u4E0D\u8981\u91CD\u8BD5\u65E7\u7F16\u53F7"
|
|
66
|
-
},
|
|
67
|
-
"update-busy": {
|
|
68
|
-
zh: "\u540C\u4E00\u4F7F\u7528\u8303\u56F4\u6B63\u5728\u88C5\u53E6\u4E00\u4E2A",
|
|
69
|
-
act: "\u7B49\u5F53\u524D\u4EFB\u52A1\u79BB\u5F00 installing/verifying \u518D\u70B9\uFF1B\u6392\u961F\u4E2D\u53BB\u67E5\u72B6\u6001\u770B\u4F4D\u7F6E"
|
|
70
|
-
},
|
|
71
|
-
"install-failed": {
|
|
72
|
-
zh: "\u88C5\u4E0D\u4E0A\uFF08\u8BE6\u89C1\u8BCA\u65AD\u6458\u8981\uFF09",
|
|
73
|
-
act: "\u5148\u770B\u590D\u5236\u8BCA\u65AD\uFF1B\u5B98\u65B9\u684C\u9762\u7248\u628A\u8FD9\u6BB5\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005"
|
|
74
|
-
},
|
|
75
|
-
internal: {
|
|
76
|
-
zh: "\u51FA\u4E86\u70B9\u95EE\u9898\uFF0C\u8BA4\u4E0D\u51FA\u5177\u4F53\u539F\u56E0",
|
|
77
|
-
act: "\u5148\u91CD\u8BD5\u4E00\u6B21\uFF1B\u4E00\u76F4\u8FD9\u6837\u5C31\u628A\u590D\u5236\u8BCA\u65AD\u4EA4\u7ED9\u63D2\u4EF6\u4F5C\u8005"
|
|
78
|
-
}
|
|
135
|
+
const PHONE_FAILURE_KEYS = {
|
|
136
|
+
"check-failed": { title: "panel.failure.check-failed.title", action: "panel.failure.check-failed.action" },
|
|
137
|
+
"invalid-release": { title: "panel.failure.invalid-release.title", action: "panel.failure.invalid-release.action" },
|
|
138
|
+
"check-expired": { title: "panel.failure.check-expired.title", action: "panel.failure.check-expired.action" },
|
|
139
|
+
"update-busy": { title: "panel.failure.update-busy.title", action: "panel.failure.update-busy.action" },
|
|
140
|
+
"install-failed": { title: "panel.failure.install-failed.title", action: "panel.failure.install-failed.action" },
|
|
141
|
+
internal: { title: "panel.failure.internal.title", action: "panel.failure.internal.action" }
|
|
79
142
|
};
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
143
|
+
const UNKNOWN_FAILURE_KEYS = {
|
|
144
|
+
title: "panel.failure.unknown.title",
|
|
145
|
+
action: "panel.failure.unknown.action"
|
|
83
146
|
};
|
|
84
147
|
function isKnownFailureCode(code) {
|
|
85
148
|
if (typeof code !== "string" || !code) return false;
|
|
86
149
|
const c = code.trim();
|
|
87
150
|
if (!c) return false;
|
|
88
|
-
return c in
|
|
151
|
+
return c in BLOCKED_KEYS || c in PHONE_FAILURE_KEYS;
|
|
89
152
|
}
|
|
90
|
-
function failureCopy(code) {
|
|
153
|
+
function failureCopy(code, lang) {
|
|
91
154
|
if (typeof code !== "string") return null;
|
|
92
155
|
const c = code.trim();
|
|
93
156
|
if (!c) return null;
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return
|
|
157
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
158
|
+
const blocked = BLOCKED_KEYS[c];
|
|
159
|
+
if (blocked) return { zh: copyText(blocked.title, l), act: copyText(blocked.action, l) };
|
|
160
|
+
const phone = PHONE_FAILURE_KEYS[c];
|
|
161
|
+
if (phone) return { zh: copyText(phone.title, l), act: copyText(phone.action, l) };
|
|
162
|
+
return { zh: copyText(UNKNOWN_FAILURE_KEYS.title, l), act: copyText(UNKNOWN_FAILURE_KEYS.action, l) };
|
|
99
163
|
}
|
|
100
164
|
function failureCodeOf(reply, fallback) {
|
|
101
165
|
const kind = reply && typeof reply.errorKind === "string" ? reply.errorKind.trim() : "";
|
|
@@ -109,24 +173,27 @@ const PANEL_DIAG_MAX_CHARS = COPY_BUDGET_CHARS;
|
|
|
109
173
|
function redactForCopy(text) {
|
|
110
174
|
return sanitizeForCopy(text);
|
|
111
175
|
}
|
|
112
|
-
function buildDiagnosticText(input) {
|
|
176
|
+
function buildDiagnosticText(input, langOverride) {
|
|
177
|
+
const l = normalizeLangTag(langOverride ?? input.lang ?? "zh");
|
|
178
|
+
const unknown = copyText("panel.diag.copy.unknown", l);
|
|
113
179
|
const code = String(input.code || "check-failed");
|
|
114
|
-
const lines = [
|
|
180
|
+
const lines = [copyText("panel.diag.header", l, { pluginId: String(input.pluginId), code })];
|
|
115
181
|
const detail = redactForCopy(input.detail ?? "");
|
|
116
|
-
|
|
182
|
+
const fallbackAct = failureCopy(code, l)?.act || code;
|
|
183
|
+
lines.push(copyText("panel.diag.label.human", l, { detail: detail || fallbackAct }));
|
|
117
184
|
const versions = [
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
185
|
+
copyText("panel.diag.label.running", l, { version: input.runningVersion ?? unknown }),
|
|
186
|
+
copyText("panel.diag.label.installed", l, { version: input.installedVersion ?? unknown }),
|
|
187
|
+
copyText("panel.diag.label.latest", l, { version: input.latestVersion ?? (l === "en" ? "Not checked" : "\u672A\u67E5\u8FC7") })
|
|
121
188
|
].join(" / ");
|
|
122
189
|
lines.push(versions);
|
|
123
|
-
const queue = input.queuePosition
|
|
124
|
-
const hostLine = [
|
|
125
|
-
if (typeof input.profileName === "string" && input.profileName) hostLine.push(
|
|
126
|
-
hostLine.push(
|
|
127
|
-
lines.push(hostLine.join(" / ") + (input.requestId ? ` /
|
|
190
|
+
const queue = queueTextOf(input.queuePosition ?? null, l);
|
|
191
|
+
const hostLine = [copyText("panel.diag.label.host", l, { host: input.hostKind ?? unknown })];
|
|
192
|
+
if (typeof input.profileName === "string" && input.profileName) hostLine.push(copyText("panel.diag.label.profile", l, { profile: input.profileName }));
|
|
193
|
+
hostLine.push(copyText("panel.diag.label.queue", l, { queue }));
|
|
194
|
+
lines.push(hostLine.join(" / ") + (input.requestId ? ` / ${copyText("panel.diag.label.request", l, { requestId: input.requestId })}` : ""));
|
|
128
195
|
const manual = redactForCopy(input.manual ?? "");
|
|
129
|
-
if (manual) lines.push(
|
|
196
|
+
if (manual) lines.push(copyText("panel.diag.label.manual", l, { manual }));
|
|
130
197
|
return redactForCopy(lines.join("\n"));
|
|
131
198
|
}
|
|
132
199
|
const DIAG_KNOWN_TYPES = {
|
|
@@ -185,52 +252,56 @@ function pickText(value, fallback) {
|
|
|
185
252
|
if (typeof value === "string" && value.trim()) return value.trim();
|
|
186
253
|
return fallback;
|
|
187
254
|
}
|
|
188
|
-
function queueTextOf(queuePosition, _diagQueuePos) {
|
|
255
|
+
function queueTextOf(queuePosition, lang, _diagQueuePos) {
|
|
189
256
|
void _diagQueuePos;
|
|
257
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
190
258
|
const pos = typeof queuePosition === "number" ? queuePosition : null;
|
|
191
|
-
if (pos === 0) return "
|
|
192
|
-
if (typeof pos === "number") return
|
|
193
|
-
return "
|
|
259
|
+
if (pos === 0) return copyText("panel.diag.queue.installing", l);
|
|
260
|
+
if (typeof pos === "number") return copyText("panel.diag.queue.position", l, { n: pos });
|
|
261
|
+
return copyText("panel.diag.queue.absent", l);
|
|
194
262
|
}
|
|
195
|
-
function buildUpdateDiagCopy(input) {
|
|
263
|
+
function buildUpdateDiagCopy(input, langOverride) {
|
|
264
|
+
const l = normalizeLangTag(langOverride ?? input.lang ?? "zh");
|
|
265
|
+
const unknown = copyText("panel.diag.copy.unknown", l);
|
|
266
|
+
const unknownPkg = copyText("panel.diag.copy.unknown-package", l);
|
|
196
267
|
const rawCode = String(input.code ?? "").trim() || "internal";
|
|
197
|
-
const copy = failureCopy(rawCode) ??
|
|
268
|
+
const copy = failureCopy(rawCode, l) ?? failureCopy("unknown", l);
|
|
198
269
|
const diag = readDiagTolerant(input.diag);
|
|
199
270
|
const detailRaw = diag.detail ?? input.detail ?? "";
|
|
200
|
-
const detail = redactForCopy(detailRaw) || "
|
|
201
|
-
const pluginName = pickText(diag.targetPackageName ?? input.pluginId,
|
|
271
|
+
const detail = redactForCopy(detailRaw) || copyText("panel.diag.copy.no-detail", l);
|
|
272
|
+
const pluginName = pickText(diag.targetPackageName ?? input.pluginId, unknownPkg);
|
|
202
273
|
const runVer = pickText(diag.runningVersion ?? input.runningVersion, "?");
|
|
203
274
|
const instVer = pickText(input.installedVersion ?? diag.latestVersion, "?");
|
|
204
|
-
const host = pickText(diag.environmentKind ?? input.hostKind,
|
|
275
|
+
const host = pickText(diag.environmentKind ?? input.hostKind, unknown);
|
|
205
276
|
const routeRaw = diag.route ?? input.route;
|
|
206
277
|
const requestRaw = diag.requestId ?? input.requestId;
|
|
207
278
|
const checkRaw = diag.checkId ?? input.checkId;
|
|
208
|
-
const queue = queueTextOf(input.queuePosition ?? null);
|
|
209
|
-
const prov = [
|
|
210
|
-
prov.push(
|
|
211
|
-
if (typeof routeRaw === "string" && routeRaw.trim()) prov.push(
|
|
212
|
-
if (diag.stage) prov.push(
|
|
213
|
-
if (diag.method) prov.push(
|
|
279
|
+
const queue = queueTextOf(input.queuePosition ?? null, l);
|
|
280
|
+
const prov = [copyText("panel.diag.copy.field.plugin", l, { plugin: pluginName }), copyText("panel.diag.copy.field.version", l, { run: runVer, inst: instVer }), copyText("panel.diag.copy.field.host", l, { host })];
|
|
281
|
+
prov.push(copyText("panel.diag.copy.field.profile", l, { profile: pickText(input.profileName, unknown) }));
|
|
282
|
+
if (typeof routeRaw === "string" && routeRaw.trim()) prov.push(copyText("panel.diag.copy.field.route", l, { route: routeRaw.trim() }));
|
|
283
|
+
if (diag.stage) prov.push(copyText("panel.diag.copy.field.stage", l, { stage: diag.stage }));
|
|
284
|
+
if (diag.method) prov.push(copyText("panel.diag.copy.field.method", l, { method: diag.method }));
|
|
214
285
|
if (typeof diag.httpStatus === "number") prov.push(`HTTP=${diag.httpStatus}`);
|
|
215
286
|
if (typeof diag.exitCode === "number") prov.push(`exit=${diag.exitCode}`);
|
|
216
|
-
if (typeof diag.latencyMs === "number") prov.push(
|
|
217
|
-
if (diag.registryHost) prov.push(
|
|
218
|
-
else prov.push("
|
|
219
|
-
if (diag.action) prov.push(
|
|
220
|
-
if (typeof requestRaw === "string" && requestRaw.trim()) prov.push(
|
|
221
|
-
if (typeof checkRaw === "string" && checkRaw.trim()) prov.push(
|
|
222
|
-
prov.push(
|
|
287
|
+
if (typeof diag.latencyMs === "number") prov.push(`${copyText("panel.diag.copy.field.latency", l, { latency: diag.latencyMs })}ms`);
|
|
288
|
+
if (diag.registryHost) prov.push(copyText("panel.diag.copy.field.registry", l, { host: diag.registryHost }));
|
|
289
|
+
else prov.push(copyText("panel.diag.copy.field.registry-unknown", l));
|
|
290
|
+
if (diag.action) prov.push(copyText("panel.diag.copy.field.action", l, { action: diag.action }));
|
|
291
|
+
if (typeof requestRaw === "string" && requestRaw.trim()) prov.push(copyText("panel.diag.copy.field.request", l, { request: requestRaw.trim() }));
|
|
292
|
+
if (typeof checkRaw === "string" && checkRaw.trim()) prov.push(copyText("panel.diag.copy.field.check", l, { check: checkRaw.trim() }));
|
|
293
|
+
prov.push(copyText("panel.diag.copy.field.queue", l, { queue }));
|
|
223
294
|
const format = input.format === "line" ? "line" : "block";
|
|
224
295
|
const provLine = redactForCopy(prov.join(" \xB7 "));
|
|
225
296
|
if (format === "line") {
|
|
226
|
-
const line = `[update-diag] code=${rawCode} \xB7 ${copy.zh} \xB7
|
|
297
|
+
const line = `[update-diag] code=${rawCode} \xB7 ${copy.zh} \xB7 ${copyText("panel.diag.copy.line.summary", l, { summary: detail })} \xB7 ${provLine} \xB7 ${copyText("panel.diag.copy.line.remedy", l, { remedy: copy.act })}`;
|
|
227
298
|
return redactForCopy(line);
|
|
228
299
|
}
|
|
229
300
|
const block = [
|
|
230
301
|
`[update-diag] ${rawCode} \u2014 ${copy.zh}`,
|
|
231
|
-
`
|
|
232
|
-
`
|
|
233
|
-
`
|
|
302
|
+
` ${copyText("panel.diag.copy.block.summary", l, { summary: detail })}`,
|
|
303
|
+
` ${copyText("panel.diag.copy.block.source", l, { source: provLine })}`,
|
|
304
|
+
` ${copyText("panel.diag.copy.block.remedy", l, { remedy: copy.act })}`
|
|
234
305
|
].join("\n");
|
|
235
306
|
return block;
|
|
236
307
|
}
|
|
@@ -331,40 +402,47 @@ function createBrowserSkipStore(pluginId, storage, now = Date.now) {
|
|
|
331
402
|
}
|
|
332
403
|
};
|
|
333
404
|
}
|
|
334
|
-
const
|
|
335
|
-
loading: { text: "
|
|
336
|
-
idle: { text: "
|
|
337
|
-
update: { text: "
|
|
338
|
-
busy: { text: "
|
|
339
|
-
restart: { text: "
|
|
340
|
-
blocked: { text: "
|
|
341
|
-
failed: { text: "
|
|
342
|
-
done: { text: "
|
|
405
|
+
const SEAL_KEYS = {
|
|
406
|
+
loading: { text: "panel.seal.loading.text", mini: "panel.seal.loading.mini", tone: "ink" },
|
|
407
|
+
idle: { text: "panel.seal.idle.text", mini: "panel.seal.idle.mini", tone: "ink" },
|
|
408
|
+
update: { text: "panel.seal.update.text", mini: "panel.seal.update.mini", tone: "green" },
|
|
409
|
+
busy: { text: "panel.seal.busy.text", mini: "panel.seal.busy.mini", tone: "yellow" },
|
|
410
|
+
restart: { text: "panel.seal.restart.text", mini: "panel.seal.restart.mini", tone: "yellow" },
|
|
411
|
+
blocked: { text: "panel.seal.blocked.text", mini: "panel.seal.blocked.mini", tone: "red" },
|
|
412
|
+
failed: { text: "panel.seal.failed.text", mini: "panel.seal.failed.mini", tone: "red" },
|
|
413
|
+
done: { text: "panel.seal.done.text", mini: "panel.seal.done.mini", tone: "green" }
|
|
343
414
|
};
|
|
415
|
+
function panelSealFor(kind, lang) {
|
|
416
|
+
const keys = SEAL_KEYS[kind] ?? SEAL_KEYS.idle;
|
|
417
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
418
|
+
return { text: copyText(keys.text, l), mini: copyText(keys.mini, l), tone: keys.tone };
|
|
419
|
+
}
|
|
344
420
|
function messageCodeOf(message) {
|
|
345
421
|
if (typeof message !== "string" || !message) return "";
|
|
346
422
|
const at = message.indexOf(":");
|
|
347
423
|
return (at < 0 ? message : message.slice(0, at)).trim();
|
|
348
424
|
}
|
|
349
|
-
function panelViewModel(input) {
|
|
350
|
-
const
|
|
351
|
-
|
|
425
|
+
function panelViewModel(input, lang) {
|
|
426
|
+
const l = normalizeLangTag(lang ?? input.lang ?? "zh");
|
|
427
|
+
const view = panelViewModelCore(input, l);
|
|
428
|
+
return { ...view, seal: panelSealFor(view.banner.kind, l) };
|
|
352
429
|
}
|
|
353
|
-
function panelViewModelCore(input) {
|
|
430
|
+
function panelViewModelCore(input, lang) {
|
|
354
431
|
const { snapshot, manual, queue, skippedLatest, lastError } = input;
|
|
355
432
|
const errorKind = input.errorKind;
|
|
433
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
356
434
|
if (!snapshot) {
|
|
357
435
|
const earlyCode = typeof errorKind === "string" && errorKind.trim() || lastError || "";
|
|
358
436
|
if (earlyCode) {
|
|
359
|
-
const copy = failureCopy(earlyCode);
|
|
437
|
+
const copy = failureCopy(earlyCode, l);
|
|
360
438
|
return {
|
|
361
439
|
banner: {
|
|
362
440
|
kind: "failed",
|
|
363
|
-
title:
|
|
364
|
-
action: copy?.act || "
|
|
441
|
+
title: copyText("panel.banner.error.title", l, { code: earlyCode, detail: copy?.zh ?? earlyCode }),
|
|
442
|
+
action: copy?.act || copyText("panel.banner.error.action-fallback", l)
|
|
365
443
|
},
|
|
366
444
|
installEnabled: false,
|
|
367
|
-
installLabel: "
|
|
445
|
+
installLabel: copyText("panel.action.retry-install", l),
|
|
368
446
|
skippedLatest: false,
|
|
369
447
|
showManual: manual ? true : false,
|
|
370
448
|
showReset: false,
|
|
@@ -372,9 +450,9 @@ function panelViewModelCore(input) {
|
|
|
372
450
|
};
|
|
373
451
|
}
|
|
374
452
|
return {
|
|
375
|
-
banner: { kind: "loading", title: "
|
|
453
|
+
banner: { kind: "loading", title: copyText("panel.banner.loading", l), action: "" },
|
|
376
454
|
installEnabled: false,
|
|
377
|
-
installLabel: "
|
|
455
|
+
installLabel: copyText("panel.action.install", l),
|
|
378
456
|
skippedLatest: false,
|
|
379
457
|
showManual: false,
|
|
380
458
|
showReset: false,
|
|
@@ -383,16 +461,16 @@ function panelViewModelCore(input) {
|
|
|
383
461
|
}
|
|
384
462
|
const job = snapshot.job ?? null;
|
|
385
463
|
const jobState = job?.state ?? null;
|
|
386
|
-
const queueNote = queue && queue.busy ? queue.position === 0 ? "
|
|
464
|
+
const queueNote = queue && queue.busy ? queue.position === 0 ? copyText("panel.queue.busy-self", l) : typeof queue.position === "number" ? copyText("panel.queue.busy-queued", l, { n: queue.position }) : copyText("panel.queue.busy-other", l) : null;
|
|
387
465
|
if (skippedLatest && snapshot.latestVersion) {
|
|
388
466
|
return {
|
|
389
467
|
banner: {
|
|
390
468
|
kind: "idle",
|
|
391
|
-
title:
|
|
392
|
-
action: "
|
|
469
|
+
title: copyText("panel.skip.skipped-title", l, { latest: snapshot.latestVersion }),
|
|
470
|
+
action: copyText("panel.skip.skipped-action", l)
|
|
393
471
|
},
|
|
394
472
|
installEnabled: false,
|
|
395
|
-
installLabel: "
|
|
473
|
+
installLabel: copyText("panel.action.install", l),
|
|
396
474
|
skippedLatest: true,
|
|
397
475
|
showManual: false,
|
|
398
476
|
showReset: true,
|
|
@@ -404,13 +482,13 @@ function panelViewModelCore(input) {
|
|
|
404
482
|
return {
|
|
405
483
|
banner: {
|
|
406
484
|
kind: "restart",
|
|
407
|
-
// 文案照原型(
|
|
485
|
+
// 文案照原型(archive.html:329):不带 emoji——警示由横幅左侧的手绘 SVG 标承担,
|
|
408
486
|
// 印章在状态一侧,两者各司其职,不再三重标记。
|
|
409
|
-
title:
|
|
410
|
-
action:
|
|
487
|
+
title: copyText("panel.banner.restart-title", l, { latest }),
|
|
488
|
+
action: blockedCopy("pending-restart", l)?.action ?? ""
|
|
411
489
|
},
|
|
412
490
|
installEnabled: false,
|
|
413
|
-
installLabel: "
|
|
491
|
+
installLabel: copyText("panel.action.install", l),
|
|
414
492
|
skippedLatest: false,
|
|
415
493
|
showManual: manual ? true : false,
|
|
416
494
|
showReset: false,
|
|
@@ -418,14 +496,17 @@ function panelViewModelCore(input) {
|
|
|
418
496
|
};
|
|
419
497
|
}
|
|
420
498
|
if (jobState === "installing" || jobState === "verifying") {
|
|
499
|
+
const ver = typeof job?.targetVersion === "string" && job.targetVersion.trim() ? job.targetVersion.trim() : "";
|
|
500
|
+
let installingTitle = copyText("panel.banner.installing-title", l, { version: ver || " " });
|
|
501
|
+
if (!ver) installingTitle = installingTitle.replace(" \u2026", "\u2026").replace(" ...", "...");
|
|
421
502
|
return {
|
|
422
503
|
banner: {
|
|
423
504
|
kind: "busy",
|
|
424
|
-
title:
|
|
425
|
-
action: "
|
|
505
|
+
title: installingTitle,
|
|
506
|
+
action: copyText("panel.banner.installing-action", l)
|
|
426
507
|
},
|
|
427
508
|
installEnabled: false,
|
|
428
|
-
installLabel: "
|
|
509
|
+
installLabel: copyText("panel.action.installing", l),
|
|
429
510
|
skippedLatest: false,
|
|
430
511
|
showManual: false,
|
|
431
512
|
showReset: false,
|
|
@@ -436,15 +517,15 @@ function panelViewModelCore(input) {
|
|
|
436
517
|
const failedCode = typeof errorKind === "string" && errorKind.trim() || lastError || jobCode || "";
|
|
437
518
|
if (failedCode || jobState === "failed" || jobState === "interrupted") {
|
|
438
519
|
const code = failedCode || "install-failed";
|
|
439
|
-
const copy = failureCopy(code);
|
|
520
|
+
const copy = failureCopy(code, l);
|
|
440
521
|
return {
|
|
441
522
|
banner: {
|
|
442
523
|
kind: "failed",
|
|
443
|
-
title:
|
|
444
|
-
action: copy?.act || "
|
|
524
|
+
title: copyText("panel.banner.error.title", l, { code, detail: copy?.zh ?? code }),
|
|
525
|
+
action: copy?.act || copyText("panel.banner.error.action-fallback", l)
|
|
445
526
|
},
|
|
446
527
|
installEnabled: snapshot.canInstall,
|
|
447
|
-
installLabel: "
|
|
528
|
+
installLabel: copyText("panel.action.retry-install", l),
|
|
448
529
|
skippedLatest: false,
|
|
449
530
|
showManual: manual ? true : false,
|
|
450
531
|
showReset: false,
|
|
@@ -452,15 +533,16 @@ function panelViewModelCore(input) {
|
|
|
452
533
|
};
|
|
453
534
|
}
|
|
454
535
|
if (snapshot.blockedReason) {
|
|
455
|
-
const copy = blockedCopy(snapshot.blockedReason);
|
|
536
|
+
const copy = blockedCopy(snapshot.blockedReason, l);
|
|
537
|
+
const stop = l === "en" ? "." : "\u3002";
|
|
456
538
|
return {
|
|
457
539
|
banner: {
|
|
458
540
|
kind: "blocked",
|
|
459
|
-
title: copy ? `${copy.title}
|
|
541
|
+
title: copy ? `${copy.title}${stop}` : `${snapshot.blockedReason}${stop}`,
|
|
460
542
|
action: copy?.action || ""
|
|
461
543
|
},
|
|
462
544
|
installEnabled: false,
|
|
463
|
-
installLabel: "
|
|
545
|
+
installLabel: copyText("panel.action.install", l),
|
|
464
546
|
skippedLatest: false,
|
|
465
547
|
showManual: manual ? true : false,
|
|
466
548
|
showReset: false,
|
|
@@ -471,11 +553,11 @@ function panelViewModelCore(input) {
|
|
|
471
553
|
return {
|
|
472
554
|
banner: {
|
|
473
555
|
kind: "update",
|
|
474
|
-
title:
|
|
475
|
-
action: "
|
|
556
|
+
title: copyText("panel.banner.update-title", l, { latest: snapshot.latestVersion, running: snapshot.runningVersion }),
|
|
557
|
+
action: copyText("panel.banner.update-action", l)
|
|
476
558
|
},
|
|
477
559
|
installEnabled: true,
|
|
478
|
-
installLabel:
|
|
560
|
+
installLabel: copyText("panel.action.install-version", l, { latest: snapshot.latestVersion }),
|
|
479
561
|
skippedLatest: false,
|
|
480
562
|
showManual: manual ? true : false,
|
|
481
563
|
showReset: false,
|
|
@@ -483,9 +565,9 @@ function panelViewModelCore(input) {
|
|
|
483
565
|
};
|
|
484
566
|
}
|
|
485
567
|
return {
|
|
486
|
-
banner: { kind: "done", title: "
|
|
568
|
+
banner: { kind: "done", title: copyText("panel.banner.done", l), action: "" },
|
|
487
569
|
installEnabled: false,
|
|
488
|
-
installLabel: "
|
|
570
|
+
installLabel: copyText("panel.action.install", l),
|
|
489
571
|
skippedLatest: false,
|
|
490
572
|
showManual: false,
|
|
491
573
|
showReset: false,
|
|
@@ -493,23 +575,23 @@ function panelViewModelCore(input) {
|
|
|
493
575
|
};
|
|
494
576
|
}
|
|
495
577
|
const UPDATE_PANEL_CSS = [
|
|
496
|
-
'.dsh-upd{font:14px/1.6 system-ui,"Microsoft YaHei",sans-serif;color:var(--dsh-
|
|
497
|
-
"background:var(--dsh-
|
|
578
|
+
'.dsh-upd{font:14px/1.6 system-ui,"Microsoft YaHei",sans-serif;color:var(--dsh-update-text,#1f2937);',
|
|
579
|
+
"background:var(--dsh-update-bg,#ffffff);border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:8px;padding:12px 14px;max-width:560px;",
|
|
498
580
|
// 横幅配色走变量(浅色默认 + 深色覆盖,见下方 dark 媒体块):硬编码浅色会让深色下
|
|
499
581
|
// 「浅底 + 浅字」读不出来(现场回归:默认主题深色模式更新横幅白底浅字)。
|
|
500
|
-
"--dsh-
|
|
501
|
-
"--dsh-
|
|
582
|
+
"--dsh-update-ok-bg:#ecfdf5;--dsh-update-ok-border:#059669;--dsh-update-warn-bg:#fffbeb;--dsh-update-warn-border:#d97706;",
|
|
583
|
+
"--dsh-update-bad-bg:#fef2f2;--dsh-update-bad-border:#dc2626;--dsh-update-busy-bg:#eff6ff;--dsh-update-busy-border:#2563eb}",
|
|
502
584
|
".dsh-upd *{box-sizing:border-box}",
|
|
503
|
-
".dsh-upd button{font:inherit;border:1px solid var(--dsh-
|
|
585
|
+
".dsh-upd button{font:inherit;border:1px solid var(--dsh-update-border-strong,#d1d5db);border-radius:var(--dsh-update-radius-button,6px);background:var(--dsh-update-button-bg,#f9fafb);",
|
|
504
586
|
"color:inherit;padding:4px 12px;cursor:pointer;margin:2px 6px 2px 0}",
|
|
505
587
|
".dsh-upd button:disabled{opacity:.45;cursor:not-allowed}",
|
|
506
|
-
".dsh-upd button:focus-visible{outline:2px solid var(--dsh-
|
|
507
|
-
'.dsh-upd button[data-primary="1"]{background:var(--dsh-
|
|
508
|
-
".dsh-upd-banner{border-left:4px solid var(--dsh-
|
|
509
|
-
'.dsh-upd-banner[data-kind="restart"]{border-color:var(--dsh-
|
|
510
|
-
'.dsh-upd-banner[data-kind="failed"],.dsh-upd-banner[data-kind="blocked"]{border-color:var(--dsh-
|
|
511
|
-
'.dsh-upd-banner[data-kind="update"]{border-color:var(--dsh-
|
|
512
|
-
'.dsh-upd-banner[data-kind="busy"]{border-color:var(--dsh-
|
|
588
|
+
".dsh-upd button:focus-visible{outline:2px solid var(--dsh-update-focus,#2563eb);outline-offset:1px}",
|
|
589
|
+
'.dsh-upd button[data-primary="1"]{background:var(--dsh-update-primary,#2563eb);border-color:var(--dsh-update-primary,#2563eb);color:#fff}',
|
|
590
|
+
".dsh-upd-banner{border-left:4px solid var(--dsh-update-border,#9ca3af);padding:6px 10px;margin:0 0 8px;background:var(--dsh-update-bg-soft,#f3f4f6)}",
|
|
591
|
+
'.dsh-upd-banner[data-kind="restart"]{border-color:var(--dsh-update-warn-border);background:var(--dsh-update-warn-bg)}',
|
|
592
|
+
'.dsh-upd-banner[data-kind="failed"],.dsh-upd-banner[data-kind="blocked"]{border-color:var(--dsh-update-bad-border);background:var(--dsh-update-bad-bg)}',
|
|
593
|
+
'.dsh-upd-banner[data-kind="update"]{border-color:var(--dsh-update-ok-border);background:var(--dsh-update-ok-bg)}',
|
|
594
|
+
'.dsh-upd-banner[data-kind="busy"]{border-color:var(--dsh-update-busy-border);background:var(--dsh-update-busy-bg)}',
|
|
513
595
|
".dsh-upd code{font-family:Consolas,Menlo,monospace;font-size:12px;word-break:break-all}",
|
|
514
596
|
".dsh-upd-manual,.dsh-upd-queue,.dsh-upd-log{margin:4px 0;font-size:13px}",
|
|
515
597
|
".dsh-upd-changelog-wrap{margin:4px 0 0;font-size:13px}",
|
|
@@ -521,71 +603,71 @@ const UPDATE_PANEL_CSS = [
|
|
|
521
603
|
".dsh-upd-changelog-fold{margin:4px 0}",
|
|
522
604
|
".dsh-upd-changelog-fold>summary{cursor:pointer}",
|
|
523
605
|
".dsh-upd-changelog-count{font-size:12px;opacity:.7;margin:2px 0 4px}",
|
|
524
|
-
".dsh-upd-changelog-yanked{border-left:4px solid var(--dsh-
|
|
606
|
+
".dsh-upd-changelog-yanked{border-left:4px solid var(--dsh-update-warn-border,#d97706);background:var(--dsh-update-warn-bg,#fffbeb);padding:6px 10px;margin:6px 0;font-size:13px}",
|
|
525
607
|
".dsh-upd-breaking-badge{display:inline-block;font-size:11px;font-weight:700;border:1px solid currentColor;border-radius:3px;padding:0 5px;margin-right:6px;vertical-align:baseline}",
|
|
526
608
|
".dsh-upd-changelog-security-more{margin:4px 0 6px}",
|
|
527
609
|
".dsh-upd-changelog-security-more>summary{cursor:pointer;font-size:12px;opacity:.8}",
|
|
528
610
|
".dsh-upd-changelog-more-note{font-size:12px;opacity:.7;margin:2px 0 4px}",
|
|
529
611
|
".dsh-upd-changelog-neutral{color:inherit;opacity:.8}",
|
|
530
612
|
".dsh-upd-overlay{position:fixed;inset:0;background:rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;z-index:9999}",
|
|
531
|
-
".dsh-upd-overlay .dsh-upd{background:var(--dsh-
|
|
613
|
+
".dsh-upd-overlay .dsh-upd{background:var(--dsh-update-bg,#ffffff);max-height:85vh;display:flex;flex-direction:column;overflow:hidden}",
|
|
532
614
|
// —— 弹窗分栏滚动:头(抬头/档案头/横幅/版本条)与尾固定,只有 01–05 章节区滚动 ——
|
|
533
615
|
".dsh-upd-body{min-height:0}",
|
|
534
|
-
".dsh-upd-overlay .dsh-upd-body{flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dsh-
|
|
616
|
+
".dsh-upd-overlay .dsh-upd-body{flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--dsh-update-border,#e5e7eb) transparent}",
|
|
535
617
|
".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar{width:8px}",
|
|
536
|
-
".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar-thumb{background:var(--dsh-
|
|
618
|
+
".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar-thumb{background:var(--dsh-update-border,#e5e7eb);border-radius:4px}",
|
|
537
619
|
".dsh-upd-overlay .dsh-upd-body::-webkit-scrollbar-track{background:transparent}",
|
|
538
|
-
// —— 章节标题磁吸:滚动时节标题贴顶(纯 CSS sticky;背景跟随主题,
|
|
539
|
-
".dsh-upd-overlay .dsh-upd-body .dsh-upd-chap-head{position:sticky;top:0;z-index:1;background:var(--dsh-
|
|
620
|
+
// —— 章节标题磁吸:滚动时节标题贴顶(纯 CSS sticky;背景跟随主题,Archive 另覆)——
|
|
621
|
+
".dsh-upd-overlay .dsh-upd-body .dsh-upd-chap-head{position:sticky;top:0;z-index:1;background:var(--dsh-update-bg,#ffffff);padding-top:2px}",
|
|
540
622
|
// —— 档案头 / 版本条 / 章节 / 进度条 / 跳过行(原型 :208-245 的新结构,默认主题给最小可用样式)——
|
|
541
623
|
".dsh-upd-head{display:flex;gap:12px;align-items:baseline;flex-wrap:wrap}",
|
|
542
|
-
// 卷宗抬头「插件更新 / 更新档案 卷」:
|
|
624
|
+
// 卷宗抬头「插件更新 / 更新档案 卷」:Archive 档案卷才画,默认(最小)主题不画。
|
|
543
625
|
// 两个主题共用同一份内核 HTML(见 renderUpdatePanelHTML 的注释),画不画是皮肤决定的事。
|
|
544
626
|
".dsh-upd-masthead{display:none}",
|
|
545
627
|
".dsh-upd-name{font-weight:700}",
|
|
546
628
|
".dsh-upd-meta{font-size:12.5px;opacity:.75}",
|
|
547
|
-
".dsh-upd-proftag{font-family:Consolas,Menlo,monospace;font-size:11px;border:1px solid var(--dsh-
|
|
548
|
-
".dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-
|
|
549
|
-
".dsh-upd-strip>div{flex:1 1 110px;padding:6px 10px;border-left:1px solid var(--dsh-
|
|
629
|
+
".dsh-upd-proftag{font-family:Consolas,Menlo,monospace;font-size:11px;border:1px solid var(--dsh-update-border,#d1d5db);border-radius:3px;padding:0 5px;margin-left:6px;letter-spacing:.06em}",
|
|
630
|
+
".dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border,#e5e7eb);border-radius:4px;overflow:hidden;font-size:12.5px}",
|
|
631
|
+
".dsh-upd-strip>div{flex:1 1 110px;padding:6px 10px;border-left:1px solid var(--dsh-update-border,#e5e7eb)}",
|
|
550
632
|
".dsh-upd-strip>div:first-child{border-left:0}",
|
|
551
633
|
".dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.14em;opacity:.7}",
|
|
552
634
|
".dsh-upd-strip-v{font-family:Consolas,Menlo,monospace;font-size:12.5px}",
|
|
553
|
-
".dsh-upd-chapter{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-
|
|
635
|
+
".dsh-upd-chapter{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
|
|
554
636
|
// 右下角独立 footer 区(#47 定案 A):与第一章 actions 脱钩,右对齐,一次找到。
|
|
555
|
-
".dsh-upd-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-
|
|
637
|
+
".dsh-upd-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
|
|
556
638
|
".dsh-upd-foot-note{margin-right:auto;font-size:12px;opacity:.7}",
|
|
557
639
|
".dsh-upd-footer button{margin:0}",
|
|
558
640
|
".dsh-upd-chap-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px}",
|
|
559
641
|
".dsh-upd-chap-no{font-size:13px;font-style:italic;opacity:.6}",
|
|
560
642
|
".dsh-upd-chap-title{font-size:14px;margin:0}",
|
|
561
|
-
".dsh-upd-chap-rule{flex:1;border-top:1px solid var(--dsh-
|
|
643
|
+
".dsh-upd-chap-rule{flex:1;border-top:1px solid var(--dsh-update-border,#e5e7eb);transform:translateY(-3px)}",
|
|
562
644
|
// 03 章标题行右端的开关(问题 3 定案:按钮形态、挪到标题行)。
|
|
563
645
|
".dsh-upd-chap-note{flex:none;font-size:12px;opacity:.75}",
|
|
564
646
|
".dsh-upd-chap-note button{margin:0}",
|
|
565
647
|
// 更新队列两行键值(用户定案的设计):结构两主题共用,皮肤各自收敛。
|
|
566
648
|
".dsh-upd-qrow{display:flex;align-items:baseline;gap:10px;padding:6px 0}",
|
|
567
|
-
".dsh-upd-qrow+.dsh-upd-qrow{border-top:1px solid var(--dsh-
|
|
649
|
+
".dsh-upd-qrow+.dsh-upd-qrow{border-top:1px solid var(--dsh-update-border,#e5e7eb)}",
|
|
568
650
|
".dsh-upd-qdot{width:8px;height:8px;border-radius:50%;flex:none;align-self:center;background:currentColor;opacity:.5}",
|
|
569
|
-
'.dsh-upd-qdot[data-tone="busy"]{background:var(--dsh-
|
|
570
|
-
'.dsh-upd-qdot[data-tone="you"]{background:var(--dsh-
|
|
651
|
+
'.dsh-upd-qdot[data-tone="busy"]{background:var(--dsh-update-warn-border,#d97706);opacity:1}',
|
|
652
|
+
'.dsh-upd-qdot[data-tone="you"]{background:var(--dsh-update-primary,#2563eb);opacity:1}',
|
|
571
653
|
".dsh-upd-qk{flex:none;width:5.5em;font-size:12px;opacity:.7}",
|
|
572
654
|
".dsh-upd-qv{font-weight:600}",
|
|
573
655
|
".dsh-upd-qn{margin-left:auto;font-size:12px;opacity:.7}",
|
|
574
656
|
".dsh-upd-qseq{font-family:Consolas,Menlo,monospace;font-size:12px;word-break:break-all}",
|
|
575
|
-
".dsh-upd-prog{height:8px;background:var(--dsh-
|
|
576
|
-
".dsh-upd-prog-bar{display:block;height:100%;background:var(--dsh-
|
|
657
|
+
".dsh-upd-prog{height:8px;background:var(--dsh-update-border,#e5e7eb);border-radius:4px;overflow:hidden;margin:10px 0 4px}",
|
|
658
|
+
".dsh-upd-prog-bar{display:block;height:100%;background:var(--dsh-update-primary,#2563eb);transition:width .3s}",
|
|
577
659
|
".dsh-upd-progtxt{font-size:12.5px;opacity:.75}",
|
|
578
660
|
".dsh-upd-skipline{font-size:13px;margin-top:8px}",
|
|
579
661
|
// 骨架微光:只在首帧 loading 出现;reduced-motion 下静止占位,不断语义。
|
|
580
662
|
".dsh-upd-skv{display:inline-block;min-width:64px;border-radius:3px;color:transparent !important;user-select:none;",
|
|
581
|
-
"background:linear-gradient(90deg,var(--dsh-
|
|
663
|
+
"background:linear-gradient(90deg,var(--dsh-update-border,#e5e7eb) 25%,var(--dsh-update-bg-soft,#f3f4f6) 50%,var(--dsh-update-border,#e5e7eb) 75%);",
|
|
582
664
|
"background-size:200% 100%;animation:dsh-upd-shimmer 1.2s linear infinite}",
|
|
583
665
|
"@keyframes dsh-upd-shimmer{to{background-position:-200% 0}}",
|
|
584
666
|
".dsh-upd-tag{display:inline-block;border:1px dashed currentColor;border-radius:3px;padding:1px 8px;margin-right:8px;font-family:Consolas,Menlo,monospace;font-size:12px}",
|
|
585
667
|
".dsh-upd-err{font-size:13px;margin:0 0 6px}",
|
|
586
668
|
// —— 全按钮交互反馈(#36:悬停/按下/过渡/在途忙态;浅深双主题通用写法,不碰上面的既有串)——
|
|
587
669
|
".dsh-upd button{transition:background-color .15s ease,border-color .15s ease,color .15s ease,transform .06s ease}",
|
|
588
|
-
".dsh-upd button:hover:not(:disabled){border-color:var(--dsh-
|
|
670
|
+
".dsh-upd button:hover:not(:disabled){border-color:var(--dsh-update-focus,#2563eb)}",
|
|
589
671
|
'.dsh-upd button[data-primary="1"]:hover:not(:disabled){filter:brightness(.93)}',
|
|
590
672
|
".dsh-upd button:active:not(:disabled){transform:translateY(1px)}",
|
|
591
673
|
'.dsh-upd button[aria-busy="true"]{cursor:wait;animation:dsh-upd-pulse 1s ease-in-out infinite}',
|
|
@@ -602,72 +684,81 @@ const UPDATE_PANEL_CSS = [
|
|
|
602
684
|
"@keyframes dsh-upd-spin{to{transform:rotate(360deg)}}",
|
|
603
685
|
'@media (prefers-reduced-motion: reduce){.dsh-upd button{transition:none}.dsh-upd button:active:not(:disabled){transform:none}.dsh-upd button[aria-busy="true"]{animation:none}.dsh-upd-skv{animation:none}.dsh-upd-banner{animation:none}.dsh-upd-changelog-foldbox{transition:none}}',
|
|
604
686
|
"@media (forced-colors: active){.dsh-upd-overlay .dsh-upd-body .dsh-upd-chap-head{background:Canvas}}",
|
|
605
|
-
|
|
606
|
-
"
|
|
687
|
+
// —— 查新版布局稳定:按钮预留宽度 + 动态区最小高度 + 锚定不漂(只稳布局,不改文案语义)——
|
|
688
|
+
".dsh-upd{overflow-anchor:none}",
|
|
689
|
+
".dsh-upd-body{overflow-anchor:none}",
|
|
690
|
+
".dsh-upd-actions{display:flex;flex-wrap:wrap;align-items:center;min-height:34px}",
|
|
691
|
+
".dsh-upd-actions button:first-child{min-width:8em;text-align:center}",
|
|
692
|
+
'.dsh-upd-actions button[data-primary="1"]{min-width:7em;text-align:center}',
|
|
693
|
+
'.dsh-upd-actions button:first-child:not([aria-busy="true"])::after{content:"";display:inline-block;width:11px;height:11px;margin-left:8px;visibility:hidden}',
|
|
694
|
+
".dsh-upd-banner{min-height:1.2em}",
|
|
695
|
+
".dsh-upd-strip{min-height:48px}",
|
|
696
|
+
"@media (prefers-color-scheme: dark){.dsh-upd{--dsh-update-text:#e5e7eb;--dsh-update-bg:#111827;--dsh-update-border:#374151;",
|
|
697
|
+
"--dsh-update-button-bg:#1f2937;--dsh-update-bg-soft:#1f2937;--dsh-update-primary:#3b82f6;--dsh-update-focus:#93c5fd;",
|
|
607
698
|
// 横幅深色覆盖:底色用低透明度同色系(不是浅色原值),边线提亮,保证「深底浅字」可读。
|
|
608
|
-
"--dsh-
|
|
609
|
-
"--dsh-
|
|
610
|
-
"--dsh-
|
|
611
|
-
"--dsh-
|
|
699
|
+
"--dsh-update-ok-bg:rgba(16,185,129,.14);--dsh-update-ok-border:#34d399;",
|
|
700
|
+
"--dsh-update-warn-bg:rgba(245,158,11,.16);--dsh-update-warn-border:#fbbf24;",
|
|
701
|
+
"--dsh-update-bad-bg:rgba(239,68,68,.16);--dsh-update-bad-border:#f87171;",
|
|
702
|
+
"--dsh-update-busy-bg:rgba(59,130,246,.16);--dsh-update-busy-border:#60a5fa}}"
|
|
612
703
|
].join("\n");
|
|
613
|
-
const
|
|
614
|
-
"/*
|
|
615
|
-
'.dsh-upd[data-theme="archive"]{--
|
|
616
|
-
"--
|
|
617
|
-
"--
|
|
618
|
-
"--
|
|
619
|
-
'--
|
|
620
|
-
'--
|
|
621
|
-
'--
|
|
622
|
-
"--
|
|
623
|
-
"font-family:var(--
|
|
624
|
-
"border:1px solid var(--
|
|
704
|
+
const UPDATE_PANEL_ARCHIVE_CSS = [
|
|
705
|
+
"/* Archive \u6863\u6848\u5377\u53EF\u9009\u4E3B\u9898\uFF1A\u53EA\u6362\u989C\u8272/\u5B57\u4F53/\u95F4\u8DDD\uFF1B\u5185\u6838 DOM \u987A\u5E8F\u4E00\u5B57\u4E0D\u52A8\uFF0C\u4E0D\u65AD\u590D\u5236\u8BCA\u65AD\u3002 */",
|
|
706
|
+
'.dsh-upd[data-theme="archive"]{--dsh-update-bg-soft:#f7f3ea;--dsh-update-bg:#fffdf6;--dsh-update-text:#1a1a1a;--dsh-update-text-muted:#6f675a;',
|
|
707
|
+
"--dsh-update-border:#e3d9c4;--dsh-update-border-strong:#c4b896;--dsh-update-primary:#c8402a;--dsh-update-primary-deep:#9c2e1d;",
|
|
708
|
+
"--dsh-update-ok-text:#1a7f37;--dsh-update-ok-bg:#e9f4ea;--dsh-update-warn-text:#8a5a00;--dsh-update-warn-bg:#fbf0d0;",
|
|
709
|
+
"--dsh-update-bad-text:#b3261e;--dsh-update-bad-bg:#fbe9e5;",
|
|
710
|
+
'--dsh-update-font-serif:Georgia,"Songti SC","STSong","SimSun","Noto Serif CJK SC","Source Han Serif SC",serif;',
|
|
711
|
+
'--dsh-update-font-sans:system-ui,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;',
|
|
712
|
+
'--dsh-update-font-mono:ui-monospace,"SF Mono",SFMono-Regular,Consolas,"Noto Sans Mono",monospace;',
|
|
713
|
+
"--dsh-update-shadow:0 1px 2px rgba(60,40,20,.08),0 12px 32px rgba(60,40,20,.10);",
|
|
714
|
+
"font-family:var(--dsh-update-font-sans);color:var(--dsh-update-text);background:var(--dsh-update-bg);",
|
|
715
|
+
"border:1px solid var(--dsh-update-border-strong);border-radius:var(--dsh-update-radius-panel,4px);box-shadow:var(--dsh-update-shadow)}",
|
|
625
716
|
// 按钮脸自己不透明(宿主底色未知时也读得出;卡片上渲染与 transparent 逐字同色)。
|
|
626
|
-
'.dsh-upd[data-theme="archive"] button{border-color:var(--
|
|
627
|
-
'.dsh-upd[data-theme="archive"] button:hover:not(:disabled){border-color:var(--
|
|
628
|
-
'.dsh-upd[data-theme="archive"] button[data-primary="1"]{background:var(--
|
|
629
|
-
'.dsh-upd[data-theme="archive"] button[data-primary="1"]:hover:not(:disabled){background:var(--
|
|
630
|
-
'.dsh-upd[data-theme="archive"] button:focus-visible{outline:2px solid var(--
|
|
631
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner{background:var(--
|
|
632
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="update"]{border-color:var(--
|
|
633
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="busy"]{border-color:var(--
|
|
634
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="restart"]{border-color:var(--
|
|
635
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="failed"],.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="blocked"]{border-color:var(--
|
|
636
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="done"]{border-color:var(--
|
|
637
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-changelog-yanked{border-color:var(--
|
|
638
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-breaking-badge{color:var(--
|
|
639
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-changelog-count{color:var(--
|
|
640
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-changelog-more-note{color:var(--
|
|
717
|
+
'.dsh-upd[data-theme="archive"] button{border-color:var(--dsh-update-border-strong);background:var(--dsh-update-button-bg);color:var(--dsh-update-text);border-radius:var(--dsh-update-radius-button,3px);font-family:var(--dsh-update-font-sans)}',
|
|
718
|
+
'.dsh-upd[data-theme="archive"] button:hover:not(:disabled){border-color:var(--dsh-update-primary);color:var(--dsh-update-primary)}',
|
|
719
|
+
'.dsh-upd[data-theme="archive"] button[data-primary="1"]{background:var(--dsh-update-primary);border-color:var(--dsh-update-primary);color:#fff}',
|
|
720
|
+
'.dsh-upd[data-theme="archive"] button[data-primary="1"]:hover:not(:disabled){background:var(--dsh-update-primary-deep);color:#fff}',
|
|
721
|
+
'.dsh-upd[data-theme="archive"] button:focus-visible{outline:2px solid var(--dsh-update-primary);outline-offset:2px}',
|
|
722
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner{background:var(--dsh-update-bg-soft);border-color:var(--dsh-update-border-strong)}',
|
|
723
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="update"]{border-color:var(--dsh-update-ok-border);background:var(--dsh-update-ok-bg)}',
|
|
724
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="busy"]{border-color:var(--dsh-update-busy-border);background:var(--dsh-update-busy-bg)}',
|
|
725
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="restart"]{border-color:var(--dsh-update-warn-border);background:var(--dsh-update-warn-bg);font-family:var(--dsh-update-font-serif);border-width:2px}',
|
|
726
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="failed"],.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="blocked"]{border-color:var(--dsh-update-bad-border);background:var(--dsh-update-bad-bg)}',
|
|
727
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="done"]{border-color:var(--dsh-update-ok-border);background:var(--dsh-update-ok-bg)}',
|
|
728
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-changelog-yanked{border-color:var(--dsh-update-warn-text);background:var(--dsh-update-warn-bg);color:var(--dsh-update-text)}',
|
|
729
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-breaking-badge{color:var(--dsh-update-primary);border-color:var(--dsh-update-primary)}',
|
|
730
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-changelog-count{color:var(--dsh-update-text-muted)}',
|
|
731
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-changelog-more-note{color:var(--dsh-update-text-muted)}',
|
|
641
732
|
// —— 大印章(原型 :206 `.seal`:右上 88px、旋转 -7°、双细框;内容与色调来自根属性,不加节点)——
|
|
642
733
|
'.dsh-upd[data-theme="archive"]{position:relative;padding:16px 20px 14px}',
|
|
643
734
|
'.dsh-upd[data-theme="archive"]::before{content:attr(data-seal);position:absolute;top:20px;right:24px;width:88px;height:88px;',
|
|
644
735
|
"display:flex;align-items:center;justify-content:center;text-align:center;letter-spacing:.18em;text-indent:.18em;line-height:1.35;",
|
|
645
|
-
"border:3px solid currentColor;border-radius:14px;transform:rotate(-7deg);font-family:var(--
|
|
736
|
+
"border:3px solid currentColor;border-radius:14px;transform:rotate(-7deg);font-family:var(--dsh-update-font-serif);font-weight:700;font-size:21px;",
|
|
646
737
|
"background:color-mix(in srgb,currentColor 8%,transparent);user-select:none;pointer-events:none;",
|
|
647
|
-
"box-shadow:inset 0 0 0 5px var(--
|
|
648
|
-
'.dsh-upd[data-theme="archive"][data-seal-tone="ink"]::before{color:var(--
|
|
649
|
-
'.dsh-upd[data-theme="archive"][data-seal-tone="green"]::before{color:var(--
|
|
650
|
-
'.dsh-upd[data-theme="archive"][data-seal-tone="yellow"]::before{color:var(--
|
|
651
|
-
'.dsh-upd[data-theme="archive"][data-seal-tone="red"]::before{color:var(--
|
|
738
|
+
"box-shadow:inset 0 0 0 5px var(--dsh-update-bg),inset 0 0 0 6px currentColor,0 2px 6px rgba(0,0,0,.12)}",
|
|
739
|
+
'.dsh-upd[data-theme="archive"][data-seal-tone="ink"]::before{color:var(--dsh-update-text-muted)}',
|
|
740
|
+
'.dsh-upd[data-theme="archive"][data-seal-tone="green"]::before{color:var(--dsh-update-ok-text)}',
|
|
741
|
+
'.dsh-upd[data-theme="archive"][data-seal-tone="yellow"]::before{color:var(--dsh-update-warn-text)}',
|
|
742
|
+
'.dsh-upd[data-theme="archive"][data-seal-tone="red"]::before{color:var(--dsh-update-bad-text)}',
|
|
652
743
|
// 印章占位:首行(横幅/状态行)右侧留出 120px,文字不许压到印章上(原型 .filehead padding-right:120px)
|
|
653
|
-
// —— 卷宗抬头(原型 :195-203 的刊头,主题切换按钮按用户口径去掉):只有
|
|
654
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead{display:block;padding:0 0 8px;margin:0 0 8px;border-bottom:1px solid var(--
|
|
655
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead-kicker{display:block;font-size:11px;letter-spacing:.35em;color:var(--
|
|
656
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead-title{font-family:var(--
|
|
657
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead-title i{color:var(--
|
|
744
|
+
// —— 卷宗抬头(原型 :195-203 的刊头,主题切换按钮按用户口径去掉):只有 Archive 档案卷才显示 ——
|
|
745
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead{display:block;padding:0 0 8px;margin:0 0 8px;border-bottom:1px solid var(--dsh-update-border)}',
|
|
746
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead-kicker{display:block;font-size:11px;letter-spacing:.35em;color:var(--dsh-update-text-muted);margin-bottom:3px}',
|
|
747
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead-title{font-family:var(--dsh-update-font-serif);font-size:26px;font-weight:700;line-height:1.2}',
|
|
748
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-masthead-title i{color:var(--dsh-update-primary);font-style:normal}',
|
|
658
749
|
// 横幅不再给大印章留 124px:实测(headless 量盒子)印章盒底边 y=109,横幅正文顶边 y=108、
|
|
659
750
|
// 状态行那句在 y=159——印章只压到横幅顶部的留白带,压不到正文。留着反而把 27px 那句话挤成两行
|
|
660
751
|
// (27px 单行需 428px,留白后只剩 366px)。档案头那 120px 保留:那里是真的重叠。
|
|
661
|
-
// —— 更新队列(03 章)
|
|
752
|
+
// —— 更新队列(03 章)Archive 皮肤 ——
|
|
662
753
|
'.dsh-upd[data-theme="archive"] .dsh-upd-qrow{padding:6px 0}',
|
|
663
754
|
'.dsh-upd[data-theme="archive"] .dsh-upd-qk{width:66px;letter-spacing:.18em}',
|
|
664
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-qv{font-family:var(--
|
|
665
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-qn{font-family:var(--
|
|
666
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-qseq{color:var(--
|
|
667
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-note{color:var(--
|
|
668
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-body .dsh-upd-chap-head{background:var(--
|
|
669
|
-
'.dsh-upd-overlay .dsh-upd[data-theme="archive"] .dsh-upd-body{scrollbar-color:var(--
|
|
670
|
-
'.dsh-upd-overlay .dsh-upd[data-theme="archive"] .dsh-upd-body::-webkit-scrollbar-thumb{background:var(--
|
|
755
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-qv{font-family:var(--dsh-update-font-serif);font-size:16px}',
|
|
756
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-qn{font-family:var(--dsh-update-font-mono);font-size:11.5px;color:var(--dsh-update-text-muted)}',
|
|
757
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-qseq{color:var(--dsh-update-text-muted)}',
|
|
758
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-note{color:var(--dsh-update-text-muted)}',
|
|
759
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-body .dsh-upd-chap-head{background:var(--dsh-update-bg)}',
|
|
760
|
+
'.dsh-upd-overlay .dsh-upd[data-theme="archive"] .dsh-upd-body{scrollbar-color:var(--dsh-update-border-strong) transparent}',
|
|
761
|
+
'.dsh-upd-overlay .dsh-upd[data-theme="archive"] .dsh-upd-body::-webkit-scrollbar-thumb{background:var(--dsh-update-border-strong)}',
|
|
671
762
|
// —— 小印章(原型 :215 `.sealmini`:30px、旋转 -5°、一字)——
|
|
672
763
|
// 待重启横幅一律不画印章:那一档的标记是左侧手绘 SVG(原型 :446 的 .mark 只有 SVG)。
|
|
673
764
|
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="loading"]::before,.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="idle"]::before,',
|
|
@@ -675,13 +766,13 @@ const UPDATE_PANEL_D5_CSS = [
|
|
|
675
766
|
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="blocked"]::before,.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="failed"]::before,',
|
|
676
767
|
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="done"]::before{content:attr(data-mini);display:inline-flex;align-items:center;justify-content:center;',
|
|
677
768
|
"width:30px;height:30px;margin-right:10px;vertical-align:middle;border:2px solid currentColor;border-radius:7px;",
|
|
678
|
-
"font-family:var(--
|
|
679
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="update"]::before{color:var(--
|
|
680
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="busy"]::before{color:var(--
|
|
681
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="blocked"]::before,.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="failed"]::before{color:var(--
|
|
682
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="done"]::before{color:var(--
|
|
683
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-log code{font-family:var(--
|
|
684
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-manual code{display:block;background:var(--
|
|
769
|
+
"font-family:var(--dsh-update-font-serif);font-weight:700;font-size:16px;line-height:26px;transform:rotate(-5deg);flex:none;color:var(--dsh-update-text-muted)}",
|
|
770
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="update"]::before{color:var(--dsh-update-ok-text)}',
|
|
771
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="busy"]::before{color:var(--dsh-update-warn-text)}',
|
|
772
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="blocked"]::before,.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="failed"]::before{color:var(--dsh-update-bad-text)}',
|
|
773
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="done"]::before{color:var(--dsh-update-ok-text)}',
|
|
774
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-log code{font-family:var(--dsh-update-font-mono);font-size:11px;color:var(--dsh-update-text-muted);border:1px solid var(--dsh-update-border-strong);border-radius:3px;padding:0 6px;letter-spacing:.06em}',
|
|
775
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-manual code{display:block;background:var(--dsh-update-text);color:var(--dsh-update-bg-soft);font-family:var(--dsh-update-font-mono);font-size:12.5px;padding:12px 14px;border-radius:4px;white-space:pre-wrap;word-break:break-all}',
|
|
685
776
|
// 待重启标记:手绘 SVG 当**独立 flex 标记**放在文字块左侧(原型 :446 `.mark` 是独立节点),
|
|
686
777
|
// 不能用行内背景——那样换行时三角会落在句子中间把话劈开(现场回归)。
|
|
687
778
|
'.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="restart"]>div:first-child{display:flex;gap:10px;align-items:flex-start}',
|
|
@@ -689,45 +780,45 @@ const UPDATE_PANEL_D5_CSS = [
|
|
|
689
780
|
'background:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2720%27 height=%2720%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%238a5a00%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z%27/%3E%3Cline x1=%2712%27 y1=%279%27 x2=%2712%27 y2=%2713%27/%3E%3Cline x1=%2712%27 y1=%2717%27 x2=%2712.01%27 y2=%2717%27/%3E%3C/svg%3E") no-repeat center/20px 20px}',
|
|
690
781
|
'.dsh-upd[data-theme="archive"] .dsh-upd-banner>div:first-child{overflow:hidden;text-overflow:ellipsis}',
|
|
691
782
|
'.dsh-upd[data-theme="archive"] .dsh-upd-actions{flex-wrap:wrap}',
|
|
692
|
-
// footer 只换肤(#47 定案 A +
|
|
693
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-footer{margin-top:14px;padding-top:10px;border-top:1px solid var(--
|
|
694
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-foot-note{color:var(--
|
|
783
|
+
// footer 只换肤(#47 定案 A + Archive 约束:不换 DOM 顺序;复制诊断永不隐藏,本串不动它)。
|
|
784
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-footer{margin-top:14px;padding-top:10px;border-top:1px solid var(--dsh-update-border)}',
|
|
785
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-foot-note{color:var(--dsh-update-text-muted)}',
|
|
695
786
|
// —— 档案头(原型 :208-211 `.filehead`:serif 插件名 22px + 使用范围 + profile 牌;右侧留章位)——
|
|
696
787
|
'.dsh-upd[data-theme="archive"] .dsh-upd-head{display:flex;gap:16px;align-items:baseline;flex-wrap:wrap;padding-right:120px}',
|
|
697
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-name{font-family:var(--
|
|
698
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-meta{width:100%;font-size:12.5px;color:var(--
|
|
699
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-meta b{color:var(--
|
|
700
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-proftag{font-family:var(--
|
|
788
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-name{font-family:var(--dsh-update-font-serif);font-size:22px;font-weight:700}',
|
|
789
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-meta{width:100%;font-size:12.5px;color:var(--dsh-update-text-muted)}',
|
|
790
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-meta b{color:var(--dsh-update-text);font-weight:600}',
|
|
791
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-proftag{font-family:var(--dsh-update-font-mono);font-size:11px;color:var(--dsh-update-text-muted);border:1px solid var(--dsh-update-border-strong);border-radius:3px;padding:0 6px;margin-left:8px;letter-spacing:.06em}',
|
|
701
792
|
// —— 版本条(原型 :216 `.strip`:三格,格间一线,左上小写标签 + 等宽值)——
|
|
702
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--
|
|
703
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-strip>div{flex:1 1 120px;padding:6px 10px;border-left:1px solid var(--
|
|
793
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-strip{display:flex;flex-wrap:wrap;margin:8px 0 0;border:1px solid var(--dsh-update-border);border-radius:4px;overflow:hidden;font-size:12.5px}',
|
|
794
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-strip>div{flex:1 1 120px;padding:6px 10px;border-left:1px solid var(--dsh-update-border)}',
|
|
704
795
|
'.dsh-upd[data-theme="archive"] .dsh-upd-strip>div:first-child{border-left:0}',
|
|
705
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.2em;color:var(--
|
|
706
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-strip-v{font-family:var(--
|
|
796
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-strip-k{display:block;font-size:11px;letter-spacing:.2em;color:var(--dsh-update-text-muted)}',
|
|
797
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-strip-v{font-family:var(--dsh-update-font-mono);font-size:13px}',
|
|
707
798
|
// —— 章节(原型 :218-245:01–05 编号 + 衬线标题 + 细线)——
|
|
708
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-chapter{margin-top:16px;padding-top:10px;border-top:1px solid var(--
|
|
799
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-chapter{margin-top:16px;padding-top:10px;border-top:1px solid var(--dsh-update-border)}',
|
|
709
800
|
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-head{display:flex;align-items:baseline;gap:12px;margin-bottom:6px}',
|
|
710
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-no{font-family:var(--
|
|
711
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-title{font-family:var(--
|
|
712
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-rule{flex:1;border-top:1px solid var(--
|
|
801
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-no{font-family:var(--dsh-update-font-serif);font-style:italic;font-size:15px;color:var(--dsh-update-text-muted)}',
|
|
802
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-title{font-family:var(--dsh-update-font-serif);font-size:17px;margin:0;letter-spacing:.1em}',
|
|
803
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-chap-rule{flex:1;border-top:1px solid var(--dsh-update-border);transform:translateY(-4px)}',
|
|
713
804
|
// —— 横幅即状态行 / 待重启横幅(原型 :81-85 `.restart-banner`:2px 边框、圆角 4、内边距 12/16、衬线;右侧留章位)——
|
|
714
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner{border:2px solid var(--
|
|
805
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner{border:2px solid var(--dsh-update-border-strong);border-radius:4px;padding:10px 12px;font-size:14.5px;font-family:var(--dsh-update-font-serif);display:flex;gap:10px;align-items:center;flex-wrap:wrap}',
|
|
715
806
|
'.dsh-upd[data-theme="archive"] .dsh-upd-banner>div:first-child{flex:1 1 auto;min-width:0}',
|
|
716
807
|
// 状态行字号照原型 .status-line=27px(实测去掉横幅右侧占位后可写 486px > 428px,一行放得下)
|
|
717
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-banner>div:first-child strong{font-family:var(--
|
|
808
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-banner>div:first-child strong{font-family:var(--dsh-update-font-serif);font-size:27px;font-weight:700;line-height:1.25}',
|
|
718
809
|
// —— 进度条 / 跳过行(原型 :132-133 `.prog`、:129-131 `.skipline .tag`)——
|
|
719
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-prog{height:8px;background:var(--
|
|
720
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-prog-bar{display:block;height:100%;background:var(--
|
|
721
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-progtxt{font-size:12.5px;color:var(--
|
|
810
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-prog{height:8px;background:var(--dsh-update-border);border-radius:4px;overflow:hidden;margin:10px 0 4px}',
|
|
811
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-prog-bar{display:block;height:100%;background:var(--dsh-update-primary);transition:width .3s}',
|
|
812
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-progtxt{font-size:12.5px;color:var(--dsh-update-text-muted)}',
|
|
722
813
|
'.dsh-upd[data-theme="archive"] .dsh-upd-skipline{font-size:13px;margin-top:8px}',
|
|
723
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-tag{display:inline-block;border:1px dashed var(--
|
|
724
|
-
'.dsh-upd[data-theme="archive"] .dsh-upd-err{font-size:13px;margin:0 0 6px;color:var(--
|
|
725
|
-
'@media (max-width:640px){.dsh-upd[data-theme="archive"]{padding:10px 12px}.dsh-upd[data-theme="archive"]::before{top:12px;right:12px;width:56px;height:56px;font-size:15px;box-shadow:inset 0 0 0 4px var(--
|
|
726
|
-
'@media (prefers-color-scheme: dark){.dsh-upd[data-theme="archive"]{--
|
|
727
|
-
"--
|
|
728
|
-
"--
|
|
729
|
-
"--
|
|
730
|
-
'@media (prefers-color-scheme: dark){.dsh-upd[data-theme="archive"] button[data-primary="1"]{color:#141210}.dsh-upd[data-theme="archive"] button:focus-visible{outline-color:var(--
|
|
814
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-tag{display:inline-block;border:1px dashed var(--dsh-update-border-strong);border-radius:3px;padding:1px 8px;margin-right:8px;font-family:var(--dsh-update-font-mono);font-size:12px}',
|
|
815
|
+
'.dsh-upd[data-theme="archive"] .dsh-upd-err{font-size:13px;margin:0 0 6px;color:var(--dsh-update-text-muted)}',
|
|
816
|
+
'@media (max-width:640px){.dsh-upd[data-theme="archive"]{padding:10px 12px}.dsh-upd[data-theme="archive"]::before{top:12px;right:12px;width:56px;height:56px;font-size:15px;box-shadow:inset 0 0 0 4px var(--dsh-update-bg),inset 0 0 0 5px currentColor}.dsh-upd[data-theme="archive"] .dsh-upd-masthead-title{font-size:19px}.dsh-upd[data-theme="archive"] .dsh-upd-banner{padding-right:16px}.dsh-upd[data-theme="archive"] .dsh-upd-banner::before{width:24px;height:24px;font-size:14px;line-height:20px;flex:none}.dsh-upd[data-theme="archive"] .dsh-upd-banner>div:first-child{white-space:normal}}',
|
|
817
|
+
'@media (prefers-color-scheme: dark){.dsh-upd[data-theme="archive"]{--dsh-update-bg-soft:#141210;--dsh-update-bg:#1e1a15;--dsh-update-text:#ece5d3;--dsh-update-text-muted:#a89c83;',
|
|
818
|
+
"--dsh-update-border:#3a3226;--dsh-update-border-strong:#5c4e3b;--dsh-update-primary:#e0684e;--dsh-update-primary-deep:#f0866b;",
|
|
819
|
+
"--dsh-update-ok-text:#8fd6a4;--dsh-update-ok-bg:rgba(80,180,120,.12);--dsh-update-warn-text:#e8c15a;--dsh-update-warn-bg:rgba(232,193,90,.12);",
|
|
820
|
+
"--dsh-update-bad-text:#ef8a7d;--dsh-update-bad-bg:rgba(239,138,125,.12);--dsh-update-shadow:0 1px 2px rgba(0,0,0,.4),0 12px 32px rgba(0,0,0,.45)}}",
|
|
821
|
+
'@media (prefers-color-scheme: dark){.dsh-upd[data-theme="archive"] button[data-primary="1"]{color:#141210}.dsh-upd[data-theme="archive"] button:focus-visible{outline-color:var(--dsh-update-primary-deep)}}',
|
|
731
822
|
'@media (prefers-color-scheme: dark){.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="restart"]>div:first-child::before{background-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2720%27 height=%2720%27 viewBox=%270 0 24 24%27 fill=%27none%27 stroke=%27%23e8c15a%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z%27/%3E%3Cline x1=%2712%27 y1=%279%27 x2=%2712%27 y2=%2713%27/%3E%3Cline x1=%2712%27 y1=%2717%27 x2=%2712.01%27 y2=%2717%27/%3E%3C/svg%3E")}}',
|
|
732
823
|
'@media (forced-colors: active){.dsh-upd[data-theme="archive"]{box-shadow:none}.dsh-upd[data-theme="archive"]::before{background:none;box-shadow:none;border-color:CanvasText;color:CanvasText}.dsh-upd[data-theme="archive"] .dsh-upd-banner{border:1px solid CanvasText}.dsh-upd[data-theme="archive"] .dsh-upd-banner::before{border-color:CanvasText;color:CanvasText;background:Canvas}.dsh-upd[data-theme="archive"] button{border:1px solid ButtonText}.dsh-upd[data-theme="archive"] button[data-primary="1"]{background:ButtonFace;color:ButtonText;border-color:ButtonText}.dsh-upd[data-theme="archive"] .dsh-upd-banner[data-kind="restart"]>div:first-child::before{background-image:none;content:"\u26A0"}}',
|
|
733
824
|
'@media (prefers-reduced-motion: reduce){.dsh-upd[data-theme="archive"] *{transition:none !important;animation:none !important}}'
|
|
@@ -735,58 +826,83 @@ const UPDATE_PANEL_D5_CSS = [
|
|
|
735
826
|
function escapeHtml(text) {
|
|
736
827
|
return String(text).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
737
828
|
}
|
|
738
|
-
const
|
|
739
|
-
|
|
829
|
+
const CHAPTER_KEYS = [
|
|
830
|
+
"panel.chapter.check",
|
|
831
|
+
"panel.chapter.changelog",
|
|
832
|
+
"panel.chapter.queue",
|
|
833
|
+
"panel.chapter.error",
|
|
834
|
+
"panel.chapter.manual"
|
|
835
|
+
];
|
|
836
|
+
function chapterTitle(index, lang) {
|
|
837
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
838
|
+
return copyText(CHAPTER_KEYS[index - 1], l);
|
|
839
|
+
}
|
|
840
|
+
function formatLatchTime(atMs, lang) {
|
|
740
841
|
if (typeof atMs !== "number" || !Number.isFinite(atMs) || atMs <= 0) return null;
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
842
|
+
const raw = typeof lang === "string" ? lang.trim().replace(/_/g, "-") : "";
|
|
843
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
844
|
+
const primary = l === "en" ? "en-US" : "zh-CN";
|
|
845
|
+
const fallback = l === "en" ? "zh-CN" : "en-US";
|
|
846
|
+
const candidates = [];
|
|
847
|
+
if (raw && raw !== primary && /^[A-Za-z]{2,3}(-[A-Za-z0-9]+)*$/.test(raw)) candidates.push(raw);
|
|
848
|
+
candidates.push(primary, fallback);
|
|
849
|
+
for (const tag of candidates) {
|
|
850
|
+
try {
|
|
851
|
+
const s = new Date(atMs).toLocaleTimeString(tag, { hour12: false });
|
|
852
|
+
if (s) return s;
|
|
853
|
+
} catch {
|
|
854
|
+
}
|
|
746
855
|
}
|
|
856
|
+
return null;
|
|
747
857
|
}
|
|
748
|
-
function chapterOf(index, inner, note = "") {
|
|
858
|
+
function chapterOf(index, inner, note = "", lang) {
|
|
749
859
|
const no = String(index).padStart(2, "0");
|
|
750
|
-
const
|
|
860
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
861
|
+
const title = chapterTitle(index, l);
|
|
751
862
|
return `<section class="dsh-upd-chapter" data-chapter="${no}"><div class="dsh-upd-chap-head"><span class="dsh-upd-chap-no">${no}</span><h3 class="dsh-upd-chap-title">${escapeHtml(title)}</h3><span class="dsh-upd-chap-rule"></span>${note}</div>${inner}</section>`;
|
|
752
863
|
}
|
|
753
|
-
function skeletonStrip(loading) {
|
|
864
|
+
function skeletonStrip(loading, lang) {
|
|
754
865
|
if (!loading) return "";
|
|
866
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
755
867
|
const cell = (k) => `<div><span class="dsh-upd-strip-k">${escapeHtml(k)}</span><span class="dsh-upd-strip-v dsh-upd-skv" aria-hidden="true">\u2026</span></div>`;
|
|
756
|
-
return `<div class="dsh-upd-strip" aria-hidden="true">` + cell("
|
|
868
|
+
return `<div class="dsh-upd-strip" aria-hidden="true">` + cell(copyText("panel.strip.running", l)) + cell(copyText("panel.strip.installed", l)) + cell(copyText("panel.strip.latest", l)) + `</div>`;
|
|
757
869
|
}
|
|
758
|
-
function versionStrip(snapshot) {
|
|
759
|
-
const
|
|
870
|
+
function versionStrip(snapshot, lang) {
|
|
871
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
872
|
+
const unknown = copyText("panel.meta.unknown", l);
|
|
873
|
+
const cell = (k, v) => `<div><span class="dsh-upd-strip-k">${escapeHtml(k)}</span><span class="dsh-upd-strip-v">${escapeHtml(v ?? unknown)}</span></div>`;
|
|
760
874
|
if (!snapshot) return "";
|
|
761
|
-
return `<div class="dsh-upd-strip">` + cell("
|
|
875
|
+
return `<div class="dsh-upd-strip">` + cell(copyText("panel.strip.running", l), snapshot.runningVersion) + cell(copyText("panel.strip.installed", l), snapshot.installedVersion) + cell(copyText("panel.strip.latest", l), snapshot.latestVersion) + `</div>`;
|
|
762
876
|
}
|
|
763
|
-
function progressBar(snapshot) {
|
|
877
|
+
function progressBar(snapshot, lang) {
|
|
764
878
|
const job = snapshot?.job;
|
|
765
879
|
if (!job) return "";
|
|
766
880
|
const state = String(job.state);
|
|
767
881
|
if (state !== "installing" && state !== "verifying") return "";
|
|
882
|
+
const l = normalizeLangTag(lang ?? "zh");
|
|
768
883
|
const width = state === "installing" ? 60 : 90;
|
|
769
|
-
const text = state === "installing" ? "
|
|
884
|
+
const text = state === "installing" ? copyText("panel.progress.installing", l) : copyText("panel.progress.verifying", l);
|
|
770
885
|
return `<div class="dsh-upd-prog" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${width}"><i class="dsh-upd-prog-bar" style="width:${width}%"></i></div><div class="dsh-upd-progtxt">${escapeHtml(text)}</div>`;
|
|
771
886
|
}
|
|
772
|
-
function renderUpdatePanelKernel(input, view) {
|
|
887
|
+
function renderUpdatePanelKernel(input, view, lang) {
|
|
773
888
|
const { snapshot, manual, queue, mode, showOthers, pluginId, copyNotice } = input;
|
|
889
|
+
const l = normalizeLangTag(lang ?? input.lang ?? "zh");
|
|
774
890
|
const changelogMarkdown = input.changelogMarkdown ?? null;
|
|
775
891
|
const profileName = typeof input.profileName === "string" && input.profileName ? input.profileName : null;
|
|
776
892
|
const b = view.banner;
|
|
777
893
|
const seal = view.seal;
|
|
778
894
|
const parts = [];
|
|
779
895
|
parts.push(
|
|
780
|
-
'<div class="dsh-upd-masthead"><span class="dsh-upd-masthead-kicker"
|
|
896
|
+
'<div class="dsh-upd-masthead"><span class="dsh-upd-masthead-kicker">' + escapeHtml(copyText("panel.masthead.kicker", l)) + '</span><span class="dsh-upd-masthead-title">' + escapeHtml(copyText("panel.masthead.title", l)) + " <i>" + escapeHtml(copyText("panel.masthead.volume", l)) + "</i></span></div>"
|
|
781
897
|
);
|
|
782
898
|
parts.push(
|
|
783
|
-
`<div class="dsh-upd-head"><span class="dsh-upd-name">${escapeHtml(pluginId)}</span><span class="dsh-upd-meta"
|
|
899
|
+
`<div class="dsh-upd-head"><span class="dsh-upd-name">${escapeHtml(pluginId)}</span><span class="dsh-upd-meta">${escapeHtml(copyText("panel.meta.label", l))} <b>${escapeHtml(profileName ?? copyText("panel.meta.unknown", l))}</b><span class="dsh-upd-proftag">profile</span></span></div>`
|
|
784
900
|
);
|
|
785
901
|
parts.push(`<div class="dsh-upd-banner" data-kind="${b.kind}" data-mini="${escapeHtml(seal.mini)}" role="status" aria-live="polite">`);
|
|
786
902
|
parts.push(`<div><strong>${escapeHtml(b.title)}</strong></div>`);
|
|
787
903
|
if (b.action) parts.push(`<div>${escapeHtml(b.action)}</div>`);
|
|
788
904
|
parts.push("</div>");
|
|
789
|
-
parts.push(snapshot ? versionStrip(snapshot) : skeletonStrip(view.banner.kind === "loading"));
|
|
905
|
+
parts.push(snapshot ? versionStrip(snapshot, l) : skeletonStrip(view.banner.kind === "loading", l));
|
|
790
906
|
const showActions = input.actions !== "none";
|
|
791
907
|
const actions = [];
|
|
792
908
|
if (showActions) {
|
|
@@ -795,36 +911,36 @@ function renderUpdatePanelKernel(input, view) {
|
|
|
795
911
|
const installBusy = busyAct === "install";
|
|
796
912
|
actions.push('<div class="dsh-upd-actions">');
|
|
797
913
|
actions.push(
|
|
798
|
-
(checkBusy ? `<button type="button" data-action="check" disabled aria-busy="true" title="
|
|
914
|
+
(checkBusy ? `<button type="button" data-action="check" disabled aria-busy="true" title="${escapeHtml(copyText("panel.action.checking-busy-title", l))}">${escapeHtml(copyText("panel.action.checking-busy", l))}</button>` : `<button type="button" data-action="check" title="${escapeHtml(copyText("panel.action.check-title", l))}">${escapeHtml(copyText("panel.action.check", l))}</button>`) + (installBusy ? `<button type="button" data-action="install" data-primary="1" disabled aria-busy="true" title="${escapeHtml(copyText("panel.action.installing-busy-title", l))}">${escapeHtml(copyText("panel.action.installing-busy", l))}</button>` : `<button type="button" data-action="install" data-primary="1" title="${escapeHtml(copyText("panel.action.install-title", l))}"${view.installEnabled ? "" : " disabled"}>${escapeHtml(view.installLabel)}</button>`)
|
|
799
915
|
);
|
|
800
916
|
if (snapshot?.latestVersion && !view.skippedLatest && view.banner.kind === "update") {
|
|
801
|
-
actions.push(`<button type="button" data-action="skip" title="
|
|
917
|
+
actions.push(`<button type="button" data-action="skip" title="${escapeHtml(copyText("panel.action.skip-title", l))}">${escapeHtml(copyText("panel.action.skip", l))}</button>`);
|
|
802
918
|
}
|
|
803
919
|
if (view.showReset && snapshot?.latestVersion) {
|
|
804
|
-
actions.push(`<button type="button" data-action="reset-skip" title="
|
|
920
|
+
actions.push(`<button type="button" data-action="reset-skip" title="${escapeHtml(copyText("panel.action.unskip-title", l))}">${escapeHtml(copyText("panel.action.unskip", l, { version: snapshot.latestVersion }))}</button>`);
|
|
805
921
|
}
|
|
806
922
|
if (view.showManual && manual) {
|
|
807
|
-
actions.push(`<button type="button" data-action="copy-manual" title="
|
|
923
|
+
actions.push(`<button type="button" data-action="copy-manual" title="${escapeHtml(copyText("panel.action.copy-manual-title", l))}">${escapeHtml(copyText("panel.action.copy-manual", l))}</button>`);
|
|
808
924
|
}
|
|
809
925
|
if (b.kind === "restart") {
|
|
810
|
-
actions.push(`<button type="button" data-action="restart-hint" data-primary="1" title="
|
|
926
|
+
actions.push(`<button type="button" data-action="restart-hint" data-primary="1" title="${escapeHtml(copyText("panel.action.restart-host-title", l))}">${escapeHtml(copyText("panel.action.restart-host", l))}</button>`);
|
|
811
927
|
}
|
|
812
928
|
if (b.kind === "failed") {
|
|
813
|
-
actions.push(`<button type="button" data-action="dismiss-failure" title="
|
|
929
|
+
actions.push(`<button type="button" data-action="dismiss-failure" title="${escapeHtml(copyText("panel.action.dismiss-title", l))}">${escapeHtml(copyText("panel.action.dismiss", l))}</button>`);
|
|
814
930
|
}
|
|
815
931
|
if (snapshot) {
|
|
816
|
-
actions.push(`<button type="button" data-action="copy-diag" title="
|
|
932
|
+
actions.push(`<button type="button" data-action="copy-diag" title="${escapeHtml(copyText("panel.action.copy-diag-title", l))}">${escapeHtml(copyText("panel.action.copy-diag", l))}</button>`);
|
|
817
933
|
}
|
|
818
934
|
actions.push("</div>");
|
|
819
935
|
}
|
|
820
|
-
actions.push(progressBar(snapshot));
|
|
936
|
+
actions.push(progressBar(snapshot, l));
|
|
821
937
|
if (view.skippedLatest && snapshot?.latestVersion) {
|
|
822
938
|
actions.push(
|
|
823
|
-
`<div class="dsh-upd-skipline"><span class="dsh-upd-tag"
|
|
939
|
+
`<div class="dsh-upd-skipline"><span class="dsh-upd-tag">${escapeHtml(copyText("panel.skip.line-tag", l, { version: snapshot.latestVersion }))}</span>${escapeHtml(copyText("panel.skip.line-note", l))}</div>`
|
|
824
940
|
);
|
|
825
941
|
}
|
|
826
942
|
const chapters = [];
|
|
827
|
-
chapters.push(chapterOf(1, actions.join("")));
|
|
943
|
+
chapters.push(chapterOf(1, actions.join(""), "", l));
|
|
828
944
|
{
|
|
829
945
|
let inner = "";
|
|
830
946
|
let hasLog = false;
|
|
@@ -838,10 +954,10 @@ function renderUpdatePanelKernel(input, view) {
|
|
|
838
954
|
snapshot.latestVersion,
|
|
839
955
|
snapshot.installedVersion
|
|
840
956
|
);
|
|
841
|
-
const changelogHTML = renderChangelogHTML(ranged);
|
|
957
|
+
const changelogHTML = renderChangelogHTML(ranged, { lang: l });
|
|
842
958
|
const fromText = String(snapshot.runningVersion ?? "");
|
|
843
959
|
const toText = String(snapshot.latestVersion ?? "");
|
|
844
|
-
const rangeTitle = fromText && toText ?
|
|
960
|
+
const rangeTitle = fromText && toText ? copyText("panel.changelog.heading-range", l, { from: fromText, to: toText }) : copyText("panel.changelog.heading", l);
|
|
845
961
|
let yankedBanner = "";
|
|
846
962
|
try {
|
|
847
963
|
const toEntry = Array.isArray(ranged) ? ranged.find(function(e) {
|
|
@@ -852,7 +968,7 @@ function renderUpdatePanelKernel(input, view) {
|
|
|
852
968
|
}
|
|
853
969
|
}) : null;
|
|
854
970
|
if (toEntry && toEntry.yanked === true && toText) {
|
|
855
|
-
yankedBanner = yankedBannerHTML(toText);
|
|
971
|
+
yankedBanner = yankedBannerHTML(toText, l);
|
|
856
972
|
}
|
|
857
973
|
} catch {
|
|
858
974
|
yankedBanner = "";
|
|
@@ -868,12 +984,12 @@ ${changelogHTML}
|
|
|
868
984
|
}
|
|
869
985
|
if (!inner) {
|
|
870
986
|
inner = `<div class="dsh-upd-changelog-wrap"><div class="dsh-upd-changelog-neutral">${escapeHtml(
|
|
871
|
-
snapshot && snapshot.latestVersion ? "
|
|
987
|
+
snapshot && snapshot.latestVersion ? copyText("panel.changelog.unavailable", l) : copyText("panel.changelog.unavailable-empty", l)
|
|
872
988
|
)}</div></div>`;
|
|
873
989
|
}
|
|
874
990
|
const logCollapsed = input.changelogCollapsed === true;
|
|
875
|
-
const logNote = showActions && hasLog ?
|
|
876
|
-
chapters.push(chapterOf(2, inner, logNote));
|
|
991
|
+
const logNote = showActions && hasLog ? '<span class="dsh-upd-chap-note"><button type="button" data-action="toggle-changelog" title="' + escapeHtml(copyText("panel.changelog.toggle-title", l)) + `">${escapeHtml(logCollapsed ? copyText("panel.changelog.expand", l) : copyText("panel.changelog.collapse", l))}</button></span>` : "";
|
|
992
|
+
chapters.push(chapterOf(2, inner, logNote, l));
|
|
877
993
|
}
|
|
878
994
|
{
|
|
879
995
|
const queued = !!queue && (queue.busy || queue.waiting.length > 0);
|
|
@@ -884,30 +1000,32 @@ ${changelogHTML}
|
|
|
884
1000
|
const version = ownerRaw && "targetVersion" in ownerRaw && ownerRaw.targetVersion ? `@${String(ownerRaw.targetVersion)}` : "";
|
|
885
1001
|
const aboutSelf = named !== null && named === pluginId;
|
|
886
1002
|
const reveal = showOthers === true;
|
|
887
|
-
const ownerShown = !busy ? "
|
|
1003
|
+
const ownerShown = !busy ? copyText("panel.queue.state-idle", l) : named === null ? copyText("panel.queue.other", l) : aboutSelf ? copyText("panel.queue.self", l) : reveal ? named : copyText("panel.queue.other", l);
|
|
888
1004
|
const ownerVer = busy && named !== null && (aboutSelf || reveal) ? version : "";
|
|
889
1005
|
const pos = typeof queue.position === "number" ? queue.position : null;
|
|
890
|
-
const posText = pos === null ? "
|
|
891
|
-
const posNote = pos === null ? "" : pos === 1 ? "
|
|
1006
|
+
const posText = pos === null ? copyText("panel.queue.pos-absent", l) : copyText("panel.queue.pos-n", l, { n: pos });
|
|
1007
|
+
const posNote = pos === null ? "" : pos === 1 ? copyText("panel.queue.pos-next", l) : copyText("panel.queue.pos-ahead", l, { n: pos - 1 });
|
|
892
1008
|
const rows = [
|
|
893
|
-
`<div class="dsh-upd-qrow"><span class="dsh-upd-qdot" data-tone="${busy ? "busy" : "idle"}"></span><span class="dsh-upd-qk"
|
|
894
|
-
`<div class="dsh-upd-qrow"><span class="dsh-upd-qdot" data-tone="you"></span><span class="dsh-upd-qk"
|
|
1009
|
+
`<div class="dsh-upd-qrow"><span class="dsh-upd-qdot" data-tone="${busy ? "busy" : "idle"}"></span><span class="dsh-upd-qk">${escapeHtml(copyText("panel.queue.row-installing", l))}</span><span class="dsh-upd-qv">${escapeHtml(ownerShown + ownerVer)}</span><span class="dsh-upd-qn">${escapeHtml(busy ? copyText("panel.queue.row-installing-note", l) : copyText("panel.queue.row-idle-note", l))}</span></div>`,
|
|
1010
|
+
`<div class="dsh-upd-qrow"><span class="dsh-upd-qdot" data-tone="you"></span><span class="dsh-upd-qk">${escapeHtml(copyText("panel.queue.row-position", l))}</span><span class="dsh-upd-qv">${escapeHtml(posText)}</span><span class="dsh-upd-qn">${escapeHtml(posNote)}</span></div>`
|
|
895
1011
|
];
|
|
896
1012
|
if (reveal && queue.waiting.length > 0) {
|
|
897
1013
|
const seq = queue.waiting.map((e) => `${e.pluginId}${e.targetVersion ? `@${e.targetVersion}` : ""}`).join(" \u2192 ");
|
|
898
1014
|
rows.push(
|
|
899
|
-
`<div class="dsh-upd-qrow"><span class="dsh-upd-qdot"></span><span class="dsh-upd-qk"
|
|
1015
|
+
`<div class="dsh-upd-qrow"><span class="dsh-upd-qdot"></span><span class="dsh-upd-qk">${escapeHtml(copyText("panel.queue.row-order", l))}</span><span class="dsh-upd-qseq">${escapeHtml(seq)}</span></div>`
|
|
900
1016
|
);
|
|
901
1017
|
}
|
|
902
|
-
const note = showActions ? `<span class="dsh-upd-chap-note"><button type="button" data-action="toggle-queue">${reveal ? "
|
|
903
|
-
chapters.push(chapterOf(3, `<div class="dsh-upd-queue">${rows.join("")}</div>`, note));
|
|
1018
|
+
const note = showActions ? `<span class="dsh-upd-chap-note"><button type="button" data-action="toggle-queue">${escapeHtml(reveal ? copyText("panel.queue.toggle-hide", l) : copyText("panel.queue.toggle-show", l))}</button></span>` : "";
|
|
1019
|
+
chapters.push(chapterOf(3, `<div class="dsh-upd-queue">${rows.join("")}</div>`, note, l));
|
|
904
1020
|
} else {
|
|
905
1021
|
chapters.push(
|
|
906
1022
|
chapterOf(
|
|
907
1023
|
3,
|
|
908
1024
|
`<div class="dsh-upd-queue"><div class="dsh-upd-changelog-neutral">${escapeHtml(
|
|
909
|
-
view.queueNote ?? "
|
|
910
|
-
)}</div></div
|
|
1025
|
+
view.queueNote ?? copyText("panel.queue.empty", l)
|
|
1026
|
+
)}</div></div>`,
|
|
1027
|
+
"",
|
|
1028
|
+
l
|
|
911
1029
|
)
|
|
912
1030
|
);
|
|
913
1031
|
}
|
|
@@ -919,70 +1037,84 @@ ${changelogHTML}
|
|
|
919
1037
|
if (failedNow) {
|
|
920
1038
|
const shownCode = b.kind === "blocked" ? snapshot?.blockedReason ?? b.kind : typeof input.lastError === "string" && input.lastError.trim() ? input.lastError : "install-failed";
|
|
921
1039
|
errLines.push(
|
|
922
|
-
`<div class="dsh-upd-err"
|
|
1040
|
+
`<div class="dsh-upd-err">${escapeHtml(copyText("panel.error.code-label", l))} <code>${escapeHtml(String(shownCode))}</code>${l === "en" ? ":" : "\uFF1A"}${escapeHtml(copyText("panel.error.code-note", l))}</div>`
|
|
923
1041
|
);
|
|
924
1042
|
if (b.kind === "failed" && failRef) {
|
|
925
1043
|
const keys = [];
|
|
926
|
-
if (typeof failRef.requestId === "string" && failRef.requestId) keys.push(
|
|
927
|
-
if (typeof failRef.checkId === "string" && failRef.checkId) keys.push(
|
|
928
|
-
const at = formatLatchTime(failRef.atMs);
|
|
929
|
-
if (at) keys.push(
|
|
1044
|
+
if (typeof failRef.requestId === "string" && failRef.requestId) keys.push(`${escapeHtml(copyText("panel.error.query-request", l))} <code>${escapeHtml(failRef.requestId)}</code>`);
|
|
1045
|
+
if (typeof failRef.checkId === "string" && failRef.checkId) keys.push(`${escapeHtml(copyText("panel.error.query-check", l))} <code>${escapeHtml(failRef.checkId)}</code>`);
|
|
1046
|
+
const at = formatLatchTime(failRef.atMs, input.lang ?? l);
|
|
1047
|
+
if (at) keys.push(`${escapeHtml(copyText("panel.error.failed-at", l, { time: at }))}`);
|
|
930
1048
|
if (keys.length > 0) {
|
|
931
|
-
errLines.push(`<div class="dsh-upd-err"
|
|
1049
|
+
errLines.push(`<div class="dsh-upd-err">${copyText("panel.error.query-keys", l, { keys: keys.join(" \xB7 ") })}</div>`);
|
|
932
1050
|
}
|
|
933
1051
|
if (!failRef.volatile) {
|
|
934
1052
|
errLines.push(
|
|
935
|
-
`<div class="dsh-upd-err"
|
|
1053
|
+
`<div class="dsh-upd-err">${escapeHtml(copyText("panel.error.evidence-frozen", l))}</div>`
|
|
936
1054
|
);
|
|
937
1055
|
} else {
|
|
938
1056
|
errLines.push(
|
|
939
|
-
`<div class="dsh-upd-err"
|
|
1057
|
+
`<div class="dsh-upd-err">${escapeHtml(copyText("panel.error.evidence-transient", l))}</div>`
|
|
940
1058
|
);
|
|
941
1059
|
}
|
|
942
1060
|
}
|
|
943
1061
|
} else {
|
|
944
|
-
errLines.push(`<div class="dsh-upd-changelog-neutral"
|
|
1062
|
+
errLines.push(`<div class="dsh-upd-changelog-neutral">${escapeHtml(copyText("panel.error.no-failure", l))}</div>`);
|
|
945
1063
|
}
|
|
946
1064
|
if (input.showLogHint !== false) {
|
|
947
1065
|
errLines.push(
|
|
948
|
-
`<div class="dsh-upd-log"
|
|
1066
|
+
`<div class="dsh-upd-log">${copyText("panel.error.log-hint", l, {
|
|
1067
|
+
pluginId: `<code>${escapeHtml(pluginId)}</code>`,
|
|
1068
|
+
e1: `<code>${LOG_EVENT_CALL}</code>`,
|
|
1069
|
+
e2: `<code>${LOG_EVENT_CALL_FAIL}</code>`,
|
|
1070
|
+
e3: `<code>${LOG_EVENT_INSTALL_EXEC}</code>`
|
|
1071
|
+
})}</div>`
|
|
949
1072
|
);
|
|
950
1073
|
if (b.kind === "failed" && failRef && (failRef.requestId || failRef.checkId)) {
|
|
951
1074
|
errLines.push(
|
|
952
|
-
`<div class="dsh-upd-log"
|
|
1075
|
+
`<div class="dsh-upd-log">${copyText("panel.error.log-follow", l, {
|
|
1076
|
+
eFail: `<code>${LOG_EVENT_CALL_FAIL}</code>`,
|
|
1077
|
+
eCall: `<code>${LOG_EVENT_CALL}</code>`,
|
|
1078
|
+
eExec: `<code>${LOG_EVENT_INSTALL_EXEC}</code>`
|
|
1079
|
+
})}</div>`
|
|
953
1080
|
);
|
|
954
1081
|
}
|
|
955
1082
|
}
|
|
956
1083
|
if (copyNotice) errLines.push(`<div class="dsh-upd-copy" role="status">${escapeHtml(copyNotice)}</div>`);
|
|
957
|
-
chapters.push(chapterOf(4, errLines.join("")));
|
|
1084
|
+
chapters.push(chapterOf(4, errLines.join(""), "", l));
|
|
958
1085
|
}
|
|
959
1086
|
chapters.push(
|
|
960
1087
|
chapterOf(
|
|
961
1088
|
5,
|
|
962
|
-
view.showManual && manual ? `<div class="dsh-upd-manual"><div
|
|
1089
|
+
view.showManual && manual ? `<div class="dsh-upd-manual"><div>${escapeHtml(copyText("panel.manual.heading", l))}</div><code>${escapeHtml(manual)}</code></div>` : `<div class="dsh-upd-manual"><div class="dsh-upd-changelog-neutral">${escapeHtml(copyText("panel.manual.absent", l))}</div></div>`,
|
|
1090
|
+
"",
|
|
1091
|
+
l
|
|
963
1092
|
)
|
|
964
1093
|
);
|
|
965
1094
|
parts.push('<div class="dsh-upd-body">' + chapters.join("\n") + "</div>");
|
|
966
1095
|
if (showActions && mode === "dialog") {
|
|
967
1096
|
parts.push(
|
|
968
|
-
|
|
1097
|
+
'<div class="dsh-upd-footer"><span class="dsh-upd-foot-note">' + escapeHtml(copyText("panel.footer.note", l)) + `</span><button type="button" data-action="close-view" title="${escapeHtml(copyText("panel.footer.close-title", l))}">${escapeHtml(copyText("panel.footer.close", l))}</button></div>`
|
|
969
1098
|
);
|
|
970
1099
|
}
|
|
971
1100
|
return parts.join("\n");
|
|
972
1101
|
}
|
|
973
|
-
function renderUpdatePanelHTML(input) {
|
|
974
|
-
const
|
|
975
|
-
const
|
|
976
|
-
const
|
|
977
|
-
const
|
|
1102
|
+
function renderUpdatePanelHTML(input, lang) {
|
|
1103
|
+
const l = normalizeLangTag(lang ?? input.lang ?? "zh");
|
|
1104
|
+
const view = panelViewModel(input, l);
|
|
1105
|
+
const kernel = renderUpdatePanelKernel(input, view, l);
|
|
1106
|
+
const archive = normalizePanelTheme(input.theme) === "archive";
|
|
1107
|
+
const attr = archive ? ' data-theme="archive"' : "";
|
|
1108
|
+
const tokensStyle = themeTokensStyleFor(input.themeTokens ?? void 0);
|
|
1109
|
+
const tokensAttr = tokensStyle ? ` style="${tokensStyle}"` : "";
|
|
978
1110
|
const sealAttr = ` data-seal="${escapeHtml(view.seal.text)}" data-seal-tone="${view.seal.tone}"`;
|
|
979
|
-
const body = input.mode === "dialog" ? `<div class="dsh-upd-overlay" data-mode="dialog"><div class="dsh-upd" data-mode="dialog" data-plugin="${escapeHtml(input.pluginId)}"${sealAttr}${attr}>
|
|
1111
|
+
const body = input.mode === "dialog" ? `<div class="dsh-upd-overlay" data-mode="dialog"><div class="dsh-upd" data-mode="dialog" data-plugin="${escapeHtml(input.pluginId)}"${sealAttr}${attr}${tokensAttr}>
|
|
980
1112
|
${kernel}
|
|
981
|
-
</div></div>` : `<div class="dsh-upd" data-mode="embedded" data-plugin="${escapeHtml(input.pluginId)}"${sealAttr}${attr}>
|
|
1113
|
+
</div></div>` : `<div class="dsh-upd" data-mode="embedded" data-plugin="${escapeHtml(input.pluginId)}"${sealAttr}${attr}${tokensAttr}>
|
|
982
1114
|
${kernel}
|
|
983
1115
|
</div>`;
|
|
984
|
-
const css =
|
|
985
|
-
${
|
|
1116
|
+
const css = archive ? `${UPDATE_PANEL_CSS}
|
|
1117
|
+
${UPDATE_PANEL_ARCHIVE_CSS}` : UPDATE_PANEL_CSS;
|
|
986
1118
|
return `<style>${css}</style>
|
|
987
1119
|
${body}`;
|
|
988
1120
|
}
|
|
@@ -1076,17 +1208,33 @@ function mountUpdatePanel(container, options) {
|
|
|
1076
1208
|
if (mode !== "embedded" && mode !== "dialog") {
|
|
1077
1209
|
throw new Error(`[dsh-plugin-update] \u6446\u653E\u5F62\u6001\u975E\u6CD5\uFF1A\u53EA\u6536 embedded \u6216 dialog\uFF08\u6536\u5230 ${JSON.stringify(options.mode)}\uFF09`);
|
|
1078
1210
|
}
|
|
1079
|
-
if (options.theme !== void 0 && options.theme !== "default" && options.theme !== "archive"
|
|
1080
|
-
throw new Error(`[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\
|
|
1211
|
+
if (options.theme !== void 0 && options.theme !== "default" && options.theme !== "archive") {
|
|
1212
|
+
throw new Error(`[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\uFF08\u6536\u5230 ${JSON.stringify(options.theme)}\uFF09`);
|
|
1081
1213
|
}
|
|
1082
1214
|
let theme = normalizePanelTheme(options.theme ?? "default");
|
|
1215
|
+
themeTokensStyleFor(options.themeTokens ?? void 0);
|
|
1216
|
+
let themeTokens = options.themeTokens;
|
|
1217
|
+
const localeOpt = options.locale ?? void 0;
|
|
1218
|
+
if (localeOpt !== void 0 && localeOpt !== null) {
|
|
1219
|
+
const isStr = typeof localeOpt === "string";
|
|
1220
|
+
const isObj = typeof localeOpt === "object" && typeof localeOpt.getActive === "function";
|
|
1221
|
+
if (!isStr && !isObj) {
|
|
1222
|
+
throw new Error("[dsh-plugin-update] invalid locale: expected zh / en / BCP47 or { getActive(), subscribe? }");
|
|
1223
|
+
}
|
|
1224
|
+
if (isStr && !localeOpt.trim()) {
|
|
1225
|
+
throw new Error("[dsh-plugin-update] invalid locale: empty string");
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
function currentLang() {
|
|
1229
|
+
return resolveLang(localeOpt);
|
|
1230
|
+
}
|
|
1083
1231
|
let showOthers = options.showOthers === true;
|
|
1084
1232
|
let changelogCollapsed = false;
|
|
1085
1233
|
const call = options.call;
|
|
1086
1234
|
const onRestartRequested = options.onRestartRequested;
|
|
1087
1235
|
const onCloseRequested = typeof options.onCloseRequested === "function" ? options.onCloseRequested : null;
|
|
1088
1236
|
let lastHTML = "";
|
|
1089
|
-
const
|
|
1237
|
+
const copyTextOut = options.copyText ?? defaultCopyText;
|
|
1090
1238
|
const skipStore = options.skipStore ?? createBrowserSkipStore(pluginId);
|
|
1091
1239
|
const hostKind = typeof options.hostKind === "string" && options.hostKind ? options.hostKind : null;
|
|
1092
1240
|
const profileNameOption = typeof options.profileName === "string" && options.profileName ? options.profileName : null;
|
|
@@ -1271,12 +1419,86 @@ function mountUpdatePanel(container, options) {
|
|
|
1271
1419
|
let envHostKind = null;
|
|
1272
1420
|
function sayCopy(text) {
|
|
1273
1421
|
copyNotice = text;
|
|
1422
|
+
}
|
|
1423
|
+
function sayCopyKey(key, values) {
|
|
1424
|
+
try {
|
|
1425
|
+
copyNotice = copyText(key, currentLang(), values);
|
|
1426
|
+
} catch {
|
|
1427
|
+
copyNotice = copyText(key, "zh", values);
|
|
1428
|
+
}
|
|
1274
1429
|
try {
|
|
1275
1430
|
noticeExpiresAt = Date.now() + 5e3;
|
|
1276
1431
|
} catch {
|
|
1277
1432
|
noticeExpiresAt = 0;
|
|
1278
1433
|
}
|
|
1279
1434
|
}
|
|
1435
|
+
function setStableHTML(target, html) {
|
|
1436
|
+
try {
|
|
1437
|
+
const g = globalThis;
|
|
1438
|
+
const doc = g["document"];
|
|
1439
|
+
const el = target;
|
|
1440
|
+
if (!doc || typeof el.querySelectorAll !== "function") {
|
|
1441
|
+
target.innerHTML = html;
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
let focusAction = null;
|
|
1445
|
+
try {
|
|
1446
|
+
const active = doc.activeElement;
|
|
1447
|
+
if (active && typeof active.getAttribute === "function") {
|
|
1448
|
+
focusAction = active.getAttribute("data-action");
|
|
1449
|
+
}
|
|
1450
|
+
} catch {
|
|
1451
|
+
focusAction = null;
|
|
1452
|
+
}
|
|
1453
|
+
let scrolls = [];
|
|
1454
|
+
try {
|
|
1455
|
+
const nodes = el.querySelectorAll(".dsh-upd-body");
|
|
1456
|
+
if (nodes) {
|
|
1457
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
1458
|
+
const n = nodes[i];
|
|
1459
|
+
scrolls.push(typeof n.scrollTop === "number" ? n.scrollTop : 0);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
} catch {
|
|
1463
|
+
scrolls = [];
|
|
1464
|
+
}
|
|
1465
|
+
target.innerHTML = html;
|
|
1466
|
+
try {
|
|
1467
|
+
const bodies = el.querySelectorAll(".dsh-upd-body");
|
|
1468
|
+
if (bodies) {
|
|
1469
|
+
for (let i = 0; i < bodies.length && i < scrolls.length; i++) {
|
|
1470
|
+
const n = bodies[i];
|
|
1471
|
+
try {
|
|
1472
|
+
n.scrollTop = scrolls[i];
|
|
1473
|
+
} catch {
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
} catch {
|
|
1478
|
+
}
|
|
1479
|
+
try {
|
|
1480
|
+
if (focusAction && typeof el.querySelector === "function") {
|
|
1481
|
+
const next = el.querySelector('[data-action="' + focusAction + '"]');
|
|
1482
|
+
if (next && typeof next.focus === "function") {
|
|
1483
|
+
try {
|
|
1484
|
+
next.focus.call(next, { preventScroll: true });
|
|
1485
|
+
} catch {
|
|
1486
|
+
try {
|
|
1487
|
+
next.focus.call(next);
|
|
1488
|
+
} catch {
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
} catch {
|
|
1494
|
+
}
|
|
1495
|
+
} catch {
|
|
1496
|
+
try {
|
|
1497
|
+
target.innerHTML = html;
|
|
1498
|
+
} catch {
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1280
1502
|
function queueArgs() {
|
|
1281
1503
|
return { includeQueue: true, includeEnv: true, showOthers, ...requestId ? { requestId } : {} };
|
|
1282
1504
|
}
|
|
@@ -1289,11 +1511,13 @@ function mountUpdatePanel(container, options) {
|
|
|
1289
1511
|
}
|
|
1290
1512
|
const latest = snapshot?.latestVersion ?? null;
|
|
1291
1513
|
const skippedLatest = !!latest && validReleaseVersion(latest) && skipStore.has(latest);
|
|
1514
|
+
const langNow = currentLang();
|
|
1292
1515
|
const nextHTML = renderUpdatePanelHTML({
|
|
1293
1516
|
snapshot,
|
|
1294
1517
|
manual,
|
|
1295
1518
|
queue,
|
|
1296
1519
|
busyAct,
|
|
1520
|
+
lang: langNow,
|
|
1297
1521
|
skippedLatest,
|
|
1298
1522
|
lastError: latch?.code ?? null,
|
|
1299
1523
|
errorKind: latch?.kind ?? null,
|
|
@@ -1306,13 +1530,14 @@ function mountUpdatePanel(container, options) {
|
|
|
1306
1530
|
pluginId,
|
|
1307
1531
|
copyNotice,
|
|
1308
1532
|
theme,
|
|
1533
|
+
themeTokens,
|
|
1309
1534
|
// 使用范围与宿主种类:调用方显式传的优先,否则用宿主回的真值。
|
|
1310
1535
|
profileName: profileNameOption ?? envProfileName,
|
|
1311
1536
|
hostKind: hostKind ?? envHostKind
|
|
1312
1537
|
});
|
|
1313
1538
|
if (nextHTML !== lastHTML) {
|
|
1314
1539
|
lastHTML = nextHTML;
|
|
1315
|
-
container
|
|
1540
|
+
setStableHTML(container, nextHTML);
|
|
1316
1541
|
}
|
|
1317
1542
|
}
|
|
1318
1543
|
function applyStatusReply(reply, via) {
|
|
@@ -1456,7 +1681,7 @@ function mountUpdatePanel(container, options) {
|
|
|
1456
1681
|
case "check": {
|
|
1457
1682
|
if (busyAct) return;
|
|
1458
1683
|
busyAct = "check";
|
|
1459
|
-
copyNotice = "
|
|
1684
|
+
copyNotice = copyText("panel.toast.checking", currentLang());
|
|
1460
1685
|
render();
|
|
1461
1686
|
try {
|
|
1462
1687
|
const reply = await call(phoneNames.updateCheck, queueArgs());
|
|
@@ -1468,7 +1693,13 @@ function mountUpdatePanel(container, options) {
|
|
|
1468
1693
|
setLatch(userThrowLatch("check", err));
|
|
1469
1694
|
} finally {
|
|
1470
1695
|
busyAct = null;
|
|
1471
|
-
|
|
1696
|
+
try {
|
|
1697
|
+
const zh = copyText("panel.toast.checking", "zh");
|
|
1698
|
+
const en = copyText("panel.toast.checking", "en");
|
|
1699
|
+
if (copyNotice === zh || copyNotice === en) copyNotice = null;
|
|
1700
|
+
} catch {
|
|
1701
|
+
copyNotice = null;
|
|
1702
|
+
}
|
|
1472
1703
|
}
|
|
1473
1704
|
render();
|
|
1474
1705
|
maybeAutoChangelog();
|
|
@@ -1477,7 +1708,7 @@ function mountUpdatePanel(container, options) {
|
|
|
1477
1708
|
case "install": {
|
|
1478
1709
|
if (busyAct) return;
|
|
1479
1710
|
busyAct = "install";
|
|
1480
|
-
copyNotice = "
|
|
1711
|
+
copyNotice = copyText("panel.toast.installing", currentLang());
|
|
1481
1712
|
render();
|
|
1482
1713
|
try {
|
|
1483
1714
|
if (!receipt) {
|
|
@@ -1528,7 +1759,13 @@ function mountUpdatePanel(container, options) {
|
|
|
1528
1759
|
setLatch(userThrowLatch("install", err));
|
|
1529
1760
|
} finally {
|
|
1530
1761
|
busyAct = null;
|
|
1531
|
-
|
|
1762
|
+
try {
|
|
1763
|
+
const zh = copyText("panel.toast.installing", "zh");
|
|
1764
|
+
const en = copyText("panel.toast.installing", "en");
|
|
1765
|
+
if (copyNotice === zh || copyNotice === en) copyNotice = null;
|
|
1766
|
+
} catch {
|
|
1767
|
+
copyNotice = null;
|
|
1768
|
+
}
|
|
1532
1769
|
}
|
|
1533
1770
|
render();
|
|
1534
1771
|
maybeAutoChangelog();
|
|
@@ -1556,10 +1793,10 @@ function mountUpdatePanel(container, options) {
|
|
|
1556
1793
|
case "copy-manual": {
|
|
1557
1794
|
if (manual) {
|
|
1558
1795
|
try {
|
|
1559
|
-
await
|
|
1560
|
-
|
|
1796
|
+
await copyTextOut(manual);
|
|
1797
|
+
sayCopyKey("panel.toast.copy-manual-ok");
|
|
1561
1798
|
} catch {
|
|
1562
|
-
|
|
1799
|
+
sayCopyKey("panel.toast.copy-manual-fail");
|
|
1563
1800
|
}
|
|
1564
1801
|
}
|
|
1565
1802
|
render();
|
|
@@ -1585,10 +1822,10 @@ function mountUpdatePanel(container, options) {
|
|
|
1585
1822
|
].map((s) => redactForCopy(s));
|
|
1586
1823
|
const text2 = diagCopyFormat === "line" ? segs.join(" \xB7 ") : segs.join("\n");
|
|
1587
1824
|
try {
|
|
1588
|
-
await
|
|
1589
|
-
|
|
1825
|
+
await copyTextOut(text2);
|
|
1826
|
+
sayCopyKey("panel.toast.copy-state-ok");
|
|
1590
1827
|
} catch {
|
|
1591
|
-
|
|
1828
|
+
sayCopyKey("panel.toast.copy-diag-fail");
|
|
1592
1829
|
}
|
|
1593
1830
|
render();
|
|
1594
1831
|
return;
|
|
@@ -1611,20 +1848,21 @@ function mountUpdatePanel(container, options) {
|
|
|
1611
1848
|
route: null,
|
|
1612
1849
|
diag: frozen?.diag ?? null,
|
|
1613
1850
|
manual,
|
|
1614
|
-
format: diagCopyFormat
|
|
1851
|
+
format: diagCopyFormat,
|
|
1852
|
+
lang: currentLang()
|
|
1615
1853
|
});
|
|
1616
1854
|
try {
|
|
1617
|
-
await
|
|
1618
|
-
|
|
1855
|
+
await copyTextOut(text);
|
|
1856
|
+
sayCopyKey("panel.toast.copy-diag-ok");
|
|
1619
1857
|
} catch {
|
|
1620
|
-
|
|
1858
|
+
sayCopyKey("panel.toast.copy-diag-fail");
|
|
1621
1859
|
}
|
|
1622
1860
|
render();
|
|
1623
1861
|
return;
|
|
1624
1862
|
}
|
|
1625
1863
|
case "dismiss-failure": {
|
|
1626
1864
|
clearLatch();
|
|
1627
|
-
|
|
1865
|
+
sayCopyKey("panel.toast.failure-dismissed");
|
|
1628
1866
|
render();
|
|
1629
1867
|
return;
|
|
1630
1868
|
}
|
|
@@ -1644,12 +1882,12 @@ function mountUpdatePanel(container, options) {
|
|
|
1644
1882
|
try {
|
|
1645
1883
|
if (typeof onRestartRequested === "function") {
|
|
1646
1884
|
await onRestartRequested();
|
|
1647
|
-
|
|
1885
|
+
sayCopyKey("panel.toast.restart-delegated");
|
|
1648
1886
|
} else {
|
|
1649
|
-
|
|
1887
|
+
sayCopyKey("panel.toast.restart-manual");
|
|
1650
1888
|
}
|
|
1651
1889
|
} catch {
|
|
1652
|
-
|
|
1890
|
+
sayCopyKey("panel.toast.restart-failed");
|
|
1653
1891
|
}
|
|
1654
1892
|
render();
|
|
1655
1893
|
return;
|
|
@@ -1668,12 +1906,17 @@ function mountUpdatePanel(container, options) {
|
|
|
1668
1906
|
render();
|
|
1669
1907
|
}
|
|
1670
1908
|
async function setTheme(next) {
|
|
1671
|
-
if (next !== "default" && next !== "archive"
|
|
1672
|
-
throw new Error(`[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\
|
|
1909
|
+
if (next !== "default" && next !== "archive") {
|
|
1910
|
+
throw new Error(`[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\uFF08\u6536\u5230 ${JSON.stringify(next)}\uFF09`);
|
|
1673
1911
|
}
|
|
1674
1912
|
theme = normalizePanelTheme(next);
|
|
1675
1913
|
render();
|
|
1676
1914
|
}
|
|
1915
|
+
async function setThemeTokens(next) {
|
|
1916
|
+
themeTokensStyleFor(next ?? void 0);
|
|
1917
|
+
themeTokens = next ?? void 0;
|
|
1918
|
+
render();
|
|
1919
|
+
}
|
|
1677
1920
|
async function setShowOthers(show) {
|
|
1678
1921
|
showOthers = show === true;
|
|
1679
1922
|
await refresh();
|
|
@@ -1718,6 +1961,10 @@ function mountUpdatePanel(container, options) {
|
|
|
1718
1961
|
function unmount() {
|
|
1719
1962
|
if (!mounted) return;
|
|
1720
1963
|
mounted = false;
|
|
1964
|
+
try {
|
|
1965
|
+
unsubLang();
|
|
1966
|
+
} catch {
|
|
1967
|
+
}
|
|
1721
1968
|
autoSeq++;
|
|
1722
1969
|
changelogInflight.clear();
|
|
1723
1970
|
try {
|
|
@@ -1733,6 +1980,9 @@ function mountUpdatePanel(container, options) {
|
|
|
1733
1980
|
} catch {
|
|
1734
1981
|
}
|
|
1735
1982
|
}
|
|
1983
|
+
const unsubLang = subscribeLang(() => {
|
|
1984
|
+
render();
|
|
1985
|
+
}, localeOpt);
|
|
1736
1986
|
render();
|
|
1737
1987
|
try {
|
|
1738
1988
|
container.addEventListener?.("click", onClick);
|
|
@@ -1744,6 +1994,7 @@ function mountUpdatePanel(container, options) {
|
|
|
1744
1994
|
}
|
|
1745
1995
|
const timer = getTimer();
|
|
1746
1996
|
const handle = timer.set(() => {
|
|
1997
|
+
if (busyAct) return;
|
|
1747
1998
|
void refresh();
|
|
1748
1999
|
}, pollMs);
|
|
1749
2000
|
try {
|
|
@@ -1758,7 +2009,7 @@ function mountUpdatePanel(container, options) {
|
|
|
1758
2009
|
} catch {
|
|
1759
2010
|
}
|
|
1760
2011
|
})();
|
|
1761
|
-
return { refresh, act, setMode, setTheme, setShowOthers, setChangelogCollapsed, setChangelogMarkdown, unmount };
|
|
2012
|
+
return { refresh, act, setMode, setTheme, setThemeTokens, setShowOthers, setChangelogCollapsed, setChangelogMarkdown, unmount };
|
|
1762
2013
|
}
|
|
1763
2014
|
import { buildPhoneNames as buildPhoneNames2 } from "./config.js";
|
|
1764
2015
|
import { buildChangelogPhoneName as buildChangelogPhoneName2 } from "./config.js";
|
|
@@ -1809,8 +2060,8 @@ export {
|
|
|
1809
2060
|
PANEL_DIAG_MAX_CHARS,
|
|
1810
2061
|
PANEL_POLL,
|
|
1811
2062
|
QUEUE_INTENT_TTL_MS,
|
|
2063
|
+
UPDATE_PANEL_ARCHIVE_CSS,
|
|
1812
2064
|
UPDATE_PANEL_CSS,
|
|
1813
|
-
UPDATE_PANEL_D5_CSS,
|
|
1814
2065
|
blockedCopy,
|
|
1815
2066
|
buildDiagnosticText,
|
|
1816
2067
|
buildChangelogPhoneName2 as buildPanelChangelogPhoneName,
|
|
@@ -1827,10 +2078,12 @@ export {
|
|
|
1827
2078
|
isHeadOfQueue,
|
|
1828
2079
|
isKnownFailureCode,
|
|
1829
2080
|
isQueueBusy,
|
|
2081
|
+
isSafeThemeCssValue,
|
|
1830
2082
|
isUnreleasedVersion,
|
|
1831
2083
|
mountUpdatePanel,
|
|
1832
2084
|
normalizePanelTheme,
|
|
1833
2085
|
normalizeQueueState,
|
|
2086
|
+
panelSealFor,
|
|
1834
2087
|
panelViewModel,
|
|
1835
2088
|
parseChangelog2 as parseChangelog,
|
|
1836
2089
|
pendingAutoCheck,
|
|
@@ -1843,5 +2096,6 @@ export {
|
|
|
1843
2096
|
renderUpdatePanelHTML,
|
|
1844
2097
|
renderUpdatePanelKernel,
|
|
1845
2098
|
selectChangelogEntries,
|
|
2099
|
+
themeTokensStyleFor,
|
|
1846
2100
|
visibleQueueFor2 as visibleQueueFor
|
|
1847
2101
|
};
|