@linxin666/dsh-client-ui-skin-center 0.3.20 → 0.3.21
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/contracts/semantic-attrs-v1.md +11 -3
- package/lib/client.js +97 -33
- package/lib/client.js.map +1 -1
- package/lib/index.js +22 -16
- package/package.json +1 -1
- package/skins/blue-fantasy/patches.css +369 -0
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
| `data-dsh-wallpaper-active` | html + body(body/html 级,另行管理) | WE 壁纸挂载期间置 `true`,卸载 / 禁用清除;供皮肤 CSS 与壁纸中和规则锚定(#734) |
|
|
46
46
|
| `data-dsh-wallpaper-surface` | 官方 shell 全视口背景元素 + 侧栏工作区淡化条(元素级) | `WallpaperController.markWallpaperSurfaces()` 在 WE 壁纸挂载期间打标(全视口 bg-base 背景 + `data-slot="sidebar.workspaces"` 内渐变淡化条),命中 `html[data-dsh-wallpaper-active] [data-dsh-wallpaper-surface]` 中和;卸载清除,不含哈希类依赖(#734) |
|
|
47
47
|
|
|
48
|
-
## part 组(
|
|
48
|
+
## part 组(79 行,含各 owner 行)
|
|
49
49
|
|
|
50
50
|
shell 区域(owner: shell):
|
|
51
51
|
|
|
@@ -113,13 +113,15 @@ family / 插件区域:
|
|
|
113
113
|
| `bubble` | miku-pet | 对话气泡;`[data-dsh-part="bubble"]` |
|
|
114
114
|
| `float` | miku-pet | 互动飘字;`[data-dsh-part="float"]` |
|
|
115
115
|
| `header` | usage | 使用统计分区头部(当前提供方 + 刷新钮);`[data-dsh-plugin="usage"] [data-dsh-part="header"]` |
|
|
116
|
-
| `tabs` / `tab` | usage |
|
|
116
|
+
| `tabs` / `tab` | usage | 用量/个人套餐/Token 银行页签;`[role="tablist"]` / `[role="tab"]` |
|
|
117
117
|
| `today-card` | usage | 今日用量统计卡;`[data-dsh-part="today-card"]` |
|
|
118
118
|
| `provider-list` / `provider-row` | usage | 今日分 provider 用量列表 / 余额行;卡片内行容器 |
|
|
119
119
|
| `balance-card` | usage | 各 provider 余额卡;`[data-dsh-part="balance-card"]` |
|
|
120
120
|
| `trend-card` / `usage-chart` | usage | 近 30 天卡 / 其中的提供方-模型条形图;`[data-dsh-part="trend-card"]` 内 `[data-dsh-part="usage-chart"]` |
|
|
121
121
|
| `settings-row` | usage | 插件设置行;`[data-dsh-part="settings-row"]` |
|
|
122
122
|
| `plan-card` / `plan-window` | usage | 套餐卡 / 套餐窗口行(个人套餐页签);`[data-dsh-part="plan-card"]` 内窗口行 |
|
|
123
|
+
| `bank-card` | usage | Token 银行卡(鲸元券,无官方用量时为空状态);`[data-dsh-part="bank-card"]` |
|
|
124
|
+
| `voucher-preview` | usage | 票面 canvas 容器;bank-card 内 `[data-dsh-part="voucher-preview"]` |
|
|
123
125
|
| `panel` | model-capabilities | 提供方卡片能力扩展区根;`[data-dsh-plugin="model-capabilities"][data-dsh-part="panel"]` |
|
|
124
126
|
| `toggle` | model-capabilities | 扩展区折叠头按钮;panel 内 `button[data-dsh-part="toggle"]` |
|
|
125
127
|
| `model-row` / `model-toggle` | model-capabilities | 逐模型能力行与其展开按钮;panel 内 `li[data-dsh-part="model-row"]` 及其中 `button[data-dsh-part="model-toggle"]` |
|
|
@@ -128,8 +130,13 @@ family / 插件区域:
|
|
|
128
130
|
| `save` / `reset` / `disable` / `enable` / `reload` | model-capabilities | 扩展区动作按钮(保存 / 重置 / 禁用此提供方 / 启用 / 重新读取);panel 内裸值按钮 |
|
|
129
131
|
| `disabled-state` | model-capabilities | 已禁用提供方的卡片提示区(含启用按钮);panel 内 `[data-dsh-part="disabled-state"]` |
|
|
130
132
|
| `disabled-footer` / `disabled-row` | model-capabilities | Models 页底部存档区与其行;`settings.models.footer` 槽内 `section[data-dsh-part="disabled-footer"]` 与其中 `li[data-dsh-part="disabled-row"]` |
|
|
133
|
+
| `lever` | liangshen | 首页输入框内的梁神模式拨杆根(模型选择器左侧);`[data-dsh-plugin="liangshen"][data-dsh-part="lever"]`,状态由 `data-state`(`on` / `off` / `locked` / `missing`)锚定 |
|
|
134
|
+
| `lever-track` | liangshen | 拨杆底座槽(臂的转动轨道);lever 内 `[data-dsh-part="lever-track"]` |
|
|
135
|
+
| `lever-arm` | liangshen | 拨杆臂(拉杆 + 球头,随状态转动);lever 内 `[data-dsh-part="lever-arm"]` |
|
|
136
|
+
| `lever-burst` | liangshen | 拨下命中后的中奖特效浮层(闪光 / 冲击环 / 火花 / 横幅);`[data-dsh-part="lever-burst"]`,`prefers-reduced-motion` 下退化为淡出 |
|
|
137
|
+
| `lever-banner` | liangshen | 特效中的梁神横幅(模式名 + 文言文/二进制/摩斯三行);burst 内 `[data-dsh-part="lever-banner"]` |
|
|
131
138
|
|
|
132
|
-
## plugin 组(
|
|
139
|
+
## plugin 组(15 个)
|
|
133
140
|
|
|
134
141
|
| data-dsh-plugin | owner | 锚定方式 |
|
|
135
142
|
| --- | --- | --- |
|
|
@@ -147,6 +154,7 @@ family / 插件区域:
|
|
|
147
154
|
| `usage` | dsh-usage | 一级设置分区 settings.section id `dsh-usage`(创意工坊下方);`[data-dsh-plugin="usage"]` |
|
|
148
155
|
| `model-capabilities` | dsh-model-capabilities | Models 页 `settings.models.provider-card` keyed 槽 key `llm-pi-ai`(提供方卡片扩展区)+ `settings.models.footer` 槽 entry id `ui-model-capabilities`(存档区);`[data-dsh-plugin="model-capabilities"]` |
|
|
149
156
|
| `preset-center` | dsh-preset-center | 创意工坊卡片的「预设」标签页面板(`dsh-workshop.panel` keyed 槽 key `preset`);`[data-dsh-plugin="preset-center"]` |
|
|
157
|
+
| `liangshen` | dsh-liangshen | 首页输入框内的梁神模式拨杆;`[data-dsh-plugin="liangshen"][data-dsh-part="lever"]`,slot entry id `liangshen-lever` |
|
|
150
158
|
|
|
151
159
|
## 已知脆弱点(上游主题缝 PR 诉求)
|
|
152
160
|
|
package/lib/client.js
CHANGED
|
@@ -401,6 +401,16 @@ window.__ModuleLoader__.load({
|
|
|
401
401
|
].join(", ");
|
|
402
402
|
const sourceSets = /* @__PURE__ */ new WeakMap();
|
|
403
403
|
const contentObservers = /* @__PURE__ */ new WeakMap();
|
|
404
|
+
const contentFrames = /* @__PURE__ */ new WeakMap();
|
|
405
|
+
/** Write a marker attribute only when the desired state is not applied yet. */
|
|
406
|
+
function applyMarker(el, attr, active) {
|
|
407
|
+
if (el === null) return;
|
|
408
|
+
if (active) {
|
|
409
|
+
if (el.getAttribute(attr) !== "true") el.setAttribute(attr, "true");
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (el.hasAttribute(attr)) el.removeAttribute(attr);
|
|
413
|
+
}
|
|
404
414
|
/**
|
|
405
415
|
* Report one source's backdrop-art presence. The marker stays on while any
|
|
406
416
|
* source is active, so the skin and wallpaper controllers never clobber each
|
|
@@ -418,16 +428,13 @@ window.__ModuleLoader__.load({
|
|
|
418
428
|
}
|
|
419
429
|
/** Reflect the source set onto html/body and ensure the neutralizer on use. */
|
|
420
430
|
function syncMarker(doc, sources) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
431
|
+
const active = sources.size > 0;
|
|
432
|
+
applyMarker(doc.body, BACKDROP_ACTIVE_ATTR, active);
|
|
433
|
+
applyMarker(doc.documentElement, BACKDROP_ACTIVE_ATTR, active);
|
|
434
|
+
if (active) {
|
|
424
435
|
ensureSceneNeutralizer(doc);
|
|
425
436
|
startContentObserver(doc);
|
|
426
|
-
} else
|
|
427
|
-
doc.body?.removeAttribute(BACKDROP_ACTIVE_ATTR);
|
|
428
|
-
doc.documentElement?.removeAttribute(BACKDROP_ACTIVE_ATTR);
|
|
429
|
-
stopContentObserver(doc);
|
|
430
|
-
}
|
|
437
|
+
} else stopContentObserver(doc);
|
|
431
438
|
}
|
|
432
439
|
/**
|
|
433
440
|
* Track whether the active conversation scrollport has message rows for the
|
|
@@ -436,13 +443,27 @@ window.__ModuleLoader__.load({
|
|
|
436
443
|
* those stale rows and flash the composer frost over the new empty topic.
|
|
437
444
|
*/
|
|
438
445
|
function updateConversationContent(doc) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
446
|
+
const has = doc.body !== null && doc.body.querySelector(ACTIVE_CONVERSATION_CONTENT_SELECTOR) !== null;
|
|
447
|
+
applyMarker(doc.body, CONVERSATION_CONTENT_ATTR, has);
|
|
448
|
+
applyMarker(doc.documentElement, CONVERSATION_CONTENT_ATTR, has);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Coalesce the mutation bursts of a streaming conversation into one content
|
|
452
|
+
* check per frame; a check scheduled for a document that stopped observing is
|
|
453
|
+
* dropped so a late frame can never re-add the marker after teardown.
|
|
454
|
+
*/
|
|
455
|
+
function scheduleConversationContent(doc) {
|
|
456
|
+
if (contentFrames.has(doc)) return;
|
|
457
|
+
const win = doc.defaultView;
|
|
458
|
+
if (win === null || typeof win.requestAnimationFrame !== "function") {
|
|
459
|
+
updateConversationContent(doc);
|
|
460
|
+
return;
|
|
445
461
|
}
|
|
462
|
+
contentFrames.set(doc, win.requestAnimationFrame(() => {
|
|
463
|
+
contentFrames.delete(doc);
|
|
464
|
+
if (!contentObservers.has(doc)) return;
|
|
465
|
+
updateConversationContent(doc);
|
|
466
|
+
}));
|
|
446
467
|
}
|
|
447
468
|
/** Observe the conversation tree while a backdrop is visible. */
|
|
448
469
|
function startContentObserver(doc) {
|
|
@@ -450,22 +471,28 @@ window.__ModuleLoader__.load({
|
|
|
450
471
|
updateConversationContent(doc);
|
|
451
472
|
const win = doc.defaultView;
|
|
452
473
|
if (win === null || typeof win.MutationObserver !== "function") return;
|
|
453
|
-
const observer = new win.MutationObserver(() =>
|
|
474
|
+
const observer = new win.MutationObserver(() => scheduleConversationContent(doc));
|
|
454
475
|
observer.observe(doc.body ?? doc.documentElement, {
|
|
455
476
|
childList: true,
|
|
456
477
|
subtree: true
|
|
457
478
|
});
|
|
458
479
|
contentObservers.set(doc, observer);
|
|
459
480
|
}
|
|
460
|
-
/** Stop the content observer and drop the
|
|
481
|
+
/** Stop the content observer, cancel pending work and drop the marker. */
|
|
461
482
|
function stopContentObserver(doc) {
|
|
483
|
+
const frame = contentFrames.get(doc);
|
|
484
|
+
if (frame !== void 0) {
|
|
485
|
+
const win = doc.defaultView;
|
|
486
|
+
if (win !== null && typeof win.cancelAnimationFrame === "function") win.cancelAnimationFrame(frame);
|
|
487
|
+
contentFrames.delete(doc);
|
|
488
|
+
}
|
|
462
489
|
const observer = contentObservers.get(doc);
|
|
463
490
|
if (observer !== void 0) {
|
|
464
491
|
observer.disconnect();
|
|
465
492
|
contentObservers.delete(doc);
|
|
466
493
|
}
|
|
467
|
-
doc.body
|
|
468
|
-
doc.documentElement
|
|
494
|
+
applyMarker(doc.body, CONVERSATION_CONTENT_ATTR, false);
|
|
495
|
+
applyMarker(doc.documentElement, CONVERSATION_CONTENT_ATTR, false);
|
|
469
496
|
}
|
|
470
497
|
/**
|
|
471
498
|
* Install the shared composer-seat neutralizer, keyed by head presence so a
|
|
@@ -4056,9 +4083,12 @@ window.__ModuleLoader__.load({
|
|
|
4056
4083
|
/* #1117: The upstream recommended badge pairs two background-fill tokens
|
|
4057
4084
|
as bg + text — in dark mode, skins like Blue Fantasy collapse them to
|
|
4058
4085
|
near-identical dark navy values (contrast ~1:1). Override the text
|
|
4059
|
-
color to a readable foreground and tweak the background for contrast.
|
|
4060
|
-
|
|
4061
|
-
|
|
4086
|
+
color to a readable foreground and tweak the background for contrast.
|
|
4087
|
+
The dark-theme attribute lives on <body>, so it belongs inside the
|
|
4088
|
+
scoped selector: prefixing the already-scoped list produced
|
|
4089
|
+
"body ... html ...", a descendant chain that can never match (#1490). */
|
|
4090
|
+
${scoped("body[data-ds-dark-theme] [data-question-key] [class*=\"_badge\"]")},
|
|
4091
|
+
${scoped("body[data-ds-dark-theme] [data-question-scroll] [class*=\"_badge\"]")} {
|
|
4062
4092
|
color: var(--dsw-alias-label-primary, #ffffff) !important;
|
|
4063
4093
|
background: var(--dsw-alias-interactive-bg-active, color-mix(in srgb, var(--dsw-alias-button-info-fill, #4a5fa8) 50%, transparent)) !important;
|
|
4064
4094
|
}
|
|
@@ -4076,35 +4106,62 @@ window.__ModuleLoader__.load({
|
|
|
4076
4106
|
try {
|
|
4077
4107
|
win?.scrollTo?.(0, 0);
|
|
4078
4108
|
} catch {}
|
|
4109
|
+
const composerSelector = COMPOSER_SEAT_SELECTORS.join(", ");
|
|
4079
4110
|
let resizeObserver = null;
|
|
4080
4111
|
let mutationObserver = null;
|
|
4081
4112
|
let observedComposer = null;
|
|
4113
|
+
let appliedHeight = "";
|
|
4114
|
+
let scheduledFrame = null;
|
|
4115
|
+
let disposed = false;
|
|
4116
|
+
const resolveComposer = () => {
|
|
4117
|
+
if (observedComposer !== null && observedComposer.isConnected) return observedComposer;
|
|
4118
|
+
return doc.body === null ? null : doc.body.querySelector(composerSelector);
|
|
4119
|
+
};
|
|
4082
4120
|
const syncHeight = () => {
|
|
4083
4121
|
if (doc.body === null) return;
|
|
4084
|
-
const composer =
|
|
4085
|
-
if (composer
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
}
|
|
4091
|
-
const rect = composer.getBoundingClientRect();
|
|
4092
|
-
if (rect.height > 0) doc.documentElement?.style.setProperty("--dsh-composer-height", `${Math.ceil(rect.height)}px`);
|
|
4122
|
+
const composer = resolveComposer();
|
|
4123
|
+
if (composer === null) return;
|
|
4124
|
+
if (observedComposer !== composer) {
|
|
4125
|
+
if (observedComposer !== null && resizeObserver !== null) resizeObserver.unobserve(observedComposer);
|
|
4126
|
+
observedComposer = composer;
|
|
4127
|
+
if (resizeObserver !== null) resizeObserver.observe(composer);
|
|
4093
4128
|
}
|
|
4129
|
+
const rect = composer.getBoundingClientRect();
|
|
4130
|
+
if (rect.height <= 0) return;
|
|
4131
|
+
const root = doc.documentElement;
|
|
4132
|
+
const next = `${Math.ceil(rect.height)}px`;
|
|
4133
|
+
if (next === appliedHeight || root === null) return;
|
|
4134
|
+
appliedHeight = next;
|
|
4135
|
+
root.style.setProperty("--dsh-composer-height", next);
|
|
4136
|
+
};
|
|
4137
|
+
const scheduleSync = () => {
|
|
4138
|
+
if (scheduledFrame !== null || disposed) return;
|
|
4139
|
+
if (win === null || typeof win.requestAnimationFrame !== "function") {
|
|
4140
|
+
syncHeight();
|
|
4141
|
+
return;
|
|
4142
|
+
}
|
|
4143
|
+
scheduledFrame = win.requestAnimationFrame(() => {
|
|
4144
|
+
scheduledFrame = null;
|
|
4145
|
+
if (disposed) return;
|
|
4146
|
+
syncHeight();
|
|
4147
|
+
});
|
|
4094
4148
|
};
|
|
4095
4149
|
if (win !== null && typeof win.ResizeObserver === "function") resizeObserver = new win.ResizeObserver(() => syncHeight());
|
|
4096
4150
|
if (win !== null && typeof win.MutationObserver === "function" && doc.body !== null) {
|
|
4097
|
-
mutationObserver = new win.MutationObserver(() =>
|
|
4151
|
+
mutationObserver = new win.MutationObserver(() => scheduleSync());
|
|
4098
4152
|
mutationObserver.observe(doc.body, {
|
|
4099
4153
|
childList: true,
|
|
4100
4154
|
subtree: true
|
|
4101
4155
|
});
|
|
4102
4156
|
}
|
|
4103
4157
|
syncHeight();
|
|
4104
|
-
let disposed = false;
|
|
4105
4158
|
return () => {
|
|
4106
4159
|
if (disposed) return;
|
|
4107
4160
|
disposed = true;
|
|
4161
|
+
if (scheduledFrame !== null) {
|
|
4162
|
+
if (win !== null && typeof win.cancelAnimationFrame === "function") win.cancelAnimationFrame(scheduledFrame);
|
|
4163
|
+
scheduledFrame = null;
|
|
4164
|
+
}
|
|
4108
4165
|
if (resizeObserver !== null) {
|
|
4109
4166
|
resizeObserver.disconnect();
|
|
4110
4167
|
resizeObserver = null;
|
|
@@ -4114,6 +4171,7 @@ window.__ModuleLoader__.load({
|
|
|
4114
4171
|
mutationObserver = null;
|
|
4115
4172
|
}
|
|
4116
4173
|
observedComposer = null;
|
|
4174
|
+
appliedHeight = "";
|
|
4117
4175
|
doc.documentElement?.style.removeProperty("--dsh-composer-height");
|
|
4118
4176
|
style.remove();
|
|
4119
4177
|
};
|
|
@@ -4322,22 +4380,28 @@ window.__ModuleLoader__.load({
|
|
|
4322
4380
|
function setBackgroundLayer(activation, nodes) {
|
|
4323
4381
|
const style = doc.body.style;
|
|
4324
4382
|
const previousBackgroundColor = style.getPropertyValue("background-color");
|
|
4383
|
+
const previousBackgroundImage = style.getPropertyValue("background-image");
|
|
4325
4384
|
const restore = () => {
|
|
4326
4385
|
if (currentActivation !== activation) return;
|
|
4327
4386
|
clearLayer(layers.background);
|
|
4328
4387
|
setSceneBackdropActive(doc, "skin", false);
|
|
4329
4388
|
if (previousBackgroundColor === "") style.removeProperty("background-color");
|
|
4330
4389
|
else style.setProperty("background-color", previousBackgroundColor);
|
|
4390
|
+
if (previousBackgroundImage === "") style.removeProperty("background-image");
|
|
4391
|
+
else style.setProperty("background-image", previousBackgroundImage);
|
|
4331
4392
|
};
|
|
4332
4393
|
clearLayer(layers.background);
|
|
4333
4394
|
if (nodes.length > 0) {
|
|
4334
4395
|
for (const node of nodes) layers.background.appendChild(node);
|
|
4335
4396
|
style.setProperty("background-color", "transparent");
|
|
4397
|
+
style.setProperty("background-image", "none");
|
|
4336
4398
|
setSceneBackdropActive(doc, "skin", true);
|
|
4337
4399
|
} else {
|
|
4338
4400
|
setSceneBackdropActive(doc, "skin", false);
|
|
4339
4401
|
if (previousBackgroundColor === "") style.removeProperty("background-color");
|
|
4340
4402
|
else style.setProperty("background-color", previousBackgroundColor);
|
|
4403
|
+
if (previousBackgroundImage === "") style.removeProperty("background-image");
|
|
4404
|
+
else style.setProperty("background-image", previousBackgroundImage);
|
|
4341
4405
|
}
|
|
4342
4406
|
ledger.record(activation, "background:layer", restore);
|
|
4343
4407
|
}
|
|
@@ -5011,7 +5075,7 @@ window.__ModuleLoader__.load({
|
|
|
5011
5075
|
/** The building package's version, when the bundle carries it. */
|
|
5012
5076
|
function bakedVersion() {
|
|
5013
5077
|
try {
|
|
5014
|
-
return "0.3.
|
|
5078
|
+
return "0.3.21";
|
|
5015
5079
|
} catch {
|
|
5016
5080
|
return;
|
|
5017
5081
|
}
|