dsh-plugin-update 0.6.0 → 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 +4 -0
- package/README.md +24 -2
- package/dist/entry-batch.d.ts +5 -1
- package/dist/entry-batch.js +15 -3
- package/dist/entry.d.ts +7 -3
- package/dist/entry.js +16 -4
- package/dist/panel-batch.d.ts +7 -1
- package/dist/panel-batch.js +16 -3
- package/dist/panel.d.ts +50 -1
- package/dist/panel.js +115 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
格式为 Keep-a-Changelog 子集:`Added/Fixed/Changed` 必写,`Deprecated/Removed/Security` 有则透传,`Unreleased` 面板忽略,禁止 git-log 直倒。面板缺日志时中性提示,不挡安装。
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2026-10-06
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- 主题变量覆盖 `themeTokens`(第三方换肤一等口径):单面板、批量面板、入口件、批量入口件四个挂载口同收同语义(35 个语义键对 `--dsh-update-*` 变量,颜色收 hex 或英文名,其余走注入检查,非法挂载即抛);内联写根、变量继承,入口件打开的 dialog 同步透传,批量展开的详情行经继承生效;控制器同步新增 `setThemeTokens`(传 `undefined` 即清掉覆盖);被覆盖的 token 不再跟随深色媒体查询。README 补换肤章节与键表。
|
|
5
9
|
## [0.6.0] - 2026-10-06
|
|
6
10
|
|
|
7
11
|
### Changed
|
package/README.md
CHANGED
|
@@ -142,8 +142,30 @@ mountUpdatePanel(slot, { pluginId: 'my-notes-plugin', prefix: 'notes', call: hos
|
|
|
142
142
|
|
|
143
143
|
面板画成档案五章:**01 检查与安装、02 更新日志、03 更新队列、04 错误信息、05 手工命令**(五章恒在,缺内容给中性提示,不跳号)。档案头一行是「插件名 + 使用范围 + `profile` 牌」:使用范围由面板自动向宿主索取(电话入参 `includeEnv`,宿主只回**范围名与宿主种类**、不回任何路径),显示的就是更新要落到的那个 profile——`web` 与 `desktop` 各装一份,装错范围是严重故障,所以这一栏宁可显示“未知”也不猜。调用方知道得更准时可以用 `profileName` 显式覆盖。
|
|
144
144
|
|
|
145
|
-
可选档案卷主题(纸面浅色案卷风,不替换默认):挂载时加 `theme: 'archive'` 即换肤(右上大印章「待查/可装/安装中/待重启/受阻/已最新」+ 横幅小印章一字 + profile 牌 + 待重启衬线横幅配手绘 SVG 标 + 窄屏印章固定 + 省略号逐字折叠 + 浅深双主题跟随系统),内核 DOM 顺序不动、复制诊断常在;不传即最小可用默认深色样式。运行时用 `panel.setTheme('archive' | 'default')`
|
|
146
|
-
|
|
145
|
+
可选档案卷主题(纸面浅色案卷风,不替换默认):挂载时加 `theme: 'archive'` 即换肤(右上大印章「待查/可装/安装中/待重启/受阻/已最新」+ 横幅小印章一字 + profile 牌 + 待重启衬线横幅配手绘 SVG 标 + 窄屏印章固定 + 省略号逐字折叠 + 浅深双主题跟随系统),内核 DOM 顺序不动、复制诊断常在;不传即最小可用默认深色样式。运行时用 `panel.setTheme('archive' | 'default')` 可切。入口件与批量面板是同一个 `theme` 参数,取值同一套。
|
|
146
|
+
|
|
147
|
+
主题变量覆盖(第三方换肤):四个 UI 口(单面板、批量面板、入口件、批量入口件)都收 `themeTokens`,键为语义名,一次传入即换肤,不传即零回归。入口件打开的 dialog 面板同步透传;运行时用 `setThemeTokens({...})` 即时换肤,传 `undefined` 即清掉覆盖:
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
mountUpdatePanel(el, { pluginId: 'p', prefix: 'notes', call,
|
|
151
|
+
theme: 'archive',
|
|
152
|
+
themeTokens: { primary: '#c8402a', bg: '#fffdf6', radiusButton: '3px' },
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
键与样式表里的 `--dsh-update-*` 变量一一对应(括号里是变量名),手写 CSS 变量等价生效:
|
|
157
|
+
|
|
158
|
+
| 组 | 键(变量) |
|
|
159
|
+
|---|---|
|
|
160
|
+
| 文字背景边线 | `text`、`textMuted`、`bg`、`bgSoft`、`border`、`borderStrong`、`buttonBg` |
|
|
161
|
+
| 主色焦点 | `primary`、`primaryDeep`、`focus` |
|
|
162
|
+
| 状态四组 | `okBg / okBorder / okText`、`warnBg / warnBorder / warnText`、`badBg / badBorder / badText`、`busyBg / busyBorder / busyText` |
|
|
163
|
+
| 字体阴影 | `fontSans`、`fontSerif`、`fontMono`、`shadow` |
|
|
164
|
+
| 圆角 | `radiusPanel`、`radiusButton`、`radiusBadge` |
|
|
165
|
+
| 入口件尺寸 | `entryFontSize`、`entryPadding`、`entryBorderRadius`、`entryScale`(数字,大于 0) |
|
|
166
|
+
|
|
167
|
+
三条约束:颜色只收 hex(`#rgb`/`#rrggbb`/`#rrggbbaa`)或英文名单词(含 `transparent`),`rgb()`/`color-mix()` 请自行换算成 hex;其余值走注入检查(分号引号括号等不许过,见 `sizing` 同口径);未知键与非法值挂载即抛错,不静默吞掉。被覆盖的 token 不再跟随深色模式(内联值固定,调用方自己保证深浅可读)。
|
|
168
|
+
|
|
147
169
|
类型定义随包分发(`dsh-plugin-update/panel` 的 `.d.ts`),不用自编译;面板离线可读,与包版本绑定。
|
|
148
170
|
|
|
149
171
|
整组件 HTTP 版(无 `host.call` 环境即跑:浏览器面板经 HTTP POST 直达宿主网关,只传三样):
|
package/dist/entry-batch.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type BilingualKey } from './bilingual.js';
|
|
2
2
|
import { type AppLang, type LocaleOption } from './lang.js';
|
|
3
3
|
import { type BatchRowView } from './panel-batch.js';
|
|
4
|
-
import { type UpdatePanelTheme } from './panel.js';
|
|
4
|
+
import { type UpdatePanelTheme, type UpdateThemeTokens } from './panel.js';
|
|
5
5
|
/** 批量入口件的形态(与单入口同一套取值)。 */
|
|
6
6
|
export type BatchEntryVariant = 'button' | 'badge' | 'inline';
|
|
7
7
|
/** 什么时候主动查一次(只读;与单入口同一口径)。 */
|
|
@@ -42,6 +42,8 @@ export interface UpdateBatchEntryOptions {
|
|
|
42
42
|
variant?: BatchEntryVariant;
|
|
43
43
|
/** 主题:与单入口/面板同一套(default/archive)。 */
|
|
44
44
|
theme?: UpdatePanelTheme;
|
|
45
|
+
/** 主题变量覆盖:见 panel 的 UpdateThemeTokens;批量入口根 + 打开的批量面板同步生效,不传即零回归。 */
|
|
46
|
+
themeTokens?: UpdateThemeTokens;
|
|
45
47
|
/** 缺省 'mount':进页面静默查一次(只调 .batchStatus,只读)。'never' 则只在用户点击时查。 */
|
|
46
48
|
autoCheck?: BatchEntryAutoCheck;
|
|
47
49
|
/** 打开面板自动查(#59 D3,透传给批量面板):缺省 true;面板按用户偏好 > 本选项 > 缺省,并与入口预查共用知识时间戳去重(一击只查一次)。 */
|
|
@@ -82,6 +84,8 @@ export interface UpdateBatchEntryController {
|
|
|
82
84
|
/** 当前聚合读数(含七档计数,接入方排版与 onActivate 共用)。 */
|
|
83
85
|
summary(): BatchEntrySummary;
|
|
84
86
|
setTheme(theme: UpdatePanelTheme): void;
|
|
87
|
+
/** 换一套主题变量(重绘;打开的批量面板同步;传 undefined 即清掉覆盖)。 */
|
|
88
|
+
setThemeTokens(tokens: UpdateThemeTokens | undefined): void;
|
|
85
89
|
unmount(): void;
|
|
86
90
|
}
|
|
87
91
|
/**
|
package/dist/entry-batch.js
CHANGED
|
@@ -11,7 +11,8 @@ import {
|
|
|
11
11
|
} from "./panel-batch.js";
|
|
12
12
|
import {
|
|
13
13
|
failureCodeOf,
|
|
14
|
-
normalizePanelTheme
|
|
14
|
+
normalizePanelTheme,
|
|
15
|
+
themeTokensStyleFor
|
|
15
16
|
} from "./panel.js";
|
|
16
17
|
function isObject(value) {
|
|
17
18
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -149,6 +150,8 @@ function mountUpdateBatchEntry(container, options) {
|
|
|
149
150
|
throw new Error("[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\uFF08\u6536\u5230 " + JSON.stringify(options.theme) + "\uFF09");
|
|
150
151
|
}
|
|
151
152
|
let theme = normalizePanelTheme(options.theme ?? "default");
|
|
153
|
+
themeTokensStyleFor(options.themeTokens ?? void 0);
|
|
154
|
+
let themeTokens = options.themeTokens;
|
|
152
155
|
const pollMs = options.pollMs;
|
|
153
156
|
if (pollMs !== void 0 && (typeof pollMs !== "number" || !Number.isFinite(pollMs) || pollMs < MIN_PANEL_POLL_MS)) {
|
|
154
157
|
throw new Error("[dsh-plugin-update] \u9762\u677F\u8F6E\u8BE2\u95F4\u9694\u975E\u6CD5\uFF1A\u4E0D\u5F97\u5C0F\u4E8E 250 \u6BEB\u79D2\uFF08\u6536\u5230 " + JSON.stringify(options.pollMs) + "\uFF09");
|
|
@@ -220,9 +223,11 @@ function mountUpdateBatchEntry(container, options) {
|
|
|
220
223
|
const labelText = labelOverride ?? (activating ? copyText("batch-entry.action.checking", lang) : copyText(batchEntryBilingualKeyFor(stateOf()), lang, batchEntryBilingualValuesFor(stateOf())));
|
|
221
224
|
const busyAttr = activating ? ' disabled aria-busy="true"' : "";
|
|
222
225
|
const themeAttr = theme === "archive" ? ' data-theme="archive"' : "";
|
|
226
|
+
const tokensStyle = themeTokensStyleFor(themeTokens ?? void 0);
|
|
227
|
+
const tokensAttr = tokensStyle ? ' style="' + tokensStyle + '"' : "";
|
|
223
228
|
const control = variant === "badge" ? '<button type="button" class="dsh-upd-entry-dot" ' + ENTRY_ATTR + '="activate" title="' + escapeHtml(labelText) + '" aria-label="' + escapeHtml(labelText) + '"' + busyAttr + "></button>" : '<button type="button" class="dsh-upd-entry-btn" ' + ENTRY_ATTR + '="activate"' + busyAttr + ">" + labelHTML + "</button>";
|
|
224
229
|
const noteHTML = note ? '<span class="dsh-upd-entry-note" data-dsh-upd-note="1">' + escapeHtml(note) + "</span>" : "";
|
|
225
|
-
return "<style>" + UPDATE_ENTRY_CSS + "\n" + BILINGUAL_CSS + '</style>\n<span class="dsh-upd-entry" data-variant="' + variant + '" data-state="' + summary.kind + '"' + themeAttr + ">" + control + noteHTML + "</span>";
|
|
230
|
+
return "<style>" + UPDATE_ENTRY_CSS + "\n" + BILINGUAL_CSS + '</style>\n<span class="dsh-upd-entry" data-variant="' + variant + '" data-state="' + summary.kind + '"' + themeAttr + tokensAttr + ">" + control + noteHTML + "</span>";
|
|
226
231
|
}
|
|
227
232
|
function render() {
|
|
228
233
|
if (!mounted) return;
|
|
@@ -267,6 +272,7 @@ function mountUpdateBatchEntry(container, options) {
|
|
|
267
272
|
prefix: options.prefix,
|
|
268
273
|
mode,
|
|
269
274
|
theme,
|
|
275
|
+
themeTokens,
|
|
270
276
|
pollMs,
|
|
271
277
|
titles,
|
|
272
278
|
onRestartRequested: options.onRestartRequested,
|
|
@@ -346,6 +352,12 @@ function mountUpdateBatchEntry(container, options) {
|
|
|
346
352
|
if (panel) void panel.setTheme(theme);
|
|
347
353
|
else render();
|
|
348
354
|
}
|
|
355
|
+
function setThemeTokens(next) {
|
|
356
|
+
themeTokensStyleFor(next ?? void 0);
|
|
357
|
+
themeTokens = next ?? void 0;
|
|
358
|
+
if (panel) void panel.setThemeTokens(themeTokens);
|
|
359
|
+
else render();
|
|
360
|
+
}
|
|
349
361
|
function onClick(ev) {
|
|
350
362
|
if (!mounted) return;
|
|
351
363
|
try {
|
|
@@ -408,7 +420,7 @@ function mountUpdateBatchEntry(container, options) {
|
|
|
408
420
|
if (variant === "inline") mountPanel("embedded");
|
|
409
421
|
else render();
|
|
410
422
|
if (autoCheck === "mount") void refresh();
|
|
411
|
-
return { refresh, open, close, label: currentLabel, summary: summaryOf, setTheme, unmount };
|
|
423
|
+
return { refresh, open, close, label: currentLabel, summary: summaryOf, setTheme, setThemeTokens, unmount };
|
|
412
424
|
}
|
|
413
425
|
export {
|
|
414
426
|
batchEntryBilingualHTMLFor,
|
package/dist/entry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type UpdatePanelContainer, type UpdatePanelTheme } from './panel.js';
|
|
1
|
+
import { type UpdatePanelContainer, type UpdatePanelTheme, type UpdateThemeTokens } from './panel.js';
|
|
2
2
|
import type { UpdateSnapshot } from './ports.js';
|
|
3
3
|
import { type BilingualKey } from './bilingual.js';
|
|
4
4
|
import { type AppLang, type LocaleOption } from './lang.js';
|
|
@@ -24,7 +24,7 @@ export interface UpdateEntryState {
|
|
|
24
24
|
/**
|
|
25
25
|
* 入口件按钮尺寸覆盖(#69):只影响 button 本体(字号/内边距/圆角/整体缩放),不碰 dialog 面板。
|
|
26
26
|
* 缺省(不传)保持现状、零回归;badge 圆点与 inline 内嵌不读这些变量,天然不受影响。
|
|
27
|
-
* 实现口径与现有 `--dsh-
|
|
27
|
+
* 实现口径与现有 `--dsh-update-*` 颜色变量一致:本选项只是把同样的 CSS 变量以内联方式写到容器上,
|
|
28
28
|
* 手写 CSS 变量(`--dsh-update-entry-font-size` / `--dsh-update-entry-padding` /
|
|
29
29
|
* `--dsh-update-entry-border-radius` / `--dsh-update-entry-scale`)同样生效,两者等价。
|
|
30
30
|
* `scale` 即宿主临时方案里容器 `zoom: 1` 开关的正式形态:改一个数即缩放(默认 1)。
|
|
@@ -46,7 +46,7 @@ export interface UpdateEntryOptions {
|
|
|
46
46
|
/** 调宿主电话:(phoneName, args) => Promise<reply>。 */
|
|
47
47
|
call: (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
48
48
|
variant?: EntryVariant;
|
|
49
|
-
/**
|
|
49
|
+
/** 主题:与面板同一套(`default` 最小可用,`archive` 档案卷纸面浅色)。 */
|
|
50
50
|
theme?: UpdatePanelTheme;
|
|
51
51
|
/** 缺省 'mount':进页面静默查一次(只读)。'never' 则只在用户点击时查。 */
|
|
52
52
|
autoCheck?: EntryAutoCheck;
|
|
@@ -56,6 +56,8 @@ export interface UpdateEntryOptions {
|
|
|
56
56
|
label?: string;
|
|
57
57
|
/** 按钮尺寸覆盖(#69):见 EntrySizing;不传即零回归,badge/inline 不受影响。 */
|
|
58
58
|
sizing?: EntrySizing;
|
|
59
|
+
/** 主题变量覆盖:见 panel 的 UpdateThemeTokens;入口件根 + 打开的 dialog 面板同步生效,不传即零回归。 */
|
|
60
|
+
themeTokens?: UpdateThemeTokens;
|
|
59
61
|
/** 语言覆盖(#60 v2):'zh' | 'en' | { getActive(): string; subscribe?(cb): () => void },不传即跟随 html[lang] > navigator > zh。 */
|
|
60
62
|
locale?: LocaleOption;
|
|
61
63
|
profileName?: string;
|
|
@@ -82,6 +84,8 @@ export interface UpdateEntryController {
|
|
|
82
84
|
/** 当前按钮上的状态文案(接入方做自定义排版时读它)。 */
|
|
83
85
|
label(): string;
|
|
84
86
|
setTheme(theme: UpdatePanelTheme): void;
|
|
87
|
+
/** 换一套主题变量(重绘;打开的 dialog 面板同步;传 undefined 即清掉覆盖)。 */
|
|
88
|
+
setThemeTokens(tokens: UpdateThemeTokens | undefined): void;
|
|
85
89
|
unmount(): void;
|
|
86
90
|
}
|
|
87
91
|
/**
|
package/dist/entry.js
CHANGED
|
@@ -3,7 +3,8 @@ import { DEFAULT_PREFIX, MIN_PANEL_POLL_MS, buildPhoneNames } from "./config.js"
|
|
|
3
3
|
import {
|
|
4
4
|
failureCodeOf,
|
|
5
5
|
mountUpdatePanel,
|
|
6
|
-
normalizePanelTheme
|
|
6
|
+
normalizePanelTheme,
|
|
7
|
+
themeTokensStyleFor
|
|
7
8
|
} from "./panel.js";
|
|
8
9
|
import { BILINGUAL_CSS, copyHTML, copyText } from "./bilingual.js";
|
|
9
10
|
import { resolveLang, subscribeLang } from "./lang.js";
|
|
@@ -188,7 +189,8 @@ function mountUpdateEntry(container, options) {
|
|
|
188
189
|
}
|
|
189
190
|
const labelOverride = typeof options.label === "string" && options.label ? options.label : null;
|
|
190
191
|
const sizingStyle = entrySizingStyleFor(options.sizing ?? void 0);
|
|
191
|
-
|
|
192
|
+
themeTokensStyleFor(options.themeTokens ?? void 0);
|
|
193
|
+
let themeTokens = options.themeTokens;
|
|
192
194
|
const localeOpt = options.locale ?? void 0;
|
|
193
195
|
if (localeOpt !== void 0 && localeOpt !== null) {
|
|
194
196
|
const isStr = typeof localeOpt === "string";
|
|
@@ -250,11 +252,14 @@ function mountUpdateEntry(container, options) {
|
|
|
250
252
|
const labelText = labelOverride ?? (activating ? copyText("entry.action.checking", lang) : copyText(entryBilingualKeyFor(stateOf()), lang, entryBilingualValuesFor(stateOf())));
|
|
251
253
|
const busyAttr = activating ? ' disabled aria-busy="true"' : "";
|
|
252
254
|
const themeAttr = theme === "archive" ? ' data-theme="archive"' : "";
|
|
255
|
+
const tokensStyle = themeTokensStyleFor(themeTokens ?? void 0);
|
|
256
|
+
const styleBody = [sizingStyle, tokensStyle].filter((part) => part).join(";");
|
|
257
|
+
const styleAttr = styleBody ? ` style="${styleBody}"` : "";
|
|
253
258
|
const control = variant === "badge" ? `<button type="button" class="dsh-upd-entry-dot" ${ENTRY_ATTR}="activate" title="${escapeHtml(labelText)}" aria-label="${escapeHtml(labelText)}"${busyAttr}></button>` : `<button type="button" class="dsh-upd-entry-btn" ${ENTRY_ATTR}="activate"${busyAttr}>${labelHTML}</button>`;
|
|
254
259
|
const noteHTML = noteVersion ? `<span class="dsh-upd-entry-note" data-dsh-upd-note="1">${copyHTML("entry.note.up-to-date", lang, { version: noteVersion })}</span>` : "";
|
|
255
260
|
return `<style>${UPDATE_ENTRY_CSS}
|
|
256
261
|
${BILINGUAL_CSS}</style>
|
|
257
|
-
<span class="dsh-upd-entry" data-variant="${variant}" data-state="${kind}"${themeAttr}${
|
|
262
|
+
<span class="dsh-upd-entry" data-variant="${variant}" data-state="${kind}"${themeAttr}${styleAttr}>${control}${noteHTML}</span>`;
|
|
258
263
|
}
|
|
259
264
|
function render() {
|
|
260
265
|
if (!mounted) return;
|
|
@@ -299,6 +304,7 @@ ${BILINGUAL_CSS}</style>
|
|
|
299
304
|
prefix,
|
|
300
305
|
mode,
|
|
301
306
|
theme,
|
|
307
|
+
themeTokens,
|
|
302
308
|
pollMs,
|
|
303
309
|
profileName,
|
|
304
310
|
autoChangelog: options.autoChangelog,
|
|
@@ -366,6 +372,12 @@ ${BILINGUAL_CSS}</style>
|
|
|
366
372
|
if (panel) void panel.setTheme(theme);
|
|
367
373
|
else render();
|
|
368
374
|
}
|
|
375
|
+
function setThemeTokens(next) {
|
|
376
|
+
themeTokensStyleFor(next ?? void 0);
|
|
377
|
+
themeTokens = next ?? void 0;
|
|
378
|
+
if (panel) void panel.setThemeTokens(themeTokens);
|
|
379
|
+
else render();
|
|
380
|
+
}
|
|
369
381
|
function onClick(ev) {
|
|
370
382
|
if (!mounted) return;
|
|
371
383
|
try {
|
|
@@ -424,7 +436,7 @@ ${BILINGUAL_CSS}</style>
|
|
|
424
436
|
if (variant === "inline") mountPanel("embedded");
|
|
425
437
|
else render();
|
|
426
438
|
if (autoCheck === "mount") void refresh();
|
|
427
|
-
return { refresh, open, close, label: currentLabel, setTheme, unmount };
|
|
439
|
+
return { refresh, open, close, label: currentLabel, setTheme, setThemeTokens, unmount };
|
|
428
440
|
}
|
|
429
441
|
export {
|
|
430
442
|
UPDATE_ENTRY_CSS,
|
package/dist/panel-batch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type UpdatePanelTheme } from './panel.js';
|
|
1
|
+
import { type UpdatePanelTheme, type UpdateThemeTokens } from './panel.js';
|
|
2
2
|
/** 一行要画的东西(宿主回包里的形状)。 */
|
|
3
3
|
export interface BatchRowView {
|
|
4
4
|
key: string;
|
|
@@ -32,6 +32,8 @@ export interface BatchPanelOptions {
|
|
|
32
32
|
call: (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
33
33
|
/** 主题:与单插件面板同一套(缺省 default)。 */
|
|
34
34
|
theme?: UpdatePanelTheme;
|
|
35
|
+
/** 主题变量覆盖:见 panel 的 UpdateThemeTokens;批量根 + 展开详情行全继承,不传即零回归。 */
|
|
36
|
+
themeTokens?: UpdateThemeTokens;
|
|
35
37
|
/** 摆放形态:内嵌或弹窗(缺省 embedded)。 */
|
|
36
38
|
mode?: BatchPanelMode;
|
|
37
39
|
/** 轮询间隔(毫秒,缺省 1500,下限 250)。 */
|
|
@@ -82,6 +84,8 @@ export interface BatchPanelController {
|
|
|
82
84
|
refresh(): Promise<void>;
|
|
83
85
|
act(action: BatchPanelActionKind, key?: string): Promise<void>;
|
|
84
86
|
setTheme(theme: UpdatePanelTheme): void;
|
|
87
|
+
/** 换一套主题变量(重绘;传 undefined 即清掉覆盖,回主题默认)。 */
|
|
88
|
+
setThemeTokens(tokens: UpdateThemeTokens | undefined): void;
|
|
85
89
|
setMode(mode: BatchPanelMode): void;
|
|
86
90
|
unmount(): void;
|
|
87
91
|
}
|
|
@@ -159,6 +163,8 @@ export declare function batchRowKnowledgeText(row: BatchRowView, entry: BatchKno
|
|
|
159
163
|
export interface BatchPanelRenderInput {
|
|
160
164
|
rows?: readonly BatchRowView[];
|
|
161
165
|
theme?: UpdatePanelTheme;
|
|
166
|
+
/** 主题变量覆盖:见 panel 的 UpdateThemeTokens;写到批量根上,详情行经继承生效。 */
|
|
167
|
+
themeTokens?: UpdateThemeTokens;
|
|
162
168
|
mode?: BatchPanelMode;
|
|
163
169
|
/** 当前展开的那一家(键);null 即全部收起。 */
|
|
164
170
|
expandedKey?: string | null;
|
package/dist/panel-batch.js
CHANGED
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
failureCopy,
|
|
17
17
|
isKnownFailureCode,
|
|
18
18
|
normalizePanelTheme,
|
|
19
|
-
renderUpdatePanelHTML
|
|
19
|
+
renderUpdatePanelHTML,
|
|
20
|
+
themeTokensStyleFor
|
|
20
21
|
} from "./panel.js";
|
|
21
22
|
const BATCH_PANEL_POLL = {
|
|
22
23
|
defaultMs: 1500,
|
|
@@ -198,6 +199,7 @@ function renderBatchPanelHTML(input) {
|
|
|
198
199
|
busy: installing,
|
|
199
200
|
inFlight: input.inFlight === true,
|
|
200
201
|
theme,
|
|
202
|
+
themeTokens: input.themeTokens ?? void 0,
|
|
201
203
|
titles,
|
|
202
204
|
skipped: null,
|
|
203
205
|
notice: null,
|
|
@@ -285,8 +287,10 @@ function renderBatchPanelHTML(input) {
|
|
|
285
287
|
const kernel = parts.join(String.fromCharCode(10));
|
|
286
288
|
const archive = normalizePanelTheme(theme) === "archive";
|
|
287
289
|
const attr = archive ? ' data-theme="archive"' : "";
|
|
290
|
+
const tokensStyle = themeTokensStyleFor(input.themeTokens ?? void 0);
|
|
291
|
+
const tokensAttr = tokensStyle ? ' style="' + tokensStyle + '"' : "";
|
|
288
292
|
const seal = batchSealOf(counts, lang);
|
|
289
|
-
const root = '<div class="dsh-upd dsh-upd-batch" data-mode="' + mode + '" data-seal="' + escapeHtml(seal.text) + '" data-seal-tone="' + seal.tone + '"' + attr + ">\n" + kernel + "\n</div>";
|
|
293
|
+
const root = '<div class="dsh-upd dsh-upd-batch" data-mode="' + mode + '" data-seal="' + escapeHtml(seal.text) + '" data-seal-tone="' + seal.tone + '"' + attr + tokensAttr + ">\n" + kernel + "\n</div>";
|
|
290
294
|
const body = mode === "dialog" ? '<div class="dsh-upd-overlay" data-mode="dialog">' + root + "</div>" : root;
|
|
291
295
|
const css = archive ? [UPDATE_PANEL_CSS, UPDATE_BATCH_PANEL_CSS, UPDATE_PANEL_ARCHIVE_CSS, UPDATE_BATCH_PANEL_ARCHIVE_CSS].join(String.fromCharCode(10)) : [UPDATE_PANEL_CSS, UPDATE_BATCH_PANEL_CSS].join(String.fromCharCode(10));
|
|
292
296
|
return "<style>" + css + "</style>\n" + body;
|
|
@@ -411,6 +415,7 @@ function detailHTML(row, ctx) {
|
|
|
411
415
|
pluginId: pluginIdOf(row),
|
|
412
416
|
copyNotice: null,
|
|
413
417
|
theme: ctx.theme,
|
|
418
|
+
themeTokens: ctx.themeTokens,
|
|
414
419
|
profileName: typeof row.profileName === "string" && row.profileName ? row.profileName : null,
|
|
415
420
|
actions: "none"
|
|
416
421
|
}, ctx.lang);
|
|
@@ -762,6 +767,8 @@ function mountUpdateBatchPanel(container, options) {
|
|
|
762
767
|
throw new Error("[dsh-plugin-update] \u4E3B\u9898\u975E\u6CD5\uFF1A\u53EA\u6536 default \u6216 archive\uFF08\u6536\u5230 " + JSON.stringify(options.theme) + "\uFF09");
|
|
763
768
|
}
|
|
764
769
|
let theme = normalizePanelTheme(options.theme ?? "default");
|
|
770
|
+
themeTokensStyleFor(options.themeTokens ?? void 0);
|
|
771
|
+
let themeTokens = options.themeTokens;
|
|
765
772
|
const call = options.call;
|
|
766
773
|
const titles = options.titles && typeof options.titles === "object" ? options.titles : {};
|
|
767
774
|
const onRestartRequested = options.onRestartRequested;
|
|
@@ -952,6 +959,7 @@ function mountUpdateBatchPanel(container, options) {
|
|
|
952
959
|
const nextHTML = renderBatchPanelHTML({
|
|
953
960
|
rows,
|
|
954
961
|
theme,
|
|
962
|
+
themeTokens,
|
|
955
963
|
mode,
|
|
956
964
|
expandedKey,
|
|
957
965
|
lastError,
|
|
@@ -1273,6 +1281,11 @@ function mountUpdateBatchPanel(container, options) {
|
|
|
1273
1281
|
theme = normalizePanelTheme(next);
|
|
1274
1282
|
render();
|
|
1275
1283
|
}
|
|
1284
|
+
function setThemeTokens(next) {
|
|
1285
|
+
themeTokensStyleFor(next ?? void 0);
|
|
1286
|
+
themeTokens = next ?? void 0;
|
|
1287
|
+
render();
|
|
1288
|
+
}
|
|
1276
1289
|
function setMode(next) {
|
|
1277
1290
|
if (next !== "embedded" && next !== "dialog") {
|
|
1278
1291
|
throw new Error("[dsh-plugin-update] \u6446\u653E\u5F62\u6001\u975E\u6CD5\uFF1A\u53EA\u6536 embedded \u6216 dialog\uFF08\u6536\u5230 " + JSON.stringify(next) + "\uFF09");
|
|
@@ -1396,7 +1409,7 @@ function mountUpdateBatchPanel(container, options) {
|
|
|
1396
1409
|
void refresh().then(() => {
|
|
1397
1410
|
void autoOnce();
|
|
1398
1411
|
});
|
|
1399
|
-
return { refresh, act, setTheme, setMode, unmount };
|
|
1412
|
+
return { refresh, act, setTheme, setThemeTokens, setMode, unmount };
|
|
1400
1413
|
}
|
|
1401
1414
|
export {
|
|
1402
1415
|
BATCH_PANEL_POLL,
|
package/dist/panel.d.ts
CHANGED
|
@@ -6,7 +6,6 @@ export type UpdatePanelMode = 'embedded' | 'dialog';
|
|
|
6
6
|
/** 面板主题:默认最小可用样式;`archive` 为档案卷纸面浅色(只换肤,不换 DOM 顺序)。 */
|
|
7
7
|
/**
|
|
8
8
|
* 面板主题:`default` 最小可用深色;`archive` 档案卷纸面浅色(原型敲定的案卷风格,只换肤)。
|
|
9
|
-
* `archive` 是 archive 的旧别名(历史取值),仍可用,渲染逐字相同。
|
|
10
9
|
*/
|
|
11
10
|
export type UpdatePanelTheme = 'default' | 'archive';
|
|
12
11
|
/**
|
|
@@ -14,6 +13,50 @@ export type UpdatePanelTheme = 'default' | 'archive';
|
|
|
14
13
|
* 其余一律回 default(纯渲染函数永不抛;挂载/setTheme 的非法值另行抛错)。
|
|
15
14
|
*/
|
|
16
15
|
export declare function normalizePanelTheme(value: unknown): 'default' | 'archive';
|
|
16
|
+
/** 第三方主题变量覆盖:键为语义名;颜色收 hex(#rgb/#rrggbb/#rrggbbaa)或英文名单词;其余收安全 CSS 值;缺省即主题默认值,零回归。 */
|
|
17
|
+
export interface UpdateThemeTokens {
|
|
18
|
+
text?: string;
|
|
19
|
+
textMuted?: string;
|
|
20
|
+
bg?: string;
|
|
21
|
+
bgSoft?: string;
|
|
22
|
+
border?: string;
|
|
23
|
+
borderStrong?: string;
|
|
24
|
+
buttonBg?: string;
|
|
25
|
+
primary?: string;
|
|
26
|
+
primaryDeep?: string;
|
|
27
|
+
focus?: string;
|
|
28
|
+
okBg?: string;
|
|
29
|
+
okBorder?: string;
|
|
30
|
+
okText?: string;
|
|
31
|
+
warnBg?: string;
|
|
32
|
+
warnBorder?: string;
|
|
33
|
+
warnText?: string;
|
|
34
|
+
badBg?: string;
|
|
35
|
+
badBorder?: string;
|
|
36
|
+
badText?: string;
|
|
37
|
+
busyBg?: string;
|
|
38
|
+
busyBorder?: string;
|
|
39
|
+
busyText?: string;
|
|
40
|
+
fontSans?: string;
|
|
41
|
+
fontSerif?: string;
|
|
42
|
+
fontMono?: string;
|
|
43
|
+
shadow?: string;
|
|
44
|
+
radiusPanel?: string;
|
|
45
|
+
radiusButton?: string;
|
|
46
|
+
radiusBadge?: string;
|
|
47
|
+
entryFontSize?: string;
|
|
48
|
+
entryPadding?: string;
|
|
49
|
+
entryBorderRadius?: string;
|
|
50
|
+
/** 入口件整体缩放(对应 CSS `zoom`),须为大于 0 的有限数。 */
|
|
51
|
+
entryScale?: number;
|
|
52
|
+
}
|
|
53
|
+
/** CSS 值最小安全检查(与入口件 sizing 同口径):放 style 属性前先拦掉注入。 */
|
|
54
|
+
export declare function isSafeThemeCssValue(value: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* `themeTokens` → 根 style 属性体(纯函数:同一输入永远算出同一串;空/缺省回空串,即不写 style)。
|
|
57
|
+
* 非法即抛(未知键、空串、注入字符、颜色形状不对、非正有限 entryScale 都不收)。
|
|
58
|
+
*/
|
|
59
|
+
export declare function themeTokensStyleFor(tokens: UpdateThemeTokens | null | undefined): string;
|
|
17
60
|
/** 与宿主通话的传输函数:面板只认这个签名,不认任何宿主对象的具体形状。 */
|
|
18
61
|
export type UpdatePanelCall = (phoneName: string, args: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
19
62
|
/** 复制文本的出口:不传即尝试浏览器剪贴板,都没有则只留“已生成、请手动复制”提示。 */
|
|
@@ -29,6 +72,8 @@ export interface UpdatePanelOptions {
|
|
|
29
72
|
mode?: UpdatePanelMode;
|
|
30
73
|
/** 面板主题:默认 `default`(最小可用样式,一字不动);传 `archive` 切档案卷。 */
|
|
31
74
|
theme?: UpdatePanelTheme;
|
|
75
|
+
/** 主题变量覆盖:见 UpdateThemeTokens;两个主题通用,不传即零回归。 */
|
|
76
|
+
themeTokens?: UpdateThemeTokens;
|
|
32
77
|
/** 是否看他人排队明细:默认只看自己的(他人仅露正忙占位,位置照给)。 */
|
|
33
78
|
showOthers?: boolean;
|
|
34
79
|
/** 是否显示深挖日志指引:默认显示;面向纯终端用户的嵌入可关(失败证据行不受影响)。 */
|
|
@@ -90,6 +135,8 @@ export interface UpdatePanelController {
|
|
|
90
135
|
setMode(mode: UpdatePanelMode): Promise<void>;
|
|
91
136
|
/** 切换主题(同一内核重绘,只换肤;默认主题输出与旧版一字不差)。 */
|
|
92
137
|
setTheme(theme: UpdatePanelTheme): Promise<void>;
|
|
138
|
+
/** 换一套主题变量(同一内核重绘,只换变量;传 undefined 即清掉覆盖,回主题默认)。 */
|
|
139
|
+
setThemeTokens(tokens: UpdateThemeTokens | undefined): Promise<void>;
|
|
93
140
|
/** 切换排队可见性(重查一次,位置口径不变)。 */
|
|
94
141
|
setShowOthers(show: boolean): Promise<void>;
|
|
95
142
|
/** 收起/展开更新日志(纯视图态,不调电话;轮询与换肤不丢)。 */
|
|
@@ -256,6 +303,8 @@ export interface PanelRenderInput extends PanelViewInput {
|
|
|
256
303
|
lang?: AppLang | string | null;
|
|
257
304
|
/** 可选主题:不传即默认(输出与旧版一字不差);`archive` 切档案卷。 */
|
|
258
305
|
theme?: UpdatePanelTheme;
|
|
306
|
+
/** 主题变量覆盖:见 UpdateThemeTokens;写到面板根上,不传即无 style 属性。 */
|
|
307
|
+
themeTokens?: UpdateThemeTokens;
|
|
259
308
|
/** 使用范围名(profile):面板「使用范围」一栏的唯一来源,缺省显示“未知”,不猜。 */
|
|
260
309
|
profileName?: string | null;
|
|
261
310
|
/** 宿主种类:进诊断文本;缺省显示“未知”。 */
|
package/dist/panel.js
CHANGED
|
@@ -15,6 +15,106 @@ import { normalizeLangTag, resolveLang, subscribeLang } from "./lang.js";
|
|
|
15
15
|
function normalizePanelTheme(value) {
|
|
16
16
|
return value === "archive" ? "archive" : "default";
|
|
17
17
|
}
|
|
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);
|
|
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
|
+
}
|
|
18
118
|
const BLOCKED_KEYS = {
|
|
19
119
|
"unknown-profile": { title: "panel.blocked.unknown-profile.title", action: "panel.blocked.unknown-profile.action" },
|
|
20
120
|
"source-install": { title: "panel.blocked.source-install.title", action: "panel.blocked.source-install.action" },
|
|
@@ -1005,10 +1105,12 @@ function renderUpdatePanelHTML(input, lang) {
|
|
|
1005
1105
|
const kernel = renderUpdatePanelKernel(input, view, l);
|
|
1006
1106
|
const archive = normalizePanelTheme(input.theme) === "archive";
|
|
1007
1107
|
const attr = archive ? ' data-theme="archive"' : "";
|
|
1108
|
+
const tokensStyle = themeTokensStyleFor(input.themeTokens ?? void 0);
|
|
1109
|
+
const tokensAttr = tokensStyle ? ` style="${tokensStyle}"` : "";
|
|
1008
1110
|
const sealAttr = ` data-seal="${escapeHtml(view.seal.text)}" data-seal-tone="${view.seal.tone}"`;
|
|
1009
|
-
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}>
|
|
1010
1112
|
${kernel}
|
|
1011
|
-
</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}>
|
|
1012
1114
|
${kernel}
|
|
1013
1115
|
</div>`;
|
|
1014
1116
|
const css = archive ? `${UPDATE_PANEL_CSS}
|
|
@@ -1110,6 +1212,8 @@ function mountUpdatePanel(container, options) {
|
|
|
1110
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`);
|
|
1111
1213
|
}
|
|
1112
1214
|
let theme = normalizePanelTheme(options.theme ?? "default");
|
|
1215
|
+
themeTokensStyleFor(options.themeTokens ?? void 0);
|
|
1216
|
+
let themeTokens = options.themeTokens;
|
|
1113
1217
|
const localeOpt = options.locale ?? void 0;
|
|
1114
1218
|
if (localeOpt !== void 0 && localeOpt !== null) {
|
|
1115
1219
|
const isStr = typeof localeOpt === "string";
|
|
@@ -1426,6 +1530,7 @@ function mountUpdatePanel(container, options) {
|
|
|
1426
1530
|
pluginId,
|
|
1427
1531
|
copyNotice,
|
|
1428
1532
|
theme,
|
|
1533
|
+
themeTokens,
|
|
1429
1534
|
// 使用范围与宿主种类:调用方显式传的优先,否则用宿主回的真值。
|
|
1430
1535
|
profileName: profileNameOption ?? envProfileName,
|
|
1431
1536
|
hostKind: hostKind ?? envHostKind
|
|
@@ -1807,6 +1912,11 @@ function mountUpdatePanel(container, options) {
|
|
|
1807
1912
|
theme = normalizePanelTheme(next);
|
|
1808
1913
|
render();
|
|
1809
1914
|
}
|
|
1915
|
+
async function setThemeTokens(next) {
|
|
1916
|
+
themeTokensStyleFor(next ?? void 0);
|
|
1917
|
+
themeTokens = next ?? void 0;
|
|
1918
|
+
render();
|
|
1919
|
+
}
|
|
1810
1920
|
async function setShowOthers(show) {
|
|
1811
1921
|
showOthers = show === true;
|
|
1812
1922
|
await refresh();
|
|
@@ -1899,7 +2009,7 @@ function mountUpdatePanel(container, options) {
|
|
|
1899
2009
|
} catch {
|
|
1900
2010
|
}
|
|
1901
2011
|
})();
|
|
1902
|
-
return { refresh, act, setMode, setTheme, setShowOthers, setChangelogCollapsed, setChangelogMarkdown, unmount };
|
|
2012
|
+
return { refresh, act, setMode, setTheme, setThemeTokens, setShowOthers, setChangelogCollapsed, setChangelogMarkdown, unmount };
|
|
1903
2013
|
}
|
|
1904
2014
|
import { buildPhoneNames as buildPhoneNames2 } from "./config.js";
|
|
1905
2015
|
import { buildChangelogPhoneName as buildChangelogPhoneName2 } from "./config.js";
|
|
@@ -1968,6 +2078,7 @@ export {
|
|
|
1968
2078
|
isHeadOfQueue,
|
|
1969
2079
|
isKnownFailureCode,
|
|
1970
2080
|
isQueueBusy,
|
|
2081
|
+
isSafeThemeCssValue,
|
|
1971
2082
|
isUnreleasedVersion,
|
|
1972
2083
|
mountUpdatePanel,
|
|
1973
2084
|
normalizePanelTheme,
|
|
@@ -1985,5 +2096,6 @@ export {
|
|
|
1985
2096
|
renderUpdatePanelHTML,
|
|
1986
2097
|
renderUpdatePanelKernel,
|
|
1987
2098
|
selectChangelogEntries,
|
|
2099
|
+
themeTokensStyleFor,
|
|
1988
2100
|
visibleQueueFor2 as visibleQueueFor
|
|
1989
2101
|
};
|