@pixerate/editor 0.14.3 → 0.15.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 (71) hide show
  1. package/dist/agent/index.cjs +28 -220
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +1 -1
  4. package/dist/agent/index.d.ts +1 -1
  5. package/dist/agent/index.js +5 -154
  6. package/dist/agent/index.js.map +1 -1
  7. package/dist/canvas/index.cjs +113 -377
  8. package/dist/canvas/index.cjs.map +1 -1
  9. package/dist/canvas/index.d.cts +2 -2
  10. package/dist/canvas/index.d.ts +2 -2
  11. package/dist/canvas/index.js +18 -208
  12. package/dist/canvas/index.js.map +1 -1
  13. package/dist/chunk-33UVEDOS.cjs +233 -0
  14. package/dist/chunk-33UVEDOS.cjs.map +1 -0
  15. package/dist/chunk-7FWEWE6T.js +1888 -0
  16. package/dist/chunk-7FWEWE6T.js.map +1 -0
  17. package/dist/chunk-BYCOFZAA.js +514 -0
  18. package/dist/chunk-BYCOFZAA.js.map +1 -0
  19. package/dist/chunk-CYKQLDYH.cjs +1290 -0
  20. package/dist/chunk-CYKQLDYH.cjs.map +1 -0
  21. package/dist/chunk-GLSIZKOX.js +17 -0
  22. package/dist/chunk-GLSIZKOX.js.map +1 -0
  23. package/dist/chunk-GWHJVZPI.js +233 -0
  24. package/dist/chunk-GWHJVZPI.js.map +1 -0
  25. package/dist/chunk-LDES3EOS.cjs +1888 -0
  26. package/dist/chunk-LDES3EOS.cjs.map +1 -0
  27. package/dist/chunk-MPPXH7U5.cjs +336 -0
  28. package/dist/chunk-MPPXH7U5.cjs.map +1 -0
  29. package/dist/chunk-NNJRJJSC.js +1290 -0
  30. package/dist/chunk-NNJRJJSC.js.map +1 -0
  31. package/dist/chunk-O7LOPQMH.js +336 -0
  32. package/dist/chunk-O7LOPQMH.js.map +1 -0
  33. package/dist/chunk-SEDR75VH.cjs +17 -0
  34. package/dist/chunk-SEDR75VH.cjs.map +1 -0
  35. package/dist/chunk-SHWP2A43.cjs +514 -0
  36. package/dist/chunk-SHWP2A43.cjs.map +1 -0
  37. package/dist/chunk-VHZCXHS4.js +222 -0
  38. package/dist/chunk-VHZCXHS4.js.map +1 -0
  39. package/dist/chunk-WADCJ7A7.cjs +222 -0
  40. package/dist/chunk-WADCJ7A7.cjs.map +1 -0
  41. package/dist/extensions/index.cjs +25 -1920
  42. package/dist/extensions/index.cjs.map +1 -1
  43. package/dist/extensions/index.js +22 -1868
  44. package/dist/extensions/index.js.map +1 -1
  45. package/dist/grammar/index.cjs +44 -387
  46. package/dist/grammar/index.cjs.map +1 -1
  47. package/dist/grammar/index.js +23 -321
  48. package/dist/grammar/index.js.map +1 -1
  49. package/dist/history/index.cjs +6 -257
  50. package/dist/history/index.cjs.map +1 -1
  51. package/dist/history/index.js +4 -227
  52. package/dist/history/index.js.map +1 -1
  53. package/dist/image-editor/index.cjs +63 -106
  54. package/dist/image-editor/index.cjs.map +1 -1
  55. package/dist/index.cjs +324 -7232
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +0 -4
  58. package/dist/index.d.ts +0 -4
  59. package/dist/index.js +258 -7007
  60. package/dist/index.js.map +1 -1
  61. package/dist/serializers/index.cjs +28 -558
  62. package/dist/serializers/index.cjs.map +1 -1
  63. package/dist/serializers/index.js +16 -496
  64. package/dist/serializers/index.js.map +1 -1
  65. package/dist/spreadsheet/index.cjs +21 -1319
  66. package/dist/spreadsheet/index.cjs.map +1 -1
  67. package/dist/spreadsheet/index.js +14 -1274
  68. package/dist/spreadsheet/index.js.map +1 -1
  69. package/dist/{types-lGtRobRV.d.cts → types-DC8b2TsA.d.cts} +1 -1
  70. package/dist/{types-lGtRobRV.d.ts → types-DC8b2TsA.d.ts} +1 -1
  71. package/package.json +1 -1
