@pinkpixel/marzipan 1.0.5 → 1.0.7
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/dist/_basePickBy-BXyyc71p.js +152 -0
- package/dist/_basePickBy-BXyyc71p.js.map +1 -0
- package/dist/_baseUniq-Dde5pUWM.js +615 -0
- package/dist/_baseUniq-Dde5pUWM.js.map +1 -0
- package/dist/actions/core/detection.d.ts +11 -0
- package/dist/actions/core/detection.d.ts.map +1 -0
- package/dist/actions/core/detection.js +142 -0
- package/dist/actions/core/detection.js.map +1 -0
- package/dist/actions/core/formats.d.ts +5 -0
- package/dist/actions/core/formats.d.ts.map +1 -0
- package/dist/actions/core/formats.js +75 -0
- package/dist/actions/core/formats.js.map +1 -0
- package/dist/actions/core/insertion.d.ts +5 -0
- package/dist/actions/core/insertion.d.ts.map +1 -0
- package/dist/actions/core/insertion.js +116 -0
- package/dist/actions/core/insertion.js.map +1 -0
- package/dist/actions/core/selection.d.ts +13 -0
- package/dist/actions/core/selection.d.ts.map +1 -0
- package/dist/actions/core/selection.js +137 -0
- package/dist/actions/core/selection.js.map +1 -0
- package/dist/actions/debug.d.ts +10 -0
- package/dist/actions/debug.d.ts.map +1 -0
- package/dist/actions/debug.js +39 -0
- package/dist/actions/debug.js.map +1 -0
- package/dist/actions/index.d.ts +48 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +237 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/operations/block.d.ts +5 -0
- package/dist/actions/operations/block.d.ts.map +1 -0
- package/dist/actions/operations/block.js +120 -0
- package/dist/actions/operations/block.js.map +1 -0
- package/dist/actions/operations/list.d.ts +4 -0
- package/dist/actions/operations/list.d.ts.map +1 -0
- package/dist/actions/operations/list.js +151 -0
- package/dist/actions/operations/list.js.map +1 -0
- package/dist/actions/types.d.ts +43 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +2 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/arc-CfMWIGxd.js +84 -0
- package/dist/arc-CfMWIGxd.js.map +1 -0
- package/dist/architectureDiagram-VXUJARFQ-Bb4i7x-6.js +4663 -0
- package/dist/architectureDiagram-VXUJARFQ-Bb4i7x-6.js.map +1 -0
- package/dist/blockDiagram-VD42YOAC-ldSoJhgA.js +2262 -0
- package/dist/blockDiagram-VD42YOAC-ldSoJhgA.js.map +1 -0
- package/dist/c4Diagram-YG6GDRKO-D-ENeA7h.js +1581 -0
- package/dist/c4Diagram-YG6GDRKO-D-ENeA7h.js.map +1 -0
- package/dist/channel-BCTxewZI.js +6 -0
- package/dist/channel-BCTxewZI.js.map +1 -0
- package/dist/chunk-4BX2VUAB-Cfh_4i4X.js +9 -0
- package/dist/chunk-4BX2VUAB-Cfh_4i4X.js.map +1 -0
- package/dist/chunk-55IACEB6-DNOIVRvW.js +9 -0
- package/dist/chunk-55IACEB6-DNOIVRvW.js.map +1 -0
- package/dist/chunk-B4BG7PRW-C_qWbbk6.js +1376 -0
- package/dist/chunk-B4BG7PRW-C_qWbbk6.js.map +1 -0
- package/dist/chunk-DI55MBZ5-D_yXJA03.js +1371 -0
- package/dist/chunk-DI55MBZ5-D_yXJA03.js.map +1 -0
- package/dist/chunk-FMBD7UC4-B9NJjOBf.js +20 -0
- package/dist/chunk-FMBD7UC4-B9NJjOBf.js.map +1 -0
- package/dist/chunk-QN33PNHL-CVrLUVsI.js +20 -0
- package/dist/chunk-QN33PNHL-CVrLUVsI.js.map +1 -0
- package/dist/chunk-QZHKN3VN-FvAf_VJR.js +16 -0
- package/dist/chunk-QZHKN3VN-FvAf_VJR.js.map +1 -0
- package/dist/chunk-TZMSLE5B-DxYTPD3t.js +65 -0
- package/dist/chunk-TZMSLE5B-DxYTPD3t.js.map +1 -0
- package/dist/classDiagram-2ON5EDUG-Cg641kit.js +17 -0
- package/dist/classDiagram-2ON5EDUG-Cg641kit.js.map +1 -0
- package/dist/classDiagram-v2-WZHVMYZB-Cg641kit.js +17 -0
- package/dist/classDiagram-v2-WZHVMYZB-Cg641kit.js.map +1 -0
- package/dist/clone-D062_nJ-.js +9 -0
- package/dist/clone-D062_nJ-.js.map +1 -0
- package/dist/cose-bilkent-S5V4N54A-DIb5rck_.js +2609 -0
- package/dist/cose-bilkent-S5V4N54A-DIb5rck_.js.map +1 -0
- package/dist/cytoscape.esm-DfdJODL8.js +18736 -0
- package/dist/cytoscape.esm-DfdJODL8.js.map +1 -0
- package/dist/dagre-6UL2VRFP-CZKadRq9.js +445 -0
- package/dist/dagre-6UL2VRFP-CZKadRq9.js.map +1 -0
- package/dist/defaultLocale-D7EN2tov.js +172 -0
- package/dist/defaultLocale-D7EN2tov.js.map +1 -0
- package/dist/diagram-PSM6KHXK-VDtnZynV.js +532 -0
- package/dist/diagram-PSM6KHXK-VDtnZynV.js.map +1 -0
- package/dist/diagram-QEK2KX5R-DxjNZqZ_.js +218 -0
- package/dist/diagram-QEK2KX5R-DxjNZqZ_.js.map +1 -0
- package/dist/diagram-S2PKOQOG-CCX3j4vi.js +143 -0
- package/dist/diagram-S2PKOQOG-CCX3j4vi.js.map +1 -0
- package/dist/erDiagram-Q2GNP2WA-nwmrf6lJ.js +842 -0
- package/dist/erDiagram-Q2GNP2WA-nwmrf6lJ.js.map +1 -0
- package/dist/flowDiagram-NV44I4VS-DQEdMlRX.js +1621 -0
- package/dist/flowDiagram-NV44I4VS-DQEdMlRX.js.map +1 -0
- package/dist/ganttDiagram-LVOFAZNH-WMiy-Gep.js +2506 -0
- package/dist/ganttDiagram-LVOFAZNH-WMiy-Gep.js.map +1 -0
- package/dist/gitGraphDiagram-NY62KEGX-BgmbSTgN.js +700 -0
- package/dist/gitGraphDiagram-NY62KEGX-BgmbSTgN.js.map +1 -0
- package/dist/graph-CSVEP8oS.js +248 -0
- package/dist/graph-CSVEP8oS.js.map +1 -0
- package/dist/icons.d.ts +17 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +67 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +143 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infoDiagram-F6ZHWCRC-BzTgHHGF.js +25 -0
- package/dist/infoDiagram-F6ZHWCRC-BzTgHHGF.js.map +1 -0
- package/dist/init-DjUOC4st.js +17 -0
- package/dist/init-DjUOC4st.js.map +1 -0
- package/dist/journeyDiagram-XKPGCS4Q-B5P7hkT-.js +835 -0
- package/dist/journeyDiagram-XKPGCS4Q-B5P7hkT-.js.map +1 -0
- package/dist/kanban-definition-3W4ZIXB7-CLtnd0xR.js +720 -0
- package/dist/kanban-definition-3W4ZIXB7-CLtnd0xR.js.map +1 -0
- package/dist/katex-CmGeg_OO.js +11693 -0
- package/dist/katex-CmGeg_OO.js.map +1 -0
- package/dist/layout-CdTiJocX.js +1325 -0
- package/dist/layout-CdTiJocX.js.map +1 -0
- package/dist/linear-BhblBDrV.js +260 -0
- package/dist/linear-BhblBDrV.js.map +1 -0
- package/dist/link-tooltip.d.ts +27 -0
- package/dist/link-tooltip.d.ts.map +1 -0
- package/dist/link-tooltip.js +224 -0
- package/dist/link-tooltip.js.map +1 -0
- package/dist/marzipan.d.ts +472 -0
- package/dist/marzipan.d.ts.map +1 -0
- package/dist/marzipan.js +1185 -0
- package/dist/marzipan.js.map +1 -0
- package/dist/mermaid.core-DENutRS8.js +15249 -0
- package/dist/mermaid.core-DENutRS8.js.map +1 -0
- package/dist/mindmap-definition-VGOIOE7T-BXBE9eta.js +785 -0
- package/dist/mindmap-definition-VGOIOE7T-BXBE9eta.js.map +1 -0
- package/dist/ordinal-DfAQgscy.js +62 -0
- package/dist/ordinal-DfAQgscy.js.map +1 -0
- package/dist/parser.d.ts +234 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +886 -0
- package/dist/parser.js.map +1 -0
- package/dist/pieDiagram-ADFJNKIX-BND3UUQ-.js +162 -0
- package/dist/pieDiagram-ADFJNKIX-BND3UUQ-.js.map +1 -0
- package/dist/plugins/accentSwatchPlugin.d.ts +15 -0
- package/dist/plugins/accentSwatchPlugin.d.ts.map +1 -0
- package/dist/plugins/accentSwatchPlugin.js +142 -0
- package/dist/plugins/accentSwatchPlugin.js.map +1 -0
- package/dist/plugins/imageManagerPlugin.d.ts +16 -0
- package/dist/plugins/imageManagerPlugin.d.ts.map +1 -0
- package/dist/plugins/imageManagerPlugin.js +161 -0
- package/dist/plugins/imageManagerPlugin.js.map +1 -0
- package/dist/plugins/imagePicker.d.ts +7 -0
- package/dist/plugins/imagePicker.d.ts.map +1 -0
- package/dist/plugins/imagePicker.js +33 -0
- package/dist/plugins/imagePicker.js.map +1 -0
- package/dist/plugins/imagePickerPlugin.d.ts +3 -0
- package/dist/plugins/imagePickerPlugin.d.ts.map +1 -0
- package/dist/plugins/imagePickerPlugin.js +12 -0
- package/dist/plugins/imagePickerPlugin.js.map +1 -0
- package/dist/plugins/mermaidExternal.d.ts +2 -0
- package/dist/plugins/mermaidExternal.d.ts.map +1 -0
- package/dist/plugins/mermaidExternal.js +44 -0
- package/dist/plugins/mermaidExternal.js.map +1 -0
- package/dist/plugins/mermaidPlugin.d.ts +2 -0
- package/dist/plugins/mermaidPlugin.d.ts.map +1 -0
- package/dist/plugins/mermaidPlugin.js +25 -0
- package/dist/plugins/mermaidPlugin.js.map +1 -0
- package/dist/plugins/tableGenerator.d.ts +2 -0
- package/dist/plugins/tableGenerator.d.ts.map +1 -0
- package/dist/plugins/tableGenerator.js +24 -0
- package/dist/plugins/tableGenerator.js.map +1 -0
- package/dist/plugins/tableGridPlugin.d.ts +14 -0
- package/dist/plugins/tableGridPlugin.d.ts.map +1 -0
- package/dist/plugins/tableGridPlugin.js +77 -0
- package/dist/plugins/tableGridPlugin.js.map +1 -0
- package/dist/plugins/tablePlugin.d.ts +2 -0
- package/dist/plugins/tablePlugin.d.ts.map +1 -0
- package/dist/plugins/tablePlugin.js +26 -0
- package/dist/plugins/tablePlugin.js.map +1 -0
- package/dist/plugins/tinyHighlight.d.ts +10 -0
- package/dist/plugins/tinyHighlight.d.ts.map +1 -0
- package/dist/plugins/tinyHighlight.js +109 -0
- package/dist/plugins/tinyHighlight.js.map +1 -0
- package/dist/plugins/utils/table.d.ts +3 -0
- package/dist/plugins/utils/table.d.ts.map +1 -0
- package/dist/plugins/utils/table.js +25 -0
- package/dist/plugins/utils/table.js.map +1 -0
- package/dist/quadrantDiagram-AYHSOK5B-CnLHbrEF.js +1023 -0
- package/dist/quadrantDiagram-AYHSOK5B-CnLHbrEF.js.map +1 -0
- package/dist/requirementDiagram-UZGBJVZJ-caC7K17a.js +851 -0
- package/dist/requirementDiagram-UZGBJVZJ-caC7K17a.js.map +1 -0
- package/dist/sankeyDiagram-TZEHDZUN-CV5-bwv8.js +811 -0
- package/dist/sankeyDiagram-TZEHDZUN-CV5-bwv8.js.map +1 -0
- package/dist/sequenceDiagram-WL72ISMW-Cq1otbHU.js +2512 -0
- package/dist/sequenceDiagram-WL72ISMW-Cq1otbHU.js.map +1 -0
- package/dist/shortcuts.d.ts +15 -0
- package/dist/shortcuts.d.ts.map +1 -0
- package/dist/shortcuts.js +78 -0
- package/dist/shortcuts.js.map +1 -0
- package/dist/stateDiagram-FKZM4ZOC-BJ5UwskL.js +264 -0
- package/dist/stateDiagram-FKZM4ZOC-BJ5UwskL.js.map +1 -0
- package/dist/stateDiagram-v2-4FDKWEC3-H1gqsSsO.js +17 -0
- package/dist/stateDiagram-v2-4FDKWEC3-H1gqsSsO.js.map +1 -0
- package/dist/styles.d.ts +11 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +854 -0
- package/dist/styles.js.map +1 -0
- package/dist/table-DMIy93NJ.js +25 -0
- package/dist/table-DMIy93NJ.js.map +1 -0
- package/dist/themes.d.ts +197 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +120 -0
- package/dist/themes.js.map +1 -0
- package/dist/timeline-definition-IT6M3QCI-CqPEUsh4.js +796 -0
- package/dist/timeline-definition-IT6M3QCI-CqPEUsh4.js.map +1 -0
- package/dist/toolbar.d.ts +37 -0
- package/dist/toolbar.d.ts.map +1 -0
- package/dist/toolbar.js +283 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/treemap-75Q7IDZK-DmPg5GN7.js +12988 -0
- package/dist/treemap-75Q7IDZK-DmPg5GN7.js.map +1 -0
- package/dist/xychartDiagram-PRI3JC2R-C3_IO4Rm.js +1341 -0
- package/dist/xychartDiagram-PRI3JC2R-C3_IO4Rm.js.map +1 -0
- package/docs/types.d.ts +1 -1
- package/package.json +15 -11
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
const L = "marzipan.images";
|
|
2
|
+
function w(r, d) {
|
|
3
|
+
const u = r.textarea, v = u.selectionStart ?? 0, h = u.selectionEnd ?? 0;
|
|
4
|
+
u.setRangeText(d, v, h, "end"), r.updatePreview(), u.focus();
|
|
5
|
+
}
|
|
6
|
+
function R() {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(localStorage.getItem(L) || "[]");
|
|
9
|
+
} catch {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function y(r) {
|
|
14
|
+
try {
|
|
15
|
+
localStorage.setItem(L, JSON.stringify(r.slice(0, 50)));
|
|
16
|
+
} catch {
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function D(r) {
|
|
20
|
+
const d = new FileReader();
|
|
21
|
+
return new Promise((u, v) => {
|
|
22
|
+
d.onerror = () => v(d.error), d.onload = () => u(String(d.result)), d.readAsDataURL(r);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function A(r) {
|
|
26
|
+
const d = r?.label ?? "🗂️", u = r?.title ?? "Images", v = Math.max(1, r?.maxRecent ?? 24), h = r?.persistThresholdBytes ?? 1 * 1024 * 1024;
|
|
27
|
+
return (p) => {
|
|
28
|
+
const k = p.container.querySelector(".marzipan-toolbar") ?? p.container, f = document.createElement("button");
|
|
29
|
+
f.type = "button", f.className = "mz-btn mz-btn-imagemgr", f.title = u, f.textContent = d;
|
|
30
|
+
let n = null, l = R();
|
|
31
|
+
function g() {
|
|
32
|
+
n?.remove(), n = null, document.removeEventListener("click", E, !0), window.removeEventListener("resize", g), window.removeEventListener("scroll", g, !0);
|
|
33
|
+
}
|
|
34
|
+
function E(e) {
|
|
35
|
+
n && (e.target instanceof Node && (n.contains(e.target) || f.contains(e.target)) || g());
|
|
36
|
+
}
|
|
37
|
+
function z(e) {
|
|
38
|
+
const t = e.querySelector(".mz-im-grid");
|
|
39
|
+
t.innerHTML = "", l.slice(0, v).forEach((i, c) => {
|
|
40
|
+
const s = document.createElement("div");
|
|
41
|
+
s.className = "mz-im-card";
|
|
42
|
+
const b = document.createElement("img");
|
|
43
|
+
b.decoding = "async", b.loading = "lazy", b.src = i.url, b.alt = i.name;
|
|
44
|
+
const m = document.createElement("div");
|
|
45
|
+
m.className = "mz-im-actions";
|
|
46
|
+
const a = document.createElement("button");
|
|
47
|
+
a.type = "button", a.textContent = "Insert", a.onclick = () => {
|
|
48
|
+
const I = r?.onInsert ? r.onInsert(i.url) : i.url;
|
|
49
|
+
w(p, ``), g();
|
|
50
|
+
};
|
|
51
|
+
const o = document.createElement("button");
|
|
52
|
+
o.type = "button", o.textContent = "✕", o.title = "Remove from recents", o.onclick = () => {
|
|
53
|
+
l.splice(c, 1), y(l), z(e);
|
|
54
|
+
}, m.append(a, o), s.append(b, m), t.appendChild(s);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async function x(e) {
|
|
58
|
+
try {
|
|
59
|
+
let t;
|
|
60
|
+
r?.uploader ? t = await r.uploader(e) : e.size <= h ? t = await D(e) : t = URL.createObjectURL(e), l = [{ url: t, name: e.name, createdAt: Date.now(), persistent: !t.startsWith("blob:") }, ...l.filter((s) => s.url !== t)], y(l), n && z(n);
|
|
61
|
+
const c = r?.onInsert ? r.onInsert(t) : t;
|
|
62
|
+
w(p, ``);
|
|
63
|
+
} catch (t) {
|
|
64
|
+
console.error("Image add failed:", t), alert("Could not add image.");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async function S(e, t = "image") {
|
|
68
|
+
l = [{ url: e, name: t, createdAt: Date.now(), persistent: !0 }, ...l.filter((s) => s.url !== e)], y(l), n && z(n);
|
|
69
|
+
const c = r?.onInsert ? r.onInsert(e) : e;
|
|
70
|
+
w(p, ``);
|
|
71
|
+
}
|
|
72
|
+
function C() {
|
|
73
|
+
if (n) {
|
|
74
|
+
g();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
n = document.createElement("div"), n.className = "mz-pop mz-im-panel", n.innerHTML = `
|
|
78
|
+
<div class="mz-im-row">
|
|
79
|
+
<input class="mz-im-url" type="url" placeholder="https://example.com/image.png" />
|
|
80
|
+
<button class="mz-im-addurl" type="button">Add URL</button>
|
|
81
|
+
<input class="mz-im-file" type="file" accept="image/*" hidden />
|
|
82
|
+
<button class="mz-im-upload" type="button">Upload</button>
|
|
83
|
+
<button class="mz-im-clear" type="button" title="Clear recents">Clear</button>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="mz-im-drop">Drop images here, or paste into the editor.</div>
|
|
86
|
+
<div class="mz-im-grid"></div>
|
|
87
|
+
`, document.body.appendChild(n);
|
|
88
|
+
const e = f.getBoundingClientRect();
|
|
89
|
+
n.style.left = `${Math.round(window.scrollX + e.left)}px`, n.style.top = `${Math.round(window.scrollY + e.bottom + 6)}px`;
|
|
90
|
+
const t = n.querySelector(".mz-im-url"), i = n.querySelector(".mz-im-addurl"), c = n.querySelector(".mz-im-file"), s = n.querySelector(".mz-im-upload"), b = n.querySelector(".mz-im-clear"), m = n.querySelector(".mz-im-drop");
|
|
91
|
+
i.onclick = () => {
|
|
92
|
+
const a = t.value.trim();
|
|
93
|
+
a && (S(a), t.value = "");
|
|
94
|
+
}, s.onclick = () => c.click(), c.onchange = () => {
|
|
95
|
+
const a = c.files?.[0];
|
|
96
|
+
a && x(a);
|
|
97
|
+
}, b.onclick = () => {
|
|
98
|
+
confirm("Clear recent images?") && (l = [], y(l), z(n));
|
|
99
|
+
}, ["dragenter", "dragover"].forEach(
|
|
100
|
+
(a) => m.addEventListener(a, (o) => {
|
|
101
|
+
o.preventDefault(), m.classList.add("on");
|
|
102
|
+
})
|
|
103
|
+
), ["dragleave", "drop"].forEach(
|
|
104
|
+
(a) => m.addEventListener(a, (o) => {
|
|
105
|
+
o.preventDefault(), m.classList.remove("on");
|
|
106
|
+
})
|
|
107
|
+
), m.addEventListener("drop", (a) => {
|
|
108
|
+
const o = a.dataTransfer?.files;
|
|
109
|
+
!o || !o.length || Array.from(o).forEach(x);
|
|
110
|
+
}), z(n), setTimeout(() => {
|
|
111
|
+
document.addEventListener("click", E, !0), window.addEventListener("resize", g), window.addEventListener("scroll", g, !0);
|
|
112
|
+
}, 0);
|
|
113
|
+
}
|
|
114
|
+
p.textarea.addEventListener("paste", (e) => {
|
|
115
|
+
const t = e.clipboardData?.items && Array.from(e.clipboardData.items).find((c) => c.kind === "file" && c.type.startsWith("image/"));
|
|
116
|
+
if (!t) return;
|
|
117
|
+
const i = t.getAsFile();
|
|
118
|
+
i && (e.preventDefault(), x(i));
|
|
119
|
+
}), p.container.addEventListener("dragover", (e) => {
|
|
120
|
+
Array.from(e.dataTransfer?.items || []).some((t) => t.kind === "file") && e.preventDefault();
|
|
121
|
+
}), p.container.addEventListener("drop", (e) => {
|
|
122
|
+
const t = e.dataTransfer?.files;
|
|
123
|
+
!t || !t.length || (e.preventDefault(), Array.from(t).forEach(x));
|
|
124
|
+
}), f.onclick = C, k.appendChild(f);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const U = `
|
|
128
|
+
.mz-im-panel { width: 440px; max-width: calc(100vw - 24px); }
|
|
129
|
+
.mz-im-row { display: grid; grid-template-columns: 1fr auto auto auto; gap: 6px; margin-bottom: 8px; }
|
|
130
|
+
.mz-im-row input[type="url"] {
|
|
131
|
+
background: var(--mz-ip-bg, #0f1216); color: var(--mz-ip-fg, #e7e7e7);
|
|
132
|
+
border: 1px solid var(--mz-ip-bd, #2b2f36); border-radius: 8px; padding: 6px 8px;
|
|
133
|
+
}
|
|
134
|
+
.mz-im-row button {
|
|
135
|
+
padding: 6px 10px; border-radius: 8px; border: 1px solid var(--mz-bd, #2b2f36);
|
|
136
|
+
background: var(--mz-btn-bg, #1a1e24); color: var(--mz-btn-fg, #e7e7e7); cursor: pointer;
|
|
137
|
+
}
|
|
138
|
+
.mz-im-drop {
|
|
139
|
+
border: 1px dashed var(--mz-drop-bd, #3b4350); border-radius: 8px;
|
|
140
|
+
padding: 10px; text-align: center; font-size: 12px; margin-bottom: 8px;
|
|
141
|
+
background: var(--mz-drop-bg, #0e1116);
|
|
142
|
+
}
|
|
143
|
+
.mz-im-drop.on { background: var(--mz-drop-on, #172033); }
|
|
144
|
+
.mz-im-grid {
|
|
145
|
+
display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
|
|
146
|
+
gap: 8px; max-height: 320px; overflow: auto; padding: 2px;
|
|
147
|
+
}
|
|
148
|
+
.mz-im-card { border: 1px solid var(--mz-card-bd, #2b2f36); border-radius: 8px; overflow: hidden;
|
|
149
|
+
background: var(--mz-card-bg, #12151a); display: flex; flex-direction: column; }
|
|
150
|
+
.mz-im-card img { width: 100%; height: 82px; object-fit: cover; display: block; }
|
|
151
|
+
.mz-im-actions { display: flex; gap: 6px; padding: 6px; justify-content: space-between; }
|
|
152
|
+
.mz-im-actions button {
|
|
153
|
+
flex: 1; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--mz-bd, #2b2f36);
|
|
154
|
+
background: var(--mz-btn2-bg, #1b2027); color: var(--mz-btn2-fg, #e7e7e7); cursor: pointer; font-size: 12px;
|
|
155
|
+
}
|
|
156
|
+
`;
|
|
157
|
+
export {
|
|
158
|
+
A as imageManagerPlugin,
|
|
159
|
+
U as imageManagerStyles
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=imageManagerPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imageManagerPlugin.js","sources":["../../src/plugins/imageManagerPlugin.ts"],"sourcesContent":["// plugins/imageManagerPlugin.ts` — recents, upload, URL add, drag-drop, paste\n// =====================================================\n// Persists “recents” in `localStorage` (data-URLs for small files ≤ default 1 MB).\n// Optional `uploader(file) => Promise<string>` to store remotely and return a URL.\n// Drag files onto the editor, or paste images from clipboard—instant preview and insert.\n// Tiny panel with thumbnails; click to insert; remove/clear as needed.\n\ntype MzEditor = {\n container: HTMLElement;\n textarea: HTMLTextAreaElement;\n updatePreview: () => void;\n};\n\ntype RecentImage = { url: string; name: string; createdAt: number; persistent: boolean };\n\nconst LS_KEY = 'marzipan.images';\n\nfunction insertAtCursor(editor: MzEditor, text: string) {\n const ta = editor.textarea;\n const s = ta.selectionStart ?? 0, e = ta.selectionEnd ?? 0;\n ta.setRangeText(text, s, e, 'end');\n editor.updatePreview();\n ta.focus();\n}\n\nfunction loadRecents(): RecentImage[] {\n try { return JSON.parse(localStorage.getItem(LS_KEY) || '[]'); }\n catch { return []; }\n}\nfunction saveRecents(list: RecentImage[]) {\n try { localStorage.setItem(LS_KEY, JSON.stringify(list.slice(0, 50))); } catch {}\n}\n\nasync function fileToDataURL(file: File): Promise<string> {\n const fr = new FileReader();\n return new Promise((res, rej) => {\n fr.onerror = () => rej(fr.error);\n fr.onload = () => res(String(fr.result));\n fr.readAsDataURL(file);\n });\n}\n\nexport function imageManagerPlugin(opts?: {\n label?: string; // toolbar label\n title?: string; // tooltip\n maxRecent?: number; // default 24\n persistThresholdBytes?: number; // default 1 MiB\n uploader?: (file: File) => Promise<string>; // optional remote upload\n onInsert?: (url: string) => string; // transform URL before insert\n}) {\n const label = opts?.label ?? '🗂️';\n const title = opts?.title ?? 'Images';\n const maxRecent = Math.max(1, opts?.maxRecent ?? 24);\n const threshold = opts?.persistThresholdBytes ?? (1 * 1024 * 1024);\n\n return (editor: MzEditor) => {\n const bar = editor.container.querySelector('.marzipan-toolbar') as HTMLElement ?? editor.container;\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'mz-btn mz-btn-imagemgr';\n btn.title = title;\n btn.textContent = label;\n\n let panel: HTMLElement | null = null;\n let recents: RecentImage[] = loadRecents();\n\n function closePanel() {\n panel?.remove(); panel = null;\n document.removeEventListener('click', outsideClose, true);\n window.removeEventListener('resize', closePanel);\n window.removeEventListener('scroll', closePanel, true);\n }\n function outsideClose(e: MouseEvent) {\n if (!panel) return;\n if (e.target instanceof Node && (panel.contains(e.target) || btn.contains(e.target))) return;\n closePanel();\n }\n\n function renderGrid(root: HTMLElement) {\n const grid = root.querySelector('.mz-im-grid') as HTMLElement;\n grid.innerHTML = '';\n recents.slice(0, maxRecent).forEach((img, idx) => {\n const card = document.createElement('div');\n card.className = 'mz-im-card';\n\n const image = document.createElement('img');\n image.decoding = 'async';\n image.loading = 'lazy';\n image.src = img.url;\n image.alt = img.name;\n\n const row = document.createElement('div');\n row.className = 'mz-im-actions';\n\n const insertBtn = document.createElement('button');\n insertBtn.type = 'button';\n insertBtn.textContent = 'Insert';\n insertBtn.onclick = () => {\n const url = opts?.onInsert ? opts.onInsert(img.url) : img.url;\n insertAtCursor(editor, ``);\n closePanel();\n };\n\n const delBtn = document.createElement('button');\n delBtn.type = 'button';\n delBtn.textContent = '✕';\n delBtn.title = 'Remove from recents';\n delBtn.onclick = () => {\n recents.splice(idx, 1);\n saveRecents(recents);\n renderGrid(root);\n };\n\n row.append(insertBtn, delBtn);\n card.append(image, row);\n grid.appendChild(card);\n });\n }\n\n async function addFromFile(file: File) {\n try {\n let url: string;\n if (opts?.uploader) {\n url = await opts.uploader(file);\n } else if (file.size <= threshold) {\n url = await fileToDataURL(file); // persist across reload\n } else {\n url = URL.createObjectURL(file); // session-only\n }\n const item: RecentImage = { url, name: file.name, createdAt: Date.now(), persistent: !url.startsWith('blob:') };\n recents = [item, ...recents.filter(r => r.url !== url)];\n saveRecents(recents);\n if (panel) renderGrid(panel);\n const finalUrl = opts?.onInsert ? opts.onInsert(url) : url;\n insertAtCursor(editor, ``);\n } catch (e) {\n console.error('Image add failed:', e);\n alert('Could not add image.');\n }\n }\n\n async function addFromUrl(url: string, name = 'image') {\n const item: RecentImage = { url, name, createdAt: Date.now(), persistent: true };\n recents = [item, ...recents.filter(r => r.url !== url)];\n saveRecents(recents);\n if (panel) renderGrid(panel);\n const finalUrl = opts?.onInsert ? opts.onInsert(url) : url;\n insertAtCursor(editor, ``);\n }\n\n function openPanel() {\n if (panel) { closePanel(); return; }\n\n panel = document.createElement('div');\n panel.className = 'mz-pop mz-im-panel';\n panel.innerHTML = `\n <div class=\"mz-im-row\">\n <input class=\"mz-im-url\" type=\"url\" placeholder=\"https://example.com/image.png\" />\n <button class=\"mz-im-addurl\" type=\"button\">Add URL</button>\n <input class=\"mz-im-file\" type=\"file\" accept=\"image/*\" hidden />\n <button class=\"mz-im-upload\" type=\"button\">Upload</button>\n <button class=\"mz-im-clear\" type=\"button\" title=\"Clear recents\">Clear</button>\n </div>\n <div class=\"mz-im-drop\">Drop images here, or paste into the editor.</div>\n <div class=\"mz-im-grid\"></div>\n `;\n document.body.appendChild(panel);\n\n // position panel\n const br = btn.getBoundingClientRect();\n panel.style.left = `${Math.round(window.scrollX + br.left)}px`;\n panel.style.top = `${Math.round(window.scrollY + br.bottom + 6)}px`;\n\n // Wire buttons\n const urlIn = panel.querySelector('.mz-im-url') as HTMLInputElement;\n const addUrl = panel.querySelector('.mz-im-addurl') as HTMLButtonElement;\n const fileIn = panel.querySelector('.mz-im-file') as HTMLInputElement;\n const upBtn = panel.querySelector('.mz-im-upload') as HTMLButtonElement;\n const clrBtn = panel.querySelector('.mz-im-clear') as HTMLButtonElement;\n const drop = panel.querySelector('.mz-im-drop') as HTMLElement;\n\n addUrl.onclick = () => {\n const val = urlIn.value.trim();\n if (!val) return;\n addFromUrl(val);\n urlIn.value = '';\n };\n\n upBtn.onclick = () => fileIn.click();\n fileIn.onchange = () => { const f = fileIn.files?.[0]; if (f) addFromFile(f); };\n\n clrBtn.onclick = () => {\n if (confirm('Clear recent images?')) {\n recents = [];\n saveRecents(recents);\n renderGrid(panel!);\n }\n };\n\n // Drag & drop\n ;['dragenter','dragover'].forEach(ev =>\n drop.addEventListener(ev, e => { e.preventDefault(); drop.classList.add('on'); })\n );\n ;['dragleave','drop'].forEach(ev =>\n drop.addEventListener(ev, e => { e.preventDefault(); drop.classList.remove('on'); })\n );\n drop.addEventListener('drop', (e: DragEvent) => {\n const files = e.dataTransfer?.files;\n if (!files || !files.length) return;\n Array.from(files).forEach(addFromFile);\n });\n\n // Render\n renderGrid(panel);\n\n // Close management\n setTimeout(() => {\n document.addEventListener('click', outsideClose, true);\n window.addEventListener('resize', closePanel);\n window.addEventListener('scroll', closePanel, true);\n }, 0);\n }\n\n // Paste support (into the editor textarea)\n editor.textarea.addEventListener('paste', (e: ClipboardEvent) => {\n const item = e.clipboardData?.items && Array.from(e.clipboardData.items)\n .find(i => i.kind === 'file' && i.type.startsWith('image/'));\n if (!item) return;\n const file = item.getAsFile();\n if (file) {\n e.preventDefault();\n addFromFile(file);\n }\n });\n\n // Drag & drop onto the editor container\n editor.container.addEventListener('dragover', e => {\n if (Array.from(e.dataTransfer?.items || []).some(i => i.kind === 'file')) e.preventDefault();\n });\n editor.container.addEventListener('drop', (e: DragEvent) => {\n const files = e.dataTransfer?.files;\n if (!files || !files.length) return;\n e.preventDefault();\n Array.from(files).forEach(addFromFile);\n });\n\n btn.onclick = openPanel;\n bar.appendChild(btn);\n };\n}\n\n// Minimal styles (inject once in your app)\nexport const imageManagerStyles = `\n.mz-im-panel { width: 440px; max-width: calc(100vw - 24px); }\n.mz-im-row { display: grid; grid-template-columns: 1fr auto auto auto; gap: 6px; margin-bottom: 8px; }\n.mz-im-row input[type=\"url\"] {\n background: var(--mz-ip-bg, #0f1216); color: var(--mz-ip-fg, #e7e7e7);\n border: 1px solid var(--mz-ip-bd, #2b2f36); border-radius: 8px; padding: 6px 8px;\n}\n.mz-im-row button {\n padding: 6px 10px; border-radius: 8px; border: 1px solid var(--mz-bd, #2b2f36);\n background: var(--mz-btn-bg, #1a1e24); color: var(--mz-btn-fg, #e7e7e7); cursor: pointer;\n}\n.mz-im-drop {\n border: 1px dashed var(--mz-drop-bd, #3b4350); border-radius: 8px;\n padding: 10px; text-align: center; font-size: 12px; margin-bottom: 8px;\n background: var(--mz-drop-bg, #0e1116);\n}\n.mz-im-drop.on { background: var(--mz-drop-on, #172033); }\n.mz-im-grid {\n display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));\n gap: 8px; max-height: 320px; overflow: auto; padding: 2px;\n}\n.mz-im-card { border: 1px solid var(--mz-card-bd, #2b2f36); border-radius: 8px; overflow: hidden;\n background: var(--mz-card-bg, #12151a); display: flex; flex-direction: column; }\n.mz-im-card img { width: 100%; height: 82px; object-fit: cover; display: block; }\n.mz-im-actions { display: flex; gap: 6px; padding: 6px; justify-content: space-between; }\n.mz-im-actions button {\n flex: 1; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--mz-bd, #2b2f36);\n background: var(--mz-btn2-bg, #1b2027); color: var(--mz-btn2-fg, #e7e7e7); cursor: pointer; font-size: 12px;\n}\n`;"],"names":["LS_KEY","insertAtCursor","editor","text","ta","s","e","loadRecents","saveRecents","list","fileToDataURL","file","fr","res","rej","imageManagerPlugin","opts","label","title","maxRecent","threshold","bar","btn","panel","recents","closePanel","outsideClose","renderGrid","root","grid","img","idx","card","image","row","insertBtn","url","delBtn","addFromFile","r","finalUrl","addFromUrl","name","openPanel","br","urlIn","addUrl","fileIn","upBtn","clrBtn","drop","val","f","ev","files","item","i","imageManagerStyles"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagePicker.d.ts","sourceRoot":"","sources":["../../src/plugins/imagePicker.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAUF,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,kBAAuB,IAIrD,QAAQ,GAAG,UAuCpB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function s(e, l) {
|
|
2
|
+
const t = e.textarea, n = t.selectionStart ?? 0, r = t.selectionEnd ?? 0;
|
|
3
|
+
t.setRangeText(l, n, r, "end"), e.updatePreview?.(), t.focus();
|
|
4
|
+
}
|
|
5
|
+
function m(e = {}) {
|
|
6
|
+
const l = e.label ?? "🖼️", t = e.title ?? "Insert image";
|
|
7
|
+
return (n) => {
|
|
8
|
+
const r = n.container?.querySelector?.(".marzipan-toolbar") ?? n.container, a = document.createElement("button");
|
|
9
|
+
a.type = "button", a.title = t, a.className = "mz-btn mz-btn-image", a.textContent = l, a.onclick = async () => {
|
|
10
|
+
const i = prompt('Paste an image URL, or type "upload" to pick a file:');
|
|
11
|
+
if (!i) return;
|
|
12
|
+
if (i.toLowerCase() !== "upload") {
|
|
13
|
+
s(n, ``);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const c = document.createElement("input");
|
|
17
|
+
c.type = "file", c.accept = "image/*", c.onchange = async () => {
|
|
18
|
+
const o = c.files?.[0];
|
|
19
|
+
if (o)
|
|
20
|
+
try {
|
|
21
|
+
const u = e.uploader ? await e.uploader(o) : URL.createObjectURL(o);
|
|
22
|
+
s(n, ``);
|
|
23
|
+
} catch (u) {
|
|
24
|
+
console.error("Image upload failed:", u), alert("Image upload failed.");
|
|
25
|
+
}
|
|
26
|
+
}, c.click();
|
|
27
|
+
}, r?.appendChild(a);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
m as imagePickerPlugin
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=imagePicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagePicker.js","sources":["../../src/plugins/imagePicker.ts"],"sourcesContent":["// plugins/imagePicker.ts\n// Adds a toolbar button to insert images. Supports URL or file -> blob URL.\n// Optional uploader(file) => Promise<string> to persist and return a real URL.\n\nexport type ImagePickerOptions = {\n uploader?: (file: File) => Promise<string>;\n label?: string; // button label or emoji\n title?: string; // tooltip\n};\n\nfunction insertAtCursor(editor: any, text: string) {\n const ta = editor.textarea as HTMLTextAreaElement;\n const s = ta.selectionStart ?? 0, e = ta.selectionEnd ?? 0;\n ta.setRangeText(text, s, e, 'end');\n editor.updatePreview?.();\n ta.focus();\n}\n\nexport function imagePickerPlugin(opts: ImagePickerOptions = {}) {\n const label = opts.label ?? '🖼️';\n const title = opts.title ?? 'Insert image';\n\n return (editor: any) => {\n // Find or create a toolbar container\n const bar = editor.container?.querySelector?.('.marzipan-toolbar') as HTMLElement\n ?? editor.container;\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = title;\n btn.className = 'mz-btn mz-btn-image';\n btn.textContent = label;\n\n btn.onclick = async () => {\n const mode = prompt('Paste an image URL, or type \"upload\" to pick a file:');\n if (!mode) return;\n\n if (mode.toLowerCase() !== 'upload') {\n insertAtCursor(editor, ``);\n return;\n }\n\n const input = document.createElement('input');\n input.type = 'file';\n input.accept = 'image/*';\n input.onchange = async () => {\n const file = input.files?.[0];\n if (!file) return;\n try {\n const url = opts.uploader ? await opts.uploader(file) : URL.createObjectURL(file);\n insertAtCursor(editor, ``);\n } catch (e) {\n console.error('Image upload failed:', e);\n alert('Image upload failed.');\n }\n };\n input.click();\n };\n\n bar?.appendChild(btn);\n };\n}"],"names":["insertAtCursor","editor","text","ta","s","e","imagePickerPlugin","opts","label","title","bar","btn","mode","input","file","url"],"mappings":"AAUA,SAASA,EAAeC,GAAaC,GAAc;AACjD,QAAMC,IAAKF,EAAO,UACZG,IAAID,EAAG,kBAAkB,GAAGE,IAAIF,EAAG,gBAAgB;AACzD,EAAAA,EAAG,aAAaD,GAAME,GAAGC,GAAG,KAAK,GACjCJ,EAAO,gBAAA,GACPE,EAAG,MAAA;AACL;AAEO,SAASG,EAAkBC,IAA2B,IAAI;AAC/D,QAAMC,IAAQD,EAAK,SAAS,OACtBE,IAAQF,EAAK,SAAS;AAE5B,SAAO,CAACN,MAAgB;AAEtB,UAAMS,IAAMT,EAAO,WAAW,gBAAgB,mBAAmB,KAC5DA,EAAO,WAENU,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,OAAO,UACXA,EAAI,QAAQF,GACZE,EAAI,YAAY,uBAChBA,EAAI,cAAcH,GAElBG,EAAI,UAAU,YAAY;AACxB,YAAMC,IAAO,OAAO,sDAAsD;AAC1E,UAAI,CAACA,EAAM;AAEX,UAAIA,EAAK,YAAA,MAAkB,UAAU;AACnC,QAAAZ,EAAeC,GAAQ,eAAeW,CAAI,GAAG;AAC7C;AAAA,MACF;AAEA,YAAMC,IAAQ,SAAS,cAAc,OAAO;AAC5C,MAAAA,EAAM,OAAO,QACbA,EAAM,SAAS,WACfA,EAAM,WAAW,YAAY;AAC3B,cAAMC,IAAOD,EAAM,QAAQ,CAAC;AAC5B,YAAKC;AACL,cAAI;AACF,kBAAMC,IAAMR,EAAK,WAAW,MAAMA,EAAK,SAASO,CAAI,IAAI,IAAI,gBAAgBA,CAAI;AAChF,YAAAd,EAAeC,GAAQ,KAAKa,EAAK,IAAI,KAAKC,CAAG,GAAG;AAAA,UAClD,SAASV,GAAG;AACV,oBAAQ,MAAM,wBAAwBA,CAAC,GACvC,MAAM,sBAAsB;AAAA,UAC9B;AAAA,MACF,GACAQ,EAAM,MAAA;AAAA,IACR,GAEAH,GAAK,YAAYC,CAAG;AAAA,EACtB;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagePickerPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/imagePickerPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEpG,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,kBAAkB,yBAM1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imagePickerPlugin.js","sources":["../../src/plugins/imagePickerPlugin.ts"],"sourcesContent":["import { imagePickerPlugin as coreImagePickerPlugin, type ImagePickerOptions } from './imagePicker';\n\nexport function imagePickerPlugin(opts?: ImagePickerOptions) {\n return coreImagePickerPlugin({\n label: '🖼️',\n title: 'Insert image',\n ...opts,\n });\n}\n"],"names":["imagePickerPlugin","opts","coreImagePickerPlugin"],"mappings":";AAEO,SAASA,EAAkBC,GAA2B;AAC3D,SAAOC,EAAsB;AAAA,IAC3B,OAAO;AAAA,IACP,OAAO;AAAA,IACP,GAAGD;AAAA,EAAA,CACJ;AACH;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaidExternal.d.ts","sourceRoot":"","sources":["../../src/plugins/mermaidExternal.ts"],"names":[],"mappings":"AAIA,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAiBnE,QAAQ,GAAG,UAwCpB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function k(d) {
|
|
2
|
+
let m = 0;
|
|
3
|
+
function l() {
|
|
4
|
+
return window.mermaid || null;
|
|
5
|
+
}
|
|
6
|
+
async function u(e, o) {
|
|
7
|
+
const n = l();
|
|
8
|
+
if (!n) return null;
|
|
9
|
+
try {
|
|
10
|
+
n.initialize?.({ startOnLoad: !1, theme: e, ...o });
|
|
11
|
+
} catch {
|
|
12
|
+
}
|
|
13
|
+
return n;
|
|
14
|
+
}
|
|
15
|
+
return (e) => {
|
|
16
|
+
const o = e.options.hooks?.afterPreviewRender;
|
|
17
|
+
e.options.hooks = e.options.hooks || {}, e.options.hooks.afterPreviewRender = async (n, f) => {
|
|
18
|
+
o?.(n, f);
|
|
19
|
+
const a = n.querySelectorAll("pre code.language-mermaid");
|
|
20
|
+
if (!a.length) return;
|
|
21
|
+
const p = document.documentElement.classList.contains("dark") ? "dark" : "default", i = await u(p, d);
|
|
22
|
+
if (!i) {
|
|
23
|
+
window.__mzMermaidWarned || (console.warn("[Marzipan] Mermaid block found, but window.mermaid is not loaded."), window.__mzMermaidWarned = !0);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
for (const s of Array.from(a)) {
|
|
27
|
+
const w = s.closest("pre"), c = (s.textContent || "").trim();
|
|
28
|
+
if (!c)
|
|
29
|
+
continue;
|
|
30
|
+
const h = `mz-mermaid-${m++}`;
|
|
31
|
+
try {
|
|
32
|
+
const r = await i.render(h, c), t = document.createElement("div");
|
|
33
|
+
t.className = "marzipan-mermaid", t.innerHTML = r?.svg || "", w.replaceWith(t), r?.bindFunctions?.(t);
|
|
34
|
+
} catch (r) {
|
|
35
|
+
console.error("Mermaid render error:", r);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
k as mermaidExternalPlugin
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=mermaidExternal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaidExternal.js","sources":["../../src/plugins/mermaidExternal.ts"],"sourcesContent":["// plugins/mermaidExternal.ts\n// Renders ```mermaid fences when window.mermaid is available (CDN script).\n// Does nothing otherwise.\n\nexport function mermaidExternalPlugin(init?: Parameters<any[\"initialize\"]>[0]) {\n let id = 0;\n\n function getMermaid(): any | null {\n return (window as any).mermaid || null;\n }\n\n async function ensureInit(theme: 'dark' | 'light', config?: any) {\n const m = getMermaid();\n if (!m) return null;\n // Mermaid v10+: initialize({ startOnLoad: false, theme })\n try {\n m.initialize?.({ startOnLoad: false, theme, ...config });\n } catch { /* ignore */ }\n return m;\n }\n\n return (editor: any) => {\n const prev = editor.options.hooks?.afterPreviewRender;\n editor.options.hooks = editor.options.hooks || {};\n\n editor.options.hooks.afterPreviewRender = async (root: HTMLElement, e: any) => {\n prev?.(root, e);\n\n const nodes = root.querySelectorAll('pre code.language-mermaid');\n if (!nodes.length) return;\n\n const theme = document.documentElement.classList.contains('dark') ? 'dark' : 'default';\n const m = await ensureInit(theme as any, init);\n if (!m) {\n // Optional: visible hint once per session\n if (!(window as any).__mzMermaidWarned) {\n console.warn('[Marzipan] Mermaid block found, but window.mermaid is not loaded.');\n (window as any).__mzMermaidWarned = true;\n }\n return;\n }\n\n for (const codeEl of Array.from(nodes)) {\n const parentPre = (codeEl as HTMLElement).closest('pre') as HTMLElement;\n const code = (codeEl.textContent || '').trim();\n if (!code) { continue; }\n const domId = `mz-mermaid-${id++}`;\n try {\n // Mermaid v10: render(id, code) -> { svg, bindFunctions }\n const res = await m.render(domId, code);\n const wrapper = document.createElement('div');\n wrapper.className = 'marzipan-mermaid';\n wrapper.innerHTML = res?.svg || '';\n parentPre.replaceWith(wrapper);\n res?.bindFunctions?.(wrapper);\n } catch (err) {\n console.error('Mermaid render error:', err);\n }\n }\n };\n };\n}"],"names":["mermaidExternalPlugin","init","id","getMermaid","ensureInit","theme","config","m","editor","prev","root","e","nodes","codeEl","parentPre","code","domId","res","wrapper","err"],"mappings":"AAIO,SAASA,EAAsBC,GAAyC;AAC7E,MAAIC,IAAK;AAET,WAASC,IAAyB;AAChC,WAAQ,OAAe,WAAW;AAAA,EACpC;AAEA,iBAAeC,EAAWC,GAAyBC,GAAc;AAC/D,UAAMC,IAAIJ,EAAA;AACV,QAAI,CAACI,EAAG,QAAO;AAEf,QAAI;AACF,MAAAA,EAAE,aAAa,EAAE,aAAa,IAAO,OAAAF,GAAO,GAAGC,GAAQ;AAAA,IACzD,QAAQ;AAAA,IAAe;AACvB,WAAOC;AAAA,EACT;AAEA,SAAO,CAACC,MAAgB;AACtB,UAAMC,IAAOD,EAAO,QAAQ,OAAO;AACnC,IAAAA,EAAO,QAAQ,QAAQA,EAAO,QAAQ,SAAS,CAAA,GAE/CA,EAAO,QAAQ,MAAM,qBAAqB,OAAOE,GAAmBC,MAAW;AAC7E,MAAAF,IAAOC,GAAMC,CAAC;AAEd,YAAMC,IAAQF,EAAK,iBAAiB,2BAA2B;AAC/D,UAAI,CAACE,EAAM,OAAQ;AAEnB,YAAMP,IAAQ,SAAS,gBAAgB,UAAU,SAAS,MAAM,IAAI,SAAS,WACvEE,IAAI,MAAMH,EAAWC,GAAcJ,CAAI;AAC7C,UAAI,CAACM,GAAG;AAEN,QAAM,OAAe,sBACnB,QAAQ,KAAK,mEAAmE,GAC/E,OAAe,oBAAoB;AAEtC;AAAA,MACF;AAEA,iBAAWM,KAAU,MAAM,KAAKD,CAAK,GAAG;AACtC,cAAME,IAAaD,EAAuB,QAAQ,KAAK,GACjDE,KAAQF,EAAO,eAAe,IAAI,KAAA;AACxC,YAAI,CAACE;AAAQ;AACb,cAAMC,IAAQ,cAAcd,GAAI;AAChC,YAAI;AAEF,gBAAMe,IAAM,MAAMV,EAAE,OAAOS,GAAOD,CAAI,GAChCG,IAAU,SAAS,cAAc,KAAK;AAC5C,UAAAA,EAAQ,YAAY,oBACpBA,EAAQ,YAAYD,GAAK,OAAO,IAChCH,EAAU,YAAYI,CAAO,GAC7BD,GAAK,gBAAgBC,CAAO;AAAA,QAC9B,SAASC,GAAK;AACZ,kBAAQ,MAAM,yBAAyBA,CAAG;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaidPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/mermaidPlugin.ts"],"names":[],"mappings":"AACA,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,GAAG,IAIhC,QAAQ,GAAG,UA8BpB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function u(s) {
|
|
2
|
+
let r, i = 0;
|
|
3
|
+
return (e) => {
|
|
4
|
+
const m = async (t) => {
|
|
5
|
+
const n = t.querySelectorAll("pre code.language-mermaid");
|
|
6
|
+
if (!n.length) return;
|
|
7
|
+
const l = await import("../mermaid.core-DENutRS8.js").then((a) => a.bD);
|
|
8
|
+
r ?? (r = l.default), r.initialize({
|
|
9
|
+
startOnLoad: !1,
|
|
10
|
+
theme: document.documentElement.classList.contains("dark") ? "dark" : "default",
|
|
11
|
+
...s
|
|
12
|
+
}), await Promise.all(Array.from(n).map(async (a) => {
|
|
13
|
+
const d = a.closest("pre"), { svg: p } = await r.render(`m-${i++}`, a.textContent || ""), o = document.createElement("div");
|
|
14
|
+
o.className = "marzipan-mermaid", o.innerHTML = p, d.replaceWith(o);
|
|
15
|
+
}));
|
|
16
|
+
}, c = e.options.hooks?.afterPreviewRender;
|
|
17
|
+
e.options.hooks = e.options.hooks || {}, e.options.hooks.afterPreviewRender = (t, n) => {
|
|
18
|
+
c?.(t, n), m(t);
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
u as mermaidPlugin
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=mermaidPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaidPlugin.js","sources":["../../src/plugins/mermaidPlugin.ts"],"sourcesContent":["// mermaidPlugin.ts\nexport function mermaidPlugin(config?: any) {\n let mermaid: any;\n let id = 0;\n\n return (editor: any) => {\n const render = async (root: HTMLElement) => {\n const nodes = root.querySelectorAll('pre code.language-mermaid');\n if (!nodes.length) return;\n\n const mod = await import('mermaid');\n mermaid ??= mod.default;\n mermaid.initialize({\n startOnLoad: false,\n theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default',\n ...config\n });\n\n await Promise.all(Array.from(nodes).map(async (codeEl) => {\n const parentPre = codeEl.closest('pre') as HTMLElement;\n const { svg } = await mermaid.render(`m-${id++}`, codeEl.textContent || '');\n const wrapper = document.createElement('div');\n wrapper.className = 'marzipan-mermaid';\n wrapper.innerHTML = svg; // SVG from mermaid is safe-by-design\n parentPre.replaceWith(wrapper);\n }));\n };\n\n const prev = editor.options.hooks?.afterPreviewRender;\n editor.options.hooks = editor.options.hooks || {};\n editor.options.hooks.afterPreviewRender = (root: HTMLElement, e: any) => {\n prev?.(root, e);\n render(root);\n };\n };\n}\n\n// Write Markdown:\n\n// ````md\n// ```mermaid\n// graph TD\n// A[Start] --> B{Choice}\n// B -->|Yes| C[Path 1]\n// B -->|No| D[Path 2]\n//````\n//````"],"names":["mermaidPlugin","config","mermaid","id","editor","render","root","nodes","mod","n","codeEl","parentPre","svg","wrapper","prev","e"],"mappings":"AACO,SAASA,EAAcC,GAAc;AAC1C,MAAIC,GACAC,IAAK;AAET,SAAO,CAACC,MAAgB;AACtB,UAAMC,IAAS,OAAOC,MAAsB;AAC1C,YAAMC,IAAQD,EAAK,iBAAiB,2BAA2B;AAC/D,UAAI,CAACC,EAAM,OAAQ;AAEnB,YAAMC,IAAM,MAAM,OAAO,6BAAS,EAAA,KAAA,CAAAC,MAAAA,EAAA,EAAA;AAClC,MAAAP,UAAYM,EAAI,UAChBN,EAAQ,WAAW;AAAA,QACjB,aAAa;AAAA,QACb,OAAO,SAAS,gBAAgB,UAAU,SAAS,MAAM,IAAI,SAAS;AAAA,QACtE,GAAGD;AAAA,MAAA,CACJ,GAED,MAAM,QAAQ,IAAI,MAAM,KAAKM,CAAK,EAAE,IAAI,OAAOG,MAAW;AACxD,cAAMC,IAAYD,EAAO,QAAQ,KAAK,GAChC,EAAE,KAAAE,EAAA,IAAQ,MAAMV,EAAQ,OAAO,KAAKC,GAAI,IAAIO,EAAO,eAAe,EAAE,GACpEG,IAAU,SAAS,cAAc,KAAK;AAC5C,QAAAA,EAAQ,YAAY,oBACpBA,EAAQ,YAAYD,GACpBD,EAAU,YAAYE,CAAO;AAAA,MAC/B,CAAC,CAAC;AAAA,IACJ,GAEMC,IAAOV,EAAO,QAAQ,OAAO;AACnC,IAAAA,EAAO,QAAQ,QAAQA,EAAO,QAAQ,SAAS,CAAA,GAC/CA,EAAO,QAAQ,MAAM,qBAAqB,CAACE,GAAmBS,MAAW;AACvE,MAAAD,IAAOR,GAAMS,CAAC,GACdV,EAAOC,CAAI;AAAA,IACb;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableGenerator.d.ts","sourceRoot":"","sources":["../../src/plugins/tableGenerator.ts"],"names":[],"mappings":"AAcA,wBAAgB,oBAAoB,KAC1B,QAAQ,GAAG,UAuBpB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { r as a, b as c } from "../table-DMIy93NJ.js";
|
|
2
|
+
function l(n, r) {
|
|
3
|
+
const t = n.textarea, e = t.selectionStart ?? 0, o = t.selectionEnd ?? 0;
|
|
4
|
+
t.setRangeText(r, e, o, "end"), n.updatePreview?.(), t.focus();
|
|
5
|
+
}
|
|
6
|
+
function i() {
|
|
7
|
+
return (n) => {
|
|
8
|
+
const r = n.container?.querySelector?.(".marzipan-toolbar") ?? n.container, t = document.createElement("button");
|
|
9
|
+
t.type = "button", t.title = "Insert table", t.className = "mz-btn mz-btn-table", t.textContent = "▦", t.onclick = () => {
|
|
10
|
+
const e = a(prompt("Rows (excluding header)?"), 2);
|
|
11
|
+
if (e === null) return;
|
|
12
|
+
const o = a(prompt("Columns?"), 2);
|
|
13
|
+
if (o === null) return;
|
|
14
|
+
const s = c(e, o);
|
|
15
|
+
l(n, `
|
|
16
|
+
${s}
|
|
17
|
+
`);
|
|
18
|
+
}, r?.appendChild(t);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
i as tableGeneratorPlugin
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=tableGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableGenerator.js","sources":["../../src/plugins/tableGenerator.ts"],"sourcesContent":["// plugins/tableGenerator.ts\n// Quick GFM table inserter.\n\nimport { buildTableMarkdown, resolvePositiveInteger } from './utils/table';\n\nfunction insertAtCursor(editor: any, text: string) {\n const ta = editor.textarea as HTMLTextAreaElement;\n const s = ta.selectionStart ?? 0;\n const e = ta.selectionEnd ?? 0;\n ta.setRangeText(text, s, e, 'end');\n editor.updatePreview?.();\n ta.focus();\n}\n\nexport function tableGeneratorPlugin() {\n return (editor: any) => {\n const bar = editor.container?.querySelector?.('.marzipan-toolbar') as HTMLElement\n ?? editor.container;\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = 'Insert table';\n btn.className = 'mz-btn mz-btn-table';\n btn.textContent = '▦';\n\n btn.onclick = () => {\n const rowInput = resolvePositiveInteger(prompt('Rows (excluding header)?'), 2);\n if (rowInput === null) return;\n\n const colInput = resolvePositiveInteger(prompt('Columns?'), 2);\n if (colInput === null) return;\n\n const md = buildTableMarkdown(rowInput, colInput);\n insertAtCursor(editor, `\\n${md}\\n`);\n };\n\n bar?.appendChild(btn);\n };\n}\n"],"names":["insertAtCursor","editor","text","ta","s","e","tableGeneratorPlugin","bar","btn","rowInput","resolvePositiveInteger","colInput","md","buildTableMarkdown"],"mappings":";AAKA,SAASA,EAAeC,GAAaC,GAAc;AACjD,QAAMC,IAAKF,EAAO,UACZG,IAAID,EAAG,kBAAkB,GACzBE,IAAIF,EAAG,gBAAgB;AAC7B,EAAAA,EAAG,aAAaD,GAAME,GAAGC,GAAG,KAAK,GACjCJ,EAAO,gBAAA,GACPE,EAAG,MAAA;AACL;AAEO,SAASG,IAAuB;AACrC,SAAO,CAACL,MAAgB;AACtB,UAAMM,IAAMN,EAAO,WAAW,gBAAgB,mBAAmB,KAC5DA,EAAO,WAENO,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,OAAO,UACXA,EAAI,QAAQ,gBACZA,EAAI,YAAY,uBAChBA,EAAI,cAAc,KAElBA,EAAI,UAAU,MAAM;AAClB,YAAMC,IAAWC,EAAuB,OAAO,0BAA0B,GAAG,CAAC;AAC7E,UAAID,MAAa,KAAM;AAEvB,YAAME,IAAWD,EAAuB,OAAO,UAAU,GAAG,CAAC;AAC7D,UAAIC,MAAa,KAAM;AAEvB,YAAMC,IAAKC,EAAmBJ,GAAUE,CAAQ;AAChD,MAAAX,EAAeC,GAAQ;AAAA,EAAKW,CAAE;AAAA,CAAI;AAAA,IACpC,GAEAL,GAAK,YAAYC,CAAG;AAAA,EACtB;AACF;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type MzEditor = {
|
|
2
|
+
container: HTMLElement;
|
|
3
|
+
textarea: HTMLTextAreaElement;
|
|
4
|
+
updatePreview: () => void;
|
|
5
|
+
};
|
|
6
|
+
export declare function tableGridPlugin(opts?: {
|
|
7
|
+
maxRows?: number;
|
|
8
|
+
maxCols?: number;
|
|
9
|
+
label?: string;
|
|
10
|
+
title?: string;
|
|
11
|
+
}): (editor: MzEditor) => void;
|
|
12
|
+
export declare const tableGridStyles = "\n.mz-pop {\n position: absolute; z-index: 9999; user-select: none;\n background: var(--mz-pop-bg, #111); color: var(--mz-pop-fg, #eee);\n border: 1px solid var(--mz-pop-bd, #333); border-radius: 10px;\n box-shadow: 0 8px 24px rgba(0,0,0,.35); padding: 10px;\n}\n.mz-tablegrid {\n display: grid; grid-template-rows: repeat(var(--r), 16px);\n grid-template-columns: repeat(var(--c), 16px);\n gap: 4px; margin: 4px;\n}\n.mz-tablegrid .mz-cell {\n width: 16px; height: 16px; border-radius: 4px;\n background: var(--mz-cell-bg, #1d1f23); border: 1px solid var(--mz-cell-bd, #2b2f36);\n}\n.mz-tablegrid .mz-cell.sel {\n background: var(--mz-cell-sel-bg, #2f6feb); border-color: var(--mz-cell-sel-bd, #3b82f6);\n}\n.mz-tablegrid-status { font-size: 12px; opacity: .8; padding: 6px 4px 2px; text-align: center; }\n.mz-btn { cursor: pointer; }\n";
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=tableGridPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableGridPlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/tableGridPlugin.ts"],"names":[],"mappings":"AAKA,KAAK,QAAQ,GAAG;IACd,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAWF,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,IAMS,QAAQ,QAAQ,UAiFzB;AAGD,eAAO,MAAM,eAAe,o1BAqB3B,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { b as h } from "../table-DMIy93NJ.js";
|
|
2
|
+
function y(r, i) {
|
|
3
|
+
const o = r.textarea, m = o.selectionStart ?? 0, p = o.selectionEnd ?? 0;
|
|
4
|
+
o.setRangeText(i, m, p, "end"), r.updatePreview(), o.focus();
|
|
5
|
+
}
|
|
6
|
+
function E(r) {
|
|
7
|
+
const i = Math.max(1, r?.maxRows ?? 10), o = Math.max(1, r?.maxCols ?? 10), m = r?.label ?? "▦", p = r?.title ?? "Insert table";
|
|
8
|
+
return (u) => {
|
|
9
|
+
const z = u.container.querySelector(".marzipan-toolbar") ?? u.container, n = document.createElement("button");
|
|
10
|
+
n.type = "button", n.className = "mz-btn mz-btn-tablegrid", n.title = p, n.textContent = m;
|
|
11
|
+
let e = null;
|
|
12
|
+
function a() {
|
|
13
|
+
e?.remove(), e = null, document.removeEventListener("click", g, !0), window.removeEventListener("resize", a), window.removeEventListener("scroll", a, !0);
|
|
14
|
+
}
|
|
15
|
+
function g(t) {
|
|
16
|
+
e && (t.target instanceof Node && (e.contains(t.target) || n.contains(t.target)) || a());
|
|
17
|
+
}
|
|
18
|
+
function v() {
|
|
19
|
+
if (e) {
|
|
20
|
+
a();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
e = document.createElement("div"), e.className = "mz-pop mz-tablegrid-pop";
|
|
24
|
+
const t = document.createElement("div");
|
|
25
|
+
t.className = "mz-tablegrid", t.style.setProperty("--r", String(i)), t.style.setProperty("--c", String(o));
|
|
26
|
+
const d = document.createElement("div");
|
|
27
|
+
d.className = "mz-tablegrid-status", d.textContent = "0 × 0";
|
|
28
|
+
for (let l = 1; l <= i; l++)
|
|
29
|
+
for (let s = 1; s <= o; s++) {
|
|
30
|
+
const c = document.createElement("div");
|
|
31
|
+
c.className = "mz-cell", c.dataset.r = String(l), c.dataset.c = String(s), c.onmouseenter = () => {
|
|
32
|
+
d.textContent = `${l} × ${s}`, t.querySelectorAll(".mz-cell").forEach((b) => {
|
|
33
|
+
const f = Number(b.dataset.r), w = Number(b.dataset.c);
|
|
34
|
+
b.classList.toggle("sel", f <= l && w <= s);
|
|
35
|
+
});
|
|
36
|
+
}, c.onclick = () => {
|
|
37
|
+
y(u, `
|
|
38
|
+
${h(l, s)}
|
|
39
|
+
`), a();
|
|
40
|
+
}, t.appendChild(c);
|
|
41
|
+
}
|
|
42
|
+
e.appendChild(t), e.appendChild(d), document.body.appendChild(e);
|
|
43
|
+
const x = n.getBoundingClientRect();
|
|
44
|
+
e.style.left = `${Math.round(window.scrollX + x.left)}px`, e.style.top = `${Math.round(window.scrollY + x.bottom + 6)}px`, setTimeout(() => {
|
|
45
|
+
document.addEventListener("click", g, !0), window.addEventListener("resize", a), window.addEventListener("scroll", a, !0);
|
|
46
|
+
}, 0);
|
|
47
|
+
}
|
|
48
|
+
n.onclick = v, z.appendChild(n);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const k = `
|
|
52
|
+
.mz-pop {
|
|
53
|
+
position: absolute; z-index: 9999; user-select: none;
|
|
54
|
+
background: var(--mz-pop-bg, #111); color: var(--mz-pop-fg, #eee);
|
|
55
|
+
border: 1px solid var(--mz-pop-bd, #333); border-radius: 10px;
|
|
56
|
+
box-shadow: 0 8px 24px rgba(0,0,0,.35); padding: 10px;
|
|
57
|
+
}
|
|
58
|
+
.mz-tablegrid {
|
|
59
|
+
display: grid; grid-template-rows: repeat(var(--r), 16px);
|
|
60
|
+
grid-template-columns: repeat(var(--c), 16px);
|
|
61
|
+
gap: 4px; margin: 4px;
|
|
62
|
+
}
|
|
63
|
+
.mz-tablegrid .mz-cell {
|
|
64
|
+
width: 16px; height: 16px; border-radius: 4px;
|
|
65
|
+
background: var(--mz-cell-bg, #1d1f23); border: 1px solid var(--mz-cell-bd, #2b2f36);
|
|
66
|
+
}
|
|
67
|
+
.mz-tablegrid .mz-cell.sel {
|
|
68
|
+
background: var(--mz-cell-sel-bg, #2f6feb); border-color: var(--mz-cell-sel-bd, #3b82f6);
|
|
69
|
+
}
|
|
70
|
+
.mz-tablegrid-status { font-size: 12px; opacity: .8; padding: 6px 4px 2px; text-align: center; }
|
|
71
|
+
.mz-btn { cursor: pointer; }
|
|
72
|
+
`;
|
|
73
|
+
export {
|
|
74
|
+
E as tableGridPlugin,
|
|
75
|
+
k as tableGridStyles
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=tableGridPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tableGridPlugin.js","sources":["../../src/plugins/tableGridPlugin.ts"],"sourcesContent":["// plugins/tableGridPlugin.ts\n// Zero-dep \"grid popover\" table inserter (like Notion). GFM markdown output.\n\nimport { buildTableMarkdown } from './utils/table';\n\ntype MzEditor = {\n container: HTMLElement;\n textarea: HTMLTextAreaElement;\n updatePreview: () => void;\n};\n\nfunction insertAtCursor(editor: MzEditor, text: string) {\n const ta = editor.textarea;\n const s = ta.selectionStart ?? 0;\n const e = ta.selectionEnd ?? 0;\n ta.setRangeText(text, s, e, 'end');\n editor.updatePreview();\n ta.focus();\n}\n\nexport function tableGridPlugin(opts?: {\n maxRows?: number; // default 10\n maxCols?: number; // default 10\n label?: string; // toolbar label\n title?: string; // tooltip\n}) {\n const maxR = Math.max(1, opts?.maxRows ?? 10);\n const maxC = Math.max(1, opts?.maxCols ?? 10);\n const label = opts?.label ?? '▦';\n const title = opts?.title ?? 'Insert table';\n\n return (editor: MzEditor) => {\n const bar = editor.container.querySelector('.marzipan-toolbar') as HTMLElement ?? editor.container;\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className = 'mz-btn mz-btn-tablegrid';\n btn.title = title;\n btn.textContent = label;\n\n let pop: HTMLElement | null = null;\n\n function closePop() {\n pop?.remove();\n pop = null;\n document.removeEventListener('click', outsideClose, true);\n window.removeEventListener('resize', closePop);\n window.removeEventListener('scroll', closePop, true);\n }\n\n function outsideClose(e: MouseEvent) {\n if (!pop) return;\n if (e.target instanceof Node && (pop.contains(e.target) || btn.contains(e.target))) return;\n closePop();\n }\n\n function openPop() {\n if (pop) { closePop(); return; }\n\n pop = document.createElement('div');\n pop.className = 'mz-pop mz-tablegrid-pop';\n\n const grid = document.createElement('div');\n grid.className = 'mz-tablegrid';\n grid.style.setProperty('--r', String(maxR));\n grid.style.setProperty('--c', String(maxC));\n\n const status = document.createElement('div');\n status.className = 'mz-tablegrid-status';\n status.textContent = '0 × 0';\n\n for (let r = 1; r <= maxR; r++) {\n for (let c = 1; c <= maxC; c++) {\n const cell = document.createElement('div');\n cell.className = 'mz-cell';\n cell.dataset.r = String(r);\n cell.dataset.c = String(c);\n cell.onmouseenter = () => {\n status.textContent = `${r} × ${c}`;\n // highlight\n grid.querySelectorAll<HTMLElement>('.mz-cell').forEach(el => {\n const rr = Number(el.dataset.r), cc = Number(el.dataset.c);\n el.classList.toggle('sel', rr <= r && cc <= c);\n });\n };\n cell.onclick = () => {\n insertAtCursor(editor, `\\n${buildTableMarkdown(r, c)}\\n`);\n closePop();\n };\n grid.appendChild(cell);\n }\n }\n\n pop.appendChild(grid);\n pop.appendChild(status);\n document.body.appendChild(pop);\n\n // position under button\n const br = btn.getBoundingClientRect();\n pop.style.left = `${Math.round(window.scrollX + br.left)}px`;\n pop.style.top = `${Math.round(window.scrollY + br.bottom + 6)}px`;\n\n setTimeout(() => {\n document.addEventListener('click', outsideClose, true);\n window.addEventListener('resize', closePop);\n window.addEventListener('scroll', closePop, true);\n }, 0);\n }\n\n btn.onclick = openPop;\n bar.appendChild(btn);\n };\n}\n\n// Minimal styles (inject once in your app)\nexport const tableGridStyles = `\n.mz-pop {\n position: absolute; z-index: 9999; user-select: none;\n background: var(--mz-pop-bg, #111); color: var(--mz-pop-fg, #eee);\n border: 1px solid var(--mz-pop-bd, #333); border-radius: 10px;\n box-shadow: 0 8px 24px rgba(0,0,0,.35); padding: 10px;\n}\n.mz-tablegrid {\n display: grid; grid-template-rows: repeat(var(--r), 16px);\n grid-template-columns: repeat(var(--c), 16px);\n gap: 4px; margin: 4px;\n}\n.mz-tablegrid .mz-cell {\n width: 16px; height: 16px; border-radius: 4px;\n background: var(--mz-cell-bg, #1d1f23); border: 1px solid var(--mz-cell-bd, #2b2f36);\n}\n.mz-tablegrid .mz-cell.sel {\n background: var(--mz-cell-sel-bg, #2f6feb); border-color: var(--mz-cell-sel-bd, #3b82f6);\n}\n.mz-tablegrid-status { font-size: 12px; opacity: .8; padding: 6px 4px 2px; text-align: center; }\n.mz-btn { cursor: pointer; }\n`;\n"],"names":["insertAtCursor","editor","text","ta","s","e","tableGridPlugin","opts","maxR","maxC","label","title","bar","btn","pop","closePop","outsideClose","openPop","grid","status","r","c","cell","el","rr","cc","buildTableMarkdown","br","tableGridStyles"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tablePlugin.d.ts","sourceRoot":"","sources":["../../src/plugins/tablePlugin.ts"],"names":[],"mappings":"AAaA,wBAAgB,WAAW,KACjB,QAAQ,GAAG,UAqBpB"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { r as s, b as l } from "../table-DMIy93NJ.js";
|
|
2
|
+
function a(e, n) {
|
|
3
|
+
const t = e.textarea, o = t.selectionStart ?? 0, r = t.selectionEnd ?? 0;
|
|
4
|
+
t.setRangeText(n, o, r, "end"), e.updatePreview(), t.focus();
|
|
5
|
+
}
|
|
6
|
+
function i() {
|
|
7
|
+
return (e) => {
|
|
8
|
+
const n = e.container.querySelector(".marzipan-toolbar");
|
|
9
|
+
if (!n) return;
|
|
10
|
+
const t = document.createElement("button");
|
|
11
|
+
t.type = "button", t.title = "Insert table", t.textContent = "▦", t.onclick = () => {
|
|
12
|
+
const o = s(prompt("Rows (excluding header)?"), 2);
|
|
13
|
+
if (o === null) return;
|
|
14
|
+
const r = s(prompt("Columns?"), 2);
|
|
15
|
+
if (r === null) return;
|
|
16
|
+
const c = l(o, r);
|
|
17
|
+
a(e, `
|
|
18
|
+
${c}
|
|
19
|
+
`);
|
|
20
|
+
}, n.appendChild(t);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
i as tablePlugin
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=tablePlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tablePlugin.js","sources":["../../src/plugins/tablePlugin.ts"],"sourcesContent":["// tablePlugin.ts\n\nimport { buildTableMarkdown, resolvePositiveInteger } from './utils/table';\n\nfunction insertAtCursor(editor: any, text: string) {\n const ta = editor.textarea as HTMLTextAreaElement;\n const s = ta.selectionStart ?? 0;\n const e = ta.selectionEnd ?? 0;\n ta.setRangeText(text, s, e, 'end');\n editor.updatePreview();\n ta.focus();\n}\n\nexport function tablePlugin() {\n return (editor: any) => {\n const bar = editor.container.querySelector('.marzipan-toolbar') as HTMLElement;\n if (!bar) return;\n\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.title = 'Insert table';\n btn.textContent = '▦'; // or an icon\n btn.onclick = () => {\n const rows = resolvePositiveInteger(prompt('Rows (excluding header)?'), 2);\n if (rows === null) return;\n\n const cols = resolvePositiveInteger(prompt('Columns?'), 2);\n if (cols === null) return;\n\n const md = buildTableMarkdown(rows, cols);\n insertAtCursor(editor, `\\n${md}\\n`);\n };\n\n bar.appendChild(btn);\n };\n}\n"],"names":["insertAtCursor","editor","text","ta","s","e","tablePlugin","bar","btn","rows","resolvePositiveInteger","cols","md","buildTableMarkdown"],"mappings":";AAIA,SAASA,EAAeC,GAAaC,GAAc;AACjD,QAAMC,IAAKF,EAAO,UACZG,IAAID,EAAG,kBAAkB,GACzBE,IAAIF,EAAG,gBAAgB;AAC7B,EAAAA,EAAG,aAAaD,GAAME,GAAGC,GAAG,KAAK,GACjCJ,EAAO,cAAA,GACPE,EAAG,MAAA;AACL;AAEO,SAASG,IAAc;AAC5B,SAAO,CAACL,MAAgB;AACtB,UAAMM,IAAMN,EAAO,UAAU,cAAc,mBAAmB;AAC9D,QAAI,CAACM,EAAK;AAEV,UAAMC,IAAM,SAAS,cAAc,QAAQ;AAC3C,IAAAA,EAAI,OAAO,UACXA,EAAI,QAAQ,gBACZA,EAAI,cAAc,KAClBA,EAAI,UAAU,MAAM;AAClB,YAAMC,IAAOC,EAAuB,OAAO,0BAA0B,GAAG,CAAC;AACzE,UAAID,MAAS,KAAM;AAEnB,YAAME,IAAOD,EAAuB,OAAO,UAAU,GAAG,CAAC;AACzD,UAAIC,MAAS,KAAM;AAEnB,YAAMC,IAAKC,EAAmBJ,GAAME,CAAI;AACxC,MAAAX,EAAeC,GAAQ;AAAA,EAAKW,CAAE;AAAA,CAAI;AAAA,IACpC,GAEAL,EAAI,YAAYC,CAAG;AAAA,EACrB;AACF;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type MarzipanLike = {
|
|
2
|
+
options: {
|
|
3
|
+
hooks?: {
|
|
4
|
+
afterPreviewRender?: (root: HTMLElement, editor: any) => void;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export declare function tinyHighlightPlugin(): (editor: MarzipanLike) => void;
|
|
9
|
+
export declare const tinyHighlightStyles = "\n.marzipan-highlight { line-height: 1.5; overflow: auto; border-radius: 8px; }\n.tok.kw { color: var(--mz-k, #c678dd); font-weight: 600; }\n.tok.type { color: var(--mz-t, #56b6c2); }\n.tok.prop { color: var(--mz-p, #e5c07b); }\n.tok.num { color: var(--mz-n, #d19a66); }\n.tok.str { color: var(--mz-s, #98c379); }\n.tok.com { color: var(--mz-c, #7f848e); font-style: italic; }\n.tok.tag { color: var(--mz-tag, #e06c75); }\n.tok.attr { color: var(--mz-attr, #61afef); }\n.tok.var { color: var(--mz-var, #61afef); }\n.tok.code { color: var(--mz-code, #e5c07b); }\n.tok.strong { font-weight: 700; }\n.tok.em { font-style: italic; }\n";
|
|
10
|
+
//# sourceMappingURL=tinyHighlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinyHighlight.d.ts","sourceRoot":"","sources":["../../src/plugins/tinyHighlight.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAA;SAAE,CAAA;KAAE,CAAC;CACxF,CAAC;AA6FF,wBAAgB,mBAAmB,KACzB,QAAQ,YAAY,UAqB7B;AAGD,eAAO,MAAM,mBAAmB,2nBAc/B,CAAC"}
|