dn-react-text-editor 0.1.1 → 0.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 (55) hide show
  1. package/README.md +14 -214
  2. package/dist/attach_file.d.mts +20 -18
  3. package/dist/attach_file.d.ts +20 -18
  4. package/dist/attach_file.js +18 -9
  5. package/dist/attach_file.mjs +18 -9
  6. package/dist/base64_file_uploader.d.mts +6 -0
  7. package/dist/base64_file_uploader.d.ts +6 -0
  8. package/dist/{plugins/trailing_paragraph.js → base64_file_uploader.js} +19 -22
  9. package/dist/base64_file_uploader.mjs +18 -0
  10. package/dist/commands.d.mts +23 -0
  11. package/dist/commands.d.ts +23 -0
  12. package/dist/commands.js +110 -0
  13. package/dist/commands.mjs +75 -0
  14. package/dist/create_text_editor.d.mts +28 -0
  15. package/dist/create_text_editor.d.ts +28 -0
  16. package/dist/create_text_editor.js +1082 -0
  17. package/dist/create_text_editor.mjs +1053 -0
  18. package/dist/html.d.mts +8 -0
  19. package/dist/html.d.ts +8 -0
  20. package/dist/html.js +136 -0
  21. package/dist/html.mjs +98 -0
  22. package/dist/index.d.mts +7 -4
  23. package/dist/index.d.ts +7 -4
  24. package/dist/index.js +790 -380
  25. package/dist/index.mjs +789 -377
  26. package/dist/input.d.mts +21 -0
  27. package/dist/input.d.ts +21 -0
  28. package/dist/input.js +70 -0
  29. package/dist/input.mjs +37 -0
  30. package/dist/plugins/drag_and_drop.d.mts +1 -1
  31. package/dist/plugins/drag_and_drop.d.ts +1 -1
  32. package/dist/plugins/drag_and_drop.js +3 -0
  33. package/dist/plugins/drag_and_drop.mjs +3 -0
  34. package/dist/plugins/highlighter.d.mts +6 -0
  35. package/dist/plugins/highlighter.d.ts +6 -0
  36. package/dist/plugins/highlighter.js +105 -0
  37. package/dist/plugins/highlighter.mjs +69 -0
  38. package/dist/plugins/keymap.js +17 -0
  39. package/dist/plugins/keymap.mjs +17 -0
  40. package/dist/schema.d.mts +2 -2
  41. package/dist/schema.d.ts +2 -2
  42. package/dist/schema.js +255 -14
  43. package/dist/schema.mjs +245 -14
  44. package/dist/text_editor_controller.d.mts +46 -0
  45. package/dist/text_editor_controller.d.ts +46 -0
  46. package/dist/text_editor_controller.js +503 -0
  47. package/dist/text_editor_controller.mjs +470 -0
  48. package/package.json +3 -1
  49. package/dist/plugins/trailing_paragraph.d.mts +0 -5
  50. package/dist/plugins/trailing_paragraph.d.ts +0 -5
  51. package/dist/plugins/trailing_paragraph.mjs +0 -21
  52. package/dist/text_editor.d.mts +0 -37
  53. package/dist/text_editor.d.ts +0 -37
  54. package/dist/text_editor.js +0 -720
  55. package/dist/text_editor.mjs +0 -687
