dsh-plugin-table-zoom 0.3.1 → 0.3.3
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 +26 -0
- package/README.md +24 -3
- package/lib/client.js +71 -28
- package/package.json +1 -1
- package/scripts/selfcheck.mjs +8 -0
- package/scripts/smoke-client.mjs +55 -9
- package//350/256/276/350/256/241/350/257/264/346/230/216.md +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.3] - 2026-08-22
|
|
4
|
+
|
|
5
|
+
- **修复:dsh `0.1.1-rc.2` 兼容——宽表「超出会话显示、无滚动条」**。rc2 起
|
|
6
|
+
核心渲染器给 4+ 列宽表新增 `md-table-wide` 分支:宽表宽度扩展到聊天
|
|
7
|
+
内容列两侧留白(`AssistantMarkdown.module.css` 的
|
|
8
|
+
`width/margin-left/padding-left` 联动),且默认 `overflow-x:hidden`
|
|
9
|
+
(仅 hover / focus-visible 才显示横向滚动条)。插件注入一条覆盖规则
|
|
10
|
+
(`[class*="tableScroll"].md-table-wide`)把宽表拉回内容列宽度并常驻
|
|
11
|
+
横向滚动条,恢复 `0.1.0-rc.8` 及以前「超宽在会话列内滚动查看」的行为;
|
|
12
|
+
旧版 dsh 无 `md-table-wide` 类,规则不命中,行为不变。
|
|
13
|
+
- 测试:selfcheck 新增 1 项(client.js 样式数组必须包含 rc2 覆盖规则,
|
|
14
|
+
防止后续编辑误删),共 selfcheck 13 项 + 冒烟 13 项。
|
|
15
|
+
|
|
16
|
+
## [0.3.2] - 2026-08-22
|
|
17
|
+
|
|
18
|
+
- README:新增「相关插件」互相引用段(列出同系列已发布插件,npm / GitHub 链接 + 一句话说明),互相引流。
|
|
19
|
+
- **修复:放大/溢出表格里拖动不再被平移劫持**——此前正文内容溢出
|
|
20
|
+
(缩放后或表超宽)时,左键按住正文任意位置拖动即进入平移,并主动清空
|
|
21
|
+
选区,导致**无法在放大的表格里框选文字**。现在普通左键拖动保留浏览器
|
|
22
|
+
原生行为,可直接框选表格文字(含放大后);滚动条 / 滚轮照常滚动。
|
|
23
|
+
- **平移改为显式手势**:表格超宽/超高时,**按住空格再按住正文拖动**
|
|
24
|
+
才左右/上下滚动(grab 光标仅在按住空格时出现,拖拽中为 grabbing);
|
|
25
|
+
触屏仍走原生滚动;拖动中松开空格即结束平移;关闭浮窗时清理空格监听。
|
|
26
|
+
- 测试:冒烟拆分/新增 2 项(未按空格左键拖动不启动平移 / 按住空格可平移
|
|
27
|
+
且光标随空格状态切换),共 selfcheck 12 项 + 冒烟 13 项。
|
|
28
|
+
|
|
3
29
|
## [0.3.1] - 2026-08-22
|
|
4
30
|
|
|
5
31
|
- **每次打开自适应,不再继承任何布局**:移除尺寸/位置/缩放的跨次记忆
|
package/README.md
CHANGED
|
@@ -29,8 +29,10 @@ DeepSeek Harness (dsh) Web GUI 聊天表格浮窗插件。
|
|
|
29
29
|
位置只影响当次打开;
|
|
30
30
|
- **Ctrl+滚轮缩放**:浮窗内按住 Ctrl 滚动滚轮,表格字体 60%–250% 缩放
|
|
31
31
|
(步进 10%),标题栏实时显示百分比;**缩放不记忆,每次打开回到 100%**;
|
|
32
|
-
-
|
|
33
|
-
|
|
32
|
+
- **框选文字**:普通左键在表格(含放大后)里拖动即可框选文字,
|
|
33
|
+
不会被平移劫持;
|
|
34
|
+
- **按住空格拖拽平移**:表格超宽/超高时,按住空格再按住正文拖动即可
|
|
35
|
+
左右/上下滚动(grab 光标仅在按住空格时出现;触屏走原生滚动);
|
|
34
36
|
- **滚动条清晰**:正文滚动条加深加粗,浅色主题下也能看清;
|
|
35
37
|
- **列宽适配**:列宽上限与聊天内一致(`min(30vw, 320px)`),超宽列自动换行收缩,
|
|
36
38
|
表格整体不再撑破浮窗。
|
|
@@ -108,7 +110,26 @@ npm run pack # 打包
|
|
|
108
110
|
- 目标:DeepSeek Harness Web GUI(dsh web),皮肤与主题 CSS 变量自适应;
|
|
109
111
|
- 依赖浏览器 `MutationObserver` / `requestAnimationFrame`,无 DOM 环境自动禁用;
|
|
110
112
|
- 不影响其他插件:只认 `tableScroll` 容器内的表格,跳过浮窗与 image-tools
|
|
111
|
-
lightbox
|
|
113
|
+
lightbox 内的表格;
|
|
114
|
+
- **dsh `0.1.1-rc.2` 起核心渲染器为 4+ 列宽表新增 `md-table-wide` 分支**
|
|
115
|
+
(宽度扩展到聊天内容列两侧留白,默认 `overflow-x:hidden`、仅 hover 才出
|
|
116
|
+
滚动条)。插件注入一条覆盖规则把宽表拉回内容列宽度并常驻横向滚动条,
|
|
117
|
+
恢复旧版「超宽在会话列内滚动查看」体验;旧版 dsh 无 `md-table-wide`
|
|
118
|
+
类,规则不命中,行为不变。
|
|
119
|
+
|
|
120
|
+
## 相关插件
|
|
121
|
+
|
|
122
|
+
本插件属于 **Pasumao 的 dsh 插件生态**,同系列已发布插件可搭配使用:
|
|
123
|
+
|
|
124
|
+
| 插件(npm) | GitHub | 说明 |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| [dsh-notify](https://www.npmjs.com/package/dsh-notify) | [GitHub 仓库](https://github.com/Pasumao/dsh-plugin-notify) | Windows 原生通知 + 系统托盘 |
|
|
127
|
+
| [dsh-plugin-choice-refresh](https://www.npmjs.com/package/dsh-plugin-choice-refresh) | [GitHub 仓库](https://github.com/Pasumao/dsh-plugin-choice-refresh) | 选择增强:重新生成选项 / 更多选项 |
|
|
128
|
+
| [dsh-plugin-dev-kb](https://www.npmjs.com/package/dsh-plugin-dev-kb) | [GitHub 仓库](https://github.com/Pasumao/dsh-plugin-dev-kb) | 插件开发知识库(官方文档完整镜像 + 技能) |
|
|
129
|
+
| [dsh-plugin-image-tools](https://www.npmjs.com/package/dsh-plugin-image-tools) | [GitHub 仓库](https://github.com/Pasumao/dsh-plugin-image-tools) | 图片选择卡 + 回复内嵌图片 + 盲模型收图 |
|
|
130
|
+
| [dsh-plugin-workbench](https://www.npmjs.com/package/dsh-plugin-workbench) | [GitHub 仓库](https://github.com/Pasumao/dsh-plugin-workbench) | VS Code 风格文件浏览器 + 可编辑预览 |
|
|
131
|
+
|
|
132
|
+
> 本系列其余插件见 [Pasumao · dsh 插件](https://github.com/Pasumao);觉得好用欢迎到 GitHub 点 ⭐。
|
|
112
133
|
|
|
113
134
|
## AI 生成声明
|
|
114
135
|
|
package/lib/client.js
CHANGED
|
@@ -46,7 +46,14 @@ window.__ModuleLoader__.load({
|
|
|
46
46
|
'.dstz-resizeSE{position:absolute;right:2px;bottom:2px;width:22px;height:22px;cursor:nwse-resize;z-index:4;touch-action:none}',
|
|
47
47
|
'.dstz-resizeSE::after{content:"";position:absolute;right:5px;bottom:5px;width:9px;height:9px;border-right:2px solid var(--dsw-alias-label-tertiary);border-bottom:2px solid var(--dsw-alias-label-tertiary);border-bottom-right-radius:2px;pointer-events:none}',
|
|
48
48
|
'.dstz-resizeSE:hover::after,.dstz-panel.dstz-resizing .dstz-resizeSE::after{border-color:var(--dsw-alias-label-primary)}',
|
|
49
|
-
'@media (width<=720px){.dstz-panel{width:min(96vw,960px);max-height:88vh}.dstz-body{padding:10px 12px 12px}}'
|
|
49
|
+
'@media (width<=720px){.dstz-panel{width:min(96vw,960px);max-height:88vh}.dstz-body{padding:10px 12px 12px}}',
|
|
50
|
+
// rc2 兼容:dsh 0.1.1-rc.2 起核心渲染器给 4+ 列宽表额外加上 `md-table-wide`——
|
|
51
|
+
// 默认 overflow-x:hidden(仅 hover/focus-visible 才出滚动条),且
|
|
52
|
+
// AssistantMarkdown 配套规则把表格宽度扩展到聊天内容列两侧留白区
|
|
53
|
+
// (.Sxvs8a_body .md-table-wide 的 width/margin/padding 联动)。
|
|
54
|
+
// 这里把宽表拉回内容列宽度并常驻横向滚动条,恢复 0.1.0-rc.8 及以前
|
|
55
|
+
// 「超宽在会话列内滚动查看」的行为;旧版 dsh 无 md-table-wide 类,规则不命中。
|
|
56
|
+
'[class*="tableScroll"].md-table-wide{box-sizing:border-box;width:auto!important;max-width:100%!important;margin-left:0!important;padding-left:0!important;padding-bottom:0!important;overflow-x:auto!important}'
|
|
50
57
|
].join('');
|
|
51
58
|
var tagId = 'dsh-plugin-table-zoom/zoom.module.css';
|
|
52
59
|
if (typeof document !== 'undefined' && document.querySelector('style[data-plugin-css=' + JSON.stringify(tagId) + ']') === null) {
|
|
@@ -279,12 +286,19 @@ window.__ModuleLoader__.load({
|
|
|
279
286
|
panel.style.top = y + 'px';
|
|
280
287
|
}
|
|
281
288
|
|
|
282
|
-
/**
|
|
289
|
+
/**
|
|
290
|
+
* 内容溢出且按住空格(平移预备)时才给正文加 grab 光标提示。
|
|
291
|
+
* 空格状态由 attachPan 维护在 body._dstzSpaceArmed 上;
|
|
292
|
+
* 布局变化(打开/改尺寸/缩放)后调用本函数即可同步光标。
|
|
293
|
+
*/
|
|
283
294
|
function refreshGrabbable(body) {
|
|
284
295
|
var overX = body.scrollWidth > body.clientWidth + 1;
|
|
285
296
|
var overY = body.scrollHeight > body.clientHeight + 1;
|
|
286
|
-
if (overX || overY) body.
|
|
287
|
-
|
|
297
|
+
if ((overX || overY) && body._dstzSpaceArmed === true) {
|
|
298
|
+
body.classList.add('dstz-grabbable');
|
|
299
|
+
} else {
|
|
300
|
+
body.classList.remove('dstz-grabbable');
|
|
301
|
+
}
|
|
288
302
|
}
|
|
289
303
|
|
|
290
304
|
/** 命中可交互元素(链接/按钮/输入框等)时让给默认行为,不启动拖拽。 */
|
|
@@ -389,22 +403,65 @@ window.__ModuleLoader__.load({
|
|
|
389
403
|
}
|
|
390
404
|
|
|
391
405
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
406
|
+
* 给正文挂载「按住空格拖动平移」:内容溢出时,按住空格再按住表格
|
|
407
|
+
* 左右/上下拖动即可滚动(鼠标/触控笔;触屏保留原生滚动)。
|
|
408
|
+
* 普通左键拖动不再被平移劫持,而是保留浏览器原生行为——可在表格
|
|
409
|
+
* (含放大后)里直接框选文字;只有按住空格时拖动才平移。
|
|
410
|
+
* grab 光标仅在按住空格悬停正文且内容溢出时出现;
|
|
411
|
+
* 拖动结束松手落在遮罩上不会误关浮窗。
|
|
395
412
|
* @param {object} body - .dstz-body 元素。
|
|
396
|
-
* @param {object} overlay - .dstz-popup 元素(承载 _suppressClick)。
|
|
413
|
+
* @param {object} overlay - .dstz-popup 元素(承载 _suppressClick / _cleanups)。
|
|
397
414
|
*/
|
|
398
415
|
function attachPan(body, overlay) {
|
|
399
416
|
var state = null;
|
|
417
|
+
var endPan = function () {
|
|
418
|
+
if (state === null) return;
|
|
419
|
+
state = null;
|
|
420
|
+
body.classList.remove('dstz-panning');
|
|
421
|
+
window.setTimeout(function () { overlay._suppressClick = false; }, 0);
|
|
422
|
+
};
|
|
423
|
+
var setArmed = function (on) {
|
|
424
|
+
body._dstzSpaceArmed = on === true;
|
|
425
|
+
refreshGrabbable(body);
|
|
426
|
+
};
|
|
427
|
+
var onKeyDown = function (e) {
|
|
428
|
+
if (e.key === ' ' || e.code === 'Space') setArmed(true);
|
|
429
|
+
};
|
|
430
|
+
var onKeyUp = function (e) {
|
|
431
|
+
if (e.key === ' ' || e.code === 'Space') {
|
|
432
|
+
setArmed(false);
|
|
433
|
+
if (state !== null) endPan(); // 拖动中松开空格:结束平移
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
var onBlur = function () {
|
|
437
|
+
setArmed(false);
|
|
438
|
+
if (state !== null) endPan();
|
|
439
|
+
};
|
|
440
|
+
if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
|
|
441
|
+
window.addEventListener('keydown', onKeyDown, true);
|
|
442
|
+
window.addEventListener('keyup', onKeyUp, true);
|
|
443
|
+
window.addEventListener('blur', onBlur);
|
|
444
|
+
if (Array.isArray(overlay._cleanups)) {
|
|
445
|
+
overlay._cleanups.push(function () {
|
|
446
|
+
window.removeEventListener('keydown', onKeyDown, true);
|
|
447
|
+
window.removeEventListener('keyup', onKeyUp, true);
|
|
448
|
+
window.removeEventListener('blur', onBlur);
|
|
449
|
+
setArmed(false);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
400
453
|
body.addEventListener('pointerdown', function (e) {
|
|
401
454
|
if (e.button !== 0) return;
|
|
402
455
|
if (e.pointerType !== undefined && e.pointerType !== 'mouse' && e.pointerType !== 'pen') return;
|
|
456
|
+
if (!body._dstzSpaceArmed) return; // 未按住空格:让给浏览器原生文本选择(框选文字)
|
|
403
457
|
if (isInteractive(e.target)) return;
|
|
404
458
|
var overX = body.scrollWidth > body.clientWidth + 1;
|
|
405
459
|
var overY = body.scrollHeight > body.clientHeight + 1;
|
|
406
460
|
if (!overX && !overY) return;
|
|
407
|
-
|
|
461
|
+
if (typeof e.preventDefault === 'function') e.preventDefault();
|
|
462
|
+
state = { x: e.clientX, y: e.clientY, sl: body.scrollLeft, st: body.scrollTop };
|
|
463
|
+
body.classList.add('dstz-panning');
|
|
464
|
+
overlay._suppressClick = true;
|
|
408
465
|
if (typeof body.setPointerCapture === 'function') {
|
|
409
466
|
try { body.setPointerCapture(e.pointerId); } catch (err) { /* ignore */ }
|
|
410
467
|
}
|
|
@@ -413,28 +470,12 @@ window.__ModuleLoader__.load({
|
|
|
413
470
|
if (state === null) return;
|
|
414
471
|
var dx = e.clientX - state.x;
|
|
415
472
|
var dy = e.clientY - state.y;
|
|
416
|
-
if (!state.moved && Math.abs(dx) + Math.abs(dy) < 4) return;
|
|
417
|
-
if (!state.moved) {
|
|
418
|
-
state.moved = true;
|
|
419
|
-
body.classList.add('dstz-panning');
|
|
420
|
-
overlay._suppressClick = true;
|
|
421
|
-
if (typeof document !== 'undefined' && typeof document.getSelection === 'function') {
|
|
422
|
-
try { document.getSelection().removeAllRanges(); } catch (err) { /* ignore */ }
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
473
|
body.scrollLeft = state.sl - dx;
|
|
426
474
|
body.scrollTop = state.st - dy;
|
|
427
475
|
if (typeof e.preventDefault === 'function') e.preventDefault();
|
|
428
476
|
});
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
var wasMoved = state.moved;
|
|
432
|
-
state = null;
|
|
433
|
-
body.classList.remove('dstz-panning');
|
|
434
|
-
if (wasMoved) window.setTimeout(function () { overlay._suppressClick = false; }, 0);
|
|
435
|
-
};
|
|
436
|
-
body.addEventListener('pointerup', end);
|
|
437
|
-
body.addEventListener('pointercancel', end);
|
|
477
|
+
body.addEventListener('pointerup', endPan);
|
|
478
|
+
body.addEventListener('pointercancel', endPan);
|
|
438
479
|
}
|
|
439
480
|
|
|
440
481
|
/**
|
|
@@ -507,6 +548,9 @@ window.__ModuleLoader__.load({
|
|
|
507
548
|
panel.appendChild(body);
|
|
508
549
|
overlay.appendChild(panel);
|
|
509
550
|
|
|
551
|
+
// 清理登记(attachPan 等挂载的全局监听会 push 进来,关闭时统一移除)
|
|
552
|
+
overlay._cleanups = [];
|
|
553
|
+
|
|
510
554
|
// 拖拽改尺寸 + 拖标题栏移动 + 内容溢出拖拽平移 + Ctrl+滚轮缩放
|
|
511
555
|
attachResize(panel, overlay);
|
|
512
556
|
attachMove(panel, overlay);
|
|
@@ -542,7 +586,6 @@ window.__ModuleLoader__.load({
|
|
|
542
586
|
clampPanelPosition(panel);
|
|
543
587
|
refreshGrabbable(body);
|
|
544
588
|
};
|
|
545
|
-
overlay._cleanups = [];
|
|
546
589
|
if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
|
|
547
590
|
window.addEventListener('resize', onWindowResize);
|
|
548
591
|
overlay._cleanups.push(function () {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-table-zoom",
|
|
3
3
|
"description": "DSH 聊天表格浮窗插件:聊天里 markdown 表格太长(行多/超宽)看不完时,表格上方自动出现「浮窗查看」按钮,点击弹出可滚动的小浮窗完整显示表格,并支持一键复制为 Markdown。纯前端 DOM 增强,不改核心包、不注册工具、无服务端逻辑。",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
package/scripts/selfcheck.mjs
CHANGED
|
@@ -118,4 +118,12 @@ ok('tableToMarkdown 空表', () => {
|
|
|
118
118
|
assert.equal(mod.tableToMarkdown(null), '')
|
|
119
119
|
})
|
|
120
120
|
|
|
121
|
+
// --- rc2 兼容:client.js 样式数组必须含宽表覆盖规则(防后续编辑误删) ---
|
|
122
|
+
ok('client.js 样式数组含 rc2 宽表覆盖规则', () => {
|
|
123
|
+
assert.ok(
|
|
124
|
+
code.includes('[class*="tableScroll"].md-table-wide{box-sizing:border-box'),
|
|
125
|
+
'missing rc2 md-table-wide override rule in injected CSS',
|
|
126
|
+
)
|
|
127
|
+
})
|
|
128
|
+
|
|
121
129
|
console.log(`[dsh-plugin-table-zoom] selfcheck: ${passed} passed`)
|
package/scripts/smoke-client.mjs
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* 3. openPopup 创建浮窗(标题含行列数、表格克隆、关闭按钮),
|
|
8
8
|
* closePopup 关闭并还原 body 滚动;
|
|
9
9
|
* 4. 表格克隆在浮窗内不会被再次增强(跳过 .dstz-popup);
|
|
10
|
-
* 5.
|
|
11
|
-
*
|
|
10
|
+
* 5. 右下角改尺寸手柄可拖拽改面板大小;溢出时左键拖动保留原生文本
|
|
11
|
+
* 选择(不启动平移),按住空格拖动才平移;标题栏可拖拽移动浮窗
|
|
12
|
+
* (不越出视口);Ctrl+滚轮缩放表格字体;
|
|
12
13
|
* 每次打开都按内容自适应宽度并居中(不继承上次的尺寸/位置/缩放)。
|
|
13
14
|
*
|
|
14
15
|
* 运行:node scripts/smoke-client.mjs
|
|
@@ -132,7 +133,22 @@ const documentEl = {
|
|
|
132
133
|
removeEventListener() {},
|
|
133
134
|
}
|
|
134
135
|
globalThis.document = documentEl
|
|
135
|
-
globalThis.window = {
|
|
136
|
+
globalThis.window = {
|
|
137
|
+
setTimeout: (fn) => fn(),
|
|
138
|
+
_listeners: {},
|
|
139
|
+
addEventListener(type, fn) { (this._listeners[type] ??= []).push(fn) },
|
|
140
|
+
removeEventListener(type, fn) {
|
|
141
|
+
const arr = this._listeners[type]
|
|
142
|
+
if (!arr) return
|
|
143
|
+
const idx = arr.indexOf(fn)
|
|
144
|
+
if (idx >= 0) arr.splice(idx, 1)
|
|
145
|
+
},
|
|
146
|
+
dispatch(type, event = {}) {
|
|
147
|
+
const arr = this._listeners[type]
|
|
148
|
+
if (!arr) return
|
|
149
|
+
for (const fn of [...arr]) fn({ target: documentEl, stopPropagation() {}, ...event })
|
|
150
|
+
},
|
|
151
|
+
}
|
|
136
152
|
Object.defineProperty(globalThis, 'navigator', {
|
|
137
153
|
value: { clipboard: { writeText: async (t) => { globalThis.__copied = t } } },
|
|
138
154
|
configurable: true,
|
|
@@ -304,7 +320,7 @@ ok('每次打开不继承上次尺寸,始终按内容自适应', () => {
|
|
|
304
320
|
mod.closePopup()
|
|
305
321
|
})
|
|
306
322
|
|
|
307
|
-
ok('
|
|
323
|
+
ok('溢出时左键拖动不启动平移(保留原生文本选择)', () => {
|
|
308
324
|
mod.closePopup()
|
|
309
325
|
const table = makeEl('table')
|
|
310
326
|
table.rows = []
|
|
@@ -318,16 +334,46 @@ ok('溢出时正文可拖拽平移', () => {
|
|
|
318
334
|
body.scrollLeft = 300
|
|
319
335
|
body.scrollTop = 100
|
|
320
336
|
mod.refreshGrabbable(body)
|
|
321
|
-
assert.ok(body.classList.contains('dstz-grabbable'), '
|
|
337
|
+
assert.ok(!body.classList.contains('dstz-grabbable'), '未按空格时不应显示 grab 光标')
|
|
338
|
+
// 未按空格:左键拖动不进入平移,也不吞掉遮罩点击(让给浏览器原生框选文字)
|
|
339
|
+
body.dispatch('pointerdown', { button: 0, clientX: 10, clientY: 10, pointerId: 1 })
|
|
340
|
+
body.dispatch('pointermove', { clientX: 110, clientY: 60 })
|
|
341
|
+
assert.ok(!body.classList.contains('dstz-panning'), '未按空格拖动不应进入平移')
|
|
342
|
+
assert.equal(body.scrollLeft, 300)
|
|
343
|
+
assert.equal(body.scrollTop, 100)
|
|
344
|
+
assert.ok(popup._suppressClick !== true, '未按空格拖动不应吞掉遮罩点击')
|
|
345
|
+
body.dispatch('pointerup', {})
|
|
346
|
+
mod.closePopup()
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
ok('按住空格拖动可平移溢出内容,光标随空格状态切换', () => {
|
|
350
|
+
mod.closePopup()
|
|
351
|
+
const table = makeEl('table')
|
|
352
|
+
table.rows = []
|
|
353
|
+
mod.openPopup(table)
|
|
354
|
+
const popup = documentEl.body.children.find((c) => c.className === 'dstz-popup')
|
|
355
|
+
const body = popup.children[0].children[1]
|
|
356
|
+
body.scrollWidth = 1200
|
|
357
|
+
body.clientWidth = 600
|
|
358
|
+
body.scrollHeight = 400
|
|
359
|
+
body.clientHeight = 300
|
|
360
|
+
body.scrollLeft = 300
|
|
361
|
+
body.scrollTop = 100
|
|
362
|
+
// 按住空格:内容溢出时出现 grab 光标
|
|
363
|
+
globalThis.window.dispatch('keydown', { key: ' ', code: 'Space' })
|
|
364
|
+
assert.ok(body.classList.contains('dstz-grabbable'), '按住空格且溢出时应显示 grab 光标')
|
|
322
365
|
body.dispatch('pointerdown', { button: 0, clientX: 10, clientY: 10, pointerId: 1 })
|
|
323
366
|
body.dispatch('pointermove', { clientX: 110, clientY: 60 })
|
|
324
|
-
assert.ok(body.classList.contains('dstz-panning'), '
|
|
367
|
+
assert.ok(body.classList.contains('dstz-panning'), '按住空格拖动应进入平移')
|
|
325
368
|
assert.equal(body.scrollLeft, 200)
|
|
326
369
|
assert.equal(body.scrollTop, 50)
|
|
327
|
-
assert.ok(popup._suppressClick === true, '
|
|
370
|
+
assert.ok(popup._suppressClick === true, '平移应吞掉遮罩关闭')
|
|
328
371
|
body.dispatch('pointerup', {})
|
|
329
|
-
assert.ok(!body.classList.contains('dstz-panning'), '
|
|
330
|
-
assert.ok(popup._suppressClick === false, '
|
|
372
|
+
assert.ok(!body.classList.contains('dstz-panning'), '松手后退出平移')
|
|
373
|
+
assert.ok(popup._suppressClick === false, '平移结束恢复遮罩点击')
|
|
374
|
+
// 松开空格:grab 光标消失
|
|
375
|
+
globalThis.window.dispatch('keyup', { key: ' ', code: 'Space' })
|
|
376
|
+
assert.ok(!body.classList.contains('dstz-grabbable'), '松开空格后 grab 光标消失')
|
|
331
377
|
mod.closePopup()
|
|
332
378
|
})
|
|
333
379
|
|
|
@@ -57,9 +57,11 @@ cordis.patch.yml 挂载一行,交 profile 的 dsh.profile.bundles 自
|
|
|
57
57
|
每次打开都从 100% 开始;
|
|
58
58
|
- **滚动条**:正文滚动条加深加粗(WebKit 伪元素 + Firefox `scrollbar-color`),
|
|
59
59
|
浅色主题下也清晰可见;
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
- **框选文字优先**:普通左键拖动保留浏览器原生文本选择(表格放大后也能
|
|
61
|
+
直接框选文字),不再被平移劫持;
|
|
62
|
+
- **按住空格拖拽平移**:表格内容溢出正文时,按住空格再按住表格即可
|
|
63
|
+
左右/上下拖动滚动(grab 光标仅在按住空格时出现,拖拽中为 grabbing;
|
|
64
|
+
触屏保留浏览器原生滚动);拖完松手落在遮罩上不会误关浮窗;
|
|
63
65
|
- **列宽上限**:与核心渲染器 `tableScroll` 一致(`max-width:min(30vw,320px)`、
|
|
64
66
|
`min-width:100px`),超宽列在浮窗内收缩换行,表整体不再超出浮窗。
|
|
65
67
|
|