dsh-md-plus 0.4.4 → 0.5.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 +26 -1
- package/README.md +9 -6
- package/lib/client.js +691 -86
- package/lib/mermaid-runtime.js +1 -1
- package/package.json +9 -3
package/lib/client.js
CHANGED
|
@@ -18,6 +18,8 @@ window.__ModuleLoader__.load({
|
|
|
18
18
|
var BTN_CLASS = "md-plus-btn";
|
|
19
19
|
var ZOOM_IN_CLASS = "md-plus-zoom-in";
|
|
20
20
|
var ZOOM_OUT_CLASS = "md-plus-zoom-out";
|
|
21
|
+
var COPY_SOURCE_CLASS = "md-plus-copy-source";
|
|
22
|
+
var DOWNLOAD_CLASS = "md-plus-download";
|
|
21
23
|
var ZOOM_ATTR = "data-md-plus-zoom";
|
|
22
24
|
var ZOOM_STEP = 1.25;
|
|
23
25
|
var ZOOM_MAX = 6;
|
|
@@ -52,6 +54,10 @@ window.__ModuleLoader__.load({
|
|
|
52
54
|
toggleAria: "\u5207\u6362\u56FE\u5F62\u4E0E\u4EE3\u7801",
|
|
53
55
|
fullscreen: "\u5168\u5C4F\u67E5\u770B",
|
|
54
56
|
fullscreenAria: "\u5168\u5C4F\u67E5\u770B\u6D41\u7A0B\u56FE",
|
|
57
|
+
copySource: "\u590D\u5236\u56FE\u6E90",
|
|
58
|
+
copySourceAria: "\u590D\u5236 Mermaid \u56FE\u6E90",
|
|
59
|
+
downloadCode: "\u4E0B\u8F7D\u4EE3\u7801",
|
|
60
|
+
downloadCodeAria: "\u4E0B\u8F7D\u4EE3\u7801\u4E3A\u6587\u4EF6",
|
|
55
61
|
theme: "\u5207\u6362 Mermaid \u914D\u8272",
|
|
56
62
|
themeAria: "\u5207\u6362 Mermaid \u914D\u8272",
|
|
57
63
|
themePrefix: "\u914D\u8272\uFF1A",
|
|
@@ -65,11 +71,16 @@ window.__ModuleLoader__.load({
|
|
|
65
71
|
fit: "\u9002\u5E94\u6574\u56FE",
|
|
66
72
|
downloadSvg: "\u4E0B\u8F7D SVG",
|
|
67
73
|
downloadPng: "\u4E0B\u8F7D PNG",
|
|
74
|
+
exportFailed: "\u5BFC\u51FA\u5931\u8D25\uFF0C\u8BF7\u6539\u7528 SVG",
|
|
68
75
|
close: "\u5173\u95ED",
|
|
69
76
|
tableCsv: "CSV",
|
|
77
|
+
tableTsv: "TSV",
|
|
70
78
|
tableMd: "Markdown",
|
|
79
|
+
tableHtml: "\u5BCC\u6587\u672C",
|
|
71
80
|
copyCsvTitle: "\u590D\u5236\u8868\u683C\u4E3A CSV",
|
|
81
|
+
copyTsvTitle: "\u590D\u5236\u8868\u683C\u4E3A TSV",
|
|
72
82
|
copyMdTitle: "\u590D\u5236\u8868\u683C\u4E3A Markdown",
|
|
83
|
+
copyHtmlTitle: "\u590D\u5236\u8868\u683C\u4E3A\u5BCC\u6587\u672C",
|
|
73
84
|
copied: "\u5DF2\u590D\u5236",
|
|
74
85
|
copyFailed: "\u590D\u5236\u5931\u8D25",
|
|
75
86
|
imageViewer: "\u56FE\u7247\u9884\u89C8",
|
|
@@ -83,6 +94,8 @@ window.__ModuleLoader__.load({
|
|
|
83
94
|
settingsViewDiagram: "\u56FE\u5F62",
|
|
84
95
|
settingsViewCode: "\u4EE3\u7801",
|
|
85
96
|
settingsFold: "\u957F\u5185\u5BB9\u6298\u53E0\u9608\u503C",
|
|
97
|
+
settingsFoldGroup: "\u6298\u53E0\u5185\u5BB9",
|
|
98
|
+
settingsFileGroup: "\u8BBE\u7F6E\u6587\u4EF6",
|
|
86
99
|
settingsFoldCode: "\u4EE3\u7801\u5757",
|
|
87
100
|
settingsFoldTable: "\u8868\u683C",
|
|
88
101
|
settingsFoldDiagram: "\u56FE\u8868",
|
|
@@ -90,6 +103,15 @@ window.__ModuleLoader__.load({
|
|
|
90
103
|
settingsFoldTableHint: "\u8868\u683C\u9AD8\u5EA6\u8D85\u8FC7\u6B64\u503C\u540E\u6298\u53E0",
|
|
91
104
|
settingsFoldDiagramHint: "\u56FE\u5F62\u9AD8\u5EA6\u8D85\u8FC7\u6B64\u503C\u540E\u6298\u53E0",
|
|
92
105
|
settingsFoldHint: "\u5355\u4F4D px\uFF0C0 \u8868\u793A\u4E0D\u6298\u53E0",
|
|
106
|
+
settingsFreezeRows: "\u51BB\u7ED3\u884C\u6570",
|
|
107
|
+
settingsFreezeRowsHint: "\u9ED8\u8BA4\u51BB\u7ED3 1 \u884C\u8868\u5934\uFF0C0 \u8868\u793A\u4E0D\u51BB\u7ED3",
|
|
108
|
+
settingsFreezeCols: "\u51BB\u7ED3\u5217\u6570",
|
|
109
|
+
settingsFreezeColsHint: "\u9ED8\u8BA4 0 \u5217\uFF0C\u6309\u9700\u6307\u5B9A",
|
|
110
|
+
foldExpandAll: "\u5168\u90E8\u5C55\u5F00",
|
|
111
|
+
foldCollapseAll: "\u5168\u90E8\u6536\u8D77",
|
|
112
|
+
settingsExport: "\u5BFC\u51FA\u8BBE\u7F6E",
|
|
113
|
+
settingsImport: "\u5BFC\u5165\u8BBE\u7F6E",
|
|
114
|
+
settingsImportFailed: "\u5BFC\u5165\u5931\u8D25",
|
|
93
115
|
settingsSave: "\u4FDD\u5B58",
|
|
94
116
|
settingsReset: "\u6062\u590D\u9ED8\u8BA4",
|
|
95
117
|
settingsClose: "\u5173\u95ED"
|
|
@@ -105,6 +127,10 @@ window.__ModuleLoader__.load({
|
|
|
105
127
|
toggleAria: "Switch diagram and code",
|
|
106
128
|
fullscreen: "Fullscreen",
|
|
107
129
|
fullscreenAria: "View diagram fullscreen",
|
|
130
|
+
copySource: "Copy source",
|
|
131
|
+
copySourceAria: "Copy Mermaid source",
|
|
132
|
+
downloadCode: "Download code",
|
|
133
|
+
downloadCodeAria: "Download code as a file",
|
|
108
134
|
theme: "Change Mermaid theme",
|
|
109
135
|
themeAria: "Change Mermaid theme",
|
|
110
136
|
themePrefix: "Theme: ",
|
|
@@ -118,11 +144,16 @@ window.__ModuleLoader__.load({
|
|
|
118
144
|
fit: "Fit",
|
|
119
145
|
downloadSvg: "Download SVG",
|
|
120
146
|
downloadPng: "Download PNG",
|
|
147
|
+
exportFailed: "Export failed; try SVG instead",
|
|
121
148
|
close: "Close",
|
|
122
149
|
tableCsv: "CSV",
|
|
150
|
+
tableTsv: "TSV",
|
|
123
151
|
tableMd: "Markdown",
|
|
152
|
+
tableHtml: "Rich",
|
|
124
153
|
copyCsvTitle: "Copy table as CSV",
|
|
154
|
+
copyTsvTitle: "Copy table as TSV",
|
|
125
155
|
copyMdTitle: "Copy table as Markdown",
|
|
156
|
+
copyHtmlTitle: "Copy table as rich text",
|
|
126
157
|
copied: "Copied",
|
|
127
158
|
copyFailed: "Copy failed",
|
|
128
159
|
imageViewer: "Image preview",
|
|
@@ -136,6 +167,8 @@ window.__ModuleLoader__.load({
|
|
|
136
167
|
settingsViewDiagram: "Diagram",
|
|
137
168
|
settingsViewCode: "Code",
|
|
138
169
|
settingsFold: "Fold thresholds",
|
|
170
|
+
settingsFoldGroup: "Fold content",
|
|
171
|
+
settingsFileGroup: "Settings file",
|
|
139
172
|
settingsFoldCode: "Code block",
|
|
140
173
|
settingsFoldTable: "Table",
|
|
141
174
|
settingsFoldDiagram: "Diagram",
|
|
@@ -143,6 +176,15 @@ window.__ModuleLoader__.load({
|
|
|
143
176
|
settingsFoldTableHint: "Fold when the table is taller than this",
|
|
144
177
|
settingsFoldDiagramHint: "Fold when the diagram is taller than this",
|
|
145
178
|
settingsFoldHint: "Pixels; 0 disables folding",
|
|
179
|
+
settingsFreezeRows: "Freeze rows",
|
|
180
|
+
settingsFreezeRowsHint: "Defaults to 1 header row; 0 disables freezing",
|
|
181
|
+
settingsFreezeCols: "Freeze columns",
|
|
182
|
+
settingsFreezeColsHint: "Defaults to 0 columns; set as needed",
|
|
183
|
+
foldExpandAll: "Expand all",
|
|
184
|
+
foldCollapseAll: "Collapse all",
|
|
185
|
+
settingsExport: "Export settings",
|
|
186
|
+
settingsImport: "Import settings",
|
|
187
|
+
settingsImportFailed: "Import failed",
|
|
146
188
|
settingsSave: "Save",
|
|
147
189
|
settingsReset: "Reset to defaults",
|
|
148
190
|
settingsClose: "Close"
|
|
@@ -154,7 +196,6 @@ window.__ModuleLoader__.load({
|
|
|
154
196
|
}
|
|
155
197
|
var MODAL_CLASS = "md-plus-mmd-modal";
|
|
156
198
|
var DONE_ATTR = "data-md-plus";
|
|
157
|
-
var KEY_ATTR = "data-md-plus-key";
|
|
158
199
|
var WRAP_ATTR = "data-md-plus-wrap";
|
|
159
200
|
var MMD_ATTR = "data-md-plus-mmd";
|
|
160
201
|
var FOLD_ATTR = "data-md-plus-fold";
|
|
@@ -163,6 +204,9 @@ window.__ModuleLoader__.load({
|
|
|
163
204
|
var FOLD_LIMITS = { code: 480, table: 520, diagram: 720 };
|
|
164
205
|
var TABLE_TOOLS_CLASS = "md-plus-table-tools";
|
|
165
206
|
var TABLE_DONE_ATTR = "data-md-plus-table";
|
|
207
|
+
var FREEZE_ROW_CLASS = "md-plus-freeze-row";
|
|
208
|
+
var FREEZE_COL_CLASS = "md-plus-freeze-col";
|
|
209
|
+
var FREEZE_CROSS_CLASS = "md-plus-freeze-cross";
|
|
166
210
|
var IMG_MODAL_CLASS = "md-plus-img-modal";
|
|
167
211
|
var NATIVE_IMAGE_BUTTON = 'button[class*="imageButton"]';
|
|
168
212
|
var SETTINGS_BTN_CLASS = "md-plus-settings-btn";
|
|
@@ -173,14 +217,19 @@ window.__ModuleLoader__.load({
|
|
|
173
217
|
diagramView: "diagram",
|
|
174
218
|
foldCode: FOLD_LIMITS.code,
|
|
175
219
|
foldTable: FOLD_LIMITS.table,
|
|
176
|
-
foldDiagram: FOLD_LIMITS.diagram
|
|
220
|
+
foldDiagram: FOLD_LIMITS.diagram,
|
|
221
|
+
freezeRows: 1,
|
|
222
|
+
freezeCols: 0
|
|
177
223
|
};
|
|
178
224
|
var STYLE_ATTR = "data-md-plus-style";
|
|
179
225
|
var RUNTIME_ATTR = "data-md-plus-runtime";
|
|
180
226
|
var DEBOUNCE_MS = 160;
|
|
181
227
|
var memorySettings = null;
|
|
182
228
|
var memoryTheme = null;
|
|
229
|
+
var settingsCache = null;
|
|
230
|
+
var themeCache = null;
|
|
183
231
|
function readSettings() {
|
|
232
|
+
if (settingsCache !== null) return { ...settingsCache };
|
|
184
233
|
var settings = { ...DEFAULT_SETTINGS };
|
|
185
234
|
try {
|
|
186
235
|
var raw = window.localStorage.getItem(SETTINGS_KEY);
|
|
@@ -195,15 +244,23 @@ window.__ModuleLoader__.load({
|
|
|
195
244
|
var value = Number(saved[key]);
|
|
196
245
|
if (Number.isFinite(value) && value >= 0) settings[key] = Math.min(4e3, Math.round(value));
|
|
197
246
|
}
|
|
247
|
+
for (var freezeKey of ["freezeRows", "freezeCols"]) {
|
|
248
|
+
var freezeValue = Number(saved[freezeKey]);
|
|
249
|
+
if (saved[freezeKey] !== void 0 && Number.isFinite(freezeValue) && freezeValue >= 0) {
|
|
250
|
+
settings[freezeKey] = Math.min(5, Math.round(freezeValue));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
198
253
|
}
|
|
199
254
|
memorySettings = { ...settings };
|
|
200
255
|
} catch {
|
|
201
|
-
if (memorySettings !== null)
|
|
256
|
+
if (memorySettings !== null) settings = { ...DEFAULT_SETTINGS, ...memorySettings };
|
|
202
257
|
}
|
|
203
|
-
|
|
258
|
+
settingsCache = { ...settings };
|
|
259
|
+
return { ...settingsCache };
|
|
204
260
|
}
|
|
205
261
|
function saveSettings(next) {
|
|
206
262
|
memorySettings = { ...next };
|
|
263
|
+
settingsCache = { ...next };
|
|
207
264
|
try {
|
|
208
265
|
window.localStorage.setItem(SETTINGS_KEY, JSON.stringify(next));
|
|
209
266
|
} catch {
|
|
@@ -350,6 +407,9 @@ window.__ModuleLoader__.load({
|
|
|
350
407
|
var ICON_COPY = icon(
|
|
351
408
|
"<rect x='9' y='9' width='12' height='12' rx='2.5'/><path d='M6 15H5.5A2.5 2.5 0 0 1 3 12.5v-7A2.5 2.5 0 0 1 5.5 3h7A2.5 2.5 0 0 1 15 5.5V6'/>"
|
|
352
409
|
);
|
|
410
|
+
var ICON_DOWNLOAD = icon(
|
|
411
|
+
"<path d='M12 3v12'/><path d='m7 10 5 5 5-5'/><path d='M5 21h14'/>"
|
|
412
|
+
);
|
|
353
413
|
var ICON_NOWRAP = icon(
|
|
354
414
|
"<path d='M3 12h12.5'/><path d='M12.5 8.5 16.5 12l-4 3.5'/><path d='M20 6v12'/>"
|
|
355
415
|
);
|
|
@@ -379,7 +439,7 @@ window.__ModuleLoader__.load({
|
|
|
379
439
|
var TABLE_VARS_DARK = "--md-plus-tbl-line:#2f2f2f;--md-plus-tbl-head:#1f1f1f;--md-plus-tbl-head-fg:#f9fafb;--md-plus-tbl-hover:#1f1f1f";
|
|
380
440
|
var CSS = [
|
|
381
441
|
// ── 卡片:整块一个底色,顶栏不再是独立色带 ──────────────────────
|
|
382
|
-
".md-code-block{--md-plus-mmd-min-height:200px;--md-plus-icon:" + ICON_CODE + ";--md-plus-icon-copy:" + ICON_COPY + ";--md-plus-icon-nowrap:" + ICON_NOWRAP + ";--md-plus-icon-diagram:" + ICON_DIAGRAM + ";--md-plus-icon-zoom-in:" + ICON_ZOOM_IN + ";--md-plus-icon-zoom-out:" + ICON_ZOOM_OUT + ";--md-plus-icon-expand:" + ICON_EXPAND + ";--md-plus-icon-theme:" + ICON_THEME + ";--md-plus-icon-retry:" + ICON_RETRY + "}",
|
|
442
|
+
".md-code-block{--md-plus-mmd-min-height:200px;--md-plus-icon:" + ICON_CODE + ";--md-plus-icon-copy:" + ICON_COPY + ";--md-plus-icon-download:" + ICON_DOWNLOAD + ";--md-plus-icon-nowrap:" + ICON_NOWRAP + ";--md-plus-icon-diagram:" + ICON_DIAGRAM + ";--md-plus-icon-zoom-in:" + ICON_ZOOM_IN + ";--md-plus-icon-zoom-out:" + ICON_ZOOM_OUT + ";--md-plus-icon-expand:" + ICON_EXPAND + ";--md-plus-icon-theme:" + ICON_THEME + ";--md-plus-icon-retry:" + ICON_RETRY + "}",
|
|
383
443
|
// bannerWrap 的原底色是 --dsw-alias-bg-base(#fff),会跟卡片灰拉开一条带
|
|
384
444
|
".md-code-block > div:has(> " + BANNER + "){background:transparent}",
|
|
385
445
|
// ── 头部:收紧,并把空着的左边填上 ─────────────────────────────
|
|
@@ -395,8 +455,10 @@ window.__ModuleLoader__.load({
|
|
|
395
455
|
// ── 间距:头部与首行代码之间补 6px ──────────────────────────────
|
|
396
456
|
// pre 的行高本身就在首行文字上方留了约半行空白;补 6px 后实测间距约 17px
|
|
397
457
|
// (原来给 0 时只有 11px,贴着看太挤)
|
|
398
|
-
|
|
399
|
-
|
|
458
|
+
// 未设字号时不能回退 inherit:pre 的父级是正文,会把宿主的代码字号
|
|
459
|
+
// (--dsh-code-font-size)盖成正文大小;回退到宿主变量才是真「跟随宿主」。
|
|
460
|
+
".md-code-block pre{padding:6px 16px 16px;font-size:var(--md-plus-code-font-size,var(--dsh-code-font-size,11px))}",
|
|
461
|
+
".md-code-block pre{line-height:var(--md-plus-code-line-height,calc(19px + var(--dsh-code-font-delta,0px)))}",
|
|
400
462
|
// DSH 0.2.1 把内容容器设成 display:contents,折叠需要真实的盒子才能量高度和裁剪
|
|
401
463
|
".md-code-block > [data-code-block-content]{display:block}",
|
|
402
464
|
// ── 头部按钮:文字换成图标 ──────────────────────────────────────
|
|
@@ -417,6 +479,8 @@ window.__ModuleLoader__.load({
|
|
|
417
479
|
".md-code-block " + BANNER + " ." + ZOOM_OUT_CLASS + "::before{-webkit-mask:var(--md-plus-icon-zoom-out) center/contain no-repeat;mask:var(--md-plus-icon-zoom-out) center/contain no-repeat}",
|
|
418
480
|
".md-code-block " + BANNER + " ." + EXPAND_CLASS + "::before{-webkit-mask:var(--md-plus-icon-expand) center/contain no-repeat;mask:var(--md-plus-icon-expand) center/contain no-repeat}",
|
|
419
481
|
".md-code-block " + BANNER + " ." + THEME_CLASS + "::before{-webkit-mask:var(--md-plus-icon-theme) center/contain no-repeat;mask:var(--md-plus-icon-theme) center/contain no-repeat}",
|
|
482
|
+
".md-code-block " + BANNER + " ." + COPY_SOURCE_CLASS + "::before{-webkit-mask:var(--md-plus-icon-copy) center/contain no-repeat;mask:var(--md-plus-icon-copy) center/contain no-repeat}",
|
|
483
|
+
".md-code-block " + BANNER + " ." + DOWNLOAD_CLASS + "::before{-webkit-mask:var(--md-plus-icon-download) center/contain no-repeat;mask:var(--md-plus-icon-download) center/contain no-repeat}",
|
|
420
484
|
".md-code-block " + BANNER + " ." + RETRY_CLASS + "::before{-webkit-mask:var(--md-plus-icon-retry) center/contain no-repeat;mask:var(--md-plus-icon-retry) center/contain no-repeat}",
|
|
421
485
|
"[" + MMD_ATTR + '="diagram"] .' + TOGGLE_CLASS + "{color:var(--dsw-alias-button-primary-fill,#4c6ef5);background:var(--dsw-alias-interactive-bg-active,rgb(76 110 245 / 12%))}",
|
|
422
486
|
// 已经到最小 / 最大时,对应那颗按钮变淡且不可点
|
|
@@ -465,19 +529,29 @@ window.__ModuleLoader__.load({
|
|
|
465
529
|
"." + SETTINGS_BTN_CLASS + "::before{content:'';width:16px;height:16px;background:currentColor;-webkit-mask:var(--md-plus-icon-gear) center/contain no-repeat;mask:var(--md-plus-icon-gear) center/contain no-repeat}",
|
|
466
530
|
"." + SETTINGS_MODAL_CLASS + "{position:fixed;inset:0;z-index:2147483000;display:flex;align-items:center;justify-content:center;padding:calc(var(--dsh-windows-titlebar-height,0px) + 16px) 24px 24px;background:rgb(0 0 0 / 48%)}",
|
|
467
531
|
"." + SETTINGS_MODAL_CLASS + "-panel{width:min(440px,100%);max-height:86vh;overflow:auto;padding:16px 18px 14px;border:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 18%));border-radius:12px;background:var(--dsw-alias-bg-base,#fff);box-shadow:0 24px 80px rgb(0 0 0 / 25%)}",
|
|
468
|
-
"." + SETTINGS_MODAL_CLASS + "-title{margin:0 0
|
|
469
|
-
"." + SETTINGS_MODAL_CLASS + "-row{display:flex;align-items:center;gap:12px;margin:
|
|
532
|
+
"." + SETTINGS_MODAL_CLASS + "-title{margin:0 0 10px;font:600 14px/22px var(--dsw-font-family-sans,system-ui,sans-serif);color:var(--dsw-alias-label-primary)}",
|
|
533
|
+
"." + SETTINGS_MODAL_CLASS + "-row{display:flex;align-items:center;gap:12px;min-height:36px;margin:0 0 10px}",
|
|
470
534
|
"." + SETTINGS_MODAL_CLASS + "-label{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0;font:13px/20px var(--dsw-font-family-sans,system-ui,sans-serif);color:var(--dsw-alias-label-primary)}",
|
|
471
535
|
"." + SETTINGS_MODAL_CLASS + "-label-title{display:block}",
|
|
472
536
|
"." + SETTINGS_MODAL_CLASS + "-label-hint{display:block;font:11px/16px var(--dsw-font-family-sans,system-ui,sans-serif);color:var(--dsw-alias-label-tertiary)}",
|
|
473
537
|
"." + SETTINGS_MODAL_CLASS + "-hint{margin:-4px 0 8px;font:11px/16px var(--dsw-font-family-sans,system-ui,sans-serif);color:var(--dsw-alias-label-tertiary)}",
|
|
538
|
+
"." + SETTINGS_MODAL_CLASS + "-section{margin:14px 0 8px;font:600 12px/18px var(--dsw-font-family-sans,system-ui,sans-serif);color:var(--dsw-alias-label-secondary)}",
|
|
474
539
|
"." + SETTINGS_MODAL_CLASS + " input[type=number]{width:78px;padding:4px 6px;border:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 22%));border-radius:6px;background:var(--dsw-alias-bg-layer-2,rgb(127 127 127 / 6%));color:var(--dsw-alias-label-primary);font:13px/18px var(--dsw-font-family-sans,system-ui,sans-serif)}",
|
|
475
540
|
"." + SETTINGS_MODAL_CLASS + " select{padding:4px 6px;border:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 22%));border-radius:6px;background:var(--dsw-alias-bg-layer-2,rgb(127 127 127 / 6%));color:var(--dsw-alias-label-primary);font:13px/18px var(--dsw-font-family-sans,system-ui,sans-serif)}",
|
|
476
|
-
"." + SETTINGS_MODAL_CLASS + "-
|
|
477
|
-
"." + SETTINGS_MODAL_CLASS + "-
|
|
478
|
-
"." + SETTINGS_MODAL_CLASS + "-actions
|
|
541
|
+
"." + SETTINGS_MODAL_CLASS + "-footer{margin-top:18px;padding-top:14px;border-top:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 18%))}",
|
|
542
|
+
"." + SETTINGS_MODAL_CLASS + "-utilities{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 18px;margin:0 0 14px}",
|
|
543
|
+
"." + SETTINGS_MODAL_CLASS + "-fold-actions,." + SETTINGS_MODAL_CLASS + "-transfer-actions{display:flex;align-items:center;gap:8px}",
|
|
544
|
+
"." + SETTINGS_MODAL_CLASS + "-utility-label{font:11px/16px var(--dsw-font-family-sans,system-ui,sans-serif);color:var(--dsw-alias-label-tertiary);white-space:nowrap}",
|
|
545
|
+
"." + SETTINGS_MODAL_CLASS + "-segment{display:inline-flex;align-items:center;gap:1px;padding:2px;border:1px solid var(--dsw-alias-border-secondary,rgb(127 127 127 / 18%));border-radius:8px;background:var(--dsw-alias-bg-layer-2,rgb(127 127 127 / 5%))}",
|
|
546
|
+
"." + SETTINGS_MODAL_CLASS + "-segment button{appearance:none;border:0;border-radius:6px;padding:4px 8px;background:transparent;color:var(--dsw-alias-label-secondary);font:12px/18px var(--dsw-font-family-sans,system-ui,sans-serif);cursor:pointer}",
|
|
547
|
+
"." + SETTINGS_MODAL_CLASS + "-segment button:hover{background:var(--dsw-alias-interactive-bg-hover,rgb(127 127 127 / 12%));color:var(--dsw-alias-label-primary)}",
|
|
548
|
+
"." + SETTINGS_MODAL_CLASS + "-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:0}",
|
|
549
|
+
"." + SETTINGS_MODAL_CLASS + "-actions button{appearance:none;border:0;border-radius:7px;min-height:30px;padding:5px 12px;background:transparent;color:var(--dsw-alias-label-secondary);font:12px/18px var(--dsw-font-family-sans,system-ui,sans-serif);cursor:pointer}",
|
|
550
|
+
"." + SETTINGS_MODAL_CLASS + "-actions button:first-child{margin-right:auto;color:var(--dsw-alias-label-tertiary)}",
|
|
551
|
+
"." + SETTINGS_MODAL_CLASS + "-actions button:not(." + SETTINGS_MODAL_CLASS + "-primary):hover{background:var(--dsw-alias-interactive-bg-hover,rgb(127 127 127 / 12%));color:var(--dsw-alias-label-primary)}",
|
|
479
552
|
"." + SETTINGS_MODAL_CLASS + "-actions ." + SETTINGS_MODAL_CLASS + "-primary{background:var(--dsw-alias-button-primary-fill,#4c6ef5);color:var(--dsw-alias-label-primary-foreground,#fff)}",
|
|
480
553
|
"." + SETTINGS_MODAL_CLASS + "-actions ." + SETTINGS_MODAL_CLASS + "-primary:hover{background:var(--dsw-alias-button-primary-hover,var(--dsw-alias-button-primary-fill,#4c6ef5))}",
|
|
554
|
+
"." + SETTINGS_MODAL_CLASS + "-fold-actions button:focus-visible,." + SETTINGS_MODAL_CLASS + "-transfer-actions button:focus-visible,." + SETTINGS_MODAL_CLASS + "-actions button:focus-visible{outline:2px solid var(--dsw-alias-button-primary-fill,#4c6ef5);outline-offset:1px}",
|
|
481
555
|
// 高亮宿主不参与布局,让里面的 <pre> 直接吃到卡片样式
|
|
482
556
|
"." + HOST_CLASS + "{display:contents}",
|
|
483
557
|
// 藏掉纯文本回退,只留着色结果;原节点仍在,复制读的还是它
|
|
@@ -513,8 +587,15 @@ window.__ModuleLoader__.load({
|
|
|
513
587
|
TABLE + " > table tr:last-child td{border-bottom:0}",
|
|
514
588
|
// 宽表横向扫读时给个落点
|
|
515
589
|
TABLE + " > table tbody tr:hover td{background:var(--md-plus-tbl-hover)}",
|
|
516
|
-
//
|
|
517
|
-
TABLE + " > table
|
|
590
|
+
// 冻结行 / 列:具体偏移由客户端按实际行列尺寸算好,支持设置多行多列
|
|
591
|
+
TABLE + " > table ." + FREEZE_ROW_CLASS + "{position:sticky;z-index:2;box-shadow:0 1px 0 var(--md-plus-tbl-line)}",
|
|
592
|
+
TABLE + " > table th." + FREEZE_ROW_CLASS + "{background:var(--md-plus-tbl-head)}",
|
|
593
|
+
TABLE + " > table td." + FREEZE_ROW_CLASS + "{background:var(--dsw-alias-bg-base,#fff)}",
|
|
594
|
+
TABLE + " > table ." + FREEZE_COL_CLASS + "{position:sticky;z-index:1;box-shadow:1px 0 0 var(--md-plus-tbl-line)}",
|
|
595
|
+
TABLE + " > table th." + FREEZE_COL_CLASS + "{background:var(--md-plus-tbl-head)}",
|
|
596
|
+
TABLE + " > table td." + FREEZE_COL_CLASS + "{background:var(--dsw-alias-bg-base,#fff)}",
|
|
597
|
+
TABLE + " > table ." + FREEZE_CROSS_CLASS + "{z-index:3}",
|
|
598
|
+
TABLE + " > table tbody tr:hover td." + FREEZE_ROW_CLASS + "," + TABLE + " > table tbody tr:hover td." + FREEZE_COL_CLASS + "{background:var(--md-plus-tbl-hover)}",
|
|
518
599
|
// 复制按钮放在表尾右侧:不压住表头文字,表格折叠时也能随展开一起出现
|
|
519
600
|
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
601
|
TABLE + " > table > caption." + TABLE_TOOLS_CLASS + " > span{position:absolute;right:0;top:0;display:flex;gap:0;white-space:nowrap}",
|
|
@@ -531,14 +612,26 @@ window.__ModuleLoader__.load({
|
|
|
531
612
|
// overscroll-behavior:auto 时才会把纵向滚轮交还给页面。
|
|
532
613
|
// 这里同时写明 min/max-height:基础表格规则的 max-height 特异性更高,不补会压过设置值;
|
|
533
614
|
// 最小高度保证极低阈值下「展开」按钮仍完整可见。
|
|
534
|
-
TABLE + "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{min-height:48px;max-height:var(--md-plus-fold-max-height);overflow-x:auto;overflow-y:clip}'
|
|
615
|
+
TABLE + "." + FOLD_CLASS + "[" + FOLD_ATTR + '="on"]{min-height:48px;max-height:var(--md-plus-fold-max-height);overflow-x:auto;overflow-y:clip}',
|
|
616
|
+
// 展开态的「收起」按钮在表尾文档流里,纵向保持滚到底才出现;
|
|
617
|
+
// 横向用 sticky 钉在可视区中间,宽表左右滚动时不会跟着表内容跑掉。
|
|
618
|
+
// 折叠态按钮是绝对定位,横向跟随由 sync() 写 left 完成。
|
|
619
|
+
TABLE + " ." + FOLD_BTN_CLASS + "{position:sticky;left:50%;transform:translateX(-50%)}"
|
|
535
620
|
].join("\n");
|
|
536
621
|
var scripts = /* @__PURE__ */ new Map();
|
|
537
622
|
var pending = /* @__PURE__ */ new Set();
|
|
538
623
|
var foldSyncs = /* @__PURE__ */ new WeakMap();
|
|
624
|
+
var foldTargets = /* @__PURE__ */ new Set();
|
|
625
|
+
var foldResizeObserver = null;
|
|
626
|
+
var foldResizeHandler = null;
|
|
627
|
+
var diagramKindCache = /* @__PURE__ */ new WeakMap();
|
|
628
|
+
var cacheKeys = /* @__PURE__ */ new WeakMap();
|
|
539
629
|
var timer = null;
|
|
540
630
|
var rescanQueued = false;
|
|
541
631
|
var injected = /* @__PURE__ */ new Set();
|
|
632
|
+
var tableFreezeObserver = null;
|
|
633
|
+
var tableFreezeTargets = /* @__PURE__ */ new Set();
|
|
634
|
+
var tableFreezeState = /* @__PURE__ */ new WeakMap();
|
|
542
635
|
var diagramSeq = 0;
|
|
543
636
|
var disposed = false;
|
|
544
637
|
function injectStyle() {
|
|
@@ -668,7 +761,7 @@ window.__ModuleLoader__.load({
|
|
|
668
761
|
var single = MMD_SINGLE.exec(value);
|
|
669
762
|
return single === null ? null : single[1];
|
|
670
763
|
}
|
|
671
|
-
function
|
|
764
|
+
function computeDiagramKind(block) {
|
|
672
765
|
var lang = readLang(block);
|
|
673
766
|
if (MMD_LANGS.has(lang)) return "diagram";
|
|
674
767
|
if (lang !== "") return null;
|
|
@@ -676,12 +769,22 @@ window.__ModuleLoader__.load({
|
|
|
676
769
|
if (pre === null) return null;
|
|
677
770
|
return sniffDiagramType(pre.textContent ?? "") === null ? null : "diagram";
|
|
678
771
|
}
|
|
772
|
+
function diagramKind(block) {
|
|
773
|
+
if (diagramKindCache.has(block)) return diagramKindCache.get(block);
|
|
774
|
+
var kind = computeDiagramKind(block);
|
|
775
|
+
diagramKindCache.set(block, kind);
|
|
776
|
+
return kind;
|
|
777
|
+
}
|
|
679
778
|
function isOurs(node) {
|
|
680
779
|
var element = node?.nodeType === 1 ? node : node?.parentElement;
|
|
681
780
|
return element?.closest?.(
|
|
682
|
-
"." + HOST_CLASS + ", ." + BTN_CLASS + ", ." + MMD_CLASS + ", ." + FOLD_BTN_CLASS + ", ." + TABLE_TOOLS_CLASS + ", ." + IMG_MODAL_CLASS + ", ." + SETTINGS_BTN_CLASS + ", ." + SETTINGS_MODAL_CLASS
|
|
781
|
+
"." + HOST_CLASS + ", ." + BTN_CLASS + ", ." + MMD_CLASS + ", ." + FOLD_BTN_CLASS + ", ." + TABLE_TOOLS_CLASS + ", ." + IMG_MODAL_CLASS + ", ." + MODAL_CLASS + ", ." + SETTINGS_BTN_CLASS + ", ." + SETTINGS_MODAL_CLASS
|
|
683
782
|
) != null;
|
|
684
783
|
}
|
|
784
|
+
function closestStreaming(node) {
|
|
785
|
+
var element = node?.nodeType === 1 ? node : node?.parentElement;
|
|
786
|
+
return element?.closest?.("[data-streaming]") ?? null;
|
|
787
|
+
}
|
|
685
788
|
function schedule(block) {
|
|
686
789
|
if (disposed) return;
|
|
687
790
|
if (block !== void 0) pending.add(block);
|
|
@@ -692,6 +795,12 @@ window.__ModuleLoader__.load({
|
|
|
692
795
|
function flush() {
|
|
693
796
|
timer = null;
|
|
694
797
|
if (disposed) return;
|
|
798
|
+
for (const node of injected) {
|
|
799
|
+
if (!node.isConnected) injected.delete(node);
|
|
800
|
+
}
|
|
801
|
+
cleanupFoldTargets();
|
|
802
|
+
cleanupTableFreezeTargets();
|
|
803
|
+
diagramKindCache = /* @__PURE__ */ new WeakMap();
|
|
695
804
|
if (rescanQueued) {
|
|
696
805
|
rescanQueued = false;
|
|
697
806
|
for (const block of document.querySelectorAll(BLOCK)) pending.add(block);
|
|
@@ -699,6 +808,7 @@ window.__ModuleLoader__.load({
|
|
|
699
808
|
var batch = Array.from(pending);
|
|
700
809
|
pending.clear();
|
|
701
810
|
for (const block of batch) {
|
|
811
|
+
if (closestStreaming(block) !== null) continue;
|
|
702
812
|
decorate(block);
|
|
703
813
|
void enhance(block);
|
|
704
814
|
}
|
|
@@ -711,6 +821,7 @@ window.__ModuleLoader__.load({
|
|
|
711
821
|
redrawDiagrams();
|
|
712
822
|
return;
|
|
713
823
|
}
|
|
824
|
+
if (closestStreaming(record.target) !== null) continue;
|
|
714
825
|
if (isOurs(record.target)) continue;
|
|
715
826
|
var added = record.addedNodes;
|
|
716
827
|
var oursOnly = added.length > 0;
|
|
@@ -727,22 +838,27 @@ window.__ModuleLoader__.load({
|
|
|
727
838
|
function redrawDiagrams() {
|
|
728
839
|
for (const block of document.querySelectorAll("[" + MMD_ATTR + "]")) {
|
|
729
840
|
if (block.getAttribute(MMD_ATTR) === "failed") continue;
|
|
730
|
-
|
|
841
|
+
cacheKeys.delete(block);
|
|
731
842
|
pending.add(block);
|
|
732
843
|
}
|
|
733
844
|
schedule();
|
|
734
845
|
}
|
|
735
|
-
var
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
else block.setAttribute(WRAP_ATTR, "on");
|
|
743
|
-
}
|
|
846
|
+
var WRAP_BUTTON = {
|
|
847
|
+
cls: TOOL_CLASS,
|
|
848
|
+
titleKey: "wrapTitle",
|
|
849
|
+
ariaKey: "wrapAria",
|
|
850
|
+
run: (block) => {
|
|
851
|
+
if (block.getAttribute(WRAP_ATTR) === "on") block.removeAttribute(WRAP_ATTR);
|
|
852
|
+
else block.setAttribute(WRAP_ATTR, "on");
|
|
744
853
|
}
|
|
745
|
-
|
|
854
|
+
};
|
|
855
|
+
var DOWNLOAD_BUTTON = {
|
|
856
|
+
cls: DOWNLOAD_CLASS,
|
|
857
|
+
titleKey: "downloadCode",
|
|
858
|
+
ariaKey: "downloadCodeAria",
|
|
859
|
+
run: (block) => downloadCode(block)
|
|
860
|
+
};
|
|
861
|
+
var PLAIN_BUTTONS = [WRAP_BUTTON, DOWNLOAD_BUTTON];
|
|
746
862
|
var MMD_BUTTONS = [
|
|
747
863
|
{ cls: ZOOM_OUT_CLASS, titleKey: "zoomOut", ariaKey: "zoomOutAria", run: (block) => zoomBy(block, 1 / ZOOM_STEP) },
|
|
748
864
|
{ cls: ZOOM_IN_CLASS, titleKey: "zoomIn", ariaKey: "zoomInAria", run: (block) => zoomBy(block, ZOOM_STEP) },
|
|
@@ -771,6 +887,12 @@ window.__ModuleLoader__.load({
|
|
|
771
887
|
titleKey: "theme",
|
|
772
888
|
ariaKey: "themeAria",
|
|
773
889
|
run: (block) => cycleMermaidTheme(block)
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
cls: COPY_SOURCE_CLASS,
|
|
893
|
+
titleKey: "copySource",
|
|
894
|
+
ariaKey: "copySourceAria",
|
|
895
|
+
run: (block, button) => copyDiagramSource(block, button)
|
|
774
896
|
}
|
|
775
897
|
];
|
|
776
898
|
var FAILED_BUTTONS = [
|
|
@@ -779,7 +901,7 @@ window.__ModuleLoader__.load({
|
|
|
779
901
|
titleKey: "retry",
|
|
780
902
|
ariaKey: "retryAria",
|
|
781
903
|
run: (block) => {
|
|
782
|
-
|
|
904
|
+
cacheKeys.delete(block);
|
|
783
905
|
block.removeAttribute(MMD_ATTR);
|
|
784
906
|
block.querySelector("." + MMD_CLASS + "-error")?.remove();
|
|
785
907
|
void enhance(block);
|
|
@@ -804,7 +926,8 @@ window.__ModuleLoader__.load({
|
|
|
804
926
|
var label = readBannerLabel(block);
|
|
805
927
|
var lang = readLang(block);
|
|
806
928
|
if (lang !== "" && isPlaceholderLabel(label)) paintLanguageLabel(block, lang);
|
|
807
|
-
var
|
|
929
|
+
var hasNativeWrap = findNativeWrap(nativeButtons) !== null;
|
|
930
|
+
var specs = block.getAttribute(MMD_ATTR) === "failed" ? FAILED_BUTTONS : diagramKind(block) !== null ? MMD_BUTTONS : hasNativeWrap ? [DOWNLOAD_BUTTON] : PLAIN_BUTTONS;
|
|
808
931
|
for (const existing of action.querySelectorAll("." + BTN_CLASS)) {
|
|
809
932
|
if (specs.some((spec) => existing.classList.contains(spec.cls))) continue;
|
|
810
933
|
existing.remove();
|
|
@@ -822,7 +945,7 @@ window.__ModuleLoader__.load({
|
|
|
822
945
|
created.title = themeText;
|
|
823
946
|
created.setAttribute("aria-label", themeText);
|
|
824
947
|
}
|
|
825
|
-
created.addEventListener("click", () => spec.run(block));
|
|
948
|
+
created.addEventListener("click", () => spec.run(block, created));
|
|
826
949
|
action.insertBefore(created, copy);
|
|
827
950
|
injected.add(created);
|
|
828
951
|
}
|
|
@@ -832,13 +955,13 @@ window.__ModuleLoader__.load({
|
|
|
832
955
|
if (host === null) return false;
|
|
833
956
|
if (content.querySelector("pre.shiki:not(.md-plus-pre)") === null) return false;
|
|
834
957
|
host.remove();
|
|
835
|
-
|
|
958
|
+
cacheKeys.delete(block);
|
|
836
959
|
block.removeAttribute(DONE_ATTR);
|
|
837
960
|
return true;
|
|
838
961
|
}
|
|
839
962
|
async function enhance(block) {
|
|
840
963
|
if (!block.isConnected) return;
|
|
841
|
-
if (block
|
|
964
|
+
if (closestStreaming(block) !== null) return;
|
|
842
965
|
var content = block.querySelector(CONTENT);
|
|
843
966
|
if (content === null) return;
|
|
844
967
|
if (releaseTakenOver(block, content)) return;
|
|
@@ -858,7 +981,7 @@ window.__ModuleLoader__.load({
|
|
|
858
981
|
var code = pre.textContent ?? "";
|
|
859
982
|
if (code.trim() === "") return;
|
|
860
983
|
var key = lang + "\0" + code;
|
|
861
|
-
if (
|
|
984
|
+
if (cacheKeys.get(block) === key) return;
|
|
862
985
|
var html;
|
|
863
986
|
try {
|
|
864
987
|
html = await api.highlight(code, lang);
|
|
@@ -883,21 +1006,27 @@ window.__ModuleLoader__.load({
|
|
|
883
1006
|
content.querySelector("." + HOST_CLASS)?.remove();
|
|
884
1007
|
resetFold(content);
|
|
885
1008
|
pre.after(host);
|
|
886
|
-
|
|
1009
|
+
cacheKeys.set(block, key);
|
|
887
1010
|
block.setAttribute(DONE_ATTR, "done");
|
|
888
1011
|
scheduleFold(content, foldLimit("code"));
|
|
889
1012
|
}
|
|
890
1013
|
function getMermaidTheme() {
|
|
1014
|
+
if (themeCache !== null) return themeCache;
|
|
891
1015
|
try {
|
|
892
1016
|
var saved = window.localStorage.getItem(THEME_KEY);
|
|
893
1017
|
if (saved !== null && THEME_ORDER.indexOf(saved) !== -1) {
|
|
894
1018
|
memoryTheme = saved;
|
|
1019
|
+
themeCache = saved;
|
|
895
1020
|
return saved;
|
|
896
1021
|
}
|
|
897
1022
|
memoryTheme = null;
|
|
898
1023
|
} catch {
|
|
899
|
-
if (memoryTheme !== null)
|
|
1024
|
+
if (memoryTheme !== null) {
|
|
1025
|
+
themeCache = memoryTheme;
|
|
1026
|
+
return memoryTheme;
|
|
1027
|
+
}
|
|
900
1028
|
}
|
|
1029
|
+
themeCache = "blue";
|
|
901
1030
|
return "blue";
|
|
902
1031
|
}
|
|
903
1032
|
function themeLabel(name) {
|
|
@@ -915,6 +1044,7 @@ window.__ModuleLoader__.load({
|
|
|
915
1044
|
var index = THEME_ORDER.indexOf(current);
|
|
916
1045
|
var next = THEME_ORDER[(index + 1) % THEME_ORDER.length];
|
|
917
1046
|
memoryTheme = next;
|
|
1047
|
+
themeCache = next;
|
|
918
1048
|
try {
|
|
919
1049
|
window.localStorage.setItem(THEME_KEY, next);
|
|
920
1050
|
} catch {
|
|
@@ -926,7 +1056,7 @@ window.__ModuleLoader__.load({
|
|
|
926
1056
|
var code = (pre.textContent ?? "").trim();
|
|
927
1057
|
if (code === "") return;
|
|
928
1058
|
var key = "mmd\0" + code;
|
|
929
|
-
if (
|
|
1059
|
+
if (cacheKeys.get(block) === key) return;
|
|
930
1060
|
var api = await loadScript(MMD_URL, MMD_GLOBAL);
|
|
931
1061
|
if (disposed || api === null) return;
|
|
932
1062
|
if (!pre.isConnected) return;
|
|
@@ -959,7 +1089,7 @@ window.__ModuleLoader__.load({
|
|
|
959
1089
|
if (viewport !== null) bindViewport(block, viewport);
|
|
960
1090
|
pre.before(host);
|
|
961
1091
|
content.querySelector("." + MMD_CLASS + "-error")?.remove();
|
|
962
|
-
|
|
1092
|
+
cacheKeys.set(block, key);
|
|
963
1093
|
var view = block.getAttribute(MMD_ATTR);
|
|
964
1094
|
if (view !== "code" && view !== "diagram") block.setAttribute(MMD_ATTR, readSettings().diagramView);
|
|
965
1095
|
zooms.delete(block);
|
|
@@ -1072,14 +1202,65 @@ window.__ModuleLoader__.load({
|
|
|
1072
1202
|
var sync = foldSyncs.get(target);
|
|
1073
1203
|
if (sync !== void 0) {
|
|
1074
1204
|
target.removeEventListener("scroll", sync);
|
|
1075
|
-
window.removeEventListener("resize", sync);
|
|
1076
1205
|
foldSyncs.delete(target);
|
|
1077
1206
|
}
|
|
1207
|
+
foldTargets.delete(target);
|
|
1208
|
+
if (foldTargets.size === 0) {
|
|
1209
|
+
if (foldResizeObserver !== null) {
|
|
1210
|
+
foldResizeObserver.disconnect();
|
|
1211
|
+
foldResizeObserver = null;
|
|
1212
|
+
}
|
|
1213
|
+
if (foldResizeHandler !== null) {
|
|
1214
|
+
window.removeEventListener("resize", foldResizeHandler);
|
|
1215
|
+
foldResizeHandler = null;
|
|
1216
|
+
}
|
|
1217
|
+
} else if (foldResizeObserver !== null) {
|
|
1218
|
+
foldResizeObserver.unobserve(target);
|
|
1219
|
+
}
|
|
1078
1220
|
target.removeAttribute(FOLD_ATTR);
|
|
1079
1221
|
target.classList.remove(FOLD_CLASS);
|
|
1080
1222
|
target.style.removeProperty("--md-plus-fold-max-height");
|
|
1081
1223
|
target.querySelector("." + FOLD_BTN_CLASS)?.remove();
|
|
1082
1224
|
}
|
|
1225
|
+
function watchFoldTarget(target, sync) {
|
|
1226
|
+
foldSyncs.set(target, sync);
|
|
1227
|
+
foldTargets.add(target);
|
|
1228
|
+
if (typeof window.ResizeObserver === "function") {
|
|
1229
|
+
if (foldResizeObserver === null) {
|
|
1230
|
+
foldResizeObserver = new window.ResizeObserver((entries) => {
|
|
1231
|
+
for (const entry of entries) {
|
|
1232
|
+
var entryTarget = entry.target;
|
|
1233
|
+
var entrySync = foldSyncs.get(entryTarget);
|
|
1234
|
+
if (entrySync === void 0) continue;
|
|
1235
|
+
if (!entryTarget.isConnected) {
|
|
1236
|
+
resetFold(entryTarget);
|
|
1237
|
+
continue;
|
|
1238
|
+
}
|
|
1239
|
+
entrySync();
|
|
1240
|
+
}
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
foldResizeObserver.observe(target);
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
if (foldResizeHandler === null) {
|
|
1247
|
+
foldResizeHandler = () => {
|
|
1248
|
+
for (const entryTarget of foldTargets) {
|
|
1249
|
+
if (!entryTarget.isConnected) {
|
|
1250
|
+
resetFold(entryTarget);
|
|
1251
|
+
continue;
|
|
1252
|
+
}
|
|
1253
|
+
foldSyncs.get(entryTarget)?.();
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1256
|
+
window.addEventListener("resize", foldResizeHandler);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
function cleanupFoldTargets() {
|
|
1260
|
+
for (const target of foldTargets) {
|
|
1261
|
+
if (!target.isConnected) resetFold(target);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1083
1264
|
function scheduleFold(target, limit) {
|
|
1084
1265
|
if (target === null) return;
|
|
1085
1266
|
if (!(limit > 0)) {
|
|
@@ -1094,7 +1275,7 @@ window.__ModuleLoader__.load({
|
|
|
1094
1275
|
if (target.getAttribute(FOLD_ATTR) !== null) return;
|
|
1095
1276
|
var schedule2 = window.requestAnimationFrame ?? ((cb) => window.setTimeout(cb, 0));
|
|
1096
1277
|
schedule2(() => {
|
|
1097
|
-
if (!target.isConnected || target.getAttribute(FOLD_ATTR) !== null) return;
|
|
1278
|
+
if (disposed || !target.isConnected || target.getAttribute(FOLD_ATTR) !== null) return;
|
|
1098
1279
|
if (target.scrollHeight <= limit) {
|
|
1099
1280
|
target.setAttribute(FOLD_ATTR, "none");
|
|
1100
1281
|
return;
|
|
@@ -1109,12 +1290,15 @@ window.__ModuleLoader__.load({
|
|
|
1109
1290
|
button.textContent = t("foldOpen");
|
|
1110
1291
|
button.setAttribute("aria-expanded", "false");
|
|
1111
1292
|
var sync = target.hasAttribute(TABLE_DONE_ATTR) ? () => {
|
|
1112
|
-
|
|
1293
|
+
if (target.getAttribute(FOLD_ATTR) === "on") {
|
|
1294
|
+
button.style.left = target.scrollLeft + target.clientWidth / 2 + "px";
|
|
1295
|
+
} else {
|
|
1296
|
+
button.style.removeProperty("left");
|
|
1297
|
+
}
|
|
1113
1298
|
} : null;
|
|
1114
1299
|
if (sync !== null) {
|
|
1115
|
-
foldSyncs.set(target, sync);
|
|
1116
1300
|
target.addEventListener("scroll", sync, { passive: true });
|
|
1117
|
-
|
|
1301
|
+
watchFoldTarget(target, sync);
|
|
1118
1302
|
}
|
|
1119
1303
|
button.addEventListener("click", () => {
|
|
1120
1304
|
var folded = target.getAttribute(FOLD_ATTR) === "on";
|
|
@@ -1129,15 +1313,17 @@ window.__ModuleLoader__.load({
|
|
|
1129
1313
|
});
|
|
1130
1314
|
}
|
|
1131
1315
|
function scanFolds() {
|
|
1316
|
+
var codeLimit = foldLimit("code");
|
|
1317
|
+
var tableLimit = foldLimit("table");
|
|
1132
1318
|
for (const block of document.querySelectorAll(BLOCK)) {
|
|
1133
|
-
if (block
|
|
1319
|
+
if (closestStreaming(block) !== null) continue;
|
|
1134
1320
|
if (diagramKind(block) !== null) continue;
|
|
1135
|
-
scheduleFold(block.querySelector(CONTENT),
|
|
1321
|
+
scheduleFold(block.querySelector(CONTENT), codeLimit);
|
|
1136
1322
|
}
|
|
1137
1323
|
for (const table of document.querySelectorAll(TABLE)) {
|
|
1138
|
-
if (table
|
|
1324
|
+
if (closestStreaming(table) !== null) continue;
|
|
1139
1325
|
decorateTable(table);
|
|
1140
|
-
scheduleFold(table,
|
|
1326
|
+
scheduleFold(table, tableLimit);
|
|
1141
1327
|
}
|
|
1142
1328
|
}
|
|
1143
1329
|
function cellText(cell) {
|
|
@@ -1151,6 +1337,22 @@ window.__ModuleLoader__.load({
|
|
|
1151
1337
|
(row) => row.map((value) => /[",\n]/.test(value) ? '"' + value.replace(/"/g, '""') + '"' : value).join(",")
|
|
1152
1338
|
).join("\n");
|
|
1153
1339
|
}
|
|
1340
|
+
function tableToTsv(rows) {
|
|
1341
|
+
return rows.map((row) => row.map((value) => value.replace(/\t/g, " ")).join(" ")).join("\n");
|
|
1342
|
+
}
|
|
1343
|
+
function escapeHtml(text) {
|
|
1344
|
+
return text.replace(
|
|
1345
|
+
/[&<>"']/g,
|
|
1346
|
+
(character) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[character]
|
|
1347
|
+
);
|
|
1348
|
+
}
|
|
1349
|
+
function tableToHtml(rows) {
|
|
1350
|
+
if (rows.length === 0) return "";
|
|
1351
|
+
var cell = (tag, value) => "<" + tag + ">" + escapeHtml(value) + "</" + tag + ">";
|
|
1352
|
+
var header = "<thead><tr>" + rows[0].map((value) => cell("th", value)).join("") + "</tr></thead>";
|
|
1353
|
+
var body = rows.slice(1).map((row) => "<tr>" + row.map((value) => cell("td", value)).join("") + "</tr>");
|
|
1354
|
+
return "<table>" + header + (body.length === 0 ? "" : "<tbody>" + body.join("") + "</tbody>") + "</table>";
|
|
1355
|
+
}
|
|
1154
1356
|
function tableToMarkdown(rows) {
|
|
1155
1357
|
if (rows.length === 0) return "";
|
|
1156
1358
|
var width = Math.max(...rows.map((row) => row.length));
|
|
@@ -1159,10 +1361,43 @@ window.__ModuleLoader__.load({
|
|
|
1159
1361
|
for (var index = 1; index < rows.length; index += 1) output.push(line(rows[index]));
|
|
1160
1362
|
return output.join("\n");
|
|
1161
1363
|
}
|
|
1364
|
+
var CODE_EXTENSIONS = {
|
|
1365
|
+
bash: "sh",
|
|
1366
|
+
batch: "bat",
|
|
1367
|
+
c: "c",
|
|
1368
|
+
cpp: "cpp",
|
|
1369
|
+
csharp: "cs",
|
|
1370
|
+
css: "css",
|
|
1371
|
+
go: "go",
|
|
1372
|
+
html: "html",
|
|
1373
|
+
java: "java",
|
|
1374
|
+
javascript: "js",
|
|
1375
|
+
json: "json",
|
|
1376
|
+
jsx: "jsx",
|
|
1377
|
+
kotlin: "kt",
|
|
1378
|
+
markdown: "md",
|
|
1379
|
+
mermaid: "mmd",
|
|
1380
|
+
php: "php",
|
|
1381
|
+
python: "py",
|
|
1382
|
+
ruby: "rb",
|
|
1383
|
+
rust: "rs",
|
|
1384
|
+
shell: "sh",
|
|
1385
|
+
shellscript: "sh",
|
|
1386
|
+
sql: "sql",
|
|
1387
|
+
swift: "swift",
|
|
1388
|
+
tsx: "tsx",
|
|
1389
|
+
typescript: "ts",
|
|
1390
|
+
xml: "xml",
|
|
1391
|
+
yaml: "yml",
|
|
1392
|
+
yml: "yml"
|
|
1393
|
+
};
|
|
1162
1394
|
async function copyText(text) {
|
|
1163
1395
|
if (window.navigator.clipboard !== void 0 && typeof window.navigator.clipboard.writeText === "function") {
|
|
1164
|
-
|
|
1165
|
-
|
|
1396
|
+
try {
|
|
1397
|
+
await window.navigator.clipboard.writeText(text);
|
|
1398
|
+
return true;
|
|
1399
|
+
} catch {
|
|
1400
|
+
}
|
|
1166
1401
|
}
|
|
1167
1402
|
var area = document.createElement("textarea");
|
|
1168
1403
|
area.value = text;
|
|
@@ -1179,6 +1414,55 @@ window.__ModuleLoader__.load({
|
|
|
1179
1414
|
area.remove();
|
|
1180
1415
|
return ok;
|
|
1181
1416
|
}
|
|
1417
|
+
async function copyRichText(text, html) {
|
|
1418
|
+
if (window.navigator.clipboard !== void 0 && typeof window.navigator.clipboard.write === "function" && typeof window.ClipboardItem === "function") {
|
|
1419
|
+
try {
|
|
1420
|
+
await window.navigator.clipboard.write([
|
|
1421
|
+
new window.ClipboardItem({
|
|
1422
|
+
"text/plain": new Blob([text], { type: "text/plain" }),
|
|
1423
|
+
"text/html": new Blob([html], { type: "text/html" })
|
|
1424
|
+
})
|
|
1425
|
+
]);
|
|
1426
|
+
return true;
|
|
1427
|
+
} catch {
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return copyText(text);
|
|
1431
|
+
}
|
|
1432
|
+
async function copyDiagramSource(block, button) {
|
|
1433
|
+
var pre = block.querySelector(CONTENT + " pre");
|
|
1434
|
+
if (pre === null) return;
|
|
1435
|
+
var ok = false;
|
|
1436
|
+
try {
|
|
1437
|
+
ok = await copyText(pre.textContent ?? "");
|
|
1438
|
+
} catch {
|
|
1439
|
+
ok = false;
|
|
1440
|
+
}
|
|
1441
|
+
if (button !== void 0) {
|
|
1442
|
+
var original = button.title;
|
|
1443
|
+
var label = ok ? t("copied") : t("copyFailed");
|
|
1444
|
+
button.title = label;
|
|
1445
|
+
button.setAttribute("aria-label", label);
|
|
1446
|
+
window.setTimeout(() => {
|
|
1447
|
+
button.title = original;
|
|
1448
|
+
button.setAttribute("aria-label", original);
|
|
1449
|
+
}, 1200);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function downloadCode(block) {
|
|
1453
|
+
var pre = block.querySelector(CONTENT + " pre");
|
|
1454
|
+
if (pre === null) return;
|
|
1455
|
+
var lang = readLang(block);
|
|
1456
|
+
var ext = CODE_EXTENSIONS[lang] ?? "txt";
|
|
1457
|
+
try {
|
|
1458
|
+
downloadBlob(
|
|
1459
|
+
new Blob([pre.textContent ?? ""], { type: "text/plain;charset=utf-8" }),
|
|
1460
|
+
"code-snippet." + ext
|
|
1461
|
+
);
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
console.warn("[dsh-md-plus] \u4EE3\u7801\u4E0B\u8F7D\u5931\u8D25", error);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1182
1466
|
function flashButton(button, text) {
|
|
1183
1467
|
var original = button.getAttribute("data-md-plus-label") ?? button.textContent;
|
|
1184
1468
|
button.setAttribute("data-md-plus-label", original);
|
|
@@ -1187,9 +1471,88 @@ window.__ModuleLoader__.load({
|
|
|
1187
1471
|
button.textContent = original;
|
|
1188
1472
|
}, 1200);
|
|
1189
1473
|
}
|
|
1474
|
+
function clearTableFreeze(table) {
|
|
1475
|
+
for (const cell of table.querySelectorAll(
|
|
1476
|
+
"." + FREEZE_ROW_CLASS + ",." + FREEZE_COL_CLASS + ",." + FREEZE_CROSS_CLASS
|
|
1477
|
+
)) {
|
|
1478
|
+
cell.classList.remove(FREEZE_ROW_CLASS, FREEZE_COL_CLASS, FREEZE_CROSS_CLASS);
|
|
1479
|
+
cell.style.removeProperty("top");
|
|
1480
|
+
cell.style.removeProperty("left");
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
function observeTableFreeze(table) {
|
|
1484
|
+
if (tableFreezeTargets.has(table)) return;
|
|
1485
|
+
tableFreezeTargets.add(table);
|
|
1486
|
+
if (typeof window.ResizeObserver !== "function") return;
|
|
1487
|
+
if (tableFreezeObserver === null) {
|
|
1488
|
+
tableFreezeObserver = new window.ResizeObserver((entries) => {
|
|
1489
|
+
for (const entry of entries) {
|
|
1490
|
+
if (!entry.target.isConnected) {
|
|
1491
|
+
cleanupTableFreezeTargets();
|
|
1492
|
+
continue;
|
|
1493
|
+
}
|
|
1494
|
+
applyTableFreeze(entry.target);
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
tableFreezeObserver.observe(table);
|
|
1499
|
+
}
|
|
1500
|
+
function applyTableFreeze(table) {
|
|
1501
|
+
var dataTable = table.querySelector("table");
|
|
1502
|
+
if (dataTable === null) return;
|
|
1503
|
+
var settings = readSettings();
|
|
1504
|
+
var freezeRows = Math.max(0, Math.min(5, Number(settings.freezeRows) || 0));
|
|
1505
|
+
var freezeCols = Math.max(0, Math.min(5, Number(settings.freezeCols) || 0));
|
|
1506
|
+
var width = dataTable.scrollWidth;
|
|
1507
|
+
var height = dataTable.scrollHeight;
|
|
1508
|
+
var hasFrozenCells = dataTable.querySelector("." + FREEZE_ROW_CLASS + ",." + FREEZE_COL_CLASS) !== null;
|
|
1509
|
+
var state = tableFreezeState.get(table);
|
|
1510
|
+
if (state !== void 0 && state.rows === freezeRows && state.cols === freezeCols && state.width === width && state.height === height && (freezeRows === 0 && freezeCols === 0 || hasFrozenCells)) {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
clearTableFreeze(table);
|
|
1514
|
+
tableFreezeState.set(table, { rows: freezeRows, cols: freezeCols, width, height });
|
|
1515
|
+
if (freezeRows === 0 && freezeCols === 0) return;
|
|
1516
|
+
var rows = Array.from(dataTable.rows);
|
|
1517
|
+
var top = 0;
|
|
1518
|
+
for (var rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
|
|
1519
|
+
var row = rows[rowIndex];
|
|
1520
|
+
var cells = Array.from(row.cells);
|
|
1521
|
+
var frozenRow = rowIndex < freezeRows;
|
|
1522
|
+
if (frozenRow) {
|
|
1523
|
+
for (const cell2 of cells) cell2.classList.add(FREEZE_ROW_CLASS);
|
|
1524
|
+
}
|
|
1525
|
+
var left = 0;
|
|
1526
|
+
for (var cellIndex = 0; cellIndex < cells.length; cellIndex += 1) {
|
|
1527
|
+
var cell = cells[cellIndex];
|
|
1528
|
+
if (frozenRow) cell.style.top = top + "px";
|
|
1529
|
+
if (cellIndex < freezeCols) {
|
|
1530
|
+
cell.classList.add(FREEZE_COL_CLASS);
|
|
1531
|
+
if (frozenRow) cell.classList.add(FREEZE_CROSS_CLASS);
|
|
1532
|
+
cell.style.left = left + "px";
|
|
1533
|
+
left += cell.getBoundingClientRect().width;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
if (frozenRow) top += row.getBoundingClientRect().height;
|
|
1537
|
+
}
|
|
1538
|
+
observeTableFreeze(table);
|
|
1539
|
+
}
|
|
1540
|
+
function cleanupTableFreezeTargets() {
|
|
1541
|
+
for (const table of tableFreezeTargets) {
|
|
1542
|
+
if (table.isConnected) continue;
|
|
1543
|
+
if (tableFreezeObserver !== null) tableFreezeObserver.unobserve(table);
|
|
1544
|
+
tableFreezeTargets.delete(table);
|
|
1545
|
+
tableFreezeState.delete(table);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
function applyTableFreezeSettings() {
|
|
1549
|
+
tableFreezeState = /* @__PURE__ */ new WeakMap();
|
|
1550
|
+
for (const table of document.querySelectorAll(TABLE)) applyTableFreeze(table);
|
|
1551
|
+
}
|
|
1190
1552
|
function decorateTable(table) {
|
|
1191
1553
|
var dataTable = table.querySelector("table");
|
|
1192
1554
|
if (dataTable === null) return;
|
|
1555
|
+
applyTableFreeze(table);
|
|
1193
1556
|
var first = dataTable.firstElementChild;
|
|
1194
1557
|
if (first !== null && first.classList.contains(TABLE_TOOLS_CLASS)) return;
|
|
1195
1558
|
table.setAttribute(TABLE_DONE_ATTR, "1");
|
|
@@ -1197,11 +1560,13 @@ window.__ModuleLoader__.load({
|
|
|
1197
1560
|
tools.className = TABLE_TOOLS_CLASS;
|
|
1198
1561
|
var group = document.createElement("span");
|
|
1199
1562
|
group.className = TABLE_TOOLS_CLASS + "-group";
|
|
1200
|
-
for (const [kind, label, titleKey, convert] of [
|
|
1201
|
-
["csv", t("tableCsv"), "copyCsvTitle", tableToCsv],
|
|
1202
|
-
["
|
|
1563
|
+
for (const [kind, label, titleKey, convert, rich] of [
|
|
1564
|
+
["csv", t("tableCsv"), "copyCsvTitle", tableToCsv, false],
|
|
1565
|
+
["tsv", t("tableTsv"), "copyTsvTitle", tableToTsv, false],
|
|
1566
|
+
["md", t("tableMd"), "copyMdTitle", tableToMarkdown, false],
|
|
1567
|
+
["html", t("tableHtml"), "copyHtmlTitle", tableToHtml, true]
|
|
1203
1568
|
]) {
|
|
1204
|
-
|
|
1569
|
+
const button = document.createElement("button");
|
|
1205
1570
|
button.type = "button";
|
|
1206
1571
|
button.textContent = label;
|
|
1207
1572
|
button.title = t(titleKey);
|
|
@@ -1209,7 +1574,8 @@ window.__ModuleLoader__.load({
|
|
|
1209
1574
|
button.addEventListener("click", async () => {
|
|
1210
1575
|
var ok = false;
|
|
1211
1576
|
try {
|
|
1212
|
-
|
|
1577
|
+
var rows = tableRows(dataTable);
|
|
1578
|
+
ok = rich ? await copyRichText(tableToTsv(rows), convert(rows)) : await copyText(convert(rows));
|
|
1213
1579
|
} catch {
|
|
1214
1580
|
ok = false;
|
|
1215
1581
|
}
|
|
@@ -1220,6 +1586,48 @@ window.__ModuleLoader__.load({
|
|
|
1220
1586
|
tools.appendChild(group);
|
|
1221
1587
|
dataTable.insertBefore(tools, dataTable.firstChild);
|
|
1222
1588
|
}
|
|
1589
|
+
var scrollLocks = 0;
|
|
1590
|
+
var previousRootOverflow = "";
|
|
1591
|
+
function lockPageScroll() {
|
|
1592
|
+
if (scrollLocks === 0) {
|
|
1593
|
+
previousRootOverflow = document.documentElement.style.overflow;
|
|
1594
|
+
document.documentElement.style.overflow = "hidden";
|
|
1595
|
+
}
|
|
1596
|
+
scrollLocks += 1;
|
|
1597
|
+
}
|
|
1598
|
+
function unlockPageScroll() {
|
|
1599
|
+
if (scrollLocks === 0) return;
|
|
1600
|
+
scrollLocks -= 1;
|
|
1601
|
+
if (scrollLocks === 0) {
|
|
1602
|
+
document.documentElement.style.overflow = previousRootOverflow;
|
|
1603
|
+
previousRootOverflow = "";
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
function trapFocus(container) {
|
|
1607
|
+
function onKey(event) {
|
|
1608
|
+
if (event.key !== "Tab") return;
|
|
1609
|
+
var candidates = Array.from(
|
|
1610
|
+
container.querySelectorAll(
|
|
1611
|
+
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
|
1612
|
+
)
|
|
1613
|
+
).filter((node) => node.offsetParent !== null || node === document.activeElement);
|
|
1614
|
+
if (candidates.length === 0) {
|
|
1615
|
+
event.preventDefault();
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
var first = candidates[0];
|
|
1619
|
+
var last = candidates[candidates.length - 1];
|
|
1620
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
1621
|
+
event.preventDefault();
|
|
1622
|
+
last.focus();
|
|
1623
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
1624
|
+
event.preventDefault();
|
|
1625
|
+
first.focus();
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
container.addEventListener("keydown", onKey, true);
|
|
1629
|
+
return () => container.removeEventListener("keydown", onKey, true);
|
|
1630
|
+
}
|
|
1223
1631
|
function openImage(source, alt) {
|
|
1224
1632
|
if (document.querySelector("." + IMG_MODAL_CLASS) !== null) return;
|
|
1225
1633
|
var overlay = document.createElement("div");
|
|
@@ -1236,12 +1644,15 @@ window.__ModuleLoader__.load({
|
|
|
1236
1644
|
closeButton.textContent = "\xD7";
|
|
1237
1645
|
closeButton.setAttribute("aria-label", t("imageClose"));
|
|
1238
1646
|
var previousFocus = document.activeElement;
|
|
1647
|
+
var releaseFocus = null;
|
|
1239
1648
|
var closed = false;
|
|
1240
1649
|
function closeViewer() {
|
|
1241
1650
|
if (closed) return;
|
|
1242
1651
|
closed = true;
|
|
1652
|
+
releaseFocus?.();
|
|
1243
1653
|
document.removeEventListener("keydown", onKey, true);
|
|
1244
1654
|
overlay.remove();
|
|
1655
|
+
unlockPageScroll();
|
|
1245
1656
|
if (previousFocus !== null && typeof previousFocus.focus === "function") previousFocus.focus();
|
|
1246
1657
|
}
|
|
1247
1658
|
function onKey(event) {
|
|
@@ -1257,7 +1668,9 @@ window.__ModuleLoader__.load({
|
|
|
1257
1668
|
document.addEventListener("keydown", onKey, true);
|
|
1258
1669
|
overlay.appendChild(image);
|
|
1259
1670
|
overlay.appendChild(closeButton);
|
|
1671
|
+
lockPageScroll();
|
|
1260
1672
|
document.body.appendChild(overlay);
|
|
1673
|
+
releaseFocus = trapFocus(overlay);
|
|
1261
1674
|
closeButton.focus();
|
|
1262
1675
|
}
|
|
1263
1676
|
function onDocumentClick(event) {
|
|
@@ -1300,13 +1713,57 @@ window.__ModuleLoader__.load({
|
|
|
1300
1713
|
return input;
|
|
1301
1714
|
}
|
|
1302
1715
|
function rescanFolds() {
|
|
1303
|
-
|
|
1716
|
+
diagramKindCache = /* @__PURE__ */ new WeakMap();
|
|
1717
|
+
var codeLimit = foldLimit("code");
|
|
1718
|
+
var tableLimit = foldLimit("table");
|
|
1719
|
+
var diagramLimit = foldLimit("diagram");
|
|
1720
|
+
for (const node of document.querySelectorAll("[" + FOLD_ATTR + "]")) {
|
|
1721
|
+
if (node.classList.contains(MMD_CLASS + "-viewport")) continue;
|
|
1722
|
+
var limit = node.hasAttribute(TABLE_DONE_ATTR) ? tableLimit : codeLimit;
|
|
1723
|
+
if (node.getAttribute(FOLD_ATTR) === "off" && limit > 0) {
|
|
1724
|
+
node.style.setProperty("--md-plus-fold-max-height", limit + "px");
|
|
1725
|
+
continue;
|
|
1726
|
+
}
|
|
1727
|
+
resetFold(node);
|
|
1728
|
+
}
|
|
1304
1729
|
for (const viewport of document.querySelectorAll("." + MMD_CLASS + "-viewport")) {
|
|
1730
|
+
if (viewport.getAttribute(FOLD_ATTR) === "off" && diagramLimit > 0) {
|
|
1731
|
+
viewport.style.setProperty("--md-plus-fold-max-height", diagramLimit + "px");
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1305
1734
|
resetFold(viewport);
|
|
1306
|
-
scheduleFold(viewport,
|
|
1735
|
+
scheduleFold(viewport, diagramLimit);
|
|
1307
1736
|
}
|
|
1308
1737
|
scanFolds();
|
|
1309
1738
|
}
|
|
1739
|
+
function setFoldExpanded(target, expanded) {
|
|
1740
|
+
var state = target.getAttribute(FOLD_ATTR);
|
|
1741
|
+
if (state !== "on" && state !== "off") return;
|
|
1742
|
+
target.setAttribute(FOLD_ATTR, expanded ? "off" : "on");
|
|
1743
|
+
if (target.hasAttribute(TABLE_DONE_ATTR)) target.scrollTop = 0;
|
|
1744
|
+
var button = target.querySelector("." + FOLD_BTN_CLASS);
|
|
1745
|
+
if (button !== null) {
|
|
1746
|
+
button.textContent = expanded ? t("foldClose") : t("foldOpen");
|
|
1747
|
+
button.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
1748
|
+
}
|
|
1749
|
+
foldSyncs.get(target)?.();
|
|
1750
|
+
}
|
|
1751
|
+
function setAllFolds(expanded) {
|
|
1752
|
+
for (const target of document.querySelectorAll("[" + FOLD_ATTR + "]")) {
|
|
1753
|
+
setFoldExpanded(target, expanded);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
function exportSettings() {
|
|
1757
|
+
try {
|
|
1758
|
+
var payload = { settings: readSettings(), mermaidTheme: getMermaidTheme() };
|
|
1759
|
+
downloadBlob(
|
|
1760
|
+
new Blob([JSON.stringify(payload, null, 2)], { type: "application/json;charset=utf-8" }),
|
|
1761
|
+
"dsh-md-plus-settings.json"
|
|
1762
|
+
);
|
|
1763
|
+
} catch (error) {
|
|
1764
|
+
console.warn("[dsh-md-plus] \u8BBE\u7F6E\u5BFC\u51FA\u5931\u8D25", error);
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1310
1767
|
function openSettings() {
|
|
1311
1768
|
if (document.querySelector("." + SETTINGS_MODAL_CLASS) !== null) return;
|
|
1312
1769
|
var current = readSettings();
|
|
@@ -1331,11 +1788,9 @@ window.__ModuleLoader__.load({
|
|
|
1331
1788
|
themeSelect.value = getMermaidTheme();
|
|
1332
1789
|
panel.appendChild(settingRow(t("settingsTheme"), themeSelect));
|
|
1333
1790
|
var fontInput = numberInput(current.codeFontSize, 10, 20);
|
|
1334
|
-
panel.appendChild(
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
fontHint.textContent = t("settingsFontSizeHint");
|
|
1338
|
-
panel.appendChild(fontHint);
|
|
1791
|
+
panel.appendChild(
|
|
1792
|
+
settingRow(t("settingsFontSize"), fontInput, t("settingsFontSizeHint"))
|
|
1793
|
+
);
|
|
1339
1794
|
var viewSelect = document.createElement("select");
|
|
1340
1795
|
for (const [value, label] of [
|
|
1341
1796
|
["diagram", t("settingsViewDiagram")],
|
|
@@ -1349,7 +1804,7 @@ window.__ModuleLoader__.load({
|
|
|
1349
1804
|
viewSelect.value = current.diagramView;
|
|
1350
1805
|
panel.appendChild(settingRow(t("settingsView"), viewSelect));
|
|
1351
1806
|
var foldHint = document.createElement("p");
|
|
1352
|
-
foldHint.className = SETTINGS_MODAL_CLASS + "-
|
|
1807
|
+
foldHint.className = SETTINGS_MODAL_CLASS + "-section";
|
|
1353
1808
|
foldHint.textContent = t("settingsFold") + " \xB7 " + t("settingsFoldHint");
|
|
1354
1809
|
panel.appendChild(foldHint);
|
|
1355
1810
|
var foldCode = numberInput(current.foldCode, 0, 4e3);
|
|
@@ -1358,6 +1813,56 @@ window.__ModuleLoader__.load({
|
|
|
1358
1813
|
panel.appendChild(settingRow(t("settingsFoldCode"), foldCode, t("settingsFoldCodeHint")));
|
|
1359
1814
|
panel.appendChild(settingRow(t("settingsFoldTable"), foldTable, t("settingsFoldTableHint")));
|
|
1360
1815
|
panel.appendChild(settingRow(t("settingsFoldDiagram"), foldDiagram, t("settingsFoldDiagramHint")));
|
|
1816
|
+
var freezeRowsInput = numberInput(current.freezeRows, 0, 5);
|
|
1817
|
+
var freezeColsInput = numberInput(current.freezeCols, 0, 5);
|
|
1818
|
+
panel.appendChild(
|
|
1819
|
+
settingRow(t("settingsFreezeRows"), freezeRowsInput, t("settingsFreezeRowsHint"))
|
|
1820
|
+
);
|
|
1821
|
+
panel.appendChild(
|
|
1822
|
+
settingRow(t("settingsFreezeCols"), freezeColsInput, t("settingsFreezeColsHint"))
|
|
1823
|
+
);
|
|
1824
|
+
var foldActions = document.createElement("div");
|
|
1825
|
+
foldActions.className = SETTINGS_MODAL_CLASS + "-fold-actions";
|
|
1826
|
+
foldActions.setAttribute("role", "group");
|
|
1827
|
+
foldActions.setAttribute("aria-label", t("settingsFoldGroup"));
|
|
1828
|
+
var foldLabel = document.createElement("span");
|
|
1829
|
+
foldLabel.className = SETTINGS_MODAL_CLASS + "-utility-label";
|
|
1830
|
+
foldLabel.textContent = t("settingsFoldGroup");
|
|
1831
|
+
var foldSegment = document.createElement("span");
|
|
1832
|
+
foldSegment.className = SETTINGS_MODAL_CLASS + "-segment";
|
|
1833
|
+
var expandAllButton = document.createElement("button");
|
|
1834
|
+
expandAllButton.type = "button";
|
|
1835
|
+
expandAllButton.textContent = t("foldExpandAll");
|
|
1836
|
+
var collapseAllButton = document.createElement("button");
|
|
1837
|
+
collapseAllButton.type = "button";
|
|
1838
|
+
collapseAllButton.textContent = t("foldCollapseAll");
|
|
1839
|
+
foldSegment.appendChild(expandAllButton);
|
|
1840
|
+
foldSegment.appendChild(collapseAllButton);
|
|
1841
|
+
foldActions.appendChild(foldLabel);
|
|
1842
|
+
foldActions.appendChild(foldSegment);
|
|
1843
|
+
var transferActions = document.createElement("div");
|
|
1844
|
+
transferActions.className = SETTINGS_MODAL_CLASS + "-transfer-actions";
|
|
1845
|
+
transferActions.setAttribute("role", "group");
|
|
1846
|
+
transferActions.setAttribute("aria-label", t("settingsFileGroup"));
|
|
1847
|
+
var transferLabel = document.createElement("span");
|
|
1848
|
+
transferLabel.className = SETTINGS_MODAL_CLASS + "-utility-label";
|
|
1849
|
+
transferLabel.textContent = t("settingsFileGroup");
|
|
1850
|
+
var transferSegment = document.createElement("span");
|
|
1851
|
+
transferSegment.className = SETTINGS_MODAL_CLASS + "-segment";
|
|
1852
|
+
var exportButton = document.createElement("button");
|
|
1853
|
+
exportButton.type = "button";
|
|
1854
|
+
exportButton.textContent = t("settingsExport");
|
|
1855
|
+
var importButton = document.createElement("button");
|
|
1856
|
+
importButton.type = "button";
|
|
1857
|
+
importButton.textContent = t("settingsImport");
|
|
1858
|
+
var fileInput = document.createElement("input");
|
|
1859
|
+
fileInput.type = "file";
|
|
1860
|
+
fileInput.accept = ".json,application/json";
|
|
1861
|
+
fileInput.style.display = "none";
|
|
1862
|
+
transferSegment.appendChild(exportButton);
|
|
1863
|
+
transferSegment.appendChild(importButton);
|
|
1864
|
+
transferActions.appendChild(transferLabel);
|
|
1865
|
+
transferActions.appendChild(transferSegment);
|
|
1361
1866
|
var actions = document.createElement("div");
|
|
1362
1867
|
actions.className = SETTINGS_MODAL_CLASS + "-actions";
|
|
1363
1868
|
var resetButton = document.createElement("button");
|
|
@@ -1373,15 +1878,27 @@ window.__ModuleLoader__.load({
|
|
|
1373
1878
|
actions.appendChild(resetButton);
|
|
1374
1879
|
actions.appendChild(closeButton);
|
|
1375
1880
|
actions.appendChild(saveButton);
|
|
1376
|
-
|
|
1881
|
+
var utilities = document.createElement("div");
|
|
1882
|
+
utilities.className = SETTINGS_MODAL_CLASS + "-utilities";
|
|
1883
|
+
utilities.appendChild(foldActions);
|
|
1884
|
+
utilities.appendChild(transferActions);
|
|
1885
|
+
var footer = document.createElement("div");
|
|
1886
|
+
footer.className = SETTINGS_MODAL_CLASS + "-footer";
|
|
1887
|
+
footer.appendChild(utilities);
|
|
1888
|
+
footer.appendChild(actions);
|
|
1889
|
+
panel.appendChild(footer);
|
|
1890
|
+
panel.appendChild(fileInput);
|
|
1377
1891
|
overlay.appendChild(panel);
|
|
1378
1892
|
var previousFocus = document.activeElement;
|
|
1893
|
+
var releaseFocus = null;
|
|
1379
1894
|
var closed = false;
|
|
1380
1895
|
function closeSettings() {
|
|
1381
1896
|
if (closed) return;
|
|
1382
1897
|
closed = true;
|
|
1898
|
+
releaseFocus?.();
|
|
1383
1899
|
document.removeEventListener("keydown", onKey, true);
|
|
1384
1900
|
overlay.remove();
|
|
1901
|
+
unlockPageScroll();
|
|
1385
1902
|
if (previousFocus !== null && typeof previousFocus.focus === "function") previousFocus.focus();
|
|
1386
1903
|
}
|
|
1387
1904
|
function onKey(event) {
|
|
@@ -1399,6 +1916,48 @@ window.__ModuleLoader__.load({
|
|
|
1399
1916
|
if (!Number.isFinite(value) || value <= 0) return 0;
|
|
1400
1917
|
return Math.min(20, Math.max(10, Math.round(value)));
|
|
1401
1918
|
}
|
|
1919
|
+
function importSettingsFile(file) {
|
|
1920
|
+
file.text().then((text) => {
|
|
1921
|
+
var parsed = JSON.parse(text);
|
|
1922
|
+
var source = parsed !== null && typeof parsed === "object" && parsed.settings !== null && typeof parsed.settings === "object" ? parsed.settings : parsed;
|
|
1923
|
+
if (source === null || typeof source !== "object") throw new Error("\u8BBE\u7F6E\u683C\u5F0F\u65E0\u6548");
|
|
1924
|
+
var font = Number(source.codeFontSize);
|
|
1925
|
+
if (Number.isFinite(font)) {
|
|
1926
|
+
fontInput.value = font > 0 ? String(Math.min(20, Math.max(10, Math.round(font)))) : "";
|
|
1927
|
+
}
|
|
1928
|
+
for (const [key, input, max] of [
|
|
1929
|
+
["foldCode", foldCode, 4e3],
|
|
1930
|
+
["foldTable", foldTable, 4e3],
|
|
1931
|
+
["foldDiagram", foldDiagram, 4e3],
|
|
1932
|
+
["freezeRows", freezeRowsInput, 5],
|
|
1933
|
+
["freezeCols", freezeColsInput, 5]
|
|
1934
|
+
]) {
|
|
1935
|
+
var value = Number(source[key]);
|
|
1936
|
+
if (Number.isFinite(value) && value >= 0) {
|
|
1937
|
+
input.value = String(Math.min(max, Math.round(value)));
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
if (source.diagramView === "code" || source.diagramView === "diagram") {
|
|
1941
|
+
viewSelect.value = source.diagramView;
|
|
1942
|
+
}
|
|
1943
|
+
var theme = parsed !== null && typeof parsed === "object" ? parsed.mermaidTheme : null;
|
|
1944
|
+
if (typeof theme === "string" && THEME_ORDER.indexOf(theme) !== -1) {
|
|
1945
|
+
themeSelect.value = theme;
|
|
1946
|
+
}
|
|
1947
|
+
saveButton.click();
|
|
1948
|
+
}).catch(() => {
|
|
1949
|
+
flashButton(importButton, t("settingsImportFailed"));
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1952
|
+
exportButton.addEventListener("click", exportSettings);
|
|
1953
|
+
importButton.addEventListener("click", () => fileInput.click());
|
|
1954
|
+
fileInput.addEventListener("change", () => {
|
|
1955
|
+
var file = fileInput.files?.[0];
|
|
1956
|
+
if (file !== null && file !== void 0) importSettingsFile(file);
|
|
1957
|
+
fileInput.value = "";
|
|
1958
|
+
});
|
|
1959
|
+
expandAllButton.addEventListener("click", () => setAllFolds(true));
|
|
1960
|
+
collapseAllButton.addEventListener("click", () => setAllFolds(false));
|
|
1402
1961
|
resetButton.addEventListener("click", () => {
|
|
1403
1962
|
themeSelect.value = "blue";
|
|
1404
1963
|
fontInput.value = "";
|
|
@@ -1406,24 +1965,36 @@ window.__ModuleLoader__.load({
|
|
|
1406
1965
|
foldCode.value = String(DEFAULT_SETTINGS.foldCode);
|
|
1407
1966
|
foldTable.value = String(DEFAULT_SETTINGS.foldTable);
|
|
1408
1967
|
foldDiagram.value = String(DEFAULT_SETTINGS.foldDiagram);
|
|
1968
|
+
freezeRowsInput.value = String(DEFAULT_SETTINGS.freezeRows);
|
|
1969
|
+
freezeColsInput.value = String(DEFAULT_SETTINGS.freezeCols);
|
|
1409
1970
|
});
|
|
1410
1971
|
saveButton.addEventListener("click", () => {
|
|
1411
|
-
|
|
1972
|
+
var previous = readSettings();
|
|
1973
|
+
var previousTheme = getMermaidTheme();
|
|
1974
|
+
var nextTheme = THEME_ORDER.indexOf(themeSelect.value) === -1 ? "blue" : themeSelect.value;
|
|
1975
|
+
var next = {
|
|
1412
1976
|
codeFontSize: readFontSize(fontInput),
|
|
1413
1977
|
diagramView: viewSelect.value === "code" ? "code" : "diagram",
|
|
1414
1978
|
foldCode: readNumber(foldCode, DEFAULT_SETTINGS.foldCode),
|
|
1415
1979
|
foldTable: readNumber(foldTable, DEFAULT_SETTINGS.foldTable),
|
|
1416
|
-
foldDiagram: readNumber(foldDiagram, DEFAULT_SETTINGS.foldDiagram)
|
|
1417
|
-
|
|
1418
|
-
|
|
1980
|
+
foldDiagram: readNumber(foldDiagram, DEFAULT_SETTINGS.foldDiagram),
|
|
1981
|
+
freezeRows: readNumber(freezeRowsInput, DEFAULT_SETTINGS.freezeRows, 5),
|
|
1982
|
+
freezeCols: readNumber(freezeColsInput, DEFAULT_SETTINGS.freezeCols, 5)
|
|
1983
|
+
};
|
|
1984
|
+
saveSettings(next);
|
|
1985
|
+
memoryTheme = nextTheme;
|
|
1986
|
+
themeCache = nextTheme;
|
|
1419
1987
|
try {
|
|
1420
|
-
window.localStorage.setItem(THEME_KEY,
|
|
1988
|
+
window.localStorage.setItem(THEME_KEY, nextTheme);
|
|
1421
1989
|
} catch {
|
|
1422
1990
|
}
|
|
1423
1991
|
applyCodeFontSize();
|
|
1992
|
+
applyTableFreezeSettings();
|
|
1424
1993
|
refreshThemeButtons();
|
|
1425
|
-
redrawDiagrams();
|
|
1426
|
-
|
|
1994
|
+
if (previousTheme !== nextTheme) redrawDiagrams();
|
|
1995
|
+
if (previous.codeFontSize !== next.codeFontSize || previous.foldCode !== next.foldCode || previous.foldTable !== next.foldTable || previous.foldDiagram !== next.foldDiagram) {
|
|
1996
|
+
rescanFolds();
|
|
1997
|
+
}
|
|
1427
1998
|
closeSettings();
|
|
1428
1999
|
});
|
|
1429
2000
|
closeButton.addEventListener("click", closeSettings);
|
|
@@ -1431,12 +2002,18 @@ window.__ModuleLoader__.load({
|
|
|
1431
2002
|
if (event.target === overlay) closeSettings();
|
|
1432
2003
|
});
|
|
1433
2004
|
document.addEventListener("keydown", onKey, true);
|
|
2005
|
+
lockPageScroll();
|
|
1434
2006
|
document.body.appendChild(overlay);
|
|
2007
|
+
releaseFocus = trapFocus(overlay);
|
|
1435
2008
|
saveButton.focus();
|
|
1436
2009
|
}
|
|
1437
2010
|
function ensureSettingsButton() {
|
|
1438
|
-
|
|
1439
|
-
if (document.querySelector('[class*="_markdown_"], .md-code-block') === null)
|
|
2011
|
+
var existing = document.querySelector("." + SETTINGS_BTN_CLASS);
|
|
2012
|
+
if (document.querySelector('[class*="_markdown_"], .md-code-block') === null) {
|
|
2013
|
+
existing?.remove();
|
|
2014
|
+
return;
|
|
2015
|
+
}
|
|
2016
|
+
if (existing !== null) return;
|
|
1440
2017
|
var button = document.createElement("button");
|
|
1441
2018
|
button.type = "button";
|
|
1442
2019
|
button.className = SETTINGS_BTN_CLASS;
|
|
@@ -1490,16 +2067,23 @@ window.__ModuleLoader__.load({
|
|
|
1490
2067
|
link.remove();
|
|
1491
2068
|
window.setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
1492
2069
|
}
|
|
1493
|
-
function
|
|
2070
|
+
function exportFailed(button, error) {
|
|
2071
|
+
console.warn("[dsh-md-plus] \u56FE\u8868\u5BFC\u51FA\u5931\u8D25", error);
|
|
2072
|
+
if (button !== void 0) flashButton(button, t("exportFailed"));
|
|
2073
|
+
}
|
|
2074
|
+
function downloadSvg(svg, button) {
|
|
1494
2075
|
try {
|
|
1495
2076
|
downloadBlob(new Blob([serializeSvg(svg)], { type: "image/svg+xml;charset=utf-8" }), "mermaid-diagram.svg");
|
|
1496
2077
|
} catch (error) {
|
|
1497
|
-
|
|
2078
|
+
exportFailed(button, error);
|
|
1498
2079
|
}
|
|
1499
2080
|
}
|
|
1500
|
-
function downloadPng(svg) {
|
|
2081
|
+
function downloadPng(svg, button) {
|
|
1501
2082
|
var size = svgSize(svg);
|
|
1502
|
-
if (size.width <= 0 || size.height <= 0)
|
|
2083
|
+
if (size.width <= 0 || size.height <= 0) {
|
|
2084
|
+
exportFailed(button, new Error("\u56FE\u8868\u5C3A\u5BF8\u65E0\u6548"));
|
|
2085
|
+
return;
|
|
2086
|
+
}
|
|
1503
2087
|
var image = new window.Image();
|
|
1504
2088
|
var objectUrl = "";
|
|
1505
2089
|
image.onload = function() {
|
|
@@ -1513,16 +2097,17 @@ window.__ModuleLoader__.load({
|
|
|
1513
2097
|
context.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
1514
2098
|
canvas.toBlob((blob) => {
|
|
1515
2099
|
if (blob !== null) downloadBlob(blob, "mermaid-diagram.png");
|
|
2100
|
+
else exportFailed(button, new Error("canvas \u672A\u751F\u6210\u56FE\u7247"));
|
|
1516
2101
|
}, "image/png");
|
|
1517
2102
|
} catch (error) {
|
|
1518
|
-
|
|
2103
|
+
exportFailed(button, error);
|
|
1519
2104
|
} finally {
|
|
1520
2105
|
if (objectUrl !== "") URL.revokeObjectURL(objectUrl);
|
|
1521
2106
|
}
|
|
1522
2107
|
};
|
|
1523
2108
|
image.onerror = function() {
|
|
1524
2109
|
if (objectUrl !== "") URL.revokeObjectURL(objectUrl);
|
|
1525
|
-
|
|
2110
|
+
exportFailed(button, new Error("SVG \u65E0\u6CD5\u8F7D\u5165"));
|
|
1526
2111
|
};
|
|
1527
2112
|
objectUrl = URL.createObjectURL(new Blob([serializeSvg(svg)], { type: "image/svg+xml;charset=utf-8" }));
|
|
1528
2113
|
image.src = objectUrl;
|
|
@@ -1595,15 +2180,16 @@ window.__ModuleLoader__.load({
|
|
|
1595
2180
|
panel.appendChild(body);
|
|
1596
2181
|
overlay.appendChild(panel);
|
|
1597
2182
|
var previousFocus = document.activeElement;
|
|
1598
|
-
var
|
|
2183
|
+
var releaseFocus = null;
|
|
1599
2184
|
var closed = false;
|
|
1600
2185
|
var reset = () => fitToView(overlay);
|
|
1601
2186
|
function closeViewer() {
|
|
1602
2187
|
if (closed) return;
|
|
1603
2188
|
closed = true;
|
|
2189
|
+
releaseFocus?.();
|
|
1604
2190
|
document.removeEventListener("keydown", onKey, true);
|
|
1605
2191
|
overlay.remove();
|
|
1606
|
-
|
|
2192
|
+
unlockPageScroll();
|
|
1607
2193
|
zooms.delete(overlay);
|
|
1608
2194
|
if (previousFocus !== null && typeof previousFocus.focus === "function") {
|
|
1609
2195
|
previousFocus.focus();
|
|
@@ -1619,16 +2205,17 @@ window.__ModuleLoader__.load({
|
|
|
1619
2205
|
if (event.target === overlay) closeViewer();
|
|
1620
2206
|
});
|
|
1621
2207
|
fitButton.addEventListener("click", reset);
|
|
1622
|
-
svgButton.addEventListener("click", () => downloadSvg(svg));
|
|
1623
|
-
pngButton.addEventListener("click", () => downloadPng(svg));
|
|
2208
|
+
svgButton.addEventListener("click", () => downloadSvg(svg, svgButton));
|
|
2209
|
+
pngButton.addEventListener("click", () => downloadPng(svg, pngButton));
|
|
1624
2210
|
zoomOut.addEventListener("click", () => zoomBy(overlay, 1 / ZOOM_STEP));
|
|
1625
2211
|
zoomIn.addEventListener("click", () => zoomBy(overlay, ZOOM_STEP));
|
|
1626
2212
|
closeButton.addEventListener("click", closeViewer);
|
|
1627
2213
|
document.addEventListener("keydown", onKey, true);
|
|
1628
2214
|
zooms.set(overlay, { scale: 1, x: 0, y: 0, min: ZOOM_MIN_MODAL });
|
|
1629
2215
|
bindViewport(overlay, viewport, reset, true);
|
|
1630
|
-
|
|
2216
|
+
lockPageScroll();
|
|
1631
2217
|
document.body.appendChild(overlay);
|
|
2218
|
+
releaseFocus = trapFocus(overlay);
|
|
1632
2219
|
closeButton.focus();
|
|
1633
2220
|
var schedule2 = window.requestAnimationFrame ?? ((cb) => window.setTimeout(cb, 0));
|
|
1634
2221
|
schedule2(reset);
|
|
@@ -1640,7 +2227,7 @@ window.__ModuleLoader__.load({
|
|
|
1640
2227
|
var reason = (error?.message ?? String(error)).split("\n")[0] ?? "";
|
|
1641
2228
|
note.textContent = t("renderFailed") + reason;
|
|
1642
2229
|
content.appendChild(note);
|
|
1643
|
-
|
|
2230
|
+
cacheKeys.set(block, key);
|
|
1644
2231
|
block.setAttribute(MMD_ATTR, "failed");
|
|
1645
2232
|
decorate(block);
|
|
1646
2233
|
console.warn("[dsh-md-plus] mermaid \u6E32\u67D3\u5931\u8D25", error);
|
|
@@ -1649,8 +2236,11 @@ window.__ModuleLoader__.load({
|
|
|
1649
2236
|
if (typeof document === "undefined") return;
|
|
1650
2237
|
ctx.effect(() => {
|
|
1651
2238
|
disposed = false;
|
|
2239
|
+
settingsCache = null;
|
|
2240
|
+
themeCache = null;
|
|
1652
2241
|
injectStyle();
|
|
1653
2242
|
applyCodeFontSize();
|
|
2243
|
+
applyTableFreezeSettings();
|
|
1654
2244
|
ensureSettingsButton();
|
|
1655
2245
|
var root = document.body ?? document.documentElement;
|
|
1656
2246
|
document.addEventListener("click", onDocumentClick, true);
|
|
@@ -1671,6 +2261,15 @@ window.__ModuleLoader__.load({
|
|
|
1671
2261
|
}
|
|
1672
2262
|
pending.clear();
|
|
1673
2263
|
rescanQueued = false;
|
|
2264
|
+
for (const target of [...foldTargets]) resetFold(target);
|
|
2265
|
+
for (const table of [...tableFreezeTargets]) clearTableFreeze(table);
|
|
2266
|
+
tableFreezeTargets.clear();
|
|
2267
|
+
if (tableFreezeObserver !== null) {
|
|
2268
|
+
tableFreezeObserver.disconnect();
|
|
2269
|
+
tableFreezeObserver = null;
|
|
2270
|
+
}
|
|
2271
|
+
tableFreezeState = /* @__PURE__ */ new WeakMap();
|
|
2272
|
+
for (const table of document.querySelectorAll(TABLE)) clearTableFreeze(table);
|
|
1674
2273
|
observer.disconnect();
|
|
1675
2274
|
document.removeEventListener("click", onDocumentClick, true);
|
|
1676
2275
|
for (const node of injected) node.remove();
|
|
@@ -1680,7 +2279,7 @@ window.__ModuleLoader__.load({
|
|
|
1680
2279
|
for (const node of document.querySelectorAll("." + FOLD_BTN_CLASS)) node.remove();
|
|
1681
2280
|
for (const node of document.querySelectorAll("[" + FOLD_ATTR + "]")) resetFold(node);
|
|
1682
2281
|
for (const node of document.querySelectorAll("." + TABLE_TOOLS_CLASS)) node.remove();
|
|
1683
|
-
for (const attr of [DONE_ATTR,
|
|
2282
|
+
for (const attr of [DONE_ATTR, WRAP_ATTR, MMD_ATTR, TABLE_DONE_ATTR, "data-md-plus-lang", ZOOM_ATTR]) {
|
|
1684
2283
|
for (const node of document.querySelectorAll("[" + attr + "]")) node.removeAttribute(attr);
|
|
1685
2284
|
}
|
|
1686
2285
|
for (const node of document.querySelectorAll("[data-md-plus-original-label]")) {
|
|
@@ -1692,7 +2291,9 @@ window.__ModuleLoader__.load({
|
|
|
1692
2291
|
)) {
|
|
1693
2292
|
node.remove();
|
|
1694
2293
|
}
|
|
1695
|
-
|
|
2294
|
+
scrollLocks = 0;
|
|
2295
|
+
document.documentElement.style.overflow = previousRootOverflow;
|
|
2296
|
+
previousRootOverflow = "";
|
|
1696
2297
|
document.documentElement.style.removeProperty("--md-plus-code-font-size");
|
|
1697
2298
|
document.documentElement.style.removeProperty("--md-plus-code-line-height");
|
|
1698
2299
|
document.querySelector("style[" + STYLE_ATTR + "]")?.remove();
|
|
@@ -1700,6 +2301,10 @@ window.__ModuleLoader__.load({
|
|
|
1700
2301
|
script.remove();
|
|
1701
2302
|
}
|
|
1702
2303
|
scripts.clear();
|
|
2304
|
+
settingsCache = null;
|
|
2305
|
+
themeCache = null;
|
|
2306
|
+
diagramKindCache = /* @__PURE__ */ new WeakMap();
|
|
2307
|
+
cacheKeys = /* @__PURE__ */ new WeakMap();
|
|
1703
2308
|
delete window[HL_GLOBAL];
|
|
1704
2309
|
delete window[MMD_GLOBAL];
|
|
1705
2310
|
};
|