mardora 1.2.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.
Files changed (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -0
  3. package/dist/chunk-3OCUX4OO.js +7690 -0
  4. package/dist/chunk-3OCUX4OO.js.map +1 -0
  5. package/dist/chunk-3ZOCCFDL.cjs +74 -0
  6. package/dist/chunk-3ZOCCFDL.cjs.map +1 -0
  7. package/dist/chunk-7JOEPNEV.cjs +7740 -0
  8. package/dist/chunk-7JOEPNEV.cjs.map +1 -0
  9. package/dist/chunk-BIKZQZ6W.js +33 -0
  10. package/dist/chunk-BIKZQZ6W.js.map +1 -0
  11. package/dist/chunk-EQJESPP2.js +234 -0
  12. package/dist/chunk-EQJESPP2.js.map +1 -0
  13. package/dist/chunk-G4SE26YY.js +70 -0
  14. package/dist/chunk-G4SE26YY.js.map +1 -0
  15. package/dist/chunk-KNDWF2DP.cjs +35 -0
  16. package/dist/chunk-KNDWF2DP.cjs.map +1 -0
  17. package/dist/chunk-MLBEBFHB.cjs +2971 -0
  18. package/dist/chunk-MLBEBFHB.cjs.map +1 -0
  19. package/dist/chunk-P7JFCYU3.js +905 -0
  20. package/dist/chunk-P7JFCYU3.js.map +1 -0
  21. package/dist/chunk-SWFUKJDO.cjs +243 -0
  22. package/dist/chunk-SWFUKJDO.cjs.map +1 -0
  23. package/dist/chunk-WFVCG4LD.cjs +926 -0
  24. package/dist/chunk-WFVCG4LD.cjs.map +1 -0
  25. package/dist/chunk-XL6WFGJT.js +2901 -0
  26. package/dist/chunk-XL6WFGJT.js.map +1 -0
  27. package/dist/editor/index.cjs +277 -0
  28. package/dist/editor/index.cjs.map +1 -0
  29. package/dist/editor/index.d.cts +186 -0
  30. package/dist/editor/index.d.ts +186 -0
  31. package/dist/editor/index.js +4 -0
  32. package/dist/editor/index.js.map +1 -0
  33. package/dist/index.cjs +405 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.cts +13 -0
  36. package/dist/index.d.ts +13 -0
  37. package/dist/index.js +8 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/lib/index.cjs +12 -0
  40. package/dist/lib/index.cjs.map +1 -0
  41. package/dist/lib/index.d.cts +16 -0
  42. package/dist/lib/index.d.ts +16 -0
  43. package/dist/lib/index.js +3 -0
  44. package/dist/lib/index.js.map +1 -0
  45. package/dist/mardora-DCwjomil.d.cts +640 -0
  46. package/dist/mardora-DCwjomil.d.ts +640 -0
  47. package/dist/plugins/index.cjs +104 -0
  48. package/dist/plugins/index.cjs.map +1 -0
  49. package/dist/plugins/index.d.cts +740 -0
  50. package/dist/plugins/index.d.ts +740 -0
  51. package/dist/plugins/index.js +7 -0
  52. package/dist/plugins/index.js.map +1 -0
  53. package/dist/preview/index.cjs +38 -0
  54. package/dist/preview/index.cjs.map +1 -0
  55. package/dist/preview/index.d.cts +101 -0
  56. package/dist/preview/index.d.ts +101 -0
  57. package/dist/preview/index.js +5 -0
  58. package/dist/preview/index.js.map +1 -0
  59. package/dist/types-NBsaxl4d.d.cts +71 -0
  60. package/dist/types-Pw2SWWAR.d.ts +71 -0
  61. package/package.json +92 -0
  62. package/src/editor/attachments/extension.ts +181 -0
  63. package/src/editor/attachments/format.ts +63 -0
  64. package/src/editor/attachments/index.ts +3 -0
  65. package/src/editor/attachments/types.ts +37 -0
  66. package/src/editor/heading-fold/config.ts +25 -0
  67. package/src/editor/heading-fold/extension.ts +268 -0
  68. package/src/editor/heading-fold/extract.ts +88 -0
  69. package/src/editor/heading-fold/index.ts +5 -0
  70. package/src/editor/heading-fold/theme.ts +85 -0
  71. package/src/editor/heading-fold/types.ts +24 -0
  72. package/src/editor/i18n.ts +13 -0
  73. package/src/editor/icons/index.ts +367 -0
  74. package/src/editor/index.ts +16 -0
  75. package/src/editor/mardora.ts +257 -0
  76. package/src/editor/media-lightbox-theme.ts +146 -0
  77. package/src/editor/media-lightbox.ts +125 -0
  78. package/src/editor/plugin.ts +294 -0
  79. package/src/editor/selection-toolbar/activation.ts +123 -0
  80. package/src/editor/selection-toolbar/commands.ts +279 -0
  81. package/src/editor/selection-toolbar/extension.ts +564 -0
  82. package/src/editor/selection-toolbar/i18n.ts +164 -0
  83. package/src/editor/selection-toolbar/index.ts +7 -0
  84. package/src/editor/selection-toolbar/menu.ts +252 -0
  85. package/src/editor/selection-toolbar/position.ts +43 -0
  86. package/src/editor/selection-toolbar/theme.ts +195 -0
  87. package/src/editor/selection-toolbar/types.ts +155 -0
  88. package/src/editor/slash/default-commands.ts +190 -0
  89. package/src/editor/slash/extension.ts +319 -0
  90. package/src/editor/slash/index.ts +7 -0
  91. package/src/editor/slash/insertions.ts +26 -0
  92. package/src/editor/slash/menu.ts +123 -0
  93. package/src/editor/slash/position.ts +61 -0
  94. package/src/editor/slash/query.ts +33 -0
  95. package/src/editor/slash/theme.ts +113 -0
  96. package/src/editor/slash/types.ts +40 -0
  97. package/src/editor/table-of-contents/extension.ts +202 -0
  98. package/src/editor/table-of-contents/extract.ts +53 -0
  99. package/src/editor/table-of-contents/index.ts +7 -0
  100. package/src/editor/table-of-contents/panel.ts +83 -0
  101. package/src/editor/table-of-contents/slug.ts +50 -0
  102. package/src/editor/table-of-contents/storage.ts +35 -0
  103. package/src/editor/table-of-contents/theme.ts +153 -0
  104. package/src/editor/table-of-contents/types.ts +44 -0
  105. package/src/editor/theme.ts +72 -0
  106. package/src/editor/utils.ts +176 -0
  107. package/src/editor/view-plugin.ts +189 -0
  108. package/src/index.ts +5 -0
  109. package/src/lib/index.ts +2 -0
  110. package/src/lib/input-handler.ts +47 -0
  111. package/src/plugins/code-plugin.theme.ts +545 -0
  112. package/src/plugins/code-plugin.ts +1892 -0
  113. package/src/plugins/emoji-plugin.ts +140 -0
  114. package/src/plugins/heading-plugin.ts +194 -0
  115. package/src/plugins/hr-plugin.ts +102 -0
  116. package/src/plugins/html-plugin.ts +353 -0
  117. package/src/plugins/image-plugin.ts +806 -0
  118. package/src/plugins/index.ts +71 -0
  119. package/src/plugins/inline-plugin.ts +311 -0
  120. package/src/plugins/link-plugin.ts +509 -0
  121. package/src/plugins/list-plugin.ts +492 -0
  122. package/src/plugins/math-plugin.ts +526 -0
  123. package/src/plugins/mermaid-plugin.ts +513 -0
  124. package/src/plugins/paragraph-plugin.ts +38 -0
  125. package/src/plugins/quote-plugin.ts +733 -0
  126. package/src/plugins/table-controls-theme.ts +126 -0
  127. package/src/plugins/table-controls.ts +423 -0
  128. package/src/plugins/table-model.ts +661 -0
  129. package/src/plugins/table-plugin.ts +2111 -0
  130. package/src/preview/context.ts +45 -0
  131. package/src/preview/css-generator.ts +64 -0
  132. package/src/preview/default-renderers.ts +29 -0
  133. package/src/preview/index.ts +29 -0
  134. package/src/preview/preview.ts +41 -0
  135. package/src/preview/renderer.ts +184 -0
  136. package/src/preview/syntax-theme.ts +112 -0
  137. package/src/preview/toc.ts +23 -0
  138. package/src/preview/types.ts +89 -0
@@ -0,0 +1,905 @@
1
+ import { ensureSyntaxTree, syntaxTree } from '@codemirror/language';
2
+ import { EditorView, ViewPlugin } from '@codemirror/view';
3
+ import { Prec, EditorSelection } from '@codemirror/state';
4
+
5
+ // src/editor/utils.ts
6
+ function deepMerge(a, b) {
7
+ const result = { ...a };
8
+ if (!b) {
9
+ return result;
10
+ }
11
+ for (const key in b) {
12
+ if (b[key] && typeof b[key] === "object" && !Array.isArray(b[key]) && typeof a[key] === "object") {
13
+ result[key] = deepMerge(a[key], b[key]);
14
+ } else {
15
+ result[key] = b[key];
16
+ }
17
+ }
18
+ return result;
19
+ }
20
+ var ThemeEnum = /* @__PURE__ */ ((ThemeEnum2) => {
21
+ ThemeEnum2["DARK"] = "dark";
22
+ ThemeEnum2["LIGHT"] = "light";
23
+ ThemeEnum2["AUTO"] = "auto";
24
+ return ThemeEnum2;
25
+ })(ThemeEnum || {});
26
+ function createTheme({
27
+ default: defaultTheme,
28
+ dark: darkTheme,
29
+ light: lightTheme
30
+ }) {
31
+ return (theme) => {
32
+ defaultTheme = flattenThemeStyles(defaultTheme);
33
+ darkTheme = flattenThemeStyles(darkTheme || {});
34
+ lightTheme = flattenThemeStyles(lightTheme || {});
35
+ let style = defaultTheme;
36
+ if (theme === "dark" /* DARK */) {
37
+ style = deepMerge(style, darkTheme);
38
+ }
39
+ if (theme === "light" /* LIGHT */) {
40
+ style = deepMerge(style, lightTheme);
41
+ }
42
+ return style;
43
+ };
44
+ }
45
+ function flattenThemeStyles(themeStyles, parentSelector) {
46
+ const flattened = {};
47
+ for (const [selectors, styles] of Object.entries(themeStyles)) {
48
+ for (const selector of selectors.split(",")) {
49
+ if (typeof styles === "object" && !Array.isArray(styles)) {
50
+ const fullSelector = fixSelector(parentSelector ? `${parentSelector} ${selector}` : selector);
51
+ const nestedStyles = flattenThemeStyles(styles, fullSelector);
52
+ Object.assign(flattened, nestedStyles);
53
+ } else {
54
+ if (parentSelector) {
55
+ flattened[parentSelector] = { ...flattened[parentSelector], [selector]: styles };
56
+ } else {
57
+ flattened[selector] = styles;
58
+ }
59
+ }
60
+ }
61
+ }
62
+ return flattened;
63
+ }
64
+ function fixSelector(selector) {
65
+ return selector.replace(/\s&/g, "");
66
+ }
67
+ function cursorInRange(view, from, to) {
68
+ const selection = view.state.selection.main;
69
+ return selection.from <= to && selection.to >= from;
70
+ }
71
+ function selectionOverlapsRange(view, from, to) {
72
+ for (const range of view.state.selection.ranges) {
73
+ if (range.from <= to && range.to >= from) {
74
+ return true;
75
+ }
76
+ }
77
+ return false;
78
+ }
79
+ function toggleMarkdownStyle(marker) {
80
+ return (view) => {
81
+ const { state } = view;
82
+ const { from, to, empty } = state.selection.main;
83
+ const selectedText = state.sliceDoc(from, to);
84
+ const markerLen = marker.length;
85
+ const beforeFrom = Math.max(0, from - markerLen);
86
+ const afterTo = Math.min(state.doc.length, to + markerLen);
87
+ const textBefore = state.sliceDoc(beforeFrom, from);
88
+ const textAfter = state.sliceDoc(to, afterTo);
89
+ const isWrapped = textBefore === marker && textAfter === marker;
90
+ if (isWrapped) {
91
+ view.dispatch({
92
+ changes: [
93
+ { from: beforeFrom, to: from, insert: "" },
94
+ { from: to, to: afterTo, insert: "" }
95
+ ],
96
+ selection: { anchor: beforeFrom, head: beforeFrom + selectedText.length }
97
+ });
98
+ } else if (empty) {
99
+ view.dispatch({
100
+ changes: { from, to, insert: marker + marker },
101
+ selection: { anchor: from + markerLen }
102
+ });
103
+ } else {
104
+ view.dispatch({
105
+ changes: { from, to, insert: marker + selectedText + marker },
106
+ selection: { anchor: from + markerLen, head: to + markerLen }
107
+ });
108
+ }
109
+ return true;
110
+ };
111
+ }
112
+
113
+ // src/editor/icons/index.ts
114
+ var svgNamespace = "http://www.w3.org/2000/svg";
115
+ var iconDefinitions = {
116
+ "arrow-down": [
117
+ { name: "path", attrs: { d: "M12 5v14" } },
118
+ { name: "path", attrs: { d: "m19 12-7 7-7-7" } }
119
+ ],
120
+ "arrow-down-to-line": [
121
+ { name: "path", attrs: { d: "M19 21H5" } },
122
+ { name: "path", attrs: { d: "M12 3v14" } },
123
+ { name: "path", attrs: { d: "m19 10-7 7-7-7" } }
124
+ ],
125
+ "arrow-left": [
126
+ { name: "path", attrs: { d: "M19 12H5" } },
127
+ { name: "path", attrs: { d: "m12 19-7-7 7-7" } }
128
+ ],
129
+ "arrow-left-to-line": [
130
+ { name: "path", attrs: { d: "M3 5v14" } },
131
+ { name: "path", attrs: { d: "M21 12H7" } },
132
+ { name: "path", attrs: { d: "m14 19-7-7 7-7" } }
133
+ ],
134
+ "arrow-right": [
135
+ { name: "path", attrs: { d: "M5 12h14" } },
136
+ { name: "path", attrs: { d: "m12 5 7 7-7 7" } }
137
+ ],
138
+ "arrow-right-to-line": [
139
+ { name: "path", attrs: { d: "M21 5v14" } },
140
+ { name: "path", attrs: { d: "M3 12h14" } },
141
+ { name: "path", attrs: { d: "m10 5 7 7-7 7" } }
142
+ ],
143
+ "arrow-up": [
144
+ { name: "path", attrs: { d: "M12 19V5" } },
145
+ { name: "path", attrs: { d: "m5 12 7-7 7 7" } }
146
+ ],
147
+ "arrow-up-to-line": [
148
+ { name: "path", attrs: { d: "M5 3h14" } },
149
+ { name: "path", attrs: { d: "M12 21V7" } },
150
+ { name: "path", attrs: { d: "m5 14 7-7 7 7" } }
151
+ ],
152
+ "badge-alert": [
153
+ {
154
+ name: "path",
155
+ attrs: {
156
+ d: "M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z"
157
+ }
158
+ },
159
+ { name: "line", attrs: { x1: "12", x2: "12", y1: "8", y2: "12" } },
160
+ { name: "line", attrs: { x1: "12", x2: "12.01", y1: "16", y2: "16" } }
161
+ ],
162
+ baseline: [
163
+ { name: "path", attrs: { d: "M4 20h16" } },
164
+ { name: "path", attrs: { d: "m6 16 6-12 6 12" } },
165
+ { name: "path", attrs: { d: "M8 12h8" } }
166
+ ],
167
+ bold: [
168
+ {
169
+ name: "path",
170
+ attrs: {
171
+ d: "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"
172
+ }
173
+ }
174
+ ],
175
+ code: [
176
+ { name: "path", attrs: { d: "m16 18 6-6-6-6" } },
177
+ { name: "path", attrs: { d: "m8 6-6 6 6 6" } }
178
+ ],
179
+ "code-xml": [
180
+ { name: "path", attrs: { d: "m18 16 4-4-4-4" } },
181
+ { name: "path", attrs: { d: "m6 8-4 4 4 4" } },
182
+ { name: "path", attrs: { d: "m14.5 4-5 16" } }
183
+ ],
184
+ copy: [
185
+ { name: "rect", attrs: { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" } },
186
+ { name: "path", attrs: { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" } }
187
+ ],
188
+ "external-link": [
189
+ { name: "path", attrs: { d: "M15 3h6v6" } },
190
+ { name: "path", attrs: { d: "M10 14 21 3" } },
191
+ { name: "path", attrs: { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" } }
192
+ ],
193
+ file: [
194
+ {
195
+ name: "path",
196
+ attrs: {
197
+ d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"
198
+ }
199
+ },
200
+ { name: "path", attrs: { d: "M14 2v5a1 1 0 0 0 1 1h5" } }
201
+ ],
202
+ "heading-1": [
203
+ { name: "path", attrs: { d: "M4 12h8" } },
204
+ { name: "path", attrs: { d: "M4 18V6" } },
205
+ { name: "path", attrs: { d: "M12 18V6" } },
206
+ { name: "path", attrs: { d: "m17 12 3-2v8" } }
207
+ ],
208
+ "heading-2": [
209
+ { name: "path", attrs: { d: "M4 12h8" } },
210
+ { name: "path", attrs: { d: "M4 18V6" } },
211
+ { name: "path", attrs: { d: "M12 18V6" } },
212
+ { name: "path", attrs: { d: "M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1" } }
213
+ ],
214
+ "heading-3": [
215
+ { name: "path", attrs: { d: "M4 12h8" } },
216
+ { name: "path", attrs: { d: "M4 18V6" } },
217
+ { name: "path", attrs: { d: "M12 18V6" } },
218
+ { name: "path", attrs: { d: "M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2" } },
219
+ { name: "path", attrs: { d: "M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2" } }
220
+ ],
221
+ "heading-4": [
222
+ { name: "path", attrs: { d: "M12 18V6" } },
223
+ { name: "path", attrs: { d: "M17 10v3a1 1 0 0 0 1 1h3" } },
224
+ { name: "path", attrs: { d: "M21 10v8" } },
225
+ { name: "path", attrs: { d: "M4 12h8" } },
226
+ { name: "path", attrs: { d: "M4 18V6" } }
227
+ ],
228
+ "heading-5": [
229
+ { name: "path", attrs: { d: "M4 12h8" } },
230
+ { name: "path", attrs: { d: "M4 18V6" } },
231
+ { name: "path", attrs: { d: "M12 18V6" } },
232
+ { name: "path", attrs: { d: "M17 13v-3h4" } },
233
+ { name: "path", attrs: { d: "M17 17.7c.4.2.8.3 1.3.3 1.5 0 2.7-1.1 2.7-2.5S19.8 13 18.3 13H17" } }
234
+ ],
235
+ "heading-6": [
236
+ { name: "path", attrs: { d: "M4 12h8" } },
237
+ { name: "path", attrs: { d: "M4 18V6" } },
238
+ { name: "path", attrs: { d: "M12 18V6" } },
239
+ { name: "circle", attrs: { cx: "19", cy: "16", r: "2" } },
240
+ { name: "path", attrs: { d: "M20 10c-2 2-3 3.5-3 6" } }
241
+ ],
242
+ highlighter: [
243
+ { name: "path", attrs: { d: "m9 11-6 6v3h9l3-3" } },
244
+ { name: "path", attrs: { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4" } }
245
+ ],
246
+ image: [
247
+ { name: "rect", attrs: { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" } },
248
+ { name: "circle", attrs: { cx: "9", cy: "9", r: "2" } },
249
+ { name: "path", attrs: { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" } }
250
+ ],
251
+ info: [
252
+ { name: "circle", attrs: { cx: "12", cy: "12", r: "10" } },
253
+ { name: "path", attrs: { d: "M12 16v-4" } },
254
+ { name: "path", attrs: { d: "M12 8h.01" } }
255
+ ],
256
+ italic: [
257
+ { name: "line", attrs: { x1: "19", x2: "10", y1: "4", y2: "4" } },
258
+ { name: "line", attrs: { x1: "14", x2: "5", y1: "20", y2: "20" } },
259
+ { name: "line", attrs: { x1: "15", x2: "9", y1: "4", y2: "20" } }
260
+ ],
261
+ link: [
262
+ { name: "path", attrs: { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" } },
263
+ { name: "path", attrs: { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" } }
264
+ ],
265
+ lightbulb: [
266
+ {
267
+ name: "path",
268
+ attrs: {
269
+ d: "M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"
270
+ }
271
+ },
272
+ { name: "path", attrs: { d: "M9 18h6" } },
273
+ { name: "path", attrs: { d: "M10 22h4" } }
274
+ ],
275
+ list: [
276
+ { name: "path", attrs: { d: "M3 5h.01" } },
277
+ { name: "path", attrs: { d: "M3 12h.01" } },
278
+ { name: "path", attrs: { d: "M3 19h.01" } },
279
+ { name: "path", attrs: { d: "M8 5h13" } },
280
+ { name: "path", attrs: { d: "M8 12h13" } },
281
+ { name: "path", attrs: { d: "M8 19h13" } }
282
+ ],
283
+ "list-ordered": [
284
+ { name: "path", attrs: { d: "M11 5h10" } },
285
+ { name: "path", attrs: { d: "M11 12h10" } },
286
+ { name: "path", attrs: { d: "M11 19h10" } },
287
+ { name: "path", attrs: { d: "M4 4h1v5" } },
288
+ { name: "path", attrs: { d: "M4 9h2" } },
289
+ { name: "path", attrs: { d: "M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" } }
290
+ ],
291
+ "list-todo": [
292
+ { name: "path", attrs: { d: "M13 5h8" } },
293
+ { name: "path", attrs: { d: "M13 12h8" } },
294
+ { name: "path", attrs: { d: "M13 19h8" } },
295
+ { name: "path", attrs: { d: "m3 17 2 2 4-4" } },
296
+ { name: "rect", attrs: { x: "3", y: "4", width: "6", height: "6", rx: "1" } }
297
+ ],
298
+ "maximize-2": [
299
+ { name: "path", attrs: { d: "M15 3h6v6" } },
300
+ { name: "path", attrs: { d: "m21 3-7 7" } },
301
+ { name: "path", attrs: { d: "M9 21H3v-6" } },
302
+ { name: "path", attrs: { d: "m3 21 7-7" } }
303
+ ],
304
+ minus: [{ name: "path", attrs: { d: "M5 12h14" } }],
305
+ "music-2": [
306
+ { name: "circle", attrs: { cx: "8", cy: "18", r: "4" } },
307
+ { name: "path", attrs: { d: "M12 18V2l7 4" } }
308
+ ],
309
+ "octagon-alert": [
310
+ { name: "path", attrs: { d: "M12 16h.01" } },
311
+ { name: "path", attrs: { d: "M12 8v4" } },
312
+ {
313
+ name: "path",
314
+ attrs: {
315
+ d: "M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z"
316
+ }
317
+ }
318
+ ],
319
+ play: [
320
+ {
321
+ name: "path",
322
+ attrs: { d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" }
323
+ }
324
+ ],
325
+ "rotate-ccw": [
326
+ { name: "path", attrs: { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" } },
327
+ { name: "path", attrs: { d: "M3 3v5h5" } }
328
+ ],
329
+ strikethrough: [
330
+ { name: "path", attrs: { d: "M16 4H9a3 3 0 0 0-2.83 4" } },
331
+ { name: "path", attrs: { d: "M14 12a4 4 0 0 1 0 8H6" } },
332
+ { name: "line", attrs: { x1: "4", x2: "20", y1: "12", y2: "12" } }
333
+ ],
334
+ table: [
335
+ { name: "path", attrs: { d: "M12 3v18" } },
336
+ { name: "rect", attrs: { width: "18", height: "18", x: "3", y: "3", rx: "2" } },
337
+ { name: "path", attrs: { d: "M3 9h18" } },
338
+ { name: "path", attrs: { d: "M3 15h18" } }
339
+ ],
340
+ "table-delete": [
341
+ { name: "rect", attrs: { width: "18", height: "18", x: "3", y: "3", rx: "2" } },
342
+ { name: "path", attrs: { d: "M3 9h18" } },
343
+ { name: "path", attrs: { d: "M9 3v18" } },
344
+ { name: "path", attrs: { d: "m14 14 4 4" } },
345
+ { name: "path", attrs: { d: "m18 14-4 4" } }
346
+ ],
347
+ "table-of-contents": [
348
+ { name: "path", attrs: { d: "M16 5H3" } },
349
+ { name: "path", attrs: { d: "M16 12H3" } },
350
+ { name: "path", attrs: { d: "M16 19H3" } },
351
+ { name: "path", attrs: { d: "M21 5h.01" } },
352
+ { name: "path", attrs: { d: "M21 12h.01" } },
353
+ { name: "path", attrs: { d: "M21 19h.01" } }
354
+ ],
355
+ "text-align-start": [
356
+ { name: "path", attrs: { d: "M21 5H3" } },
357
+ { name: "path", attrs: { d: "M15 12H3" } },
358
+ { name: "path", attrs: { d: "M17 19H3" } }
359
+ ],
360
+ "text-quote": [
361
+ { name: "path", attrs: { d: "M17 5H3" } },
362
+ { name: "path", attrs: { d: "M21 12H8" } },
363
+ { name: "path", attrs: { d: "M21 19H8" } },
364
+ { name: "path", attrs: { d: "M3 12v7" } }
365
+ ],
366
+ "trash-2": [
367
+ { name: "path", attrs: { d: "M10 11v6" } },
368
+ { name: "path", attrs: { d: "M14 11v6" } },
369
+ { name: "path", attrs: { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" } },
370
+ { name: "path", attrs: { d: "M3 6h18" } },
371
+ { name: "path", attrs: { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" } }
372
+ ],
373
+ "triangle-alert": [
374
+ { name: "path", attrs: { d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" } },
375
+ { name: "path", attrs: { d: "M12 9v4" } },
376
+ { name: "path", attrs: { d: "M12 17h.01" } }
377
+ ],
378
+ underline: [
379
+ { name: "path", attrs: { d: "M6 4v6a6 6 0 0 0 12 0V4" } },
380
+ { name: "line", attrs: { x1: "4", x2: "20", y1: "20", y2: "20" } }
381
+ ],
382
+ type: [
383
+ { name: "path", attrs: { d: "M12 4v16" } },
384
+ { name: "path", attrs: { d: "M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2" } },
385
+ { name: "path", attrs: { d: "M9 20h6" } }
386
+ ],
387
+ x: [
388
+ { name: "path", attrs: { d: "M18 6 6 18" } },
389
+ { name: "path", attrs: { d: "m6 6 12 12" } }
390
+ ]
391
+ };
392
+ function hasMardoraIcon(name) {
393
+ return name in iconDefinitions;
394
+ }
395
+ function createMardoraIcon(name) {
396
+ if (!hasMardoraIcon(name)) return null;
397
+ const svg = document.createElementNS(svgNamespace, "svg");
398
+ svg.setAttribute("xmlns", svgNamespace);
399
+ svg.setAttribute("width", "24");
400
+ svg.setAttribute("height", "24");
401
+ svg.setAttribute("viewBox", "0 0 24 24");
402
+ svg.setAttribute("fill", "none");
403
+ svg.setAttribute("stroke", "currentColor");
404
+ svg.setAttribute("stroke-width", "2");
405
+ svg.setAttribute("stroke-linecap", "round");
406
+ svg.setAttribute("stroke-linejoin", "round");
407
+ svg.setAttribute("aria-hidden", "true");
408
+ svg.setAttribute("focusable", "false");
409
+ for (const definition of iconDefinitions[name]) {
410
+ const element = document.createElementNS(svgNamespace, definition.name);
411
+ for (const [attr, value] of Object.entries(definition.attrs)) {
412
+ element.setAttribute(attr, value);
413
+ }
414
+ svg.appendChild(element);
415
+ }
416
+ return svg;
417
+ }
418
+
419
+ // src/editor/table-of-contents/slug.ts
420
+ var defaultMinWidth = 180;
421
+ var defaultMaxWidth = 360;
422
+ var defaultWidth = 240;
423
+ function clampTocWidth(width, config) {
424
+ return Math.min(Math.max(width, config.minWidth), config.maxWidth);
425
+ }
426
+ function resolveTocConfig(config = {}) {
427
+ const minWidth = Math.max(120, config.minWidth ?? defaultMinWidth);
428
+ const maxWidth = Math.max(minWidth, config.maxWidth ?? defaultMaxWidth);
429
+ const requestedMinLevel = config.minLevel ?? 2;
430
+ const requestedMaxLevel = config.maxLevel ?? 6;
431
+ const minLevel = requestedMinLevel <= requestedMaxLevel ? requestedMinLevel : requestedMaxLevel;
432
+ const maxLevel = requestedMaxLevel >= requestedMinLevel ? requestedMaxLevel : requestedMinLevel;
433
+ const resolved = {
434
+ enabled: config.enabled !== false,
435
+ minLevel,
436
+ maxLevel,
437
+ defaultExpanded: config.defaultExpanded !== false,
438
+ defaultWidth,
439
+ minWidth,
440
+ maxWidth
441
+ };
442
+ if (config.onTocChange) resolved.onTocChange = config.onTocChange;
443
+ if (config.storageKey) resolved.storageKey = config.storageKey;
444
+ resolved.defaultWidth = clampTocWidth(config.defaultWidth ?? defaultWidth, resolved);
445
+ return resolved;
446
+ }
447
+ function normalizeHeadingText(value) {
448
+ return value.trim().toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-").replace(/^-+|-+$/g, "");
449
+ }
450
+ function createTocSlugger() {
451
+ const seen = /* @__PURE__ */ new Map();
452
+ return (text) => {
453
+ const base = normalizeHeadingText(text) || "heading";
454
+ const count = (seen.get(base) ?? 0) + 1;
455
+ seen.set(base, count);
456
+ return count === 1 ? base : `${base}-${count}`;
457
+ };
458
+ }
459
+
460
+ // src/editor/table-of-contents/storage.ts
461
+ function defaultStorage() {
462
+ if (typeof window === "undefined") return null;
463
+ return window.localStorage;
464
+ }
465
+ function readTocPanelState(storageKey, storage = defaultStorage()) {
466
+ if (!storageKey || !storage) return null;
467
+ try {
468
+ const raw = storage.getItem(storageKey);
469
+ if (!raw) return null;
470
+ const parsed = JSON.parse(raw);
471
+ if (typeof parsed.expanded !== "boolean" || typeof parsed.width !== "number") return null;
472
+ return { expanded: parsed.expanded, width: parsed.width };
473
+ } catch {
474
+ return null;
475
+ }
476
+ }
477
+ function writeTocPanelState(storageKey, state, storage = defaultStorage()) {
478
+ if (!storageKey || !storage) return;
479
+ try {
480
+ storage.setItem(storageKey, JSON.stringify({ expanded: state.expanded, width: state.width }));
481
+ } catch {
482
+ }
483
+ }
484
+ var headingPattern = /^ATXHeading([1-6])$/;
485
+ var tocParseTimeout = 100;
486
+ function headingLevel(node) {
487
+ const match = headingPattern.exec(node.name);
488
+ if (!match) return null;
489
+ const level = Number(match[1]);
490
+ return level >= 2 && level <= 6 ? level : null;
491
+ }
492
+ function stripMarkdownHeadingText(text) {
493
+ return text.replace(/^#{1,6}\s*/, "").replace(/`([^`]+)`/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/_([^_]+)_/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").trim();
494
+ }
495
+ function extractTocItemsFromState(state, config = {}) {
496
+ const resolved = resolveTocConfig(config);
497
+ const slug = createTocSlugger();
498
+ const items = [];
499
+ const tree = ensureSyntaxTree(state, state.doc.length, tocParseTimeout) ?? syntaxTree(state);
500
+ tree.iterate({
501
+ enter: (node) => {
502
+ const level = headingLevel(node);
503
+ if (!level || level < resolved.minLevel || level > resolved.maxLevel) return;
504
+ const text = stripMarkdownHeadingText(state.sliceDoc(node.from, node.to));
505
+ if (!text) return;
506
+ items.push({
507
+ id: slug(text),
508
+ level,
509
+ text,
510
+ from: node.from,
511
+ to: node.to,
512
+ active: false
513
+ });
514
+ }
515
+ });
516
+ return items;
517
+ }
518
+
519
+ // src/editor/table-of-contents/panel.ts
520
+ function appendIcon(parent, name) {
521
+ const icon = createMardoraIcon(name);
522
+ if (icon) parent.appendChild(icon);
523
+ }
524
+ function createExpandedToggle(callbacks) {
525
+ const toggle = document.createElement("button");
526
+ toggle.type = "button";
527
+ toggle.className = "cm-mardora-toc-toggle";
528
+ toggle.setAttribute("aria-label", "Toggle table of contents");
529
+ toggle.textContent = "\u2039";
530
+ toggle.addEventListener("click", callbacks.onToggle);
531
+ return toggle;
532
+ }
533
+ function createCollapsed(callbacks) {
534
+ const button = document.createElement("button");
535
+ button.type = "button";
536
+ button.className = "cm-mardora-toc-collapsed";
537
+ button.setAttribute("aria-label", "Open table of contents");
538
+ appendIcon(button, "table-of-contents");
539
+ button.addEventListener("click", callbacks.onToggle);
540
+ return button;
541
+ }
542
+ function createItem(item, callbacks) {
543
+ const button = document.createElement("button");
544
+ button.type = "button";
545
+ button.className = item.active ? "cm-mardora-toc-item cm-mardora-toc-item-active" : "cm-mardora-toc-item";
546
+ button.dataset.mardoraTocId = item.id;
547
+ button.dataset.mardoraTocLevel = String(item.level);
548
+ button.title = item.text;
549
+ button.textContent = item.text;
550
+ button.addEventListener("click", () => callbacks.onSelect(item));
551
+ return button;
552
+ }
553
+ function createTocPanelElement(state, callbacks) {
554
+ const root = document.createElement("aside");
555
+ root.className = "cm-mardora-toc";
556
+ root.dataset.mardoraTocExpanded = String(state.expanded);
557
+ root.style.setProperty("--mardora-toc-width", `${state.width}px`);
558
+ const resize = document.createElement("div");
559
+ resize.className = "cm-mardora-toc-resize";
560
+ resize.addEventListener("mousedown", callbacks.onResizeStart);
561
+ root.appendChild(resize);
562
+ if (!state.expanded) {
563
+ root.appendChild(createCollapsed(callbacks));
564
+ return root;
565
+ }
566
+ root.appendChild(createExpandedToggle(callbacks));
567
+ const list = document.createElement("nav");
568
+ list.className = "cm-mardora-toc-list";
569
+ if (state.items.length === 0) {
570
+ const empty = document.createElement("div");
571
+ empty.className = "cm-mardora-toc-empty";
572
+ empty.textContent = "\u6682\u65E0\u76EE\u5F55";
573
+ list.appendChild(empty);
574
+ } else {
575
+ for (const item of state.items) list.appendChild(createItem(item, callbacks));
576
+ }
577
+ root.appendChild(list);
578
+ return root;
579
+ }
580
+ var tocTheme = EditorView.baseTheme({
581
+ ".cm-mardora": {
582
+ position: "relative"
583
+ },
584
+ ".cm-mardora .cm-scroller": {
585
+ boxSizing: "border-box",
586
+ paddingRight: "calc(var(--mardora-toc-layout-width, 0px) + var(--mardora-toc-scrollbar-gutter, 0px))",
587
+ scrollbarGutter: "stable"
588
+ },
589
+ ".cm-mardora .cm-scroller::-webkit-scrollbar-track": {
590
+ background: "transparent"
591
+ },
592
+ ".cm-mardora-toc": {
593
+ position: "absolute",
594
+ top: "0",
595
+ right: "var(--mardora-toc-scrollbar-gutter, 0px)",
596
+ bottom: "0",
597
+ zIndex: "8",
598
+ width: "var(--mardora-toc-width, 240px)",
599
+ minWidth: "0",
600
+ borderLeft: "1px solid var(--mardora-toc-border, #ececef)",
601
+ background: "var(--mardora-toc-bg, transparent)",
602
+ color: "var(--mardora-toc-fg, #27272a)",
603
+ userSelect: "none"
604
+ },
605
+ ".cm-mardora-toc[data-mardora-toc-expanded='false']": {
606
+ width: "42px"
607
+ },
608
+ ".cm-mardora-toc-resize": {
609
+ position: "absolute",
610
+ top: "0",
611
+ bottom: "0",
612
+ left: "-4px",
613
+ zIndex: "2",
614
+ width: "8px",
615
+ cursor: "col-resize"
616
+ },
617
+ ".cm-mardora-toc-resize::after": {
618
+ position: "absolute",
619
+ top: "50%",
620
+ left: "3px",
621
+ width: "2px",
622
+ height: "64px",
623
+ borderRadius: "999px",
624
+ background: "var(--mardora-toc-handle, #d4d4d8)",
625
+ opacity: "0",
626
+ transform: "translateY(-50%)",
627
+ transition: "opacity 120ms ease",
628
+ content: "''"
629
+ },
630
+ ".cm-mardora-toc:hover .cm-mardora-toc-resize::after, .cm-mardora-toc-resizing .cm-mardora-toc-resize::after": {
631
+ opacity: "1"
632
+ },
633
+ ".cm-mardora-toc-collapsed svg": {
634
+ width: "16px",
635
+ height: "16px"
636
+ },
637
+ ".cm-mardora-toc-toggle, .cm-mardora-toc-collapsed, .cm-mardora-toc-item": {
638
+ border: "0",
639
+ background: "transparent",
640
+ color: "inherit",
641
+ cursor: "default",
642
+ font: "inherit"
643
+ },
644
+ ".cm-mardora-toc-toggle": {
645
+ position: "absolute",
646
+ top: "8px",
647
+ right: "8px",
648
+ zIndex: "1",
649
+ width: "28px",
650
+ height: "28px",
651
+ borderRadius: "6px",
652
+ color: "var(--mardora-toc-muted, #71717a)",
653
+ opacity: "0.55",
654
+ transition: "background 120ms ease, color 120ms ease, opacity 120ms ease"
655
+ },
656
+ ".cm-mardora-toc-toggle:hover": {
657
+ color: "var(--mardora-toc-active, #18181b)",
658
+ opacity: "1"
659
+ },
660
+ ".cm-mardora-toc-toggle:hover, .cm-mardora-toc-collapsed:hover, .cm-mardora-toc-item:hover": {
661
+ background: "var(--mardora-toc-hover, #f4f4f5)"
662
+ },
663
+ ".cm-mardora-toc-collapsed": {
664
+ display: "flex",
665
+ alignItems: "center",
666
+ justifyContent: "center",
667
+ width: "100%",
668
+ height: "100%",
669
+ color: "var(--mardora-toc-muted, #71717a)"
670
+ },
671
+ ".cm-mardora-toc-list": {
672
+ overflow: "auto",
673
+ height: "100%",
674
+ padding: "12px 10px 16px 18px",
675
+ scrollbarWidth: "thin"
676
+ },
677
+ ".cm-mardora-toc-list::-webkit-scrollbar": {
678
+ width: "8px"
679
+ },
680
+ ".cm-mardora-toc-list::-webkit-scrollbar-track": {
681
+ background: "transparent"
682
+ },
683
+ ".cm-mardora-toc-list::-webkit-scrollbar-thumb": {
684
+ borderRadius: "999px",
685
+ background: "var(--mardora-toc-scrollbar, #c7c7cc)"
686
+ },
687
+ ".cm-mardora-toc-item": {
688
+ display: "block",
689
+ width: "100%",
690
+ overflow: "hidden",
691
+ minHeight: "30px",
692
+ padding: "0 8px",
693
+ borderLeft: "2px solid transparent",
694
+ borderRadius: "6px",
695
+ color: "var(--mardora-toc-muted, #71717a)",
696
+ lineHeight: "30px",
697
+ textAlign: "left",
698
+ textOverflow: "ellipsis",
699
+ whiteSpace: "nowrap",
700
+ transition: "background 120ms ease, color 120ms ease"
701
+ },
702
+ ".cm-mardora-toc-item[data-mardora-toc-level='3']": { paddingLeft: "18px" },
703
+ ".cm-mardora-toc-item[data-mardora-toc-level='4']": { paddingLeft: "28px" },
704
+ ".cm-mardora-toc-item[data-mardora-toc-level='5']": { paddingLeft: "38px" },
705
+ ".cm-mardora-toc-item[data-mardora-toc-level='6']": { paddingLeft: "48px" },
706
+ ".cm-mardora-toc-item-active": {
707
+ borderLeftColor: "var(--mardora-toc-active, #18181b)",
708
+ background: "var(--mardora-toc-hover, #f4f4f5)",
709
+ color: "var(--mardora-toc-active, #18181b)",
710
+ fontWeight: "600"
711
+ },
712
+ ".cm-mardora-toc-empty": {
713
+ padding: "12px 8px",
714
+ color: "var(--mardora-toc-muted, #71717a)",
715
+ fontSize: "13px"
716
+ },
717
+ ".cm-mardora-toc-resizing": {
718
+ userSelect: "none"
719
+ },
720
+ "&dark .cm-mardora-toc": {
721
+ "--mardora-toc-bg": "#18181b",
722
+ "--mardora-toc-fg": "#f4f4f5",
723
+ "--mardora-toc-border": "#3f3f46",
724
+ "--mardora-toc-handle": "#52525b",
725
+ "--mardora-toc-hover": "#27272a",
726
+ "--mardora-toc-muted": "#a1a1aa",
727
+ "--mardora-toc-active": "#f4f4f5",
728
+ "--mardora-toc-scrollbar": "#52525b"
729
+ }
730
+ });
731
+ function sameItems(a, b) {
732
+ return JSON.stringify(a) === JSON.stringify(b);
733
+ }
734
+ var TocViewPlugin = class {
735
+ constructor(view, rawConfig) {
736
+ this.view = view;
737
+ this.config = resolveTocConfig(rawConfig);
738
+ const stored = readTocPanelState(this.config.storageKey);
739
+ this.panelState = {
740
+ expanded: stored?.expanded ?? this.config.defaultExpanded,
741
+ width: clampTocWidth(stored?.width ?? this.config.defaultWidth, this.config)
742
+ };
743
+ this.view.scrollDOM.addEventListener("scroll", this.handleScroll, { passive: true });
744
+ this.recompute();
745
+ this.scheduleRender();
746
+ this.scheduleActiveMeasure();
747
+ }
748
+ view;
749
+ panel = null;
750
+ config;
751
+ panelState;
752
+ items = [];
753
+ renderFrame = null;
754
+ measureKey = {};
755
+ update(update) {
756
+ if (update.docChanged) {
757
+ this.recompute();
758
+ return;
759
+ }
760
+ if (update.viewportChanged || update.geometryChanged) this.scheduleActiveMeasure();
761
+ }
762
+ destroy() {
763
+ this.view.scrollDOM.removeEventListener("scroll", this.handleScroll);
764
+ if (this.renderFrame !== null) {
765
+ this.view.dom.ownerDocument.defaultView?.cancelAnimationFrame(this.renderFrame);
766
+ this.renderFrame = null;
767
+ }
768
+ this.clearLayoutWidth();
769
+ this.panel?.remove();
770
+ this.panel = null;
771
+ }
772
+ handleScroll = () => {
773
+ this.scheduleActiveMeasure();
774
+ };
775
+ recompute() {
776
+ const next = extractTocItemsFromState(this.view.state, this.config);
777
+ this.items = this.withPreservedActive(next);
778
+ this.config.onTocChange?.(this.items);
779
+ this.render();
780
+ this.scheduleActiveMeasure();
781
+ }
782
+ withPreservedActive(items) {
783
+ if (items.length === 0) return [];
784
+ const previousActive = this.items.find((item) => item.active)?.id;
785
+ const fallbackActiveId = items[0]?.id;
786
+ const activeId = previousActive && items.some((item) => item.id === previousActive) ? previousActive : fallbackActiveId;
787
+ return items.map((item) => ({ ...item, active: item.id === activeId }));
788
+ }
789
+ scheduleActiveMeasure() {
790
+ if (this.items.length === 0 || !this.view.dom.isConnected) return;
791
+ this.view.requestMeasure({
792
+ key: this.measureKey,
793
+ read: (view) => {
794
+ const viewportTop = view.scrollDOM.getBoundingClientRect().top + 24;
795
+ let activeId = this.items[0]?.id ?? null;
796
+ for (const item of this.items) {
797
+ if (typeof item.from !== "number") continue;
798
+ const coords = view.coordsAtPos(item.from);
799
+ if (coords && coords.top <= viewportTop) activeId = item.id;
800
+ }
801
+ return activeId;
802
+ },
803
+ write: (activeId) => {
804
+ if (!activeId) return;
805
+ this.updateActiveItem(activeId);
806
+ }
807
+ });
808
+ }
809
+ updateActiveItem(activeId) {
810
+ const next = this.items.map((item) => ({ ...item, active: item.id === activeId }));
811
+ if (sameItems(next, this.items)) return;
812
+ this.items = next;
813
+ this.config.onTocChange?.(this.items);
814
+ this.render();
815
+ }
816
+ scheduleRender() {
817
+ const win = this.view.dom.ownerDocument.defaultView;
818
+ if (!win) {
819
+ this.render();
820
+ return;
821
+ }
822
+ if (this.renderFrame !== null) return;
823
+ this.renderFrame = win.requestAnimationFrame(() => {
824
+ this.renderFrame = null;
825
+ this.render();
826
+ });
827
+ }
828
+ render() {
829
+ if (!this.config.enabled) {
830
+ this.clearLayoutWidth();
831
+ this.panel?.remove();
832
+ this.panel = null;
833
+ return;
834
+ }
835
+ this.syncLayoutWidth();
836
+ const nextPanel = createTocPanelElement(
837
+ { expanded: this.panelState.expanded, width: this.panelState.width, items: this.items },
838
+ {
839
+ onSelect: (item) => this.selectItem(item),
840
+ onToggle: () => this.toggle(),
841
+ onResizeStart: (event) => this.startResize(event)
842
+ }
843
+ );
844
+ if (this.panel?.isConnected) {
845
+ this.panel.replaceWith(nextPanel);
846
+ } else {
847
+ this.view.dom.appendChild(nextPanel);
848
+ }
849
+ this.panel = nextPanel;
850
+ }
851
+ selectItem(item) {
852
+ if (typeof item.from !== "number") return;
853
+ this.view.dispatch({
854
+ selection: EditorSelection.cursor(item.from),
855
+ effects: EditorView.scrollIntoView(item.from, { y: "start" })
856
+ });
857
+ this.view.focus();
858
+ this.updateActiveItem(item.id);
859
+ this.scheduleActiveMeasure();
860
+ }
861
+ persistPanelState() {
862
+ writeTocPanelState(this.config.storageKey, this.panelState);
863
+ }
864
+ toggle() {
865
+ this.panelState = { ...this.panelState, expanded: !this.panelState.expanded };
866
+ this.persistPanelState();
867
+ this.render();
868
+ }
869
+ syncLayoutWidth() {
870
+ const layoutWidth = this.panelState.expanded ? this.panelState.width : 42;
871
+ this.view.dom.style.setProperty("--mardora-toc-layout-width", `${layoutWidth}px`);
872
+ this.view.dom.style.setProperty("--mardora-toc-scrollbar-gutter", "14px");
873
+ }
874
+ clearLayoutWidth() {
875
+ this.view.dom.style.removeProperty("--mardora-toc-layout-width");
876
+ this.view.dom.style.removeProperty("--mardora-toc-scrollbar-gutter");
877
+ }
878
+ startResize(event) {
879
+ event.preventDefault();
880
+ const startX = event.clientX;
881
+ const startWidth = this.panelState.width;
882
+ const doc = this.view.dom.ownerDocument;
883
+ doc.body.classList.add("cm-mardora-toc-resizing");
884
+ const move = (moveEvent) => {
885
+ const nextWidth = clampTocWidth(startWidth - (moveEvent.clientX - startX), this.config);
886
+ this.panelState = { ...this.panelState, width: nextWidth };
887
+ this.render();
888
+ };
889
+ const up = () => {
890
+ doc.body.classList.remove("cm-mardora-toc-resizing");
891
+ doc.removeEventListener("mousemove", move);
892
+ doc.removeEventListener("mouseup", up);
893
+ this.persistPanelState();
894
+ };
895
+ doc.addEventListener("mousemove", move);
896
+ doc.addEventListener("mouseup", up);
897
+ }
898
+ };
899
+ function tableOfContents(config = {}) {
900
+ return [tocTheme, Prec.low(ViewPlugin.define((view) => new TocViewPlugin(view, config)))];
901
+ }
902
+
903
+ export { ThemeEnum, clampTocWidth, createMardoraIcon, createTheme, createTocPanelElement, createTocSlugger, cursorInRange, deepMerge, extractTocItemsFromState, fixSelector, flattenThemeStyles, hasMardoraIcon, readTocPanelState, resolveTocConfig, selectionOverlapsRange, stripMarkdownHeadingText, tableOfContents, tocTheme, toggleMarkdownStyle, writeTocPanelState };
904
+ //# sourceMappingURL=chunk-P7JFCYU3.js.map
905
+ //# sourceMappingURL=chunk-P7JFCYU3.js.map