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.
- package/README.md +14 -214
- package/dist/attach_file.d.mts +20 -18
- package/dist/attach_file.d.ts +20 -18
- package/dist/attach_file.js +18 -9
- package/dist/attach_file.mjs +18 -9
- 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 +790 -380
- package/dist/index.mjs +789 -377
- 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 -720
- 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/
|
|
40
|
-
var
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
208
|
-
|
|
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
|
-
|
|
378
|
-
|
|
284
|
+
},
|
|
285
|
+
video: {
|
|
286
|
+
inline: false,
|
|
287
|
+
group: "block",
|
|
288
|
+
draggable: true,
|
|
379
289
|
attrs: {
|
|
380
|
-
|
|
381
|
-
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
|
+
}
|
|
382
307
|
},
|
|
383
|
-
inclusive: false,
|
|
384
308
|
parseDOM: [
|
|
385
309
|
{
|
|
386
|
-
tag: "
|
|
310
|
+
tag: "video",
|
|
387
311
|
getAttrs(dom) {
|
|
388
312
|
return {
|
|
389
|
-
|
|
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 {
|
|
397
|
-
const target = "_blank";
|
|
398
|
-
const rel = "noopener noreferrer";
|
|
323
|
+
const { src, title, width, height, poster } = node.attrs;
|
|
399
324
|
return [
|
|
400
|
-
"
|
|
401
|
-
{
|
|
402
|
-
|
|
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
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
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
|
-
|
|
415
|
-
|
|
348
|
+
width: {
|
|
349
|
+
default: null,
|
|
350
|
+
validate: "number|null"
|
|
416
351
|
},
|
|
417
|
-
{
|
|
418
|
-
|
|
419
|
-
|
|
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
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
|
455
|
-
nodes: (0,
|
|
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/
|
|
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 =
|
|
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/
|
|
549
|
-
|
|
550
|
-
|
|
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
|
-
|
|
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
|
|
1049
|
+
updateDelay,
|
|
572
1050
|
...props
|
|
573
1051
|
} = {}) {
|
|
574
|
-
const containerRef = (0,
|
|
575
|
-
const
|
|
576
|
-
(0, import_react2.
|
|
577
|
-
const
|
|
578
|
-
|
|
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
|
-
|
|
582
|
-
|
|
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
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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
|
-
|
|
662
|
-
|
|
663
|
-
|
|
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
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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
|
-
|
|
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
|
});
|