@helping-ai-workflow/md2doc 3.2.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/editor/client.js +1175 -85
- package/lib/editor/docsource.js +16 -6
- package/lib/editor/toolbar-model.js +23 -8
- package/lib/md2doc.js +6 -6
- package/package.json +2 -2
package/lib/editor/docsource.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
})(typeof self !== 'undefined' ? self : this, function () {
|
|
12
12
|
|
|
13
13
|
// Pure state machine + lines[]<->string conversion for the "追加 4 全文原始碼
|
|
14
|
-
// 逃生口" (whole-document source escape hatch): 編輯 ⇄
|
|
14
|
+
// 逃生口" (whole-document source escape hatch): 編輯 ⇄ 原始碼.
|
|
15
|
+
// v3.2.1: 預覽(preview)已移除,見下方 MODES 上的說明。
|
|
15
16
|
//
|
|
16
17
|
// EOL representation: `eol` is always a single literal separator string --
|
|
17
18
|
// '\n', '\r\n' or '\r' -- the same convention server.js already establishes
|
|
@@ -31,12 +32,21 @@
|
|
|
31
32
|
// 2. `\r\n` is listed before the two single-character alternatives, so a
|
|
32
33
|
// CRLF pair is always consumed as ONE separator, never split into a
|
|
33
34
|
// spurious blank line between a lone \r and a lone \n.
|
|
34
|
-
const MODES = ['edit', 'source'
|
|
35
|
+
const MODES = ['edit', 'source'];
|
|
35
36
|
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
37
|
+
// v3.2.1: 兩態循環 edit <-> source。preview 移除 —— 實測它相對 edit 只做
|
|
38
|
+
// 兩件事(applyPreviewEditability(false) 與兩行隱藏 ⠿/+ 的 CSS),卻擋在
|
|
39
|
+
// source 回 edit 的路上,而且 22 顆工具列按鈕中 13 顆在它底下仍然寫得進磁碟。
|
|
40
|
+
//
|
|
41
|
+
// 為什麼是移除而不是加閘門:一個「列舉可及面」推導出來的唯讀閘門必然漏掉
|
|
42
|
+
// 一整族 —— 切換前就已經開著的 ⠿ 選單在切換後仍是 140x118、display:flex,
|
|
43
|
+
// 其 16 個項目每一個都寫得進磁碟。閘門要約 8 個守衛點跨 2 個檔案才擋得住,
|
|
44
|
+
// 而 preview 本身沒有任何 edit 給不了的能力。
|
|
45
|
+
//
|
|
46
|
+
// An unrecognized mode (defensive: a caller passing something stale) falls
|
|
47
|
+
// back to the first state rather than throwing, matching how the rest of
|
|
48
|
+
// this module prefers a safe default over a thrown exception for malformed
|
|
49
|
+
// input.
|
|
40
50
|
function next(mode) {
|
|
41
51
|
const idx = MODES.indexOf(mode);
|
|
42
52
|
return MODES[(idx + 1) % MODES.length];
|
|
@@ -48,7 +48,13 @@ const BUTTON_DEFS = [
|
|
|
48
48
|
|
|
49
49
|
// view
|
|
50
50
|
{ id: 'outline', group: 'view', label: '☰', icon: '☰', title: '大綱', toggle: false },
|
|
51
|
-
|
|
51
|
+
// v3.2.1: 這顆是 edit <-> source 的兩態切換(preview 模式已移除)。id 保留
|
|
52
|
+
// 為 'preview' 是刻意的 —— 每一支選擇器、journey 案例與 runtime 測試都指名
|
|
53
|
+
// 它,改名只換得一個更好聽的字串。label / title 不是烘死值:deriveState()
|
|
54
|
+
// 每次都依當前 mode 覆寫成【下一個】狀態的名字,這裡的值只是 edit 模式的
|
|
55
|
+
// 起始值。toggle: false —— 兩態下 aria-pressed 講不出真話(按鈕講的是去處,
|
|
56
|
+
// 不是目前所在),真話由會變的 label / title 承擔。
|
|
57
|
+
{ id: 'preview', group: 'view', label: 'M↓', icon: 'M↓', title: '切換到原始碼模式', toggle: false },
|
|
52
58
|
];
|
|
53
59
|
|
|
54
60
|
const BUTTONS = Object.freeze(BUTTON_DEFS.map((b) => Object.freeze(Object.assign({}, b))));
|
|
@@ -76,11 +82,18 @@ function deriveState(ctx) {
|
|
|
76
82
|
state[b.id] = { active: false, disabled: false };
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
//
|
|
80
|
-
// the
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
|
|
85
|
+
// v3.2.1: the mode button names the NEXT state, never the current one.
|
|
86
|
+
// Under the old tri-state cycle it was permanently labelled 「預覽」 and
|
|
87
|
+
// reported aria-pressed=true in BOTH non-edit modes, so pressing it twice
|
|
88
|
+
// landed in source with no grips and an interface that said nothing about
|
|
89
|
+
// where you were — the reported "stuck" defect. It carries no `active`
|
|
90
|
+
// now: with two states the honest signal is the label, and the current
|
|
91
|
+
// mode is spelled out in .ed-toolbar-status by the client.
|
|
92
|
+
// It stays enabled in source mode via the mode==='source' override below
|
|
93
|
+
// (do not gate this on inList/hasBlock — it is the escape hatch OUT of
|
|
94
|
+
// those states).
|
|
95
|
+
state.preview.label = mode === 'source' ? '✎' : 'M↓';
|
|
96
|
+
state.preview.title = mode === 'source' ? '切換到編輯模式' : '切換到原始碼模式';
|
|
84
97
|
|
|
85
98
|
// headings: dropdown whose label tracks the current heading depth.
|
|
86
99
|
state.headings.label = blockType === 'heading' ? 'H' + headingDepth : 'H';
|
|
@@ -145,8 +158,10 @@ function deriveState(ctx) {
|
|
|
145
158
|
}
|
|
146
159
|
|
|
147
160
|
// mode 'source' is the full-document raw-source escape hatch: everything
|
|
148
|
-
// is disabled except the
|
|
149
|
-
//
|
|
161
|
+
// is disabled except the mode button that got you there (id 'preview',
|
|
162
|
+
// which in v3.2.1 is the edit <-> source toggle). This overrides every
|
|
163
|
+
// disabled flag computed above, and is the ONLY way back out — do not
|
|
164
|
+
// narrow it.
|
|
150
165
|
if (mode === 'source') {
|
|
151
166
|
for (const b of BUTTONS) {
|
|
152
167
|
state[b.id].disabled = b.id !== 'preview';
|
package/lib/md2doc.js
CHANGED
|
@@ -2590,16 +2590,18 @@ ${itemsHtml}
|
|
|
2590
2590
|
row's overflow-x: auto scrolls (measured identical rect at scrollLeft
|
|
2591
2591
|
0 / mid / max, where the absolute alternative moved by the exact scroll
|
|
2592
2592
|
delta). References no gutter-alignment custom property.
|
|
2593
|
-
H2 fix: pointer-events: none below is LOAD-BEARING
|
|
2594
|
-
|
|
2593
|
+
H2 fix: pointer-events: none below is LOAD-BEARING, not decorative.
|
|
2594
|
+
v3.2.1 filled this slot with the current mode's name ('編輯' / '原始碼'),
|
|
2595
|
+
so it no longer ships empty — but that content is inert TEXT, never a
|
|
2596
|
+
control, which is exactly what keeps the rule below sufficient. At narrow viewports .ed-toolbar's own
|
|
2595
2597
|
overflow-x: auto lets the button row scroll to a rest position where
|
|
2596
2598
|
this fixed 7rem box's footprint physically covers three real buttons
|
|
2597
2599
|
(image / outline / preview, measured at 420px width, scrollLeft at its
|
|
2598
2600
|
max 221) — document.elementFromPoint() over any of them resolves to
|
|
2599
2601
|
this span, not the button underneath, and a real click on it never
|
|
2600
2602
|
reaches the button's listener. Harmless today only because the span
|
|
2601
|
-
carries
|
|
2602
|
-
|
|
2603
|
+
carries nothing to interact with. WHOEVER PUTS A CONTROL HERE (or
|
|
2604
|
+
wires up two-way sync, §3) MUST remove or scope this
|
|
2603
2605
|
rule AND independently solve the overlap (e.g. reflow the slot in-flow
|
|
2604
2606
|
at narrow widths, or shrink/hide it below some width) — simply
|
|
2605
2607
|
deleting this line without doing that reopens the swallowed-click
|
|
@@ -2636,8 +2638,6 @@ ${itemsHtml}
|
|
|
2636
2638
|
border: 1px solid #d0d7de; border-radius: 8px; resize: vertical;
|
|
2637
2639
|
white-space: pre; overflow-wrap: normal;
|
|
2638
2640
|
}
|
|
2639
|
-
body[data-ed-mode="preview"] .ed-handle,
|
|
2640
|
-
body[data-ed-mode="preview"] .ed-insert { display: none !important; }
|
|
2641
2641
|
.ed-editing { position: relative; }
|
|
2642
2642
|
.ed-raw {
|
|
2643
2643
|
display: block; width: 100%; font-family: monospace; font-size: 13px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helping-ai-workflow/md2doc",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "Markdown → HTML / PDF renderer with WaveDrom, Mermaid, and Graphviz support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"preinstall": "node scripts/preinstall.js",
|
|
40
|
-
"test": "node test/md2doc.test.js && node test/blockmap.test.js && node test/images.test.js && node test/scroll-anchor.test.js && node test/lightbox.test.js && node test/lightbox-anno.test.js && node test/lightbox-anno-style.test.js && node test/reader-panels.test.js && node test/cli.test.js && node test/code-operator.test.js && node test/convert-md.test.js && node test/render-api.test.js && node test/lineops.test.js && node test/indent-clamp.test.js && node test/selection.test.js && node test/editmode-render.test.js && node test/editmode-wavedrom-reinit.test.js && node test/editor-server.test.js && node test/cli-edit.test.js && node test/open-viewer.test.js && node test/editor-client.test.js && node test/editor-client-runtime.test.js && node test/roundtrip.test.js && node test/byte-stability.test.js && node test/editor-server-throw.test.js && node test/editor-reader-rebind.test.js && node test/inline-md.test.js && node test/table-md.test.js && node test/gate-compat.test.js && node test/history.test.js && node test/list-md.test.js && node test/table-width.test.js && node test/toolbar-model.test.js && node test/docsource.test.js && node test/asset.test.js && node test/paste-md.test.js && node test/patchmap.test.js"
|
|
40
|
+
"test": "node test/md2doc.test.js && node test/blockmap.test.js && node test/images.test.js && node test/scroll-anchor.test.js && node test/lightbox.test.js && node test/lightbox-anno.test.js && node test/lightbox-anno-style.test.js && node test/reader-panels.test.js && node test/cli.test.js && node test/code-operator.test.js && node test/convert-md.test.js && node test/render-api.test.js && node test/lineops.test.js && node test/indent-clamp.test.js && node test/selection.test.js && node test/editmode-render.test.js && node test/editmode-wavedrom-reinit.test.js && node test/editor-server.test.js && node test/cli-edit.test.js && node test/open-viewer.test.js && node test/editor-client.test.js && node test/editor-client-runtime.test.js && node test/roundtrip.test.js && node test/byte-stability.test.js && node test/editor-server-throw.test.js && node test/editor-reader-rebind.test.js && node test/inline-md.test.js && node test/table-md.test.js && node test/gate-compat.test.js && node test/history.test.js && node test/list-md.test.js && node test/table-width.test.js && node test/toolbar-model.test.js && node test/docsource.test.js && node test/asset.test.js && node test/paste-md.test.js && node test/patchmap.test.js && node test/editor-journey.test.js && node test/detach-census.test.js"
|
|
41
41
|
},
|
|
42
42
|
"repository": {
|
|
43
43
|
"type": "git",
|