dn-react-text-editor 0.1.2 → 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.
- package/README.md +19 -0
- package/dist/attach_file.d.mts +20 -22
- package/dist/attach_file.d.ts +20 -22
- package/dist/attach_file.js +5 -5
- package/dist/attach_file.mjs +5 -4
- package/dist/base64_file_uploader.d.mts +6 -0
- package/dist/base64_file_uploader.d.ts +6 -0
- package/dist/{plugins/trailing_paragraph.js → base64_file_uploader.js} +19 -22
- package/dist/base64_file_uploader.mjs +18 -0
- package/dist/commands.d.mts +23 -0
- package/dist/commands.d.ts +23 -0
- package/dist/commands.js +110 -0
- package/dist/commands.mjs +75 -0
- package/dist/create_text_editor.d.mts +28 -0
- package/dist/create_text_editor.d.ts +28 -0
- package/dist/create_text_editor.js +1082 -0
- package/dist/create_text_editor.mjs +1053 -0
- package/dist/html.d.mts +8 -0
- package/dist/html.d.ts +8 -0
- package/dist/html.js +136 -0
- package/dist/html.mjs +98 -0
- package/dist/index.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +770 -364
- package/dist/index.mjs +765 -359
- package/dist/input.d.mts +21 -0
- package/dist/input.d.ts +21 -0
- package/dist/input.js +70 -0
- package/dist/input.mjs +37 -0
- package/dist/plugins/drag_and_drop.d.mts +1 -1
- package/dist/plugins/drag_and_drop.d.ts +1 -1
- package/dist/plugins/drag_and_drop.js +3 -0
- package/dist/plugins/drag_and_drop.mjs +3 -0
- package/dist/plugins/highlighter.d.mts +6 -0
- package/dist/plugins/highlighter.d.ts +6 -0
- package/dist/plugins/highlighter.js +105 -0
- package/dist/plugins/highlighter.mjs +69 -0
- package/dist/plugins/keymap.js +17 -0
- package/dist/plugins/keymap.mjs +17 -0
- package/dist/schema.d.mts +2 -2
- package/dist/schema.d.ts +2 -2
- package/dist/schema.js +255 -14
- package/dist/schema.mjs +245 -14
- package/dist/text_editor_controller.d.mts +46 -0
- package/dist/text_editor_controller.d.ts +46 -0
- package/dist/text_editor_controller.js +503 -0
- package/dist/text_editor_controller.mjs +470 -0
- package/package.json +3 -1
- package/dist/plugins/trailing_paragraph.d.mts +0 -5
- package/dist/plugins/trailing_paragraph.d.ts +0 -5
- package/dist/plugins/trailing_paragraph.mjs +0 -21
- package/dist/text_editor.d.mts +0 -37
- package/dist/text_editor.d.ts +0 -37
- package/dist/text_editor.js +0 -722
- package/dist/text_editor.mjs +0 -692
package/dist/index.js
CHANGED
|
@@ -30,185 +30,93 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
base64ImageUploader: () => base64ImageUploader,
|
|
34
33
|
createAttachFile: () => createAttachFile,
|
|
34
|
+
createInnerHTML: () => createInnerHTML,
|
|
35
35
|
createSchema: () => createSchema,
|
|
36
|
-
createTextEditor: () => createTextEditor
|
|
36
|
+
createTextEditor: () => createTextEditor,
|
|
37
|
+
createTextEditorView: () => createTextEditorView
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(index_exports);
|
|
39
40
|
|
|
40
|
-
// src/
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
var import_prosemirror_commands2 = require("prosemirror-commands");
|
|
46
|
-
var import_prosemirror_keymap = require("prosemirror-keymap");
|
|
47
|
-
|
|
48
|
-
// src/plugins/drag_and_drop.tsx
|
|
49
|
-
var import_prosemirror_state = require("prosemirror-state");
|
|
50
|
-
function dragAndDropPlugin({ attachFile }) {
|
|
51
|
-
return new import_prosemirror_state.Plugin({
|
|
52
|
-
props: {
|
|
53
|
-
handleDOMEvents: {
|
|
54
|
-
drop(view, event) {
|
|
55
|
-
const files = event.dataTransfer?.files;
|
|
56
|
-
if (!files || files.length === 0) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
event.preventDefault();
|
|
60
|
-
const pos = view.state.selection.$from.pos || view.posAtCoords({
|
|
61
|
-
left: event.clientX,
|
|
62
|
-
top: event.clientY
|
|
63
|
-
})?.pos || null;
|
|
64
|
-
if (pos === null) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const medias = Array.from(files).filter(
|
|
68
|
-
(file) => file.type.startsWith("image/") || file.type.startsWith("video/")
|
|
69
|
-
);
|
|
70
|
-
attachFile(view, medias);
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/plugins/upload_placeholder.tsx
|
|
79
|
-
var import_prosemirror_state2 = require("prosemirror-state");
|
|
80
|
-
var import_prosemirror_view = require("prosemirror-view");
|
|
81
|
-
var uploadPlaceholderPlugin = new import_prosemirror_state2.Plugin({
|
|
82
|
-
state: {
|
|
83
|
-
init() {
|
|
84
|
-
return import_prosemirror_view.DecorationSet.empty;
|
|
85
|
-
},
|
|
86
|
-
apply(tr, set) {
|
|
87
|
-
set = set.map(tr.mapping, tr.doc);
|
|
88
|
-
const action = tr.getMeta(this);
|
|
89
|
-
if (action && action.add) {
|
|
90
|
-
const { type, width, height } = action.add;
|
|
91
|
-
const widget = document.createElement("div");
|
|
92
|
-
widget.className = "upload-placeholder";
|
|
93
|
-
widget.style.width = `100%`;
|
|
94
|
-
if (type.startsWith("image/") || type.startsWith("video/")) {
|
|
95
|
-
widget.style.aspectRatio = `${width} / ${height}`;
|
|
96
|
-
widget.style.maxWidth = `${width}px`;
|
|
97
|
-
} else {
|
|
98
|
-
widget.style.height = "80px";
|
|
99
|
-
}
|
|
100
|
-
const progress = document.createElement("div");
|
|
101
|
-
progress.className = "upload-progress";
|
|
102
|
-
widget.appendChild(progress);
|
|
103
|
-
const deco = import_prosemirror_view.Decoration.widget(action.add.pos, widget, {
|
|
104
|
-
id: action.add.id
|
|
105
|
-
});
|
|
106
|
-
set = set.add(tr.doc, [deco]);
|
|
107
|
-
} else if (action && action.progress) {
|
|
108
|
-
const found = set.find(
|
|
109
|
-
void 0,
|
|
110
|
-
void 0,
|
|
111
|
-
(spec) => spec.id === action.progress.id
|
|
112
|
-
);
|
|
113
|
-
if (found.length) {
|
|
114
|
-
const widget = found[0].type.toDOM;
|
|
115
|
-
const progress = widget.querySelector(".upload-progress");
|
|
116
|
-
if (progress) {
|
|
117
|
-
progress.innerHTML = `${Math.round(action.progress.progress)}%`;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
} else if (action && action.remove) {
|
|
121
|
-
set = set.remove(
|
|
122
|
-
set.find(void 0, void 0, (spec) => spec.id === action.remove.id)
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
return set;
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
props: {
|
|
129
|
-
decorations(state) {
|
|
130
|
-
return this.getState(state);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
var findPlaceholder = (state, id) => {
|
|
135
|
-
const decos = uploadPlaceholderPlugin.getState(state);
|
|
136
|
-
if (!decos) {
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
const found = decos.find(void 0, void 0, (spec) => spec.id === id);
|
|
140
|
-
return found.length ? found[0].from : null;
|
|
141
|
-
};
|
|
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");
|
|
142
46
|
|
|
143
|
-
// src/
|
|
47
|
+
// src/schema.tsx
|
|
144
48
|
var import_prosemirror_model = require("prosemirror-model");
|
|
145
|
-
var import_prosemirror_state3 = require("prosemirror-state");
|
|
146
|
-
var import_prosemirror_view2 = require("prosemirror-view");
|
|
147
|
-
var getFirstChildDescendants = (view) => {
|
|
148
|
-
const nodes = [];
|
|
149
|
-
view.state.doc?.descendants((n) => {
|
|
150
|
-
nodes.push(n);
|
|
151
|
-
});
|
|
152
|
-
return nodes;
|
|
153
|
-
};
|
|
154
|
-
function placeholderPlugin(text) {
|
|
155
|
-
const update = (view) => {
|
|
156
|
-
const decos = uploadPlaceholderPlugin.getState(view.state);
|
|
157
|
-
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) {
|
|
158
|
-
view.dom.removeAttribute("data-placeholder");
|
|
159
|
-
} else {
|
|
160
|
-
view.dom.setAttribute("data-placeholder", text);
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
return new import_prosemirror_state3.Plugin({
|
|
164
|
-
view(view) {
|
|
165
|
-
update(view);
|
|
166
|
-
return { update };
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// src/text_editor.tsx
|
|
172
|
-
var import_prosemirror_model3 = require("prosemirror-model");
|
|
173
|
-
var import_prosemirror_history2 = require("prosemirror-history");
|
|
174
|
-
|
|
175
|
-
// src/plugins/keymap.tsx
|
|
176
|
-
var import_prosemirror_history = require("prosemirror-history");
|
|
177
|
-
var import_prosemirror_commands = require("prosemirror-commands");
|
|
178
49
|
var import_prosemirror_schema_list = require("prosemirror-schema-list");
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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;
|
|
206
116
|
|
|
207
117
|
// src/schema.tsx
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
function createSchema() {
|
|
211
|
-
const customSchema = new import_prosemirror_model2.Schema({
|
|
118
|
+
function createSchema(spec = { nodes: {}, marks: {} }) {
|
|
119
|
+
const customSchema = new import_prosemirror_model.Schema({
|
|
212
120
|
nodes: {
|
|
213
121
|
doc: { content: "block+" },
|
|
214
122
|
paragraph: {
|
|
@@ -373,70 +281,235 @@ function createSchema() {
|
|
|
373
281
|
}
|
|
374
282
|
];
|
|
375
283
|
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
284
|
+
},
|
|
285
|
+
video: {
|
|
286
|
+
inline: false,
|
|
287
|
+
group: "block",
|
|
288
|
+
draggable: true,
|
|
380
289
|
attrs: {
|
|
381
|
-
|
|
382
|
-
title: {
|
|
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
|
+
}
|
|
383
307
|
},
|
|
384
|
-
inclusive: false,
|
|
385
308
|
parseDOM: [
|
|
386
309
|
{
|
|
387
|
-
tag: "
|
|
310
|
+
tag: "video",
|
|
388
311
|
getAttrs(dom) {
|
|
389
312
|
return {
|
|
390
|
-
|
|
391
|
-
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")
|
|
392
318
|
};
|
|
393
319
|
}
|
|
394
320
|
}
|
|
395
321
|
],
|
|
396
322
|
toDOM(node) {
|
|
397
|
-
const {
|
|
398
|
-
const target = "_blank";
|
|
399
|
-
const rel = "noopener noreferrer";
|
|
323
|
+
const { src, title, width, height, poster } = node.attrs;
|
|
400
324
|
return [
|
|
401
|
-
"
|
|
402
|
-
{
|
|
403
|
-
|
|
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
|
+
}
|
|
404
336
|
];
|
|
405
337
|
}
|
|
406
338
|
},
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
339
|
+
iframe: {
|
|
340
|
+
group: "block",
|
|
341
|
+
draggable: true,
|
|
342
|
+
attrs: {
|
|
343
|
+
src: { validate: "string" },
|
|
344
|
+
title: {
|
|
345
|
+
default: null,
|
|
346
|
+
validate: "string|null"
|
|
413
347
|
},
|
|
414
|
-
{
|
|
415
|
-
|
|
416
|
-
|
|
348
|
+
width: {
|
|
349
|
+
default: null,
|
|
350
|
+
validate: "number|null"
|
|
417
351
|
},
|
|
418
|
-
{
|
|
419
|
-
|
|
420
|
-
|
|
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"
|
|
421
371
|
}
|
|
422
|
-
|
|
423
|
-
toDOM() {
|
|
424
|
-
return ["strong", 0];
|
|
425
|
-
}
|
|
426
|
-
},
|
|
427
|
-
italic: {
|
|
372
|
+
},
|
|
428
373
|
parseDOM: [
|
|
429
|
-
{ tag: "em" },
|
|
430
|
-
{ tag: "i" },
|
|
431
|
-
{ style: "font-style=italic" },
|
|
432
374
|
{
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
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
|
+
}
|
|
440
513
|
},
|
|
441
514
|
underline: {
|
|
442
515
|
parseDOM: [
|
|
@@ -449,22 +522,310 @@ function createSchema() {
|
|
|
449
522
|
toDOM() {
|
|
450
523
|
return ["u", 0];
|
|
451
524
|
}
|
|
452
|
-
}
|
|
453
|
-
|
|
525
|
+
},
|
|
526
|
+
...spec.marks
|
|
527
|
+
},
|
|
528
|
+
topNode: spec.topNode
|
|
454
529
|
});
|
|
455
|
-
const prosemirrorSchema = new
|
|
456
|
-
nodes: (0,
|
|
457
|
-
customSchema.spec.nodes,
|
|
458
|
-
"paragraph block*",
|
|
459
|
-
"block"
|
|
460
|
-
),
|
|
530
|
+
const prosemirrorSchema = new import_prosemirror_model.Schema({
|
|
531
|
+
nodes: (0, import_prosemirror_schema_list.addListNodes)(customSchema.spec.nodes, "paragraph block*", "block"),
|
|
461
532
|
marks: customSchema.spec.marks
|
|
462
533
|
});
|
|
463
534
|
return prosemirrorSchema;
|
|
464
535
|
}
|
|
465
536
|
|
|
466
|
-
// src/
|
|
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"));
|
|
467
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
|
+
}
|
|
468
829
|
|
|
469
830
|
// src/cn.ts
|
|
470
831
|
function cn(...classes) {
|
|
@@ -473,7 +834,9 @@ function cn(...classes) {
|
|
|
473
834
|
|
|
474
835
|
// src/attach_file.tsx
|
|
475
836
|
var import_prosemirror_view3 = require("prosemirror-view");
|
|
476
|
-
|
|
837
|
+
|
|
838
|
+
// src/base64_file_uploader.ts
|
|
839
|
+
var base64FileUploader = async (file) => {
|
|
477
840
|
const base64 = await new Promise((resolve, reject) => {
|
|
478
841
|
const reader = new FileReader();
|
|
479
842
|
reader.onload = () => {
|
|
@@ -487,10 +850,12 @@ var base64ImageUploader = async (file) => {
|
|
|
487
850
|
alt: file.name
|
|
488
851
|
};
|
|
489
852
|
};
|
|
853
|
+
|
|
854
|
+
// src/attach_file.tsx
|
|
490
855
|
function createAttachFile({
|
|
491
856
|
schema,
|
|
492
857
|
generateMetadata,
|
|
493
|
-
uploadFile =
|
|
858
|
+
uploadFile = base64FileUploader
|
|
494
859
|
}) {
|
|
495
860
|
const attachEachFile = async (view, file, pos) => {
|
|
496
861
|
const metadata = generateMetadata ? await generateMetadata(file) : {};
|
|
@@ -553,178 +918,219 @@ function createAttachFile({
|
|
|
553
918
|
};
|
|
554
919
|
}
|
|
555
920
|
|
|
556
|
-
// src/
|
|
557
|
-
|
|
558
|
-
|
|
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();
|
|
559
933
|
const prosemirrorParser = import_prosemirror_model3.DOMParser.fromSchema(schema);
|
|
560
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) : "");
|
|
561
943
|
const attachFile = createAttachFile({
|
|
562
944
|
schema,
|
|
563
945
|
generateMetadata: options.attachFile?.generateMetadata,
|
|
564
946
|
uploadFile: options.attachFile?.uploadFile
|
|
565
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();
|
|
566
1042
|
function Component({
|
|
567
1043
|
ref,
|
|
568
|
-
|
|
569
|
-
editor,
|
|
570
|
-
mode = "html",
|
|
571
|
-
container,
|
|
1044
|
+
className,
|
|
572
1045
|
autoFocus,
|
|
573
|
-
name,
|
|
574
1046
|
placeholder,
|
|
575
|
-
className,
|
|
576
1047
|
defaultValue,
|
|
577
|
-
onClick,
|
|
578
1048
|
onChange,
|
|
579
|
-
updateDelay
|
|
1049
|
+
updateDelay,
|
|
580
1050
|
...props
|
|
581
1051
|
} = {}) {
|
|
582
|
-
const containerRef = (0,
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
const toInnerHTML = (value) => {
|
|
589
|
-
if (mode === "html") {
|
|
590
|
-
return value;
|
|
591
|
-
}
|
|
592
|
-
return value.split("\n").map((line) => `<p>${line}</p>`).join("");
|
|
593
|
-
};
|
|
594
|
-
wrapper.innerHTML = toInnerHTML(defaultValue ? String(defaultValue) : "");
|
|
595
|
-
const view = new import_prosemirror_view4.EditorView(containerRef.current, {
|
|
596
|
-
...editor,
|
|
597
|
-
attributes: (state2) => {
|
|
598
|
-
const propsAttributes = (() => {
|
|
599
|
-
if (typeof editor?.attributes === "function") {
|
|
600
|
-
return editor.attributes(state2);
|
|
601
|
-
}
|
|
602
|
-
return editor?.attributes;
|
|
603
|
-
})();
|
|
604
|
-
return {
|
|
605
|
-
...propsAttributes,
|
|
606
|
-
class: cn(propsAttributes?.class, className),
|
|
607
|
-
spellcheck: propsAttributes?.spellcheck || "false"
|
|
608
|
-
};
|
|
609
|
-
},
|
|
610
|
-
state: import_prosemirror_state4.EditorState.create({
|
|
611
|
-
...state,
|
|
612
|
-
schema: state?.schema || schema,
|
|
613
|
-
doc: state?.doc || prosemirrorParser.parse(wrapper),
|
|
614
|
-
plugins: [
|
|
615
|
-
...state?.plugins || [],
|
|
616
|
-
(0, import_prosemirror_history2.history)({
|
|
617
|
-
newGroupDelay: updateDelay
|
|
618
|
-
}),
|
|
619
|
-
(0, import_prosemirror_keymap.keymap)(buildKeymap(schema)),
|
|
620
|
-
(0, import_prosemirror_keymap.keymap)(import_prosemirror_commands2.baseKeymap),
|
|
621
|
-
uploadPlaceholderPlugin,
|
|
622
|
-
attachFile ? dragAndDropPlugin({
|
|
623
|
-
attachFile
|
|
624
|
-
}) : null,
|
|
625
|
-
placeholder && placeholderPlugin(placeholder)
|
|
626
|
-
].filter((e) => !!e)
|
|
627
|
-
}),
|
|
628
|
-
dispatchTransaction(tr) {
|
|
629
|
-
let result;
|
|
630
|
-
if (editor?.dispatchTransaction) {
|
|
631
|
-
result = editor.dispatchTransaction(tr);
|
|
632
|
-
} else {
|
|
633
|
-
view.updateState(view.state.apply(tr));
|
|
634
|
-
}
|
|
635
|
-
subject.next(tr);
|
|
636
|
-
return result;
|
|
637
|
-
}
|
|
638
|
-
});
|
|
639
|
-
function setValue(value) {
|
|
640
|
-
const wrap = document.createElement("div");
|
|
641
|
-
wrap.innerHTML = toInnerHTML(value);
|
|
642
|
-
const doc = prosemirrorParser.parse(wrap);
|
|
643
|
-
const tr = view.state.tr.replaceWith(
|
|
644
|
-
0,
|
|
645
|
-
view.state.doc.content.size,
|
|
646
|
-
doc.content
|
|
647
|
-
);
|
|
648
|
-
view.dispatch(tr);
|
|
649
|
-
}
|
|
650
|
-
function clear() {
|
|
651
|
-
const tr = view.state.tr.replaceWith(
|
|
652
|
-
0,
|
|
653
|
-
view.state.doc.content.size,
|
|
654
|
-
schema.nodes.doc.createAndFill()
|
|
655
|
-
);
|
|
656
|
-
view.dispatch(tr);
|
|
657
|
-
}
|
|
658
|
-
function toHTML() {
|
|
659
|
-
const fragment = prosemirrorSerializer.serializeFragment(
|
|
660
|
-
view.state.doc.content
|
|
661
|
-
);
|
|
662
|
-
const container2 = document.createElement("div");
|
|
663
|
-
container2.appendChild(fragment);
|
|
664
|
-
return container2.innerHTML;
|
|
665
|
-
}
|
|
666
|
-
function toTextContent() {
|
|
667
|
-
const state2 = view.state;
|
|
668
|
-
return state2.doc.textBetween(0, state2.doc.content.size, "\n");
|
|
669
|
-
}
|
|
670
|
-
if (autoFocus) {
|
|
671
|
-
view.focus();
|
|
672
|
-
}
|
|
673
|
-
const textEditorController = {
|
|
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,
|
|
674
1058
|
schema,
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
setValue(value);
|
|
679
|
-
},
|
|
680
|
-
get value() {
|
|
681
|
-
switch (mode) {
|
|
682
|
-
case "text":
|
|
683
|
-
return toTextContent();
|
|
684
|
-
default:
|
|
685
|
-
return toHTML();
|
|
686
|
-
}
|
|
687
|
-
},
|
|
688
|
-
clear
|
|
689
|
-
};
|
|
1059
|
+
options,
|
|
1060
|
+
props
|
|
1061
|
+
);
|
|
690
1062
|
controllerRef.current = textEditorController;
|
|
691
1063
|
return textEditorController;
|
|
692
1064
|
});
|
|
693
|
-
(0,
|
|
1065
|
+
(0, import_react3.useEffect)(() => {
|
|
694
1066
|
const controller = controllerRef.current;
|
|
695
1067
|
if (!controller) {
|
|
696
1068
|
return;
|
|
697
1069
|
}
|
|
698
|
-
const sub = controller.subject.pipe(
|
|
699
|
-
(0, import_rxjs.filter)((tr) => tr.docChanged),
|
|
700
|
-
(0, import_rxjs.debounceTime)(updateDelay)
|
|
701
|
-
).subscribe(() => {
|
|
702
|
-
if (inputRef.current) {
|
|
703
|
-
inputRef.current.value = controller.value;
|
|
704
|
-
const event = new Event("input", { bubbles: true });
|
|
705
|
-
inputRef.current.dispatchEvent(event);
|
|
706
|
-
}
|
|
707
|
-
});
|
|
708
1070
|
if (autoFocus) {
|
|
709
1071
|
controller.view.focus();
|
|
710
1072
|
}
|
|
711
|
-
return () => {
|
|
712
|
-
sub.unsubscribe();
|
|
713
|
-
controller.view.destroy();
|
|
714
|
-
};
|
|
715
1073
|
}, []);
|
|
716
|
-
return /* @__PURE__ */
|
|
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
|
|
1080
|
+
}
|
|
1081
|
+
));
|
|
717
1082
|
}
|
|
718
|
-
return
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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>`;
|
|
1100
|
+
}
|
|
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
|
+
)
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
);
|
|
722
1127
|
};
|
|
723
1128
|
}
|
|
724
1129
|
// Annotate the CommonJS export names for ESM import in node:
|
|
725
1130
|
0 && (module.exports = {
|
|
726
|
-
base64ImageUploader,
|
|
727
1131
|
createAttachFile,
|
|
1132
|
+
createInnerHTML,
|
|
728
1133
|
createSchema,
|
|
729
|
-
createTextEditor
|
|
1134
|
+
createTextEditor,
|
|
1135
|
+
createTextEditorView
|
|
730
1136
|
});
|