@@ -1,1877 +1,31 @@
1
- // src/extensions/gradient-text.ts
2
- import { Mark } from "@tiptap/core";
3
- import { Plugin } from "@tiptap/pm/state";
4
- import { Decoration, DecorationSet } from "@tiptap/pm/view";
5
-
6
- // src/grammar/tokens.ts
7
- var TEMPLATE_REGEX = /{{\s*([^}]+?)\s*}}/g;
8
- var VARIABLE_REGEX = /(?<!\{)\{([^{}]+)\}(?!\})/g;
9
- var INSTRUCTION_REGEX = /__(.+?)__/g;
10
-
11
- // src/extensions/gradient-text.ts
12
- var createGradientDecorations = (doc, options) => {
13
- const decorations = [];
14
- const speed = options.speed ?? 1;
15
- const jsonVarSet = options.jsonVariables ? options.jsonVariables instanceof Set ? options.jsonVariables : new Set(options.jsonVariables) : null;
16
- doc.descendants((node, pos) => {
17
- if (node.isText) {
18
- const text = node.text || "";
19
- let match;
20
- const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);
21
- while ((match = tmplRegex.exec(text)) !== null) {
22
- const templateName = match[1].trim();
23
- const colors = options.templateColorMap?.get(templateName);
24
- if (colors) {
25
- const start = pos + match.index;
26
- const end = start + match[0].length;
27
- const { from: colorFrom, to: colorTo } = colors;
28
- const style = `--bg-size: ${speed * 300}%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important; background-image: linear-gradient(to right, ${colorFrom}, ${colorTo}, ${colorFrom}); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;`;
29
- decorations.push(
30
- Decoration.inline(start, end, {
31
- class: "inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent border border-(--color-to)/20 px-1 py-0.5 rounded-sm cursor-pointer",
32
- style,
33
- "data-template": templateName
34
- })
35
- );
36
- }
37
- }
38
- const instRegex = new RegExp(
39
- INSTRUCTION_REGEX.source,
40
- INSTRUCTION_REGEX.flags
41
- );
42
- while ((match = instRegex.exec(text)) !== null) {
43
- const content = match[1].trim();
44
- const colors = options.templateColorMap?.get(content) || {
45
- from: "#ffaa40",
46
- to: "#9c40ff"
47
- };
48
- const start = pos + match.index;
49
- const end = start + match[0].length;
50
- const { from: colorFrom, to: colorTo } = colors;
51
- const style = `--bg-size: ${speed * 300}%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important; background-image: linear-gradient(to right, #fb7185, #8b5cf6, #fb7185); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;`;
52
- decorations.push(
53
- Decoration.inline(start, end, {
54
- class: "italic animate-gradient bg-gradient-to-r from-rose-400 from-50% to-violet-500 to-50% bg-size-[200%_100%] bg-clip-text text-transparent inline-flex items-baseline gap-0.5",
55
- style
56
- })
57
- );
58
- }
59
- const varRegex = new RegExp(
60
- VARIABLE_REGEX.source,
61
- VARIABLE_REGEX.flags
62
- );
63
- while ((match = varRegex.exec(text)) !== null) {
64
- const variableName = match[1].trim();
65
- const start = pos + match.index;
66
- const end = start + match[0].length;
67
- const isJsonVar = jsonVarSet?.has(variableName);
68
- decorations.push(
69
- Decoration.inline(start, end, {
70
- class: isJsonVar ? "bg-violet-400/40 border-b-4 border-rose-300 dark:border-rose-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs" : "bg-rose-400/40 border-b-4 border-violet-300 dark:border-violet-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs",
71
- "data-variable": variableName
72
- })
73
- );
74
- }
75
- }
76
- });
77
- return decorations;
78
- };
79
- var GradientText = Mark.create({
80
- name: "gradientText",
81
- addOptions() {
82
- return {
83
- templateColorMap: /* @__PURE__ */ new Map(),
84
- speed: 1,
85
- jsonVariables: void 0,
86
- onTemplateClick: void 0
87
- };
88
- },
89
- renderHTML({ HTMLAttributes }) {
90
- const defaultColors = {
91
- from: "#ffaa40",
92
- to: "#9c40ff"
93
- };
94
- const speed = this.options.speed ?? 1;
95
- const style = `--bg-size: ${speed * 300}%; --color-from: ${defaultColors.from}; --color-to: ${defaultColors.to}; caret-color: #111 !important;`;
96
- return [
97
- "span",
98
- {
99
- class: "inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent",
100
- style,
101
- ...HTMLAttributes
102
- },
103
- 0
104
- ];
105
- },
106
- parseHTML() {
107
- return [
108
- {
109
- tag: "span",
110
- getAttrs: (node) => node.classList.contains("animate-gradient") && node.classList.contains("bg-clip-text") && null
111
- }
112
- ];
113
- },
114
- addProseMirrorPlugins() {
115
- const markOptions = this.options;
116
- return [
117
- new Plugin({
118
- state: {
119
- init(_, { doc }) {
120
- return DecorationSet.create(
121
- doc,
122
- createGradientDecorations(doc, markOptions)
123
- );
124
- },
125
- apply(tr, value) {
126
- const newDoc = tr.doc;
127
- if (tr.docChanged) {
128
- return DecorationSet.create(
129
- newDoc,
130
- createGradientDecorations(newDoc, markOptions)
131
- );
132
- }
133
- return value.map(tr.mapping, newDoc);
134
- }
135
- },
136
- props: {
137
- decorations(state) {
138
- return this.getState(state);
139
- },
140
- handleClickOn(view, pos, _node, _nodePos, event) {
141
- const decorationSet = this.getState(
142
- view.state
143
- );
144
- const decorations = decorationSet.find(pos, pos + 1);
145
- for (const decoration of decorations) {
146
- const decorationWithAttrs = decoration;
147
- const templateName = decorationWithAttrs.type?.attrs?.["data-template"];
148
- if (templateName) {
149
- if (markOptions.onTemplateClick) {
150
- markOptions.onTemplateClick(templateName, event);
151
- }
152
- if (typeof window !== "undefined") {
153
- window.dispatchEvent(
154
- new CustomEvent("show-gradient-popover", {
155
- detail: {
156
- templateName,
157
- target: event.target
158
- }
159
- })
160
- );
161
- }
162
- return true;
163
- }
164
- }
165
- return false;
166
- }
167
- }
168
- })
169
- ];
170
- }
171
- });
172
-
173
- // src/extensions/slash-commands.ts
174
- import { Extension } from "@tiptap/core";
175
- import { Plugin as Plugin2 } from "@tiptap/pm/state";
176
- var SlashCommands = Extension.create({
177
- name: "slashCommands",
178
- addOptions() {
179
- return {
180
- trigger: "/",
181
- onMatch: void 0,
182
- onClear: void 0,
183
- containerId: void 0
184
- };
185
- },
186
- addProseMirrorPlugins() {
187
- const opts = this.options;
188
- return [
189
- new Plugin2({
190
- view() {
191
- return {
192
- update(view) {
193
- const { state } = view;
194
- const { selection } = state;
195
- const { $from } = selection;
196
- if (!$from.parent.isTextblock) {
197
- opts.onClear?.();
198
- return;
199
- }
200
- const textBeforeCursor = $from.parent.textBetween(
201
- 0,
202
- $from.parentOffset
203
- );
204
- const slashMatch = textBeforeCursor.match(
205
- /(?:^|\s)\/([a-zA-Z0-9_-]*)$/
206
- );
207
- if (slashMatch) {
208
- const matchIndex = slashMatch.index ?? 0;
209
- const offsetInParent = matchIndex + (slashMatch[0].startsWith(" ") ? 1 : 0);
210
- const matchFrom = $from.start() + offsetInParent;
211
- const matchTo = $from.pos;
212
- const coords = view.coordsAtPos($from.pos);
213
- let relativeCoords = {
214
- top: coords.top,
215
- left: coords.left,
216
- bottom: coords.bottom,
217
- right: coords.right
218
- };
219
- if (opts.containerId && typeof document !== "undefined") {
220
- const container = document.getElementById(opts.containerId);
221
- if (container) {
222
- const rect = container.getBoundingClientRect();
223
- relativeCoords = {
224
- top: coords.bottom - rect.top + 5,
225
- left: coords.left - rect.left,
226
- bottom: coords.bottom - rect.top,
227
- right: coords.right - rect.left
228
- };
229
- }
230
- }
231
- opts.onMatch?.({
232
- match: slashMatch,
233
- query: slashMatch[1] || "",
234
- from: matchFrom,
235
- to: matchTo,
236
- coords: relativeCoords
237
- });
238
- } else {
239
- opts.onClear?.();
240
- }
241
- }
242
- };
243
- }
244
- })
245
- ];
246
- }
247
- });
248
-
249
- // src/extensions/template-suggestions.ts
250
- import { Extension as Extension2 } from "@tiptap/core";
251
- import Suggestion from "@tiptap/suggestion";
252
- var TemplateSuggestions = Extension2.create({
253
- name: "templateSuggestions",
254
- addOptions() {
255
- return {
256
- templates: [],
257
- char: "{{",
258
- onSuggestion: void 0
259
- };
260
- },
261
- addProseMirrorPlugins() {
262
- const opts = this.options;
263
- const suggestionConfig = {
264
- char: opts.char || "{{",
265
- items: ({ query }) => {
266
- const lower = query.toLowerCase();
267
- return (opts.templates || []).filter(
268
- (t) => t.name.toLowerCase().includes(lower)
269
- );
270
- },
271
- command: ({ editor, range, props }) => {
272
- editor.chain().focus().deleteRange(range).insertContent(`{{${props.name}}}`).run();
273
- },
274
- render: () => {
275
- return {
276
- onStart: (props) => {
277
- opts.onSuggestion?.(props);
278
- },
279
- onUpdate: (props) => {
280
- opts.onSuggestion?.(props);
281
- },
282
- onExit: () => {
283
- opts.onSuggestion?.({
284
- query: "",
285
- range: { from: 0, to: 0 },
286
- items: [],
287
- command: () => {
288
- }
289
- });
290
- }
291
- };
292
- }
293
- };
294
- const SuggestionFn = typeof Suggestion === "function" ? Suggestion : Suggestion?.default || Suggestion?.Suggestion;
295
- return [
296
- SuggestionFn({
297
- editor: this.editor,
298
- ...suggestionConfig
299
- })
300
- ];
301
- }
302
- });
303
-
304
- // src/extensions/loading-node.ts
305
- import { Node as Node2, mergeAttributes } from "@tiptap/core";
306
- var LoadingNode = Node2.create({
307
- name: "loadingNode",
308
- group: "inline",
309
- inline: true,
310
- selectable: true,
311
- atom: true,
312
- addAttributes() {
313
- return {
314
- id: {
315
- default: null,
316
- parseHTML: (element) => element.getAttribute("data-id"),
317
- renderHTML: (attributes) => {
318
- if (!attributes.id) return {};
319
- return { "data-id": attributes.id };
320
- }
321
- }
322
- };
323
- },
324
- parseHTML() {
325
- return [
326
- {
327
- tag: 'span[data-type="loading"]'
328
- }
329
- ];
330
- },
331
- renderHTML({ HTMLAttributes }) {
332
- return [
333
- "span",
334
- mergeAttributes(HTMLAttributes, {
335
- "data-type": "loading",
336
- class: "inline-flex items-center px-1.5 py-0.5 text-xs text-muted-foreground animate-pulse"
337
- }),
338
- "\u23F3"
339
- ];
340
- }
341
- });
342
-
343
- // src/extensions/SmilieReplacer.ts
344
- import { Extension as Extension3, textInputRule } from "@tiptap/core";
345
- var SmilieReplacer = Extension3.create({
346
- name: "smilieReplacer",
347
- addInputRules() {
348
- return [
349
- textInputRule({ find: /-___- $/, replace: "\u{1F611} " }),
350
- textInputRule({ find: /:'-\) $/, replace: "\u{1F602} " }),
351
- textInputRule({ find: /':-\) $/, replace: "\u{1F605} " }),
352
- textInputRule({ find: /':-D $/, replace: "\u{1F605} " }),
353
- textInputRule({ find: />:-\) $/, replace: "\u{1F606} " }),
354
- textInputRule({ find: /-__- $/, replace: "\u{1F611} " }),
355
- textInputRule({ find: /':-\( $/, replace: "\u{1F613} " }),
356
- textInputRule({ find: /:'-\( $/, replace: "\u{1F622} " }),
357
- textInputRule({ find: />:-\( $/, replace: "\u{1F620} " }),
358
- textInputRule({ find: /O:-\) $/, replace: "\u{1F607} " }),
359
- textInputRule({ find: /:'\) $/, replace: "\u{1F602} " }),
360
- textInputRule({ find: /:-D $/, replace: "\u{1F603} " }),
361
- textInputRule({ find: /':\) $/, replace: "\u{1F605} " }),
362
- textInputRule({ find: /;-\) $/, replace: "\u{1F609} " }),
363
- textInputRule({ find: /B-\) $/, replace: "\u{1F60E} " }),
364
- textInputRule({ find: /:-\* $/, replace: "\u{1F618} " }),
365
- textInputRule({ find: /:-\) $/, replace: "\u{1F642} " }),
366
- textInputRule({ find: /-_- $/, replace: "\u{1F611} " }),
367
- textInputRule({ find: /:-O $/, replace: "\u{1F62E} " }),
368
- textInputRule({ find: /:-P $/, replace: "\u{1F61B} " }),
369
- textInputRule({ find: /:-p $/, replace: "\u{1F61B} " }),
370
- textInputRule({ find: /:-\/ $/, replace: "\u{1F615} " }),
371
- textInputRule({ find: /:-\( $/, replace: "\u{1F61E} " }),
372
- textInputRule({ find: /:'\( $/, replace: "\u{1F622} " }),
373
- textInputRule({ find: /:D $/, replace: "\u{1F603} " }),
374
- textInputRule({ find: /=D $/, replace: "\u{1F603} " }),
375
- textInputRule({ find: /;\) $/, replace: "\u{1F609} " }),
376
- textInputRule({ find: /B\) $/, replace: "\u{1F60E} " }),
377
- textInputRule({ find: /:\) $/, replace: "\u{1F642} " }),
378
- textInputRule({ find: /=\) $/, replace: "\u{1F642} " }),
379
- textInputRule({ find: /:O $/, replace: "\u{1F62E} " }),
380
- textInputRule({ find: /:P $/, replace: "\u{1F61B} " }),
381
- textInputRule({ find: /:p $/, replace: "\u{1F61B} " }),
382
- textInputRule({ find: /:\/ $/, replace: "\u{1F615} " }),
383
- textInputRule({ find: /:\( $/, replace: "\u{1F61E} " }),
384
- textInputRule({ find: /<3 $/, replace: "\u2764\uFE0F " }),
385
- textInputRule({ find: /<\/3 $/, replace: "\u{1F494} " }),
386
- textInputRule({ find: /\/shrug $/, replace: "\xAF\\_(\u30C4)_/\xAF " })
387
- ];
388
- }
389
- });
390
-
391
- // src/extensions/ColorHighlighter.ts
392
- import { Extension as Extension4 } from "@tiptap/core";
393
- import { Plugin as Plugin3 } from "@tiptap/pm/state";
394
- import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "@tiptap/pm/view";
395
- function findHexColors(doc) {
396
- const hexColorRegex = /(#[0-9a-fA-F]{3,8})\b/g;
397
- const decorations = [];
398
- doc.descendants((node, position) => {
399
- if (!node.text) return;
400
- let match;
401
- while ((match = hexColorRegex.exec(node.text)) !== null) {
402
- const color = match[0];
403
- const from = position + match.index;
404
- const to = from + color.length;
405
- decorations.push(
406
- Decoration2.inline(from, to, {
407
- class: "color-highlight px-1 py-0.5 rounded text-xs font-mono border",
408
- style: `--color: ${color}; background-color: ${color}20; border-color: ${color}; color: ${color};`
409
- })
410
- );
411
- }
412
- });
413
- return DecorationSet2.create(doc, decorations);
414
- }
415
- var ColorHighlighter = Extension4.create({
416
- name: "colorHighlighter",
417
- addProseMirrorPlugins() {
418
- return [
419
- new Plugin3({
420
- state: {
421
- init(_, { doc }) {
422
- return findHexColors(doc);
423
- },
424
- apply(transaction, oldState) {
425
- return transaction.docChanged ? findHexColors(transaction.doc) : oldState;
426
- }
427
- },
428
- props: {
429
- decorations(state) {
430
- return this.getState(state);
431
- }
432
- }
433
- })
434
- ];
435
- }
436
- });
437
-
438
- // src/extensions/FontSize.ts
439
- import { Extension as Extension5 } from "@tiptap/core";
440
- import "@tiptap/extension-text-style";
441
- var FontSize = Extension5.create({
442
- name: "fontSize",
443
- addOptions() {
444
- return {
445
- types: ["textStyle"]
446
- };
447
- },
448
- addGlobalAttributes() {
449
- return [
450
- {
451
- types: this.options.types,
452
- attributes: {
453
- fontSize: {
454
- default: null,
455
- parseHTML: (element) => element.style.fontSize.replace(/['"]+/g, ""),
456
- renderHTML: (attributes) => {
457
- if (!attributes.fontSize) {
458
- return {};
459
- }
460
- return {
461
- style: `font-size: ${attributes.fontSize}`
462
- };
463
- }
464
- }
465
- }
466
- }
467
- ];
468
- },
469
- addCommands() {
470
- return {
471
- setFontSize: (fontSize) => ({ chain }) => chain().setMark("textStyle", { fontSize }).run(),
472
- unsetFontSize: () => ({ chain }) => chain().setMark("textStyle", { fontSize: null }).removeEmptyTextStyle().run()
473
- };
474
- }
475
- });
476
-
477
- // src/extensions/rich-text-preset.ts
478
- import {
479
- wrappingInputRule,
480
- markInputRule
481
- } from "@tiptap/core";
482
- import * as _StarterKit from "@tiptap/starter-kit";
483
- import * as _Color from "@tiptap/extension-color";
484
- import * as _Highlight from "@tiptap/extension-highlight";
485
- import * as _Link from "@tiptap/extension-link";
486
- import * as _TaskList from "@tiptap/extension-task-list";
487
- import * as _TaskItem from "@tiptap/extension-task-item";
488
- import * as _TextAlign from "@tiptap/extension-text-align";
489
- import * as _TextStyle from "@tiptap/extension-text-style";
490
- import * as _Typography from "@tiptap/extension-typography";
491
- import * as _Underline from "@tiptap/extension-underline";
492
- import * as _Placeholder from "@tiptap/extension-placeholder";
493
- import * as _CharacterCount from "@tiptap/extension-character-count";
494
-
495
- // src/extensions/mention.ts
496
1
  import {
497
- Mention as TipTapMention
498
- } from "@tiptap/extension-mention";
499
- var BaseMention = TipTapMention || TipTapMention?.default?.default || TipTapMention?.default || TipTapMention;
500
- var Mention = BaseMention.extend({
501
- addAttributes() {
502
- return {
503
- ...this.parent?.(),
504
- type: {
505
- default: null,
506
- parseHTML: (element) => element.getAttribute("data-type-name") || element.getAttribute("data-entity-type"),
507
- renderHTML: (attributes) => {
508
- if (!attributes.type) return {};
509
- return { "data-type-name": attributes.type };
510
- }
511
- },
512
- avatarUrl: {
513
- default: null,
514
- parseHTML: (element) => element.getAttribute("data-avatar-url"),
515
- renderHTML: (attributes) => {
516
- if (!attributes.avatarUrl) return {};
517
- return { "data-avatar-url": attributes.avatarUrl };
518
- }
519
- },
520
- color: {
521
- default: null,
522
- parseHTML: (element) => element.getAttribute("data-color"),
523
- renderHTML: (attributes) => {
524
- if (!attributes.color) return {};
525
- return { "data-color": attributes.color };
526
- }
527
- }
528
- };
529
- }
530
- });
531
- function createMentionExtension(options = {}) {
532
- const { HTMLAttributes = {}, ...rest } = options;
533
- return Mention.configure({
534
- HTMLAttributes: {
535
- class: "pixerate-mention-node",
536
- ...HTMLAttributes
537
- },
538
- ...rest
539
- });
540
- }
541
-
542
- // ../../node_modules/.pnpm/tiptap-markdown@0.8.10_@tiptap+core@2.27.3_@tiptap+pm@2.27.3_/node_modules/tiptap-markdown/dist/tiptap-markdown.es.js
543
- import { Extension as Extension6, Mark as Mark2, getHTMLFromFragment, Node as Node$1, extensions } from "@tiptap/core";
544
- import { MarkdownSerializerState as MarkdownSerializerState$1, defaultMarkdownSerializer } from "prosemirror-markdown";
545
- import markdownit from "markdown-it";
546
- import { Fragment, DOMParser } from "@tiptap/pm/model";
547
- import taskListPlugin from "markdown-it-task-lists";
548
- import { Plugin as Plugin4, PluginKey } from "@tiptap/pm/state";
549
- var __defProp = Object.defineProperty;
550
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
551
- var __publicField = (obj, key, value) => {
552
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
553
- return value;
554
- };
555
- var MarkdownTightLists = Extension6.create({
556
- name: "markdownTightLists",
557
- addOptions: () => ({
558
- tight: true,
559
- tightClass: "tight",
560
- listTypes: ["bulletList", "orderedList"]
561
- }),
562
- addGlobalAttributes() {
563
- return [{
564
- types: this.options.listTypes,
565
- attributes: {
566
- tight: {
567
- default: this.options.tight,
568
- parseHTML: (element) => element.getAttribute("data-tight") === "true" || !element.querySelector("p"),
569
- renderHTML: (attributes) => ({
570
- class: attributes.tight ? this.options.tightClass : null,
571
- "data-tight": attributes.tight ? "true" : null
572
- })
573
- }
574
- }
575
- }];
576
- },
577
- addCommands() {
578
- var _this = this;
579
- return {
580
- toggleTight: function() {
581
- let tight = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : null;
582
- return (_ref) => {
583
- let {
584
- editor,
585
- commands
586
- } = _ref;
587
- function toggleTight(name) {
588
- if (!editor.isActive(name)) {
589
- return false;
590
- }
591
- const attrs = editor.getAttributes(name);
592
- return commands.updateAttributes(name, {
593
- tight: tight !== null && tight !== void 0 ? tight : !(attrs !== null && attrs !== void 0 && attrs.tight)
594
- });
595
- }
596
- return _this.options.listTypes.some((name) => toggleTight(name));
597
- };
598
- }
599
- };
600
- }
601
- });
602
- var md = markdownit();
603
- function scanDelims(text, pos) {
604
- md.inline.State.prototype.scanDelims.call({
605
- src: text,
606
- posMax: text.length
607
- });
608
- const state = new md.inline.State(text, null, null, []);
609
- return state.scanDelims(pos, true);
610
- }
611
- function shiftDelim(text, delim, start, offset) {
612
- let res = text.substring(0, start) + text.substring(start + delim.length);
613
- res = res.substring(0, start + offset) + delim + res.substring(start + offset);
614
- return res;
615
- }
616
- function trimStart(text, delim, from, to) {
617
- let pos = from, res = text;
618
- while (pos < to) {
619
- if (scanDelims(res, pos).can_open) {
620
- break;
621
- }
622
- res = shiftDelim(res, delim, pos, 1);
623
- pos++;
624
- }
625
- return {
626
- text: res,
627
- from: pos,
628
- to
629
- };
630
- }
631
- function trimEnd(text, delim, from, to) {
632
- let pos = to, res = text;
633
- while (pos > from) {
634
- if (scanDelims(res, pos).can_close) {
635
- break;
636
- }
637
- res = shiftDelim(res, delim, pos, -1);
638
- pos--;
639
- }
640
- return {
641
- text: res,
642
- from,
643
- to: pos
644
- };
645
- }
646
- function trimInline(text, delim, from, to) {
647
- let state = {
648
- text,
649
- from,
650
- to
651
- };
652
- state = trimStart(state.text, delim, state.from, state.to);
653
- state = trimEnd(state.text, delim, state.from, state.to);
654
- if (state.to - state.from < delim.length + 1) {
655
- state.text = state.text.substring(0, state.from) + state.text.substring(state.to + delim.length);
656
- }
657
- return state.text;
658
- }
659
- var MarkdownSerializerState = class extends MarkdownSerializerState$1 {
660
- constructor(nodes, marks, options) {
661
- super(nodes, marks, options !== null && options !== void 0 ? options : {});
662
- __publicField(this, "inTable", false);
663
- this.inlines = [];
664
- }
665
- render(node, parent, index) {
666
- super.render(node, parent, index);
667
- const top = this.inlines[this.inlines.length - 1];
668
- if (top !== null && top !== void 0 && top.start && top !== null && top !== void 0 && top.end) {
669
- const {
670
- delimiter,
671
- start,
672
- end
673
- } = this.normalizeInline(top);
674
- this.out = trimInline(this.out, delimiter, start, end);
675
- this.inlines.pop();
676
- }
677
- }
678
- markString(mark, open, parent, index) {
679
- const info = this.marks[mark.type.name];
680
- if (info.expelEnclosingWhitespace) {
681
- if (open) {
682
- this.inlines.push({
683
- start: this.out.length,
684
- delimiter: info.open
685
- });
686
- } else {
687
- const top = this.inlines.pop();
688
- this.inlines.push({
689
- ...top,
690
- end: this.out.length
691
- });
692
- }
693
- }
694
- return super.markString(mark, open, parent, index);
695
- }
696
- normalizeInline(inline) {
697
- let {
698
- start,
699
- end
700
- } = inline;
701
- while (this.out.charAt(start).match(/\s/)) {
702
- start++;
703
- }
704
- return {
705
- ...inline,
706
- start
707
- };
708
- }
709
- };
710
- var HTMLMark = Mark2.create({
711
- name: "markdownHTMLMark",
712
- /**
713
- * @return {{markdown: MarkdownMarkSpec}}
714
- */
715
- addStorage() {
716
- return {
717
- markdown: {
718
- serialize: {
719
- open(state, mark) {
720
- var _getMarkTags$, _getMarkTags;
721
- if (!this.editor.storage.markdown.options.html) {
722
- console.warn(`Tiptap Markdown: "${mark.type.name}" mark is only available in html mode`);
723
- return "";
724
- }
725
- return (_getMarkTags$ = (_getMarkTags = getMarkTags(mark)) === null || _getMarkTags === void 0 ? void 0 : _getMarkTags[0]) !== null && _getMarkTags$ !== void 0 ? _getMarkTags$ : "";
726
- },
727
- close(state, mark) {
728
- var _getMarkTags$2, _getMarkTags2;
729
- if (!this.editor.storage.markdown.options.html) {
730
- return "";
731
- }
732
- return (_getMarkTags$2 = (_getMarkTags2 = getMarkTags(mark)) === null || _getMarkTags2 === void 0 ? void 0 : _getMarkTags2[1]) !== null && _getMarkTags$2 !== void 0 ? _getMarkTags$2 : "";
733
- }
734
- },
735
- parse: {
736
- // handled by markdown-it
737
- }
738
- }
739
- };
740
- }
741
- });
742
- function getMarkTags(mark) {
743
- const schema = mark.type.schema;
744
- const node = schema.text(" ", [mark]);
745
- const html = getHTMLFromFragment(Fragment.from(node), schema);
746
- const match = html.match(/^(<.*?>) (<\/.*?>)$/);
747
- return match ? [match[1], match[2]] : null;
748
- }
749
- function elementFromString(value) {
750
- const wrappedValue = `<body>${value}</body>`;
751
- return new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
752
- }
753
- function escapeHTML(value) {
754
- return value === null || value === void 0 ? void 0 : value.replace(/</g, "&lt;").replace(/>/g, "&gt;");
755
- }
756
- function extractElement(node) {
757
- const parent = node.parentElement;
758
- const prepend = parent.cloneNode();
759
- while (parent.firstChild && parent.firstChild !== node) {
760
- prepend.appendChild(parent.firstChild);
761
- }
762
- if (prepend.childNodes.length > 0) {
763
- parent.parentElement.insertBefore(prepend, parent);
764
- }
765
- parent.parentElement.insertBefore(node, parent);
766
- if (parent.childNodes.length === 0) {
767
- parent.remove();
768
- }
769
- }
770
- function unwrapElement(node) {
771
- const parent = node.parentNode;
772
- while (node.firstChild)
773
- parent.insertBefore(node.firstChild, node);
774
- parent.removeChild(node);
775
- }
776
- var HTMLNode = Node$1.create({
777
- name: "markdownHTMLNode",
778
- addStorage() {
779
- return {
780
- markdown: {
781
- serialize(state, node, parent) {
782
- if (this.editor.storage.markdown.options.html) {
783
- state.write(serializeHTML(node, parent));
784
- } else {
785
- console.warn(`Tiptap Markdown: "${node.type.name}" node is only available in html mode`);
786
- state.write(`[${node.type.name}]`);
787
- }
788
- if (node.isBlock) {
789
- state.closeBlock(node);
790
- }
791
- },
792
- parse: {
793
- // handled by markdown-it
794
- }
795
- }
796
- };
797
- }
798
- });
799
- function serializeHTML(node, parent) {
800
- const schema = node.type.schema;
801
- const html = getHTMLFromFragment(Fragment.from(node), schema);
802
- if (node.isBlock && (parent instanceof Fragment || parent.type.name === schema.topNodeType.name)) {
803
- return formatBlock(html);
804
- }
805
- return html;
806
- }
807
- function formatBlock(html) {
808
- const dom = elementFromString(html);
809
- const element = dom.firstElementChild;
810
- element.innerHTML = element.innerHTML.trim() ? `
811
- ${element.innerHTML}
812
- ` : `
813
- `;
814
- return element.outerHTML;
815
- }
816
- var Blockquote = Node$1.create({
817
- name: "blockquote"
818
- });
819
- var Blockquote$1 = Blockquote.extend({
820
- /**
821
- * @return {{markdown: MarkdownNodeSpec}}
822
- */
823
- addStorage() {
824
- return {
825
- markdown: {
826
- serialize: defaultMarkdownSerializer.nodes.blockquote,
827
- parse: {
828
- // handled by markdown-it
829
- }
830
- }
831
- };
832
- }
833
- });
834
- var BulletList = Node$1.create({
835
- name: "bulletList"
836
- });
837
- var BulletList$1 = BulletList.extend({
838
- /**
839
- * @return {{markdown: MarkdownNodeSpec}}
840
- */
841
- addStorage() {
842
- return {
843
- markdown: {
844
- serialize(state, node) {
845
- return state.renderList(node, " ", () => (this.editor.storage.markdown.options.bulletListMarker || "-") + " ");
846
- },
847
- parse: {
848
- // handled by markdown-it
849
- }
850
- }
851
- };
852
- }
853
- });
854
- var CodeBlock = Node$1.create({
855
- name: "codeBlock"
856
- });
857
- var CodeBlock$1 = CodeBlock.extend({
858
- /**
859
- * @return {{markdown: MarkdownNodeSpec}}
860
- */
861
- addStorage() {
862
- return {
863
- markdown: {
864
- serialize(state, node) {
865
- state.write("```" + (node.attrs.language || "") + "\n");
866
- state.text(node.textContent, false);
867
- state.ensureNewLine();
868
- state.write("```");
869
- state.closeBlock(node);
870
- },
871
- parse: {
872
- setup(markdownit2) {
873
- var _this$options$languag;
874
- markdownit2.set({
875
- langPrefix: (_this$options$languag = this.options.languageClassPrefix) !== null && _this$options$languag !== void 0 ? _this$options$languag : "language-"
876
- });
877
- },
878
- updateDOM(element) {
879
- element.innerHTML = element.innerHTML.replace(/\n<\/code><\/pre>/g, "</code></pre>");
880
- }
881
- }
882
- }
883
- };
884
- }
885
- });
886
- var HardBreak = Node$1.create({
887
- name: "hardBreak"
888
- });
889
- var HardBreak$1 = HardBreak.extend({
890
- /**
891
- * @return {{markdown: MarkdownNodeSpec}}
892
- */
893
- addStorage() {
894
- return {
895
- markdown: {
896
- serialize(state, node, parent, index) {
897
- for (let i = index + 1; i < parent.childCount; i++)
898
- if (parent.child(i).type != node.type) {
899
- state.write(state.inTable ? HTMLNode.storage.markdown.serialize.call(this, state, node, parent) : "\\\n");
900
- return;
901
- }
902
- },
903
- parse: {
904
- // handled by markdown-it
905
- }
906
- }
907
- };
908
- }
909
- });
910
- var Heading = Node$1.create({
911
- name: "heading"
912
- });
913
- var Heading$1 = Heading.extend({
914
- /**
915
- * @return {{markdown: MarkdownNodeSpec}}
916
- */
917
- addStorage() {
918
- return {
919
- markdown: {
920
- serialize: defaultMarkdownSerializer.nodes.heading,
921
- parse: {
922
- // handled by markdown-it
923
- }
924
- }
925
- };
926
- }
927
- });
928
- var HorizontalRule = Node$1.create({
929
- name: "horizontalRule"
930
- });
931
- var HorizontalRule$1 = HorizontalRule.extend({
932
- /**
933
- * @return {{markdown: MarkdownNodeSpec}}
934
- */
935
- addStorage() {
936
- return {
937
- markdown: {
938
- serialize: defaultMarkdownSerializer.nodes.horizontal_rule,
939
- parse: {
940
- // handled by markdown-it
941
- }
942
- }
943
- };
944
- }
945
- });
946
- var Image = Node$1.create({
947
- name: "image"
948
- });
949
- var Image$1 = Image.extend({
950
- /**
951
- * @return {{markdown: MarkdownNodeSpec}}
952
- */
953
- addStorage() {
954
- return {
955
- markdown: {
956
- serialize: defaultMarkdownSerializer.nodes.image,
957
- parse: {
958
- // handled by markdown-it
959
- }
960
- }
961
- };
962
- }
963
- });
964
- var ListItem = Node$1.create({
965
- name: "listItem"
966
- });
967
- var ListItem$1 = ListItem.extend({
968
- /**
969
- * @return {{markdown: MarkdownNodeSpec}}
970
- */
971
- addStorage() {
972
- return {
973
- markdown: {
974
- serialize: defaultMarkdownSerializer.nodes.list_item,
975
- parse: {
976
- // handled by markdown-it
977
- }
978
- }
979
- };
980
- }
981
- });
982
- var OrderedList = Node$1.create({
983
- name: "orderedList"
984
- });
985
- function findIndexOfAdjacentNode(node, parent, index) {
986
- let i = 0;
987
- for (; index - i > 0; i++) {
988
- if (parent.child(index - i - 1).type.name !== node.type.name) {
989
- break;
990
- }
991
- }
992
- return i;
993
- }
994
- var OrderedList$1 = OrderedList.extend({
995
- /**
996
- * @return {{markdown: MarkdownNodeSpec}}
997
- */
998
- addStorage() {
999
- return {
1000
- markdown: {
1001
- serialize(state, node, parent, index) {
1002
- const start = node.attrs.start || 1;
1003
- const maxW = String(start + node.childCount - 1).length;
1004
- const space = state.repeat(" ", maxW + 2);
1005
- const adjacentIndex = findIndexOfAdjacentNode(node, parent, index);
1006
- const separator = adjacentIndex % 2 ? ") " : ". ";
1007
- state.renderList(node, space, (i) => {
1008
- const nStr = String(start + i);
1009
- return state.repeat(" ", maxW - nStr.length) + nStr + separator;
1010
- });
1011
- },
1012
- parse: {
1013
- // handled by markdown-it
1014
- }
1015
- }
1016
- };
1017
- }
1018
- });
1019
- var Paragraph = Node$1.create({
1020
- name: "paragraph"
1021
- });
1022
- var Paragraph$1 = Paragraph.extend({
1023
- /**
1024
- * @return {{markdown: MarkdownNodeSpec}}
1025
- */
1026
- addStorage() {
1027
- return {
1028
- markdown: {
1029
- serialize: defaultMarkdownSerializer.nodes.paragraph,
1030
- parse: {
1031
- // handled by markdown-it
1032
- }
1033
- }
1034
- };
1035
- }
1036
- });
1037
- function childNodes(node) {
1038
- var _node$content$content, _node$content;
1039
- return (_node$content$content = node === null || node === void 0 || (_node$content = node.content) === null || _node$content === void 0 ? void 0 : _node$content.content) !== null && _node$content$content !== void 0 ? _node$content$content : [];
1040
- }
1041
- var Table = Node$1.create({
1042
- name: "table"
1043
- });
1044
- var Table$1 = Table.extend({
1045
- /**
1046
- * @return {{markdown: MarkdownNodeSpec}}
1047
- */
1048
- addStorage() {
1049
- return {
1050
- markdown: {
1051
- serialize(state, node, parent) {
1052
- if (!isMarkdownSerializable(node)) {
1053
- HTMLNode.storage.markdown.serialize.call(this, state, node, parent);
1054
- return;
1055
- }
1056
- state.inTable = true;
1057
- node.forEach((row, p, i) => {
1058
- state.write("| ");
1059
- row.forEach((col, p2, j) => {
1060
- if (j) {
1061
- state.write(" | ");
1062
- }
1063
- const cellContent = col.firstChild;
1064
- if (cellContent.textContent.trim()) {
1065
- state.renderInline(cellContent);
1066
- }
1067
- });
1068
- state.write(" |");
1069
- state.ensureNewLine();
1070
- if (!i) {
1071
- const delimiterRow = Array.from({
1072
- length: row.childCount
1073
- }).map(() => "---").join(" | ");
1074
- state.write(`| ${delimiterRow} |`);
1075
- state.ensureNewLine();
1076
- }
1077
- });
1078
- state.closeBlock(node);
1079
- state.inTable = false;
1080
- },
1081
- parse: {
1082
- // handled by markdown-it
1083
- }
1084
- }
1085
- };
1086
- }
1087
- });
1088
- function hasSpan(node) {
1089
- return node.attrs.colspan > 1 || node.attrs.rowspan > 1;
1090
- }
1091
- function isMarkdownSerializable(node) {
1092
- const rows = childNodes(node);
1093
- const firstRow = rows[0];
1094
- const bodyRows = rows.slice(1);
1095
- if (childNodes(firstRow).some((cell) => cell.type.name !== "tableHeader" || hasSpan(cell) || cell.childCount > 1)) {
1096
- return false;
1097
- }
1098
- if (bodyRows.some((row) => childNodes(row).some((cell) => cell.type.name === "tableHeader" || hasSpan(cell) || cell.childCount > 1))) {
1099
- return false;
1100
- }
1101
- return true;
1102
- }
1103
- var TaskItem = Node$1.create({
1104
- name: "taskItem"
1105
- });
1106
- var TaskItem$1 = TaskItem.extend({
1107
- /**
1108
- * @return {{markdown: MarkdownNodeSpec}}
1109
- */
1110
- addStorage() {
1111
- return {
1112
- markdown: {
1113
- serialize(state, node) {
1114
- const check = node.attrs.checked ? "[x]" : "[ ]";
1115
- state.write(`${check} `);
1116
- state.renderContent(node);
1117
- },
1118
- parse: {
1119
- updateDOM(element) {
1120
- [...element.querySelectorAll(".task-list-item")].forEach((item) => {
1121
- const input = item.querySelector("input");
1122
- item.setAttribute("data-type", "taskItem");
1123
- if (input) {
1124
- item.setAttribute("data-checked", input.checked);
1125
- input.remove();
1126
- }
1127
- });
1128
- }
1129
- }
1130
- }
1131
- };
1132
- }
1133
- });
1134
- var TaskList = Node$1.create({
1135
- name: "taskList"
1136
- });
1137
- var TaskList$1 = TaskList.extend({
1138
- /**
1139
- * @return {{markdown: MarkdownNodeSpec}}
1140
- */
1141
- addStorage() {
1142
- return {
1143
- markdown: {
1144
- serialize: BulletList$1.storage.markdown.serialize,
1145
- parse: {
1146
- setup(markdownit2) {
1147
- markdownit2.use(taskListPlugin);
1148
- },
1149
- updateDOM(element) {
1150
- [...element.querySelectorAll(".contains-task-list")].forEach((list) => {
1151
- list.setAttribute("data-type", "taskList");
1152
- });
1153
- }
1154
- }
1155
- }
1156
- };
1157
- }
1158
- });
1159
- var Text = Node$1.create({
1160
- name: "text"
1161
- });
1162
- var Text$1 = Text.extend({
1163
- /**
1164
- * @return {{markdown: MarkdownNodeSpec}}
1165
- */
1166
- addStorage() {
1167
- return {
1168
- markdown: {
1169
- serialize(state, node) {
1170
- state.text(escapeHTML(node.text));
1171
- },
1172
- parse: {
1173
- // handled by markdown-it
1174
- }
1175
- }
1176
- };
1177
- }
1178
- });
1179
- var Bold = Mark2.create({
1180
- name: "bold"
1181
- });
1182
- var Bold$1 = Bold.extend({
1183
- /**
1184
- * @return {{markdown: MarkdownMarkSpec}}
1185
- */
1186
- addStorage() {
1187
- return {
1188
- markdown: {
1189
- serialize: defaultMarkdownSerializer.marks.strong,
1190
- parse: {
1191
- // handled by markdown-it
1192
- }
1193
- }
1194
- };
1195
- }
1196
- });
1197
- var Code = Mark2.create({
1198
- name: "code"
1199
- });
1200
- var Code$1 = Code.extend({
1201
- /**
1202
- * @return {{markdown: MarkdownMarkSpec}}
1203
- */
1204
- addStorage() {
1205
- return {
1206
- markdown: {
1207
- serialize: defaultMarkdownSerializer.marks.code,
1208
- parse: {
1209
- // handled by markdown-it
1210
- }
1211
- }
1212
- };
1213
- }
1214
- });
1215
- var Italic = Mark2.create({
1216
- name: "italic"
1217
- });
1218
- var Italic$1 = Italic.extend({
1219
- /**
1220
- * @return {{markdown: MarkdownMarkSpec}}
1221
- */
1222
- addStorage() {
1223
- return {
1224
- markdown: {
1225
- serialize: defaultMarkdownSerializer.marks.em,
1226
- parse: {
1227
- // handled by markdown-it
1228
- }
1229
- }
1230
- };
1231
- }
1232
- });
1233
- var Link = Mark2.create({
1234
- name: "link"
1235
- });
1236
- var Link$1 = Link.extend({
1237
- /**
1238
- * @return {{markdown: MarkdownMarkSpec}}
1239
- */
1240
- addStorage() {
1241
- return {
1242
- markdown: {
1243
- serialize: defaultMarkdownSerializer.marks.link,
1244
- parse: {
1245
- // handled by markdown-it
1246
- }
1247
- }
1248
- };
1249
- }
1250
- });
1251
- var Strike = Mark2.create({
1252
- name: "strike"
1253
- });
1254
- var Strike$1 = Strike.extend({
1255
- /**
1256
- * @return {{markdown: MarkdownMarkSpec}}
1257
- */
1258
- addStorage() {
1259
- return {
1260
- markdown: {
1261
- serialize: {
1262
- open: "~~",
1263
- close: "~~",
1264
- expelEnclosingWhitespace: true
1265
- },
1266
- parse: {
1267
- // handled by markdown-it
1268
- }
1269
- }
1270
- };
1271
- }
1272
- });
1273
- var markdownExtensions = [Blockquote$1, BulletList$1, CodeBlock$1, HardBreak$1, Heading$1, HorizontalRule$1, HTMLNode, Image$1, ListItem$1, OrderedList$1, Paragraph$1, Table$1, TaskItem$1, TaskList$1, Text$1, Bold$1, Code$1, HTMLMark, Italic$1, Link$1, Strike$1];
1274
- function getMarkdownSpec(extension) {
1275
- var _extension$storage, _markdownExtensions$f;
1276
- const markdownSpec = (_extension$storage = extension.storage) === null || _extension$storage === void 0 ? void 0 : _extension$storage.markdown;
1277
- const defaultMarkdownSpec = (_markdownExtensions$f = markdownExtensions.find((e) => e.name === extension.name)) === null || _markdownExtensions$f === void 0 ? void 0 : _markdownExtensions$f.storage.markdown;
1278
- if (markdownSpec || defaultMarkdownSpec) {
1279
- return {
1280
- ...defaultMarkdownSpec,
1281
- ...markdownSpec
1282
- };
1283
- }
1284
- return null;
1285
- }
1286
- var MarkdownSerializer = class {
1287
- constructor(editor) {
1288
- __publicField(this, "editor", null);
1289
- this.editor = editor;
1290
- }
1291
- serialize(content) {
1292
- const state = new MarkdownSerializerState(this.nodes, this.marks, {
1293
- hardBreakNodeName: HardBreak$1.name
1294
- });
1295
- state.renderContent(content);
1296
- return state.out;
1297
- }
1298
- get nodes() {
1299
- var _this$editor$extensio;
1300
- return {
1301
- ...Object.fromEntries(Object.keys(this.editor.schema.nodes).map((name) => [name, this.serializeNode(HTMLNode)])),
1302
- ...Object.fromEntries((_this$editor$extensio = this.editor.extensionManager.extensions.filter((extension) => extension.type === "node" && this.serializeNode(extension)).map((extension) => [extension.name, this.serializeNode(extension)])) !== null && _this$editor$extensio !== void 0 ? _this$editor$extensio : [])
1303
- };
1304
- }
1305
- get marks() {
1306
- var _this$editor$extensio2;
1307
- return {
1308
- ...Object.fromEntries(Object.keys(this.editor.schema.marks).map((name) => [name, this.serializeMark(HTMLMark)])),
1309
- ...Object.fromEntries((_this$editor$extensio2 = this.editor.extensionManager.extensions.filter((extension) => extension.type === "mark" && this.serializeMark(extension)).map((extension) => [extension.name, this.serializeMark(extension)])) !== null && _this$editor$extensio2 !== void 0 ? _this$editor$extensio2 : [])
1310
- };
1311
- }
1312
- serializeNode(node) {
1313
- var _getMarkdownSpec;
1314
- return (_getMarkdownSpec = getMarkdownSpec(node)) === null || _getMarkdownSpec === void 0 || (_getMarkdownSpec = _getMarkdownSpec.serialize) === null || _getMarkdownSpec === void 0 ? void 0 : _getMarkdownSpec.bind({
1315
- editor: this.editor,
1316
- options: node.options
1317
- });
1318
- }
1319
- serializeMark(mark) {
1320
- var _getMarkdownSpec2;
1321
- const serialize = (_getMarkdownSpec2 = getMarkdownSpec(mark)) === null || _getMarkdownSpec2 === void 0 ? void 0 : _getMarkdownSpec2.serialize;
1322
- return serialize ? {
1323
- ...serialize,
1324
- open: typeof serialize.open === "function" ? serialize.open.bind({
1325
- editor: this.editor,
1326
- options: mark.options
1327
- }) : serialize.open,
1328
- close: typeof serialize.close === "function" ? serialize.close.bind({
1329
- editor: this.editor,
1330
- options: mark.options
1331
- }) : serialize.close
1332
- } : null;
1333
- }
1334
- };
1335
- var MarkdownParser = class {
1336
- constructor(editor, _ref) {
1337
- __publicField(this, "editor", null);
1338
- __publicField(this, "md", null);
1339
- let {
1340
- html,
1341
- linkify,
1342
- breaks
1343
- } = _ref;
1344
- this.editor = editor;
1345
- this.md = this.withPatchedRenderer(markdownit({
1346
- html,
1347
- linkify,
1348
- breaks
1349
- }));
1350
- }
1351
- parse(content) {
1352
- let {
1353
- inline
1354
- } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
1355
- if (typeof content === "string") {
1356
- this.editor.extensionManager.extensions.forEach((extension) => {
1357
- var _getMarkdownSpec;
1358
- return (_getMarkdownSpec = getMarkdownSpec(extension)) === null || _getMarkdownSpec === void 0 || (_getMarkdownSpec = _getMarkdownSpec.parse) === null || _getMarkdownSpec === void 0 || (_getMarkdownSpec = _getMarkdownSpec.setup) === null || _getMarkdownSpec === void 0 ? void 0 : _getMarkdownSpec.call({
1359
- editor: this.editor,
1360
- options: extension.options
1361
- }, this.md);
1362
- });
1363
- const renderedHTML = this.md.render(content);
1364
- const element = elementFromString(renderedHTML);
1365
- this.editor.extensionManager.extensions.forEach((extension) => {
1366
- var _getMarkdownSpec2;
1367
- return (_getMarkdownSpec2 = getMarkdownSpec(extension)) === null || _getMarkdownSpec2 === void 0 || (_getMarkdownSpec2 = _getMarkdownSpec2.parse) === null || _getMarkdownSpec2 === void 0 || (_getMarkdownSpec2 = _getMarkdownSpec2.updateDOM) === null || _getMarkdownSpec2 === void 0 ? void 0 : _getMarkdownSpec2.call({
1368
- editor: this.editor,
1369
- options: extension.options
1370
- }, element);
1371
- });
1372
- this.normalizeDOM(element, {
1373
- inline,
1374
- content
1375
- });
1376
- return element.innerHTML;
1377
- }
1378
- return content;
1379
- }
1380
- normalizeDOM(node, _ref2) {
1381
- let {
1382
- inline,
1383
- content
1384
- } = _ref2;
1385
- this.normalizeBlocks(node);
1386
- node.querySelectorAll("*").forEach((el) => {
1387
- var _el$nextSibling;
1388
- if (((_el$nextSibling = el.nextSibling) === null || _el$nextSibling === void 0 ? void 0 : _el$nextSibling.nodeType) === Node.TEXT_NODE && !el.closest("pre")) {
1389
- el.nextSibling.textContent = el.nextSibling.textContent.replace(/^\n/, "");
1390
- }
1391
- });
1392
- if (inline) {
1393
- this.normalizeInline(node, content);
1394
- }
1395
- return node;
1396
- }
1397
- normalizeBlocks(node) {
1398
- const blocks = Object.values(this.editor.schema.nodes).filter((node2) => node2.isBlock);
1399
- const selector = blocks.map((block) => {
1400
- var _block$spec$parseDOM;
1401
- return (_block$spec$parseDOM = block.spec.parseDOM) === null || _block$spec$parseDOM === void 0 ? void 0 : _block$spec$parseDOM.map((spec) => spec.tag);
1402
- }).flat().filter(Boolean).join(",");
1403
- if (!selector) {
1404
- return;
1405
- }
1406
- [...node.querySelectorAll(selector)].forEach((el) => {
1407
- if (el.parentElement.matches("p")) {
1408
- extractElement(el);
1409
- }
1410
- });
1411
- }
1412
- normalizeInline(node, content) {
1413
- var _node$firstElementChi;
1414
- if ((_node$firstElementChi = node.firstElementChild) !== null && _node$firstElementChi !== void 0 && _node$firstElementChi.matches("p")) {
1415
- var _content$match$, _content$match, _content$match$2, _content$match2;
1416
- const firstParagraph = node.firstElementChild;
1417
- const {
1418
- nextElementSibling
1419
- } = firstParagraph;
1420
- const startSpaces = (_content$match$ = (_content$match = content.match(/^\s+/)) === null || _content$match === void 0 ? void 0 : _content$match[0]) !== null && _content$match$ !== void 0 ? _content$match$ : "";
1421
- const endSpaces = !nextElementSibling ? (_content$match$2 = (_content$match2 = content.match(/\s+$/)) === null || _content$match2 === void 0 ? void 0 : _content$match2[0]) !== null && _content$match$2 !== void 0 ? _content$match$2 : "" : "";
1422
- if (content.match(/^\n\n/)) {
1423
- firstParagraph.innerHTML = `${firstParagraph.innerHTML}${endSpaces}`;
1424
- return;
1425
- }
1426
- unwrapElement(firstParagraph);
1427
- node.innerHTML = `${startSpaces}${node.innerHTML}${endSpaces}`;
1428
- }
1429
- }
1430
- /**
1431
- * @param {markdownit} md
1432
- */
1433
- withPatchedRenderer(md2) {
1434
- const withoutNewLine = (renderer) => function() {
1435
- const rendered = renderer(...arguments);
1436
- if (rendered === "\n") {
1437
- return rendered;
1438
- }
1439
- if (rendered[rendered.length - 1] === "\n") {
1440
- return rendered.slice(0, -1);
1441
- }
1442
- return rendered;
1443
- };
1444
- md2.renderer.rules.hardbreak = withoutNewLine(md2.renderer.rules.hardbreak);
1445
- md2.renderer.rules.softbreak = withoutNewLine(md2.renderer.rules.softbreak);
1446
- md2.renderer.rules.fence = withoutNewLine(md2.renderer.rules.fence);
1447
- md2.renderer.rules.code_block = withoutNewLine(md2.renderer.rules.code_block);
1448
- md2.renderer.renderToken = withoutNewLine(md2.renderer.renderToken.bind(md2.renderer));
1449
- return md2;
1450
- }
1451
- };
1452
- var MarkdownClipboard = Extension6.create({
1453
- name: "markdownClipboard",
1454
- addOptions() {
1455
- return {
1456
- transformPastedText: false,
1457
- transformCopiedText: false
1458
- };
1459
- },
1460
- addProseMirrorPlugins() {
1461
- return [new Plugin4({
1462
- key: new PluginKey("markdownClipboard"),
1463
- props: {
1464
- clipboardTextParser: (text, context, plainText) => {
1465
- if (plainText || !this.options.transformPastedText) {
1466
- return null;
1467
- }
1468
- const parsed = this.editor.storage.markdown.parser.parse(text, {
1469
- inline: true
1470
- });
1471
- return DOMParser.fromSchema(this.editor.schema).parseSlice(elementFromString(parsed), {
1472
- preserveWhitespace: true,
1473
- context
1474
- });
1475
- },
1476
- /**
1477
- * @param {import('prosemirror-model').Slice} slice
1478
- */
1479
- clipboardTextSerializer: (slice) => {
1480
- if (!this.options.transformCopiedText) {
1481
- return null;
1482
- }
1483
- return this.editor.storage.markdown.serializer.serialize(slice.content);
1484
- }
1485
- }
1486
- })];
1487
- }
1488
- });
1489
- var Markdown = Extension6.create({
1490
- name: "markdown",
1491
- priority: 50,
1492
- addOptions() {
1493
- return {
1494
- html: true,
1495
- tightLists: true,
1496
- tightListClass: "tight",
1497
- bulletListMarker: "-",
1498
- linkify: false,
1499
- breaks: false,
1500
- transformPastedText: false,
1501
- transformCopiedText: false
1502
- };
1503
- },
1504
- addCommands() {
1505
- const commands = extensions.Commands.config.addCommands();
1506
- return {
1507
- setContent: (content, emitUpdate, parseOptions) => (props) => {
1508
- return commands.setContent(props.editor.storage.markdown.parser.parse(content), emitUpdate, parseOptions)(props);
1509
- },
1510
- insertContentAt: (range, content, options) => (props) => {
1511
- return commands.insertContentAt(range, props.editor.storage.markdown.parser.parse(content, {
1512
- inline: true
1513
- }), options)(props);
1514
- }
1515
- };
1516
- },
1517
- onBeforeCreate() {
1518
- this.editor.storage.markdown = {
1519
- options: {
1520
- ...this.options
1521
- },
1522
- parser: new MarkdownParser(this.editor, this.options),
1523
- serializer: new MarkdownSerializer(this.editor),
1524
- getMarkdown: () => {
1525
- return this.editor.storage.markdown.serializer.serialize(this.editor.state.doc);
1526
- }
1527
- };
1528
- this.editor.options.initialContent = this.editor.options.content;
1529
- this.editor.options.content = this.editor.storage.markdown.parser.parse(this.editor.options.content);
1530
- },
1531
- onCreate() {
1532
- this.editor.options.content = this.editor.options.initialContent;
1533
- delete this.editor.options.initialContent;
1534
- },
1535
- addStorage() {
1536
- return {
1537
- /// storage will be defined in onBeforeCreate() to prevent initial object overriding
1538
- };
1539
- },
1540
- addExtensions() {
1541
- return [MarkdownTightLists.configure({
1542
- tight: this.options.tightLists,
1543
- tightClass: this.options.tightListClass
1544
- }), MarkdownClipboard.configure({
1545
- transformPastedText: this.options.transformPastedText,
1546
- transformCopiedText: this.options.transformCopiedText
1547
- })];
1548
- }
1549
- });
1550
-
1551
- // src/extensions/markdown.ts
1552
- var resolveExt = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
1553
- var Markdown2 = resolveExt(Markdown, "Markdown");
1554
-
1555
- // src/extensions/image.ts
1556
- import * as _Image from "@tiptap/extension-image";
1557
- import { Plugin as Plugin5, PluginKey as PluginKey2 } from "@tiptap/pm/state";
1558
- var resolveExt2 = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
1559
- var BaseImage = resolveExt2(_Image, "Image");
1560
- var imagePastePluginKey = new PluginKey2("imagePasteHandler");
1561
- function insertImageNode(view, src, alt) {
1562
- const { schema } = view.state;
1563
- const imageType = schema.nodes.image;
1564
- if (!imageType) return;
1565
- const node = imageType.create({ src, alt: alt || "" });
1566
- const tr = view.state.tr.replaceSelectionWith(node);
1567
- view.dispatch(tr);
1568
- }
1569
- function updateImageSrc(view, oldSrc, newSrc) {
1570
- const { doc } = view.state;
1571
- let foundPos = null;
1572
- let foundAttrs = null;
1573
- doc.descendants((node, pos) => {
1574
- if (node.type.name === "image" && node.attrs.src === oldSrc) {
1575
- foundPos = pos;
1576
- foundAttrs = node.attrs;
1577
- return false;
1578
- }
1579
- });
1580
- if (foundPos !== null && foundAttrs) {
1581
- const tr = view.state.tr.setNodeMarkup(foundPos, void 0, {
1582
- ...foundAttrs,
1583
- src: newSrc
1584
- });
1585
- view.dispatch(tr);
1586
- }
1587
- }
1588
- function removeImageNode(view, src) {
1589
- const { doc } = view.state;
1590
- let foundPos = null;
1591
- let nodeSize = 0;
1592
- doc.descendants((node, pos) => {
1593
- if (node.type.name === "image" && node.attrs.src === src) {
1594
- foundPos = pos;
1595
- nodeSize = node.nodeSize;
1596
- return false;
1597
- }
1598
- });
1599
- if (foundPos !== null) {
1600
- const tr = view.state.tr.delete(foundPos, foundPos + nodeSize);
1601
- view.dispatch(tr);
1602
- }
1603
- }
1604
- function handleImageInsertion(view, file, options) {
1605
- if (typeof options.upload === "function") {
1606
- const hasObjectUrl = typeof URL !== "undefined" && typeof URL.createObjectURL === "function";
1607
- const tempUrl = hasObjectUrl ? URL.createObjectURL(file) : null;
1608
- if (tempUrl) {
1609
- insertImageNode(view, tempUrl, file.name);
1610
- }
1611
- Promise.resolve(options.upload(file)).then((uploadedUrl) => {
1612
- if (!uploadedUrl) {
1613
- throw new Error("Upload handler returned empty URL");
1614
- }
1615
- if (tempUrl) {
1616
- updateImageSrc(view, tempUrl, uploadedUrl);
1617
- if (typeof URL.revokeObjectURL === "function") {
1618
- URL.revokeObjectURL(tempUrl);
1619
- }
1620
- } else {
1621
- insertImageNode(view, uploadedUrl, file.name);
1622
- }
1623
- }).catch((err) => {
1624
- const error = err instanceof Error ? err : new Error(String(err));
1625
- console.error("Failed to upload pasted image:", error);
1626
- if (tempUrl) {
1627
- removeImageNode(view, tempUrl);
1628
- if (typeof URL.revokeObjectURL === "function") {
1629
- URL.revokeObjectURL(tempUrl);
1630
- }
1631
- }
1632
- if (typeof options.onUploadError === "function") {
1633
- options.onUploadError(error, file);
1634
- }
1635
- });
1636
- } else if (options.allowBase64 !== false) {
1637
- const maxBase64Size = options.maxBase64Size ?? 65536;
1638
- if (file.size > maxBase64Size) {
1639
- const err = new Error(
1640
- `Image size (${Math.round(file.size / 1024)}KB) exceeds maxBase64Size (${Math.round(
1641
- maxBase64Size / 1024
1642
- )}KB). Provide an upload handler to support large images.`
1643
- );
1644
- console.warn(`[Editor] ${err.message}`);
1645
- if (typeof options.onUploadError === "function") {
1646
- options.onUploadError(err, file);
1647
- }
1648
- return;
1649
- }
1650
- if (typeof FileReader !== "undefined") {
1651
- const reader = new FileReader();
1652
- reader.onload = () => {
1653
- const src = reader.result;
1654
- if (src) {
1655
- insertImageNode(view, src, file.name);
1656
- }
1657
- };
1658
- reader.readAsDataURL(file);
1659
- }
1660
- }
1661
- }
1662
- var Image2 = BaseImage.extend({
1663
- addOptions() {
1664
- return {
1665
- ...this.parent?.(),
1666
- allowBase64: true,
1667
- maxBase64Size: 65536,
1668
- enablePaste: true,
1669
- enableDrop: true,
1670
- upload: void 0,
1671
- onUploadError: void 0,
1672
- HTMLAttributes: {
1673
- class: "rounded-md max-w-full h-auto my-2"
1674
- }
1675
- };
1676
- },
1677
- addProseMirrorPlugins() {
1678
- const parentPlugins = this.parent?.() || [];
1679
- const options = this.options;
1680
- if (!options.enablePaste && !options.enableDrop) {
1681
- return parentPlugins;
1682
- }
1683
- const pastePlugin = new Plugin5({
1684
- key: imagePastePluginKey,
1685
- props: {
1686
- handlePaste(view, event) {
1687
- if (!options.enablePaste) return false;
1688
- const items = Array.from(event.clipboardData?.items || []);
1689
- const imageItems = items.filter(
1690
- (item) => item.kind === "file" && item.type.startsWith("image/")
1691
- );
1692
- if (imageItems.length === 0) return false;
1693
- event.preventDefault();
1694
- for (const item of imageItems) {
1695
- const file = item.getAsFile();
1696
- if (!file) continue;
1697
- handleImageInsertion(view, file, options);
1698
- }
1699
- return true;
1700
- },
1701
- handleDrop(view, event) {
1702
- if (!options.enableDrop) return false;
1703
- const files = Array.from(event.dataTransfer?.files || []);
1704
- const imageFiles = files.filter((f) => f.type.startsWith("image/"));
1705
- if (imageFiles.length === 0) return false;
1706
- event.preventDefault();
1707
- for (const file of imageFiles) {
1708
- handleImageInsertion(view, file, options);
1709
- }
1710
- return true;
1711
- }
1712
- }
1713
- });
1714
- return [...parentPlugins, pastePlugin];
1715
- }
1716
- });
1717
-
1718
- // src/extensions/rich-text-preset.ts
1719
- var resolveExt3 = (mod, name) => mod?.[name] || mod?.default?.[name] || mod?.default?.default || mod?.default || mod;
1720
- var StarterKit = resolveExt3(_StarterKit, "StarterKit");
1721
- var Color = resolveExt3(_Color, "Color");
1722
- var Highlight = resolveExt3(_Highlight, "Highlight");
1723
- var Link2 = resolveExt3(_Link, "Link");
1724
- var TaskList2 = resolveExt3(_TaskList, "TaskList");
1725
- var TaskItem2 = resolveExt3(_TaskItem, "TaskItem");
1726
- var TextAlign = resolveExt3(_TextAlign, "TextAlign");
1727
- var TextStyle = resolveExt3(_TextStyle, "TextStyle");
1728
- var Typography = resolveExt3(_Typography, "Typography");
1729
- var Underline = resolveExt3(_Underline, "Underline");
1730
- var Placeholder = resolveExt3(_Placeholder, "Placeholder");
1731
- var CharacterCount = resolveExt3(_CharacterCount, "CharacterCount");
1732
- function createRichTextPreset(options = {}) {
1733
- const {
1734
- placeholder = "Start typing...",
1735
- characterLimit,
1736
- openLinksOnClick = false,
1737
- enableSmilies = true,
1738
- enableColorHighlighter = true,
1739
- headingLevels = [1, 2, 3, 4]
1740
- } = options;
1741
- const extensions2 = [
1742
- StarterKit.configure({
1743
- orderedList: {
1744
- HTMLAttributes: {
1745
- class: "list-decimal pl-4"
1746
- }
1747
- },
1748
- bulletList: {
1749
- HTMLAttributes: {
1750
- class: "list-disc pl-4"
1751
- }
1752
- },
1753
- heading: {
1754
- levels: headingLevels,
1755
- HTMLAttributes: {
1756
- class: "font-bold tracking-tight"
1757
- }
1758
- }
1759
- }),
1760
- TextStyle,
1761
- Color,
1762
- Highlight.configure({ multicolor: true }),
1763
- Underline,
1764
- Typography,
1765
- TextAlign.configure({
1766
- types: ["heading", "paragraph"]
1767
- }),
1768
- Link2.extend({
1769
- addInputRules() {
1770
- return [
1771
- markInputRule({
1772
- find: /(?:^|\s)\[([^\]]+)\]\(([^)]+)\)$/,
1773
- type: this.type,
1774
- getAttributes: (match) => ({
1775
- href: match[2]
1776
- })
1777
- })
1778
- ];
1779
- }
1780
- }).configure({
1781
- openOnClick: openLinksOnClick,
1782
- autolink: true,
1783
- defaultProtocol: "https",
1784
- protocols: ["file", "vscode", "cursor"],
1785
- HTMLAttributes: {
1786
- target: "_blank",
1787
- rel: "noopener noreferrer",
1788
- class: "text-blue-500 underline underline-offset-2"
1789
- }
1790
- }),
1791
- TaskList2,
1792
- TaskItem2.extend({
1793
- addInputRules() {
1794
- return [
1795
- wrappingInputRule({
1796
- find: /^\s*(\[([ |x])?\])\s$/i,
1797
- type: this.type,
1798
- getAttributes: (match) => ({
1799
- checked: match[2]?.toLowerCase() === "x"
1800
- })
1801
- })
1802
- ];
1803
- }
1804
- }).configure({
1805
- nested: true
1806
- }),
1807
- FontSize,
1808
- Placeholder.configure({
1809
- emptyEditorClass: "is-empty",
1810
- placeholder: typeof placeholder === "function" ? placeholder : () => placeholder
1811
- })
1812
- ];
1813
- if (characterLimit) {
1814
- extensions2.push(
1815
- CharacterCount.configure({
1816
- limit: characterLimit
1817
- })
1818
- );
1819
- }
1820
- if (enableSmilies) {
1821
- extensions2.push(SmilieReplacer);
1822
- }
1823
- if (enableColorHighlighter) {
1824
- extensions2.push(ColorHighlighter);
1825
- }
1826
- if (options.mention) {
1827
- const mentionConfig = typeof options.mention === "object" ? options.mention : {};
1828
- extensions2.push(
1829
- Mention.configure({
1830
- HTMLAttributes: {
1831
- class: "pixerate-mention-node",
1832
- ...mentionConfig.HTMLAttributes || {}
1833
- },
1834
- ...mentionConfig
1835
- })
1836
- );
1837
- }
1838
- if (options.markdown) {
1839
- const markdownConfig = typeof options.markdown === "object" ? options.markdown : {};
1840
- extensions2.push(
1841
- Markdown2.configure({
1842
- html: true,
1843
- tightLists: true,
1844
- tightListClass: "tight",
1845
- bulletListMarker: "-",
1846
- linkify: true,
1847
- breaks: true,
1848
- transformPastedText: true,
1849
- transformCopiedText: true,
1850
- ...markdownConfig
1851
- })
1852
- );
1853
- }
1854
- if (options.image !== false) {
1855
- const imageConfig = typeof options.image === "object" ? options.image : {};
1856
- extensions2.push(
1857
- Image2.configure({
1858
- HTMLAttributes: {
1859
- class: "rounded-md max-w-full h-auto my-2",
1860
- ...imageConfig.HTMLAttributes || {}
1861
- },
1862
- ...imageConfig
1863
- })
1864
- );
1865
- }
1866
- return extensions2;
1867
- }
2
+ ColorHighlighter,
3
+ FontSize,
4
+ GradientText,
5
+ Image,
6
+ LoadingNode,
7
+ Markdown,
8
+ Mention,
9
+ SlashCommands,
10
+ SmilieReplacer,
11
+ TemplateSuggestions,
12
+ createMentionExtension,
13
+ createRichTextPreset,
14
+ findHexColors,
15
+ handleImageInsertion,
16
+ imagePastePluginKey,
17
+ insertImageNode,
18
+ removeImageNode,
19
+ updateImageSrc
20
+ } from "../chunk-7FWEWE6T.js";
21
+ import "../chunk-GLSIZKOX.js";
1868
22
  export {
1869
23
  ColorHighlighter,
1870
24
  FontSize,
1871
25
  GradientText,
1872
- Image2 as Image,
26
+ Image,
1873
27
  LoadingNode,
1874
- Markdown2 as Markdown,
28
+ Markdown,
1875
29
  Mention,
1876
30
  SlashCommands,
1877
31
  SmilieReplacer,