@@ -0,0 +1,1082 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/create_text_editor.tsx
31
+ var create_text_editor_exports = {};
32
+ __export(create_text_editor_exports, {
33
+ createTextEditor: () => createTextEditor
34
+ });
35
+ module.exports = __toCommonJS(create_text_editor_exports);
36
+ var import_react2 = __toESM(require("react"));
37
+ var import_prosemirror_state6 = require("prosemirror-state");
38
+ var import_prosemirror_view5 = require("prosemirror-view");
39
+ var import_react3 = require("react");
40
+
41
+ // src/schema.tsx
42
+ var import_prosemirror_model = require("prosemirror-model");
43
+ var import_prosemirror_schema_list = require("prosemirror-schema-list");
44
+
45
+ // src/plugins/highlighter.ts
46
+ var import_highlight = __toESM(require("highlight.js"));
47
+ var import_bash = __toESM(require("highlight.js/lib/languages/bash"));
48
+ var import_c = __toESM(require("highlight.js/lib/languages/c"));
49
+ var import_cpp = __toESM(require("highlight.js/lib/languages/cpp"));
50
+ var import_css = __toESM(require("highlight.js/lib/languages/css"));
51
+ var import_java = __toESM(require("highlight.js/lib/languages/java"));
52
+ var import_typescript = __toESM(require("highlight.js/lib/languages/typescript"));
53
+ var import_javascript = __toESM(require("highlight.js/lib/languages/javascript"));
54
+ var import_json = __toESM(require("highlight.js/lib/languages/json"));
55
+ var import_xml = __toESM(require("highlight.js/lib/languages/xml"));
56
+ var import_python = __toESM(require("highlight.js/lib/languages/python"));
57
+ var import_dart = __toESM(require("highlight.js/lib/languages/dart"));
58
+ var import_csharp = __toESM(require("highlight.js/lib/languages/csharp"));
59
+ var import_markdown = __toESM(require("highlight.js/lib/languages/markdown"));
60
+ var import_nginx = __toESM(require("highlight.js/lib/languages/nginx"));
61
+ var import_php = __toESM(require("highlight.js/lib/languages/php"));
62
+ var import_ruby = __toESM(require("highlight.js/lib/languages/ruby"));
63
+ var import_sql = __toESM(require("highlight.js/lib/languages/sql"));
64
+ var import_swift = __toESM(require("highlight.js/lib/languages/swift"));
65
+ var import_yaml = __toESM(require("highlight.js/lib/languages/yaml"));
66
+ var import_rust = __toESM(require("highlight.js/lib/languages/rust"));
67
+ import_highlight.default.registerLanguage("bash", import_bash.default);
68
+ import_highlight.default.registerLanguage("c", import_c.default);
69
+ import_highlight.default.registerLanguage("cpp", import_cpp.default);
70
+ import_highlight.default.registerLanguage("css", import_css.default);
71
+ import_highlight.default.registerLanguage("java", import_java.default);
72
+ import_highlight.default.registerLanguage("markdown", import_markdown.default);
73
+ import_highlight.default.registerLanguage("nginx", import_nginx.default);
74
+ import_highlight.default.registerLanguage("php", import_php.default);
75
+ import_highlight.default.registerLanguage("ruby", import_ruby.default);
76
+ import_highlight.default.registerLanguage("sql", import_sql.default);
77
+ import_highlight.default.registerLanguage("swift", import_swift.default);
78
+ import_highlight.default.registerLanguage("yaml", import_yaml.default);
79
+ import_highlight.default.registerLanguage("rust", import_rust.default);
80
+ import_highlight.default.registerLanguage("json", import_json.default);
81
+ import_highlight.default.registerLanguage("javascript", import_javascript.default);
82
+ import_highlight.default.registerLanguage("typescript", import_typescript.default);
83
+ import_highlight.default.registerLanguage("xml", import_xml.default);
84
+ import_highlight.default.registerLanguage("python", import_python.default);
85
+ import_highlight.default.registerLanguage("dart", import_dart.default);
86
+ import_highlight.default.registerLanguage("csharp", import_csharp.default);
87
+ var supportedLanguages = [
88
+ "bash",
89
+ "c",
90
+ "cpp",
91
+ "css",
92
+ "java",
93
+ "markdown",
94
+ "nginx",
95
+ "php",
96
+ "ruby",
97
+ "sql",
98
+ "swift",
99
+ "yaml",
100
+ "rust",
101
+ "json",
102
+ "javascript",
103
+ "typescript",
104
+ "xml",
105
+ "python",
106
+ "dart",
107
+ "csharp"
108
+ ];
109
+ var highlighter = import_highlight.default;
110
+
111
+ // src/schema.tsx
112
+ function createSchema(spec = { nodes: {}, marks: {} }) {
113
+ const customSchema = new import_prosemirror_model.Schema({
114
+ nodes: {
115
+ doc: { content: "block+" },
116
+ paragraph: {
117
+ attrs: { align: { default: null } },
118
+ content: "inline*",
119
+ group: "block",
120
+ parseDOM: [
121
+ {
122
+ tag: "p",
123
+ getAttrs(dom) {
124
+ return {
125
+ align: dom.style.textAlign || null
126
+ };
127
+ }
128
+ }
129
+ ],
130
+ toDOM(node) {
131
+ return [
132
+ "p",
133
+ {
134
+ style: node.attrs.align ? `text-align: ${node.attrs.align}` : null
135
+ },
136
+ 0
137
+ ];
138
+ }
139
+ },
140
+ text: {
141
+ group: "inline"
142
+ },
143
+ hard_break: {
144
+ inline: true,
145
+ group: "inline",
146
+ selectable: false,
147
+ parseDOM: [{ tag: "br" }],
148
+ toDOM() {
149
+ return ["br"];
150
+ }
151
+ },
152
+ heading: {
153
+ attrs: { level: { default: 1 }, align: { default: null } },
154
+ content: "inline*",
155
+ group: "block",
156
+ defining: true,
157
+ parseDOM: [
158
+ {
159
+ tag: "h1",
160
+ getAttrs(node) {
161
+ return {
162
+ level: 1,
163
+ algin: node.style.textAlign || null
164
+ };
165
+ }
166
+ },
167
+ {
168
+ tag: "h2",
169
+ getAttrs(node) {
170
+ return {
171
+ level: 2,
172
+ algin: node.style.textAlign || null
173
+ };
174
+ }
175
+ },
176
+ {
177
+ tag: "h3",
178
+ getAttrs(node) {
179
+ return {
180
+ level: 3,
181
+ algin: node.style.textAlign || null
182
+ };
183
+ }
184
+ },
185
+ {
186
+ tag: "h4",
187
+ getAttrs(node) {
188
+ return {
189
+ level: 4,
190
+ algin: node.style.textAlign || null
191
+ };
192
+ }
193
+ },
194
+ {
195
+ tag: "h5",
196
+ getAttrs(node) {
197
+ return {
198
+ level: 5,
199
+ algin: node.style.textAlign || null
200
+ };
201
+ }
202
+ },
203
+ {
204
+ tag: "h6",
205
+ getAttrs(node) {
206
+ return {
207
+ level: 6,
208
+ algin: node.style.textAlign || null
209
+ };
210
+ }
211
+ }
212
+ ],
213
+ toDOM(node) {
214
+ return [
215
+ "h" + node.attrs.level,
216
+ {
217
+ id: node.textContent.toLowerCase().replace(/\s+/g, "-"),
218
+ style: node.attrs.align ? `text-align: ${node.attrs.align};` : null
219
+ },
220
+ 0
221
+ ];
222
+ }
223
+ },
224
+ horizontal_rule: {
225
+ group: "block",
226
+ parseDOM: [{ tag: "hr" }],
227
+ toDOM() {
228
+ return ["hr"];
229
+ }
230
+ },
231
+ image: {
232
+ attrs: {
233
+ src: { validate: "string" },
234
+ alt: { default: null, validate: "string|null" },
235
+ title: {
236
+ default: null,
237
+ validate: "string|null"
238
+ },
239
+ width: {
240
+ default: null,
241
+ validate: "number|null"
242
+ },
243
+ height: {
244
+ default: null,
245
+ validate: "number|null"
246
+ }
247
+ },
248
+ inline: false,
249
+ group: "block",
250
+ draggable: true,
251
+ parseDOM: [
252
+ {
253
+ tag: "img",
254
+ getAttrs(dom) {
255
+ return {
256
+ src: dom.getAttribute("src"),
257
+ alt: dom.getAttribute("alt"),
258
+ width: dom.getAttribute("width"),
259
+ height: dom.getAttribute("height")
260
+ };
261
+ }
262
+ }
263
+ ],
264
+ toDOM(node) {
265
+ const { src, alt, srcSet, sizes, width, height } = node.attrs;
266
+ return [
267
+ "img",
268
+ {
269
+ src,
270
+ alt,
271
+ srcSet,
272
+ sizes,
273
+ width,
274
+ height
275
+ }
276
+ ];
277
+ }
278
+ },
279
+ video: {
280
+ inline: false,
281
+ group: "block",
282
+ draggable: true,
283
+ attrs: {
284
+ src: { validate: "string" },
285
+ title: {
286
+ default: null,
287
+ validate: "string|null"
288
+ },
289
+ width: {
290
+ default: null,
291
+ validate: "number|null"
292
+ },
293
+ height: {
294
+ default: null,
295
+ validate: "number|null"
296
+ },
297
+ poster: {
298
+ default: null,
299
+ validate: "string|null"
300
+ }
301
+ },
302
+ parseDOM: [
303
+ {
304
+ tag: "video",
305
+ getAttrs(dom) {
306
+ return {
307
+ src: dom.getAttribute("src"),
308
+ title: dom.getAttribute("title"),
309
+ width: dom.getAttribute("width"),
310
+ height: dom.getAttribute("height"),
311
+ poster: dom.getAttribute("poster")
312
+ };
313
+ }
314
+ }
315
+ ],
316
+ toDOM(node) {
317
+ const { src, title, width, height, poster } = node.attrs;
318
+ return [
319
+ "video",
320
+ {
321
+ src,
322
+ title,
323
+ poster,
324
+ width,
325
+ height,
326
+ playsinline: "true",
327
+ controls: "controls",
328
+ style: `aspect-ratio: ${width} / ${height}`
329
+ }
330
+ ];
331
+ }
332
+ },
333
+ iframe: {
334
+ group: "block",
335
+ draggable: true,
336
+ attrs: {
337
+ src: { validate: "string" },
338
+ title: {
339
+ default: null,
340
+ validate: "string|null"
341
+ },
342
+ width: {
343
+ default: null,
344
+ validate: "number|null"
345
+ },
346
+ height: {
347
+ default: null,
348
+ validate: "number|null"
349
+ },
350
+ allow: {
351
+ default: null,
352
+ validate: "string|null"
353
+ },
354
+ allowfullscreen: {
355
+ default: null,
356
+ validate: "string|null"
357
+ },
358
+ referrerPolicy: {
359
+ default: null,
360
+ validate: "string|null"
361
+ },
362
+ style: {
363
+ default: null,
364
+ validate: "string|null"
365
+ }
366
+ },
367
+ parseDOM: [
368
+ {
369
+ tag: "iframe[src]",
370
+ getAttrs(dom) {
371
+ return {
372
+ src: dom.getAttribute("src"),
373
+ title: dom.getAttribute("title"),
374
+ width: dom.getAttribute("width"),
375
+ height: dom.getAttribute("height"),
376
+ style: dom.getAttribute("style"),
377
+ allow: dom.getAttribute("allow"),
378
+ allowfullscreen: dom.getAttribute("allowfullscreen"),
379
+ referrerpolicy: dom.getAttribute("referrerpolicy")
380
+ };
381
+ }
382
+ }
383
+ ],
384
+ toDOM(node) {
385
+ const {
386
+ src,
387
+ title,
388
+ width,
389
+ height,
390
+ allow,
391
+ allowfullscreen,
392
+ referrerpolicy,
393
+ style
394
+ } = node.attrs;
395
+ return [
396
+ "iframe",
397
+ {
398
+ src,
399
+ title,
400
+ width,
401
+ height,
402
+ style,
403
+ allow,
404
+ allowfullscreen,
405
+ referrerpolicy,
406
+ frameborder: "0"
407
+ }
408
+ ];
409
+ }
410
+ },
411
+ blockquote: {
412
+ content: "block+",
413
+ group: "block",
414
+ defining: true,
415
+ parseDOM: [{ tag: "blockquote" }],
416
+ toDOM() {
417
+ return ["blockquote", 0];
418
+ }
419
+ },
420
+ code_block: {
421
+ content: "text*",
422
+ marks: "",
423
+ group: "block",
424
+ code: true,
425
+ defining: true,
426
+ parseDOM: [{ tag: "pre", preserveWhitespace: "full" }],
427
+ toDOM(node) {
428
+ const auto = highlighter.highlightAuto(
429
+ node.textContent,
430
+ supportedLanguages
431
+ );
432
+ return [
433
+ "pre",
434
+ {
435
+ class: "hljs"
436
+ },
437
+ [
438
+ "code",
439
+ {
440
+ class: `language-${auto.language}`
441
+ },
442
+ 0
443
+ ]
444
+ ];
445
+ }
446
+ },
447
+ ...spec.nodes
448
+ },
449
+ marks: {
450
+ link: {
451
+ attrs: {
452
+ href: { default: "" },
453
+ title: { default: null }
454
+ },
455
+ inclusive: false,
456
+ parseDOM: [
457
+ {
458
+ tag: "a[href]",
459
+ getAttrs(dom) {
460
+ return {
461
+ href: dom.getAttribute("href"),
462
+ title: dom.getAttribute("title")
463
+ };
464
+ }
465
+ }
466
+ ],
467
+ toDOM(node) {
468
+ const { href, title } = node.attrs;
469
+ const target = "_blank";
470
+ const rel = "noopener noreferrer";
471
+ return ["a", { href, title: title || href, target, rel }, 0];
472
+ }
473
+ },
474
+ bold: {
475
+ parseDOM: [
476
+ { tag: "strong" },
477
+ {
478
+ tag: "b",
479
+ getAttrs: (node) => node.style.fontWeight != "normal" && null
480
+ },
481
+ {
482
+ style: "font-weight=400",
483
+ clearMark: (m) => m.type.name == "strong"
484
+ },
485
+ {
486
+ style: "font-weight",
487
+ getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null
488
+ }
489
+ ],
490
+ toDOM() {
491
+ return ["strong", 0];
492
+ }
493
+ },
494
+ italic: {
495
+ parseDOM: [
496
+ { tag: "em" },
497
+ { tag: "i" },
498
+ { style: "font-style=italic" },
499
+ {
500
+ style: "font-style=normal",
501
+ clearMark: (m) => m.type.name == "em"
502
+ }
503
+ ],
504
+ toDOM() {
505
+ return ["em", 0];
506
+ }
507
+ },
508
+ underline: {
509
+ parseDOM: [
510
+ { tag: "u" },
511
+ {
512
+ style: "text-decoration",
513
+ getAttrs: (value) => value === "underline" && null
514
+ }
515
+ ],
516
+ toDOM() {
517
+ return ["u", 0];
518
+ }
519
+ },
520
+ ...spec.marks
521
+ },
522
+ topNode: spec.topNode
523
+ });
524
+ const prosemirrorSchema = new import_prosemirror_model.Schema({
525
+ nodes: (0, import_prosemirror_schema_list.addListNodes)(customSchema.spec.nodes, "paragraph block*", "block"),
526
+ marks: customSchema.spec.marks
527
+ });
528
+ return prosemirrorSchema;
529
+ }
530
+
531
+ // src/create_text_editor.tsx
532
+ var import_rxjs3 = require("rxjs");
533
+
534
+ // src/commands.tsx
535
+ var commands = __toESM(require("prosemirror-commands"));
536
+ var schemaList = __toESM(require("prosemirror-schema-list"));
537
+ var createCommands = (schema, view, options = {}) => {
538
+ {
539
+ const isBlockTypeActive = (node, attrs, excludes = []) => {
540
+ const state = view.state;
541
+ const ranges = state.selection.ranges;
542
+ let active = false;
543
+ for (const range of ranges) {
544
+ const { $from, $to } = range;
545
+ state.doc.nodesBetween($from.pos, $to.pos, (n) => {
546
+ if (active) {
547
+ return true;
548
+ }
549
+ if (n.type !== node || excludes.includes(n.type)) {
550
+ return;
551
+ }
552
+ if (!attrs || Object.keys(attrs).every((key) => n.attrs[key] === attrs[key])) {
553
+ active = true;
554
+ }
555
+ });
556
+ return active;
557
+ }
558
+ };
559
+ const setBlockType2 = (node, attrs) => {
560
+ view.focus();
561
+ const nodeType = schema.nodes[node];
562
+ const command = commands.setBlockType(nodeType, attrs);
563
+ command(view.state, view.dispatch);
564
+ };
565
+ const toggleBlockType = (node, attrs) => {
566
+ view.focus();
567
+ const nodeType = schema.nodes[node];
568
+ const command = commands.setBlockType(nodeType, attrs);
569
+ if (isBlockTypeActive(nodeType, attrs)) {
570
+ command(view.state, view.dispatch);
571
+ }
572
+ };
573
+ const toggleMark2 = (mark, attrs, options2) => {
574
+ view.focus();
575
+ const markType = schema.marks[mark];
576
+ const command = commands.toggleMark(markType, attrs, options2);
577
+ command(view.state, view.dispatch);
578
+ };
579
+ const wrapInList2 = (listType, attrs) => {
580
+ view.focus();
581
+ const nodeType = schema.nodes[listType];
582
+ const command = schemaList.wrapInList(nodeType, attrs);
583
+ command(view.state, view.dispatch);
584
+ };
585
+ const clear = () => {
586
+ const tr = view.state.tr.replaceWith(
587
+ 0,
588
+ view.state.doc.content.size,
589
+ schema.nodes.doc.createAndFill()
590
+ );
591
+ view.dispatch(tr);
592
+ };
593
+ return {
594
+ isBlockTypeActive,
595
+ setBlockType: setBlockType2,
596
+ toggleBlockType,
597
+ toggleMark: toggleMark2,
598
+ wrapInList: wrapInList2,
599
+ clear,
600
+ attachFile: (files) => {
601
+ options.attachFile?.(view, files);
602
+ }
603
+ };
604
+ }
605
+ };
606
+
607
+ // src/input.tsx
608
+ var import_react = __toESM(require("react"));
609
+ var import_rxjs = require("rxjs");
610
+ function TextEditorInput({
611
+ ref,
612
+ onChange,
613
+ updateDelay = 0,
614
+ ...props
615
+ }) {
616
+ const inputRef = import_react.default.useRef(null);
617
+ (0, import_react.useEffect)(() => {
618
+ const controller = ref.current;
619
+ if (!controller) {
620
+ return;
621
+ }
622
+ const sub = controller.subject.pipe(
623
+ (0, import_rxjs.filter)((tr) => tr.docChanged),
624
+ (0, import_rxjs.debounceTime)(updateDelay)
625
+ ).subscribe(() => {
626
+ if (inputRef.current) {
627
+ inputRef.current.value = controller.value;
628
+ const event = new Event("input", { bubbles: true });
629
+ inputRef.current.dispatchEvent(event);
630
+ }
631
+ });
632
+ return () => {
633
+ sub.unsubscribe();
634
+ controller.view.destroy();
635
+ };
636
+ }, []);
637
+ return /* @__PURE__ */ import_react.default.createElement("input", { ...props, ref: inputRef, type: "hidden", onInput: onChange });
638
+ }
639
+
640
+ // src/text_editor_controller.tsx
641
+ var import_prosemirror_state5 = require("prosemirror-state");
642
+ var import_prosemirror_view4 = require("prosemirror-view");
643
+ var commands2 = __toESM(require("prosemirror-commands"));
644
+ var import_prosemirror_keymap = require("prosemirror-keymap");
645
+
646
+ // src/plugins/drag_and_drop.tsx
647
+ var import_prosemirror_state = require("prosemirror-state");
648
+ function dragAndDropPlugin({ attachFile }) {
649
+ return new import_prosemirror_state.Plugin({
650
+ props: {
651
+ handleDOMEvents: {
652
+ drop(view, event) {
653
+ if (!attachFile) {
654
+ return;
655
+ }
656
+ const files = event.dataTransfer?.files;
657
+ if (!files || files.length === 0) {
658
+ return;
659
+ }
660
+ event.preventDefault();
661
+ const pos = view.state.selection.$from.pos || view.posAtCoords({
662
+ left: event.clientX,
663
+ top: event.clientY
664
+ })?.pos || null;
665
+ if (pos === null) {
666
+ return;
667
+ }
668
+ const medias = Array.from(files).filter(
669
+ (file) => file.type.startsWith("image/") || file.type.startsWith("video/")
670
+ );
671
+ attachFile(view, medias);
672
+ return true;
673
+ }
674
+ }
675
+ }
676
+ });
677
+ }
678
+
679
+ // src/plugins/upload_placeholder.tsx
680
+ var import_prosemirror_state2 = require("prosemirror-state");
681
+ var import_prosemirror_view = require("prosemirror-view");
682
+ var uploadPlaceholderPlugin = new import_prosemirror_state2.Plugin({
683
+ state: {
684
+ init() {
685
+ return import_prosemirror_view.DecorationSet.empty;
686
+ },
687
+ apply(tr, set) {
688
+ set = set.map(tr.mapping, tr.doc);
689
+ const action = tr.getMeta(this);
690
+ if (action && action.add) {
691
+ const { type, width, height } = action.add;
692
+ const widget = document.createElement("div");
693
+ widget.className = "upload-placeholder";
694
+ widget.style.width = `100%`;
695
+ if (type.startsWith("image/") || type.startsWith("video/")) {
696
+ widget.style.aspectRatio = `${width} / ${height}`;
697
+ widget.style.maxWidth = `${width}px`;
698
+ } else {
699
+ widget.style.height = "80px";
700
+ }
701
+ const progress = document.createElement("div");
702
+ progress.className = "upload-progress";
703
+ widget.appendChild(progress);
704
+ const deco = import_prosemirror_view.Decoration.widget(action.add.pos, widget, {
705
+ id: action.add.id
706
+ });
707
+ set = set.add(tr.doc, [deco]);
708
+ } else if (action && action.progress) {
709
+ const found = set.find(
710
+ void 0,
711
+ void 0,
712
+ (spec) => spec.id === action.progress.id
713
+ );
714
+ if (found.length) {
715
+ const widget = found[0].type.toDOM;
716
+ const progress = widget.querySelector(".upload-progress");
717
+ if (progress) {
718
+ progress.innerHTML = `${Math.round(action.progress.progress)}%`;
719
+ }
720
+ }
721
+ } else if (action && action.remove) {
722
+ set = set.remove(
723
+ set.find(void 0, void 0, (spec) => spec.id === action.remove.id)
724
+ );
725
+ }
726
+ return set;
727
+ }
728
+ },
729
+ props: {
730
+ decorations(state) {
731
+ return this.getState(state);
732
+ }
733
+ }
734
+ });
735
+ var findPlaceholder = (state, id) => {
736
+ const decos = uploadPlaceholderPlugin.getState(state);
737
+ if (!decos) {
738
+ return null;
739
+ }
740
+ const found = decos.find(void 0, void 0, (spec) => spec.id === id);
741
+ return found.length ? found[0].from : null;
742
+ };
743
+
744
+ // src/plugins/placehoder.tsx
745
+ var import_prosemirror_model2 = require("prosemirror-model");
746
+ var import_prosemirror_state3 = require("prosemirror-state");
747
+ var import_prosemirror_view2 = require("prosemirror-view");
748
+ var getFirstChildDescendants = (view) => {
749
+ const nodes = [];
750
+ view.state.doc?.descendants((n) => {
751
+ nodes.push(n);
752
+ });
753
+ return nodes;
754
+ };
755
+ function placeholderPlugin(text) {
756
+ const update = (view) => {
757
+ const decos = uploadPlaceholderPlugin.getState(view.state);
758
+ if (decos && decos.find().length > 0 || view.state.doc.content.content.some((e) => e.type.name !== "paragraph") || view.state.doc.childCount > 1 || getFirstChildDescendants(view).length > 1 || view.state.doc.textContent) {
759
+ view.dom.removeAttribute("data-placeholder");
760
+ } else {
761
+ view.dom.setAttribute("data-placeholder", text);
762
+ }
763
+ };
764
+ return new import_prosemirror_state3.Plugin({
765
+ view(view) {
766
+ update(view);
767
+ return { update };
768
+ }
769
+ });
770
+ }
771
+
772
+ // src/text_editor_controller.tsx
773
+ var import_prosemirror_history2 = require("prosemirror-history");
774
+
775
+ // src/plugins/keymap.tsx
776
+ var import_prosemirror_state4 = require("prosemirror-state");
777
+ var import_prosemirror_history = require("prosemirror-history");
778
+ var import_prosemirror_commands = require("prosemirror-commands");
779
+ var import_prosemirror_schema_list2 = require("prosemirror-schema-list");
780
+ function buildKeymap(schema) {
781
+ const keys = {};
782
+ function bind(key, cmd) {
783
+ keys[key] = cmd;
784
+ }
785
+ bind("Mod-z", import_prosemirror_history.undo);
786
+ bind("Shift-Mod-z", import_prosemirror_history.redo);
787
+ bind("Mod-y", import_prosemirror_history.redo);
788
+ const li = schema.nodes.list_item;
789
+ bind(
790
+ "Enter",
791
+ (0, import_prosemirror_commands.chainCommands)((0, import_prosemirror_schema_list2.splitListItem)(li), (state, dispatch) => {
792
+ const { $head } = state.selection;
793
+ if ($head.parent.type === state.schema.nodes.paragraph) {
794
+ (0, import_prosemirror_commands.splitBlockAs)((n) => {
795
+ return {
796
+ type: n.type,
797
+ attrs: n.attrs
798
+ };
799
+ })(state, dispatch);
800
+ return true;
801
+ }
802
+ return false;
803
+ })
804
+ );
805
+ bind("ArrowDown", (state, dispatch) => {
806
+ const doc = state.doc;
807
+ const lastNode = doc.lastChild;
808
+ if (lastNode && lastNode.type.name !== "paragraph") {
809
+ const paragraphType = state.schema.nodes.paragraph;
810
+ let tr = state.tr;
811
+ const endPos = doc.content.size;
812
+ tr = tr.insert(endPos, paragraphType.create());
813
+ tr = tr.setSelection(import_prosemirror_state4.TextSelection.create(tr.doc, tr.doc.content.size));
814
+ if (dispatch) {
815
+ dispatch(tr);
816
+ }
817
+ return true;
818
+ }
819
+ return false;
820
+ });
821
+ return keys;
822
+ }
823
+
824
+ // src/cn.ts
825
+ function cn(...classes) {
826
+ return classes.filter(Boolean).join(" ").trim();
827
+ }
828
+
829
+ // src/attach_file.tsx
830
+ var import_prosemirror_view3 = require("prosemirror-view");
831
+
832
+ // src/base64_file_uploader.ts
833
+ var base64FileUploader = async (file) => {
834
+ const base64 = await new Promise((resolve, reject) => {
835
+ const reader = new FileReader();
836
+ reader.onload = () => {
837
+ resolve(reader.result);
838
+ };
839
+ reader.onerror = reject;
840
+ reader.readAsDataURL(file);
841
+ });
842
+ return {
843
+ src: base64,
844
+ alt: file.name
845
+ };
846
+ };
847
+
848
+ // src/attach_file.tsx
849
+ function createAttachFile({
850
+ schema,
851
+ generateMetadata,
852
+ uploadFile = base64FileUploader
853
+ }) {
854
+ const attachEachFile = async (view, file, pos) => {
855
+ const metadata = generateMetadata ? await generateMetadata(file) : {};
856
+ const id = {};
857
+ view.focus();
858
+ const tr = view.state.tr;
859
+ if (!tr.selection.empty) {
860
+ tr.deleteSelection();
861
+ }
862
+ tr.setMeta(uploadPlaceholderPlugin, {
863
+ add: {
864
+ id,
865
+ pos: pos ?? tr.selection.from,
866
+ type: file.type,
867
+ ...metadata
868
+ }
869
+ });
870
+ view.dispatch(tr);
871
+ const $pos = findPlaceholder(view.state, id);
872
+ if (!$pos) {
873
+ return;
874
+ }
875
+ try {
876
+ const { src, alt } = await uploadFile(file);
877
+ const tr2 = view.state.tr.setMeta(uploadPlaceholderPlugin, {
878
+ remove: { id }
879
+ });
880
+ const createNode = () => {
881
+ if (file.type.startsWith("image/")) {
882
+ return schema.nodes.image.create({
883
+ src,
884
+ alt,
885
+ width: metadata.width,
886
+ height: metadata.height
887
+ });
888
+ }
889
+ if (file.type.startsWith("video/")) {
890
+ return schema.nodes.video.create({
891
+ src,
892
+ width: metadata.width,
893
+ height: metadata.height,
894
+ poster: metadata.poster
895
+ });
896
+ }
897
+ };
898
+ const node = createNode();
899
+ if (!node) {
900
+ return;
901
+ }
902
+ view.dispatch(tr2.replaceWith($pos, $pos, node));
903
+ } catch (e) {
904
+ view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
905
+ }
906
+ };
907
+ return async (view, files, pos) => {
908
+ for (let i = 0; i < files.length; i++) {
909
+ const file = files[i];
910
+ await attachEachFile(view, file, pos);
911
+ }
912
+ };
913
+ }
914
+
915
+ // src/text_editor_controller.tsx
916
+ var import_prosemirror_model3 = require("prosemirror-model");
917
+ var import_rxjs2 = require("rxjs");
918
+ function createTextEditorController(container, schema, options, {
919
+ mode,
920
+ state,
921
+ editor,
922
+ defaultValue,
923
+ updateDelay = 500,
924
+ placeholder
925
+ }) {
926
+ const subject = new import_rxjs2.Subject();
927
+ const prosemirrorParser = import_prosemirror_model3.DOMParser.fromSchema(schema);
928
+ const prosemirrorSerializer = import_prosemirror_model3.DOMSerializer.fromSchema(schema);
929
+ const wrapper = document.createElement("div");
930
+ const toInnerHTML = (value) => {
931
+ if (mode === "html") {
932
+ return value;
933
+ }
934
+ return value.split("\n").map((line) => `<p>${line}</p>`).join("");
935
+ };
936
+ wrapper.innerHTML = toInnerHTML(defaultValue ? String(defaultValue) : "");
937
+ const attachFile = createAttachFile({
938
+ schema,
939
+ generateMetadata: options.attachFile?.generateMetadata,
940
+ uploadFile: options.attachFile?.uploadFile
941
+ });
942
+ const view = new import_prosemirror_view4.EditorView(container, {
943
+ ...editor,
944
+ attributes: (state2) => {
945
+ const propsAttributes = (() => {
946
+ if (typeof editor?.attributes === "function") {
947
+ return editor.attributes(state2);
948
+ }
949
+ return editor?.attributes;
950
+ })();
951
+ return {
952
+ ...propsAttributes,
953
+ class: cn(options?.className, propsAttributes?.class),
954
+ spellcheck: propsAttributes?.spellcheck || "false",
955
+ style: options.style || "width: 100%; height: inherit; outline: none;"
956
+ };
957
+ },
958
+ state: import_prosemirror_state5.EditorState.create({
959
+ ...state,
960
+ schema: state?.schema || schema,
961
+ doc: state?.doc || prosemirrorParser.parse(wrapper),
962
+ plugins: [
963
+ ...state?.plugins || [],
964
+ (0, import_prosemirror_history2.history)({
965
+ newGroupDelay: updateDelay
966
+ }),
967
+ (0, import_prosemirror_keymap.keymap)(buildKeymap(schema)),
968
+ (0, import_prosemirror_keymap.keymap)(commands2.baseKeymap),
969
+ uploadPlaceholderPlugin,
970
+ dragAndDropPlugin({
971
+ attachFile
972
+ }),
973
+ placeholder && placeholderPlugin(placeholder)
974
+ ].filter((e) => !!e)
975
+ }),
976
+ dispatchTransaction(tr) {
977
+ let result;
978
+ if (editor?.dispatchTransaction) {
979
+ result = editor.dispatchTransaction(tr);
980
+ } else {
981
+ view.updateState(view.state.apply(tr));
982
+ }
983
+ subject.next(tr);
984
+ return result;
985
+ }
986
+ });
987
+ function setValue(value) {
988
+ const wrap = document.createElement("div");
989
+ wrap.innerHTML = toInnerHTML(value);
990
+ const doc = prosemirrorParser.parse(wrap);
991
+ const tr = view.state.tr.replaceWith(
992
+ 0,
993
+ view.state.doc.content.size,
994
+ doc.content
995
+ );
996
+ view.dispatch(tr);
997
+ }
998
+ function toHTML() {
999
+ const fragment = prosemirrorSerializer.serializeFragment(
1000
+ view.state.doc.content
1001
+ );
1002
+ const container2 = document.createElement("div");
1003
+ container2.appendChild(fragment);
1004
+ return container2.innerHTML;
1005
+ }
1006
+ function toTextContent() {
1007
+ const state2 = view.state;
1008
+ return state2.doc.textBetween(0, state2.doc.content.size, "\n");
1009
+ }
1010
+ const textEditorCommands = createCommands(schema, view, {
1011
+ attachFile
1012
+ });
1013
+ const textEditorController = {
1014
+ schema,
1015
+ view,
1016
+ subject,
1017
+ set value(value) {
1018
+ setValue(value);
1019
+ },
1020
+ get value() {
1021
+ switch (mode) {
1022
+ case "text":
1023
+ return toTextContent();
1024
+ default:
1025
+ return toHTML();
1026
+ }
1027
+ },
1028
+ commands: textEditorCommands
1029
+ };
1030
+ return textEditorController;
1031
+ }
1032
+
1033
+ // src/create_text_editor.tsx
1034
+ function createTextEditor(options = {}) {
1035
+ const schema = createSchema();
1036
+ function Component({
1037
+ ref,
1038
+ className,
1039
+ autoFocus,
1040
+ placeholder,
1041
+ defaultValue,
1042
+ onChange,
1043
+ updateDelay,
1044
+ ...props
1045
+ } = {}) {
1046
+ const containerRef = (0, import_react3.useRef)(null);
1047
+ const controllerRef = (0, import_react3.useRef)(null);
1048
+ (0, import_react2.useImperativeHandle)(ref, () => {
1049
+ const container = containerRef.current;
1050
+ const textEditorController = createTextEditorController(
1051
+ container,
1052
+ schema,
1053
+ options,
1054
+ props
1055
+ );
1056
+ controllerRef.current = textEditorController;
1057
+ return textEditorController;
1058
+ });
1059
+ (0, import_react3.useEffect)(() => {
1060
+ const controller = controllerRef.current;
1061
+ if (!controller) {
1062
+ return;
1063
+ }
1064
+ if (autoFocus) {
1065
+ controller.view.focus();
1066
+ }
1067
+ }, []);
1068
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("div", { ...props, ref: containerRef, className }), /* @__PURE__ */ import_react2.default.createElement(
1069
+ TextEditorInput,
1070
+ {
1071
+ ref: controllerRef,
1072
+ updateDelay,
1073
+ onChange
1074
+ }
1075
+ ));
1076
+ }
1077
+ return Component;
1078
+ }
1079
+ // Annotate the CommonJS export names for ESM import in node:
1080
+ 0 && (module.exports = {
1081
+ createTextEditor
1082
+ });