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