dsh-md-plus 0.4.1 → 0.4.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 +20 -1
- package/README.md +4 -2
- package/lib/client.js +68 -18
- package/lib/highlight-runtime.js +1 -1
- package/lib/index.js +23 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
-
## 0.4.
|
|
3
|
+
## 0.4.3 —— 未发布
|
|
4
|
+
|
|
5
|
+
- 修复补高亮语言映射:`hbs` / `jade` / `tscn` / `tres` 分别使用 handlebars / pug / gdresource 语法着色。
|
|
6
|
+
- 修复 Mermaid 12.1 在占位标签兜底路径下的图种识别:补充 `radar-beta`、`treemap-beta`、`venn-beta`、`ishikawa-beta`、`wardley-beta`、`cynefin-beta`、`treeView-beta`、`flowchart-elk` 等,并去掉无效裸关键字的误判。
|
|
7
|
+
- 修复插件卸载后 debounce 扫描重新插入按钮、设置入口和折叠控件的问题,同时清理 `data-md-plus-zoom` 属性。
|
|
8
|
+
- 修复 localStorage 不可用时设置保存和配色切换连当前会话都不生效的问题。
|
|
9
|
+
- 修复运行时路由 ETag 只依赖文件大小和 mtime、内容更新后仍可能返回 304 的问题。
|
|
10
|
+
- 同步能力展示页和 README 预览图到当前 DSH 样式,并把所有版本引用更新为 0.4.3。
|
|
11
|
+
- 测试补到 78 条,新增别名语言、Mermaid 新图种、卸载清理、localStorage 降级和 ETag 回归用例。
|
|
12
|
+
|
|
13
|
+
## 0.4.2 —— 2026-10-30
|
|
14
|
+
|
|
15
|
+
- 修复鼠标悬浮表格或折叠内容时吞掉页面滚轮:移除表格容器的 `overscroll-behavior` containment,折叠态改为保留横向滚动、纵向 `overflow-y: clip`,并覆盖 DSH 宿主 `.tableScroll` 自带的横向 containment。
|
|
16
|
+
- 修复宽表横向滚动条出现 / 消失时鼠标移入移出表格造成的上下跳动:取消 hover 阶段的 padding 切换,固定底部留白。
|
|
17
|
+
- 修复宽表横向滚动时「展开 / 收起」按钮跟着表格内容移动:按钮中心固定跟随表格可视区域。
|
|
18
|
+
- 修复宽表横向滚动时右上角 CSV / Markdown 操作按钮跟表格内容移动:操作组固定在表格可视区域右上角。
|
|
19
|
+
- 新增 `docs/table-wheel-demo.html`:可直接检查短表、默认折叠长表(含横向滚动)和展开长表三种滚轮行为。
|
|
20
|
+
- 测试补到 73 条,新增表格和折叠内容不建立吞滚轮滚动容器的回归用例。
|
|
21
|
+
|
|
22
|
+
## 0.4.1 —— 2026-10-30
|
|
4
23
|
|
|
5
24
|
- 修复 DSH 代码块头部只显示占位文案时读不到真实围栏语言、补高亮失效的问题:现在会从宿主的 React fiber 读取真实 `lang`,读不到再退回正文嗅探,并把头部语言名显示成真实语言。
|
|
6
25
|
- 修复 `graph = nx.Graph()`、`pie = 3.14`、`timeline = []` 等普通代码被误判成 mermaid 图的问题:只嗅探第一行有效内容,并排除赋值和调用形态。
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
- **代码块**:统一成完整卡片,头部显示 `</>` 图标和语言名(无语言显示 `Plain text`),保留宿主原生的换行与复制按钮,顶栏与卡片同色。
|
|
10
10
|
- **Mermaid**:围栏渲染成 SVG,可在「图形 / 代码」间切换;支持全屏查看(滚轮缩放、拖拽、双击适应、Esc 关闭)、四套配色,以及下载 SVG / PNG。
|
|
11
11
|
- **长内容折叠**:代码块、表格、图表超过阈值自动折叠,底部出现「展开 / 收起」,长日志和长表格不会撑满聊天。
|
|
12
|
-
- **表格**:浅色 /
|
|
12
|
+
- **表格**:浅色 / 深色两套样式,表头吸顶,宽表支持表内横向滚动;每张表上方右侧有「CSV / Markdown」复制按钮。
|
|
13
13
|
- **图片放大**:只在旧宿主没有原生预览按钮时兜底,点击图片打开暗色预览,Esc 或点遮罩关闭;新版 DSH 的原生预览、头像、图标、代码块和链接里的图片都不接管。
|
|
14
14
|
- **设置面板**:右下角齿轮可调 Mermaid 配色、代码字号、图表默认视图和三类折叠阈值,阈值下方会注明按高度判断。设置存在 `localStorage`,界面文案跟随页面 `<html lang>` 切换中英文。
|
|
15
15
|
|
|
@@ -27,11 +27,13 @@ dsh plugin --profile desktop remove dsh-md-plus
|
|
|
27
27
|
```powershell
|
|
28
28
|
npm install # 顺带跑 prepare → build
|
|
29
29
|
npm run build # 产出 lib/ 下四个文件
|
|
30
|
-
npm run check # 语法检查 +
|
|
30
|
+
npm run check # 语法检查 + 78 条测试(先 build 再跑,check 不含 build)
|
|
31
31
|
npm run preview # 生成 preview.html(含真渲出来的 mermaid 图)
|
|
32
32
|
npm run shot # 用 headless Chrome 把 preview.html 截成 docs/preview.png
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
+
`npm run preview` / `scripts/showcase.mjs` 需要读取 DSH 安装目录里的主题和前端资源;如果本机 DSH 是 `app.asar` 包,请先解包到目录,并把 `DSH_APP_DIR` 指向该目录。
|
|
36
|
+
|
|
35
37
|
## 已知限制
|
|
36
38
|
|
|
37
39
|
- DSH 0.2.1-rc.4 的头部语言名由宿主决定:不认识的围栏只显示占位文案「代码块」。插件会从宿主的 React fiber 里兜底读取真实语言,读不到时才退回正文嗅探;宿主改 React 结构后这条兜底可能失效。
|
package/lib/client.js
CHANGED
|
@@ -178,6 +178,8 @@ window.__ModuleLoader__.load({
|
|
|
178
178
|
var STYLE_ATTR = "data-md-plus-style";
|
|
179
179
|
var RUNTIME_ATTR = "data-md-plus-runtime";
|
|
180
180
|
var DEBOUNCE_MS = 160;
|
|
181
|
+
var memorySettings = null;
|
|
182
|
+
var memoryTheme = null;
|
|
181
183
|
function readSettings() {
|
|
182
184
|
var settings = { ...DEFAULT_SETTINGS };
|
|
183
185
|
try {
|
|
@@ -194,11 +196,14 @@ window.__ModuleLoader__.load({
|
|
|
194
196
|
if (Number.isFinite(value) && value >= 0) settings[key] = Math.min(4e3, Math.round(value));
|
|
195
197
|
}
|
|
196
198
|
}
|
|
199
|
+
memorySettings = { ...settings };
|
|
197
200
|
} catch {
|
|
201
|
+
if (memorySettings !== null) return { ...DEFAULT_SETTINGS, ...memorySettings };
|
|
198
202
|
}
|
|
199
203
|
return settings;
|
|
200
204
|
}
|
|
201
205
|
function saveSettings(next) {
|
|
206
|
+
memorySettings = { ...next };
|
|
202
207
|
try {
|
|
203
208
|
window.localStorage.setItem(SETTINGS_KEY, JSON.stringify(next));
|
|
204
209
|
} catch {
|
|
@@ -331,10 +336,10 @@ window.__ModuleLoader__.load({
|
|
|
331
336
|
"gradle"
|
|
332
337
|
]);
|
|
333
338
|
var MMD_LANGS = /* @__PURE__ */ new Set(["mermaid", "mermaidjs", "mmd"]);
|
|
334
|
-
var MMD_FLOW = /^\s*(flowchart
|
|
335
|
-
var MMD_PIE = /^\s*pie(?:\s+title\b.*)?\s*;?\s*$/i;
|
|
339
|
+
var MMD_FLOW = /^\s*(flowchart(?:-elk)?|graph)(?:\s+(?:TD|TB|BT|RL|LR))?\s*;?\s*$/i;
|
|
340
|
+
var MMD_PIE = /^\s*pie(?:\s+(?:showData|title)\b.*)?\s*;?\s*$/i;
|
|
336
341
|
var MMD_GIT = /^\s*gitGraph(?:\s+(?:LR|TB|BT|RL))?:?\s*;?\s*$/i;
|
|
337
|
-
var MMD_SINGLE = /^\s*(sequenceDiagram|classDiagram|stateDiagram(?:-v2)?|erDiagram|journey|gantt|mindmap|timeline|quadrantChart|xychart-beta|sankey-beta|block-beta|packet-beta|architecture-beta|usecase-beta|agentflow-beta|C4Context|requirementDiagram|kanban|radar|treemap
|
|
342
|
+
var MMD_SINGLE = /^\s*(sequenceDiagram|classDiagram|stateDiagram(?:-v2)?|erDiagram|journey|gantt|mindmap|timeline|quadrantChart|xychart-beta|sankey-beta|block-beta|packet-beta|architecture-beta|usecase-beta|agentflow-beta|C4Context|requirementDiagram|kanban|radar-beta|treemap(?:-beta)?|venn-beta|ishikawa(?:-beta)?|wardley-beta|cynefin-beta|treeView-beta|info|eventmodeling|swimlane-beta|railroad-beta|railroad-abnf-beta|railroad-ebnf-beta|railroad-peg-beta)\s*;?\s*$/i;
|
|
338
343
|
function icon(paths) {
|
|
339
344
|
var svg = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'>" + paths + "</svg>";
|
|
340
345
|
return 'url("data:image/svg+xml,' + encodeURIComponent(svg) + '")';
|
|
@@ -443,8 +448,9 @@ window.__ModuleLoader__.load({
|
|
|
443
448
|
"." + MODAL_CLASS + " svg{display:block}",
|
|
444
449
|
// ── 长内容折叠:代码块、表格、图表卡共用一套按钮 ───────────────
|
|
445
450
|
"." + FOLD_CLASS + "{position:relative}",
|
|
446
|
-
|
|
447
|
-
"." +
|
|
451
|
+
// 用 clip 而不是 hidden:hidden 会建立隐形滚动容器,鼠标在折叠内容上滚轮会被它吞掉。
|
|
452
|
+
"." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{max-height:var(--md-plus-fold-max-height);overflow:clip}',
|
|
453
|
+
"." + FOLD_BTN_CLASS + "{display:block;white-space:nowrap;margin:8px auto 0;padding:4px 12px;border:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 22%));border-radius:999px;background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-label-primary);font:12px/18px var(--dsw-font-family-sans,system-ui,sans-serif);cursor:pointer;box-shadow:0 2px 8px rgb(0 0 0 / 12%);z-index:2}",
|
|
448
454
|
"." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"] .' + FOLD_BTN_CLASS + "{position:absolute;left:50%;bottom:8px;transform:translateX(-50%);margin:0}",
|
|
449
455
|
// ── 图片点击放大 ────────────────────────────────────────────────
|
|
450
456
|
'[class*="_markdown_"] img{cursor:zoom-in}',
|
|
@@ -480,7 +486,10 @@ window.__ModuleLoader__.load({
|
|
|
480
486
|
// 抓手用结构选择器而不是 DSH 的哈希类名:外层是「唯一子元素是 table 的 div」。
|
|
481
487
|
// 前面挂 [class*="_markdown_"] 有两个作用——只认 markdown 渲染出来的表格,
|
|
482
488
|
// 同时把特异性顶到 (0,1,4),压过 DSH 自己的 .tableScroll th (0,1,1)。
|
|
483
|
-
|
|
489
|
+
// 不要加 overscroll-behavior-y:contain:宿主给表格的外层是 overflow-x:auto,
|
|
490
|
+
// 两轴滚动容器上加 contain 会让没有纵向滚动的短表也吞掉页面滚轮;宿主的
|
|
491
|
+
// overscroll-behavior-x:contain 同样要清掉,Chrome 下它也会连带吞掉纵向滚轮。
|
|
492
|
+
TABLE + "{position:relative;margin-block:16px;max-height:min(70vh,720px);overflow-y:auto;overscroll-behavior:auto;" + TABLE_VARS + "}",
|
|
484
493
|
"body[data-ds-dark-theme] " + TABLE + "{" + TABLE_VARS_DARK + "}",
|
|
485
494
|
// 整张表一个 1px 边框 + 小圆角。
|
|
486
495
|
// 注意必须是 separate:collapse 模式下 Chrome 会忽略单元格的圆角,
|
|
@@ -507,27 +516,29 @@ window.__ModuleLoader__.load({
|
|
|
507
516
|
// 长表往下滚时表头留在视口顶部;底色不透明才不会透出下面的行
|
|
508
517
|
TABLE + " > table thead th{position:sticky;top:0;z-index:1}",
|
|
509
518
|
// 复制按钮放在表尾右侧:不压住表头文字,表格折叠时也能随展开一起出现
|
|
510
|
-
TABLE + " > table > caption." + TABLE_TOOLS_CLASS + "{caption-side:top;text-align:right;
|
|
519
|
+
TABLE + " > table > caption." + TABLE_TOOLS_CLASS + "{caption-side:top;position:sticky;right:0;width:0;height:30px;margin-left:auto;padding:0;text-align:right;z-index:2}",
|
|
520
|
+
TABLE + " > table > caption." + TABLE_TOOLS_CLASS + " > span{position:absolute;right:0;top:0;display:flex;gap:0;white-space:nowrap}",
|
|
511
521
|
TABLE + " > table > caption." + TABLE_TOOLS_CLASS + " button{appearance:none;border:1px solid var(--md-plus-tbl-line);border-radius:5px;padding:2px 8px;margin-left:4px;background:transparent;color:var(--dsw-alias-label-secondary);font:11px/16px var(--dsw-font-family-sans,system-ui,sans-serif);cursor:pointer}",
|
|
512
522
|
TABLE + " > table > caption." + TABLE_TOOLS_CLASS + " button:hover{color:var(--dsw-alias-label-primary);background:var(--md-plus-tbl-hover)}",
|
|
513
523
|
// 宽表(≥4 列)不收着不行。宿主给这类表加了 .md-table-wide,并让它「出血」:
|
|
514
524
|
// 包裹层撑到面板宽,再用 padding-left 把表推到正文栏左侧。那个 padding 会吃掉
|
|
515
|
-
//
|
|
516
|
-
// 才出现——文字表落进这个区间就很难读。这里按回正文栏宽,超出改为表内横滚。
|
|
525
|
+
// 可用宽度,结果是表格比正文宽出一截、右边还被裁掉;这里按回正文栏宽,超出改为表内横滚。
|
|
517
526
|
// 特异性 (0,2,2),压得住宿主的 .Pg4CGa_body .md-table-wide (0,2,0)。
|
|
518
|
-
TABLE + ".md-table-wide{width:100%;max-width:100%;margin-inline:0;padding-inline:0;overflow-x:auto}",
|
|
527
|
+
TABLE + ".md-table-wide{width:100%;max-width:100%;margin-inline:0;padding-inline:0;padding-bottom:0;overflow-x:auto}",
|
|
519
528
|
// 塞得下就撑满正文栏,塞不下保持自然宽度让外面滚,不把列挤成一列一个字
|
|
520
529
|
TABLE + ".md-table-wide > table{width:100%;max-width:none;min-width:max-content}",
|
|
521
|
-
//
|
|
522
|
-
//
|
|
523
|
-
TABLE + ".
|
|
530
|
+
// 折叠态保留横向滚动,但纵向必须 clip;横向滚动容器只有在
|
|
531
|
+
// overscroll-behavior:auto 时才会把纵向滚轮交还给页面。
|
|
532
|
+
TABLE + "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{overflow-x:auto;overflow-y:clip}'
|
|
524
533
|
].join("\n");
|
|
525
534
|
var scripts = /* @__PURE__ */ new Map();
|
|
526
535
|
var pending = /* @__PURE__ */ new Set();
|
|
536
|
+
var foldSyncs = /* @__PURE__ */ new WeakMap();
|
|
527
537
|
var timer = null;
|
|
528
538
|
var rescanQueued = false;
|
|
529
539
|
var injected = /* @__PURE__ */ new Set();
|
|
530
540
|
var diagramSeq = 0;
|
|
541
|
+
var disposed = false;
|
|
531
542
|
function injectStyle() {
|
|
532
543
|
if (document.querySelector("style[" + STYLE_ATTR + "]") !== null) return;
|
|
533
544
|
var tag = document.createElement("style");
|
|
@@ -670,6 +681,7 @@ window.__ModuleLoader__.load({
|
|
|
670
681
|
) != null;
|
|
671
682
|
}
|
|
672
683
|
function schedule(block) {
|
|
684
|
+
if (disposed) return;
|
|
673
685
|
if (block !== void 0) pending.add(block);
|
|
674
686
|
else rescanQueued = true;
|
|
675
687
|
if (timer !== null) return;
|
|
@@ -677,6 +689,7 @@ window.__ModuleLoader__.load({
|
|
|
677
689
|
}
|
|
678
690
|
function flush() {
|
|
679
691
|
timer = null;
|
|
692
|
+
if (disposed) return;
|
|
680
693
|
if (rescanQueued) {
|
|
681
694
|
rescanQueued = false;
|
|
682
695
|
for (const block of document.querySelectorAll(BLOCK)) pending.add(block);
|
|
@@ -838,7 +851,7 @@ window.__ModuleLoader__.load({
|
|
|
838
851
|
if (lang === "") return;
|
|
839
852
|
if (DSH_LANGS.has(lang)) return;
|
|
840
853
|
var api = await loadScript(HL_URL, HL_GLOBAL);
|
|
841
|
-
if (api === null || !api.supports(lang)) return;
|
|
854
|
+
if (disposed || api === null || !api.supports(lang)) return;
|
|
842
855
|
if (!pre.isConnected) return;
|
|
843
856
|
var code = pre.textContent ?? "";
|
|
844
857
|
if (code.trim() === "") return;
|
|
@@ -850,6 +863,7 @@ window.__ModuleLoader__.load({
|
|
|
850
863
|
} catch {
|
|
851
864
|
return;
|
|
852
865
|
}
|
|
866
|
+
if (disposed) return;
|
|
853
867
|
if (typeof html !== "string" || html === "") return;
|
|
854
868
|
if (!pre.isConnected || (pre.textContent ?? "") !== code) {
|
|
855
869
|
schedule(block);
|
|
@@ -874,8 +888,13 @@ window.__ModuleLoader__.load({
|
|
|
874
888
|
function getMermaidTheme() {
|
|
875
889
|
try {
|
|
876
890
|
var saved = window.localStorage.getItem(THEME_KEY);
|
|
877
|
-
if (saved !== null && THEME_ORDER.indexOf(saved) !== -1)
|
|
891
|
+
if (saved !== null && THEME_ORDER.indexOf(saved) !== -1) {
|
|
892
|
+
memoryTheme = saved;
|
|
893
|
+
return saved;
|
|
894
|
+
}
|
|
895
|
+
memoryTheme = null;
|
|
878
896
|
} catch {
|
|
897
|
+
if (memoryTheme !== null) return memoryTheme;
|
|
879
898
|
}
|
|
880
899
|
return "blue";
|
|
881
900
|
}
|
|
@@ -893,6 +912,7 @@ window.__ModuleLoader__.load({
|
|
|
893
912
|
var current = getMermaidTheme();
|
|
894
913
|
var index = THEME_ORDER.indexOf(current);
|
|
895
914
|
var next = THEME_ORDER[(index + 1) % THEME_ORDER.length];
|
|
915
|
+
memoryTheme = next;
|
|
896
916
|
try {
|
|
897
917
|
window.localStorage.setItem(THEME_KEY, next);
|
|
898
918
|
} catch {
|
|
@@ -906,16 +926,18 @@ window.__ModuleLoader__.load({
|
|
|
906
926
|
var key = "mmd\0" + code;
|
|
907
927
|
if (block.getAttribute(KEY_ATTR) === key) return;
|
|
908
928
|
var api = await loadScript(MMD_URL, MMD_GLOBAL);
|
|
909
|
-
if (api === null) return;
|
|
929
|
+
if (disposed || api === null) return;
|
|
910
930
|
if (!pre.isConnected) return;
|
|
911
931
|
var svg;
|
|
912
932
|
try {
|
|
913
933
|
var dark = document.body.hasAttribute("data-ds-dark-theme");
|
|
914
934
|
svg = await api.render("dsh-md-plus-mmd-" + ++diagramSeq, code, dark, getMermaidTheme());
|
|
915
935
|
} catch (error) {
|
|
936
|
+
if (disposed) return;
|
|
916
937
|
failDiagram(block, content, pre, key, error);
|
|
917
938
|
return;
|
|
918
939
|
}
|
|
940
|
+
if (disposed) return;
|
|
919
941
|
if (typeof svg !== "string" || svg === "") return;
|
|
920
942
|
if (svg.includes('aria-roledescription="error"')) {
|
|
921
943
|
failDiagram(block, content, pre, key, new Error("mermaid \u8FD4\u56DE\u7684\u662F\u9519\u8BEF\u5361\u7247"));
|
|
@@ -1045,6 +1067,12 @@ window.__ModuleLoader__.load({
|
|
|
1045
1067
|
}
|
|
1046
1068
|
function resetFold(target) {
|
|
1047
1069
|
if (target === null) return;
|
|
1070
|
+
var sync = foldSyncs.get(target);
|
|
1071
|
+
if (sync !== void 0) {
|
|
1072
|
+
target.removeEventListener("scroll", sync);
|
|
1073
|
+
window.removeEventListener("resize", sync);
|
|
1074
|
+
foldSyncs.delete(target);
|
|
1075
|
+
}
|
|
1048
1076
|
target.removeAttribute(FOLD_ATTR);
|
|
1049
1077
|
target.classList.remove(FOLD_CLASS);
|
|
1050
1078
|
target.style.removeProperty("--md-plus-fold-max-height");
|
|
@@ -1077,13 +1105,23 @@ window.__ModuleLoader__.load({
|
|
|
1077
1105
|
button.className = FOLD_BTN_CLASS;
|
|
1078
1106
|
button.textContent = t("foldOpen");
|
|
1079
1107
|
button.setAttribute("aria-expanded", "false");
|
|
1108
|
+
var sync = target.hasAttribute(TABLE_DONE_ATTR) ? () => {
|
|
1109
|
+
button.style.left = target.scrollLeft + target.clientWidth / 2 + "px";
|
|
1110
|
+
} : null;
|
|
1111
|
+
if (sync !== null) {
|
|
1112
|
+
foldSyncs.set(target, sync);
|
|
1113
|
+
target.addEventListener("scroll", sync, { passive: true });
|
|
1114
|
+
window.addEventListener("resize", sync);
|
|
1115
|
+
}
|
|
1080
1116
|
button.addEventListener("click", () => {
|
|
1081
1117
|
var folded = target.getAttribute(FOLD_ATTR) === "on";
|
|
1082
1118
|
target.setAttribute(FOLD_ATTR, folded ? "off" : "on");
|
|
1083
1119
|
button.textContent = folded ? t("foldClose") : t("foldOpen");
|
|
1084
1120
|
button.setAttribute("aria-expanded", folded ? "true" : "false");
|
|
1121
|
+
sync?.();
|
|
1085
1122
|
});
|
|
1086
1123
|
target.appendChild(button);
|
|
1124
|
+
sync?.();
|
|
1087
1125
|
});
|
|
1088
1126
|
}
|
|
1089
1127
|
function scanFolds() {
|
|
@@ -1153,6 +1191,8 @@ window.__ModuleLoader__.load({
|
|
|
1153
1191
|
table.setAttribute(TABLE_DONE_ATTR, "1");
|
|
1154
1192
|
var tools = document.createElement("caption");
|
|
1155
1193
|
tools.className = TABLE_TOOLS_CLASS;
|
|
1194
|
+
var group = document.createElement("span");
|
|
1195
|
+
group.className = TABLE_TOOLS_CLASS + "-group";
|
|
1156
1196
|
for (const [kind, label, titleKey, convert] of [
|
|
1157
1197
|
["csv", t("tableCsv"), "copyCsvTitle", tableToCsv],
|
|
1158
1198
|
["md", t("tableMd"), "copyMdTitle", tableToMarkdown]
|
|
@@ -1171,8 +1211,9 @@ window.__ModuleLoader__.load({
|
|
|
1171
1211
|
}
|
|
1172
1212
|
flashButton(button, ok ? t("copied") : t("copyFailed"));
|
|
1173
1213
|
});
|
|
1174
|
-
|
|
1214
|
+
group.appendChild(button);
|
|
1175
1215
|
}
|
|
1216
|
+
tools.appendChild(group);
|
|
1176
1217
|
dataTable.insertBefore(tools, dataTable.firstChild);
|
|
1177
1218
|
}
|
|
1178
1219
|
function openImage(source, alt) {
|
|
@@ -1370,6 +1411,7 @@ window.__ModuleLoader__.load({
|
|
|
1370
1411
|
foldTable: readNumber(foldTable, DEFAULT_SETTINGS.foldTable),
|
|
1371
1412
|
foldDiagram: readNumber(foldDiagram, DEFAULT_SETTINGS.foldDiagram)
|
|
1372
1413
|
});
|
|
1414
|
+
memoryTheme = themeSelect.value;
|
|
1373
1415
|
try {
|
|
1374
1416
|
window.localStorage.setItem(THEME_KEY, themeSelect.value);
|
|
1375
1417
|
} catch {
|
|
@@ -1602,6 +1644,7 @@ window.__ModuleLoader__.load({
|
|
|
1602
1644
|
function apply0(ctx) {
|
|
1603
1645
|
if (typeof document === "undefined") return;
|
|
1604
1646
|
ctx.effect(() => {
|
|
1647
|
+
disposed = false;
|
|
1605
1648
|
injectStyle();
|
|
1606
1649
|
applyCodeFontSize();
|
|
1607
1650
|
ensureSettingsButton();
|
|
@@ -1617,6 +1660,13 @@ window.__ModuleLoader__.load({
|
|
|
1617
1660
|
});
|
|
1618
1661
|
schedule();
|
|
1619
1662
|
return () => {
|
|
1663
|
+
disposed = true;
|
|
1664
|
+
if (timer !== null) {
|
|
1665
|
+
window.clearTimeout(timer);
|
|
1666
|
+
timer = null;
|
|
1667
|
+
}
|
|
1668
|
+
pending.clear();
|
|
1669
|
+
rescanQueued = false;
|
|
1620
1670
|
observer.disconnect();
|
|
1621
1671
|
document.removeEventListener("click", onDocumentClick, true);
|
|
1622
1672
|
for (const node of injected) node.remove();
|
|
@@ -1626,7 +1676,7 @@ window.__ModuleLoader__.load({
|
|
|
1626
1676
|
for (const node of document.querySelectorAll("." + FOLD_BTN_CLASS)) node.remove();
|
|
1627
1677
|
for (const node of document.querySelectorAll("[" + FOLD_ATTR + "]")) resetFold(node);
|
|
1628
1678
|
for (const node of document.querySelectorAll("." + TABLE_TOOLS_CLASS)) node.remove();
|
|
1629
|
-
for (const attr of [DONE_ATTR, KEY_ATTR, WRAP_ATTR, MMD_ATTR, TABLE_DONE_ATTR, "data-md-plus-lang"]) {
|
|
1679
|
+
for (const attr of [DONE_ATTR, KEY_ATTR, WRAP_ATTR, MMD_ATTR, TABLE_DONE_ATTR, "data-md-plus-lang", ZOOM_ATTR]) {
|
|
1630
1680
|
for (const node of document.querySelectorAll("[" + attr + "]")) node.removeAttribute(attr);
|
|
1631
1681
|
}
|
|
1632
1682
|
for (const node of document.querySelectorAll("[data-md-plus-original-label]")) {
|