dsh-model-doctor 0.5.3 → 0.5.5
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/lib/client/index.js +44 -7
- package/package.json +1 -1
package/lib/client/index.js
CHANGED
|
@@ -74,12 +74,14 @@ window.__ModuleLoader__.load({
|
|
|
74
74
|
.dmd-btn.dmd-delete:hover{color:#e5484d}
|
|
75
75
|
.dmd-btn.is-armed{width:auto;padding:0 9px;color:#e5484d;opacity:1;font-size:12px;font-weight:600;line-height:26px}
|
|
76
76
|
@keyframes dmd-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
|
|
77
|
-
.dmd-chip{font-size:11px;line-height:17px;padding:0 7px;margin-left:2px;border-radius:999px;white-space:nowrap;vertical-align:middle;display:inline-block;flex:none;
|
|
77
|
+
.dmd-chip{font-size:11px;line-height:17px;padding:0 7px;margin-left:2px;border-radius:999px;white-space:nowrap;vertical-align:middle;display:inline-block;flex:none;box-sizing:border-box;width:84px;text-align:center;overflow:hidden;text-overflow:ellipsis}
|
|
78
|
+
.dmd-chip.is-stale{opacity:.45}
|
|
78
79
|
.dmd-chip.is-ok{color:#2fa96e;background:color-mix(in srgb,#2fa96e 16%,transparent)}
|
|
79
80
|
.dmd-chip.is-bad{color:#e5484d;background:color-mix(in srgb,#e5484d 14%,transparent)}
|
|
80
81
|
.dmd-chip.is-warn{color:#d08700;background:color-mix(in srgb,#d08700 16%,transparent)}
|
|
81
|
-
/*
|
|
82
|
-
|
|
82
|
+
/* 关键:官方菜单是 width:max-content,状态条文字绝不能参与菜单的固有宽度计算。
|
|
83
|
+
width:0 + min-width:100% → 对菜单的宽度贡献为 0,但实际占满整行,不再留右侧空白。 */
|
|
84
|
+
.dmd-allbar{display:flex;align-items:center;flex-wrap:wrap;gap:4px 8px;padding:6px 10px;margin:2px 0;font-size:11px;border-radius:8px;background:color-mix(in srgb,currentColor 6%,transparent);box-sizing:border-box;width:0;min-width:100%;max-width:100%}
|
|
83
85
|
.dmd-allbar button{font:inherit;font-size:11px;line-height:16px;padding:2px 9px;border-radius:6px;border:1px solid color-mix(in srgb,currentColor 25%,transparent);background:transparent;color:inherit;cursor:pointer;flex:none}
|
|
84
86
|
.dmd-allbar button:disabled,.dmd-allbar button.is-busy{opacity:.45;cursor:default}
|
|
85
87
|
.dmd-allbar .dmd-status,.dmd-allbar .dmd-balance{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
@@ -155,6 +157,8 @@ window.__ModuleLoader__.load({
|
|
|
155
157
|
/** 本轮扫描是否改动过菜单 DOM(用于决定要不要让官方菜单立刻重新锚定)。 */
|
|
156
158
|
let mutatedThisPass = false
|
|
157
159
|
let reanchorAt = 0
|
|
160
|
+
/** 上一轮看到的官方菜单尺寸(宽x高):尺寸一变就立刻让官方重新锚定。 */
|
|
161
|
+
let lastMenuSize = ''
|
|
158
162
|
|
|
159
163
|
/** 本页会话内已删除的模型键,防目录未刷新时行又冒出来。 */
|
|
160
164
|
const deletedKeys = new Set()
|
|
@@ -727,8 +731,10 @@ window.__ModuleLoader__.load({
|
|
|
727
731
|
barBusy = true
|
|
728
732
|
status.textContent = '探测中…'
|
|
729
733
|
balance.textContent = ''
|
|
734
|
+
// 只把旧结果「变灰」,绝不删除:删徽章会让行变窄、菜单跟着变窄,
|
|
735
|
+
// 而官方 place() 要等下次滚动才重算 —— 表现就是检测期间一滚动菜单就右移。
|
|
730
736
|
rowByKey.forEach((row) => {
|
|
731
|
-
row.querySelectorAll('.dmd-chip').forEach((chip) => chip.
|
|
737
|
+
row.querySelectorAll('.dmd-chip').forEach((chip) => chip.classList.add('is-stale'))
|
|
732
738
|
})
|
|
733
739
|
doctor.checkAll().then((result) => {
|
|
734
740
|
if (disposed) return
|
|
@@ -760,6 +766,8 @@ window.__ModuleLoader__.load({
|
|
|
760
766
|
.map(([providerId, value]) => `${providerLabel(providerId)}: ¥${value}`)
|
|
761
767
|
balance.textContent = parts.join(' · ')
|
|
762
768
|
}
|
|
769
|
+
// 状态条文案变长也会改菜单尺寸:补一次重锚定
|
|
770
|
+
reanchorOfficialMenu(true)
|
|
763
771
|
})
|
|
764
772
|
})
|
|
765
773
|
// preventDefault 阻止焦点转移到本按钮:焦点一旦离开菜单,官方 onBlur 就会关闭菜单
|
|
@@ -774,6 +782,14 @@ window.__ModuleLoader__.load({
|
|
|
774
782
|
if (hint) status.textContent = hint
|
|
775
783
|
if (before !== null && before.parentNode === host) host.insertBefore(bar, before)
|
|
776
784
|
else host.insertBefore(bar, host.firstChild)
|
|
785
|
+
// 保险:状态条靠「width:0 + min-width:100%」占满整行且不参与菜单的固有宽度计算。
|
|
786
|
+
// 万一该技巧在某引擎上没生效,条形会塌成 0 宽 —— 这里实测一次,退化成像素宽度。
|
|
787
|
+
window.requestAnimationFrame(() => {
|
|
788
|
+
if (disposed || !bar.isConnected) return
|
|
789
|
+
const hostWidth = host.clientWidth
|
|
790
|
+
if (hostWidth <= 40) return
|
|
791
|
+
if (bar.getBoundingClientRect().width < hostWidth * 0.5) bar.style.width = `${hostWidth}px`
|
|
792
|
+
})
|
|
777
793
|
}
|
|
778
794
|
|
|
779
795
|
function providerLabel(providerId) {
|
|
@@ -1037,17 +1053,33 @@ window.__ModuleLoader__.load({
|
|
|
1037
1053
|
* 这里向菜单派发一个 scroll 事件:它不冒泡,所以只会在捕获阶段命中官方监听,
|
|
1038
1054
|
* 不会惊动其它监听 window 滚动(冒泡阶段)的组件。
|
|
1039
1055
|
*/
|
|
1040
|
-
function reanchorOfficialMenu() {
|
|
1056
|
+
function reanchorOfficialMenu(force = false) {
|
|
1041
1057
|
const menu = document.querySelector(`[class*="${OFFICIAL_MENU_SUFFIX}"]`)
|
|
1042
1058
|
if (menu === null) return
|
|
1043
1059
|
const now = Date.now()
|
|
1044
|
-
if (now - reanchorAt < 200) return
|
|
1060
|
+
if (!force && now - reanchorAt < 200) return
|
|
1045
1061
|
reanchorAt = now
|
|
1046
1062
|
try {
|
|
1063
|
+
// 官方 place() 同时监听 window 的 scroll(捕获阶段)与 resize:
|
|
1064
|
+
// 前者精准(不冒泡,不会惊动其它滚动监听),后者作为保底。
|
|
1047
1065
|
menu.dispatchEvent(new Event('scroll'))
|
|
1066
|
+
window.dispatchEvent(new Event('resize'))
|
|
1048
1067
|
} catch { /* 忽略派发失败 */ }
|
|
1049
1068
|
}
|
|
1050
1069
|
|
|
1070
|
+
/** 菜单尺寸(宽x高)是否与上一轮不同;不同就说明位置需要立刻重算。 */
|
|
1071
|
+
function officialMenuSizeChanged() {
|
|
1072
|
+
const menu = document.querySelector(`[class*="${OFFICIAL_MENU_SUFFIX}"]`)
|
|
1073
|
+
if (menu === null) {
|
|
1074
|
+
lastMenuSize = ''
|
|
1075
|
+
return false
|
|
1076
|
+
}
|
|
1077
|
+
const size = `${menu.offsetWidth}x${menu.offsetHeight}`
|
|
1078
|
+
if (size === lastMenuSize) return false
|
|
1079
|
+
lastMenuSize = size
|
|
1080
|
+
return true
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1051
1083
|
function enhanceInner() {
|
|
1052
1084
|
if (directory === null || Date.now() - directoryAt >= DIRECTORY_TTL_MS) {
|
|
1053
1085
|
void fetchDirectory()
|
|
@@ -1069,7 +1101,12 @@ window.__ModuleLoader__.load({
|
|
|
1069
1101
|
|
|
1070
1102
|
const wired = official.wired + legacyWired + genericWired
|
|
1071
1103
|
if (wired > 0) paintLastRun('上次结果:')
|
|
1072
|
-
if (
|
|
1104
|
+
if (official.menuFound) {
|
|
1105
|
+
// 兜底:无论尺寸变化是谁造成的(我们加/删元素、官方自身重渲染、状态条文案变长),
|
|
1106
|
+
// 只要实测尺寸变了,就立刻让官方重新锚定,绝不把这个问题留给用户的下一次滚动。
|
|
1107
|
+
const sizeChanged = officialMenuSizeChanged()
|
|
1108
|
+
if (mutatedThisPass || sizeChanged) reanchorOfficialMenu(sizeChanged)
|
|
1109
|
+
}
|
|
1073
1110
|
|
|
1074
1111
|
const menuVisible = official.menuFound || menu !== null
|
|
1075
1112
|
reportDiagnostics({
|
package/package.json
CHANGED