react-headless-mde 1.0.3 → 2.0.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 +32 -11
- package/dist/cjs/index.js +344 -484
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +324 -463
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +92 -77
- package/package.json +2 -3
package/dist/esm/index.js
CHANGED
|
@@ -1,74 +1,25 @@
|
|
|
1
1
|
import { useRef, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
class CommandController {
|
|
4
|
+
constructor(textController, commandMap) {
|
|
5
5
|
this.textController = textController;
|
|
6
|
+
this.commandMap = commandMap;
|
|
6
7
|
}
|
|
7
|
-
|
|
8
|
+
executeCommand(commandName) {
|
|
8
9
|
var _a;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
if (command.undo && ((_a = command.shouldUndo) === null || _a === void 0 ? void 0 : _a.call(command,
|
|
14
|
-
command.undo(
|
|
10
|
+
const command = this.commandMap[commandName];
|
|
11
|
+
if (!command) {
|
|
12
|
+
throw new Error(`Cannot execute command. Command not found: ${commandName}`);
|
|
13
|
+
}
|
|
14
|
+
if (command.undo && ((_a = command.shouldUndo) === null || _a === void 0 ? void 0 : _a.call(command, this.textController))) {
|
|
15
|
+
command.undo(this.textController);
|
|
15
16
|
}
|
|
16
17
|
else {
|
|
17
|
-
command.
|
|
18
|
+
command.do(this.textController);
|
|
18
19
|
}
|
|
19
|
-
};
|
|
20
|
-
return CommandController;
|
|
21
|
-
}());
|
|
22
|
-
|
|
23
|
-
var TextAreaTextController = /** @class */ (function () {
|
|
24
|
-
function TextAreaTextController(textAreaRef) {
|
|
25
|
-
this.textAreaRef = textAreaRef;
|
|
26
20
|
}
|
|
27
|
-
TextAreaTextController.prototype.getTextArea = function () {
|
|
28
|
-
var textArea = this.textAreaRef.current;
|
|
29
|
-
if (!textArea) {
|
|
30
|
-
throw new Error('TextAreaRef is not set');
|
|
31
|
-
}
|
|
32
|
-
return textArea;
|
|
33
|
-
};
|
|
34
|
-
TextAreaTextController.prototype.setSelection = function (selection) {
|
|
35
|
-
var textArea = this.getTextArea();
|
|
36
|
-
textArea.focus();
|
|
37
|
-
textArea.selectionStart = selection.start;
|
|
38
|
-
textArea.selectionEnd = selection.end;
|
|
39
|
-
return getStateFromTextArea(textArea);
|
|
40
|
-
};
|
|
41
|
-
TextAreaTextController.prototype.replaceSelection = function (text) {
|
|
42
|
-
var textArea = this.getTextArea();
|
|
43
|
-
insertText(textArea, text);
|
|
44
|
-
return getStateFromTextArea(textArea);
|
|
45
|
-
};
|
|
46
|
-
TextAreaTextController.prototype.replaceText = function (text, newText) {
|
|
47
|
-
var textArea = this.getTextArea();
|
|
48
|
-
textArea.value = textArea.value.replace(text, newText);
|
|
49
|
-
return getStateFromTextArea(textArea);
|
|
50
|
-
};
|
|
51
|
-
TextAreaTextController.prototype.getState = function () {
|
|
52
|
-
var textArea = this.getTextArea();
|
|
53
|
-
return getStateFromTextArea(textArea);
|
|
54
|
-
};
|
|
55
|
-
TextAreaTextController.prototype.moveCursorToTheEnd = function () {
|
|
56
|
-
var textArea = this.getTextArea();
|
|
57
|
-
textArea.focus();
|
|
58
|
-
textArea.selectionEnd = textArea.selectionStart = textArea.value.length;
|
|
59
|
-
return getStateFromTextArea(textArea);
|
|
60
|
-
};
|
|
61
|
-
return TextAreaTextController;
|
|
62
|
-
}());
|
|
63
|
-
function getStateFromTextArea(textArea) {
|
|
64
|
-
return {
|
|
65
|
-
selection: {
|
|
66
|
-
start: textArea.selectionStart,
|
|
67
|
-
end: textArea.selectionEnd,
|
|
68
|
-
},
|
|
69
|
-
text: textArea.value,
|
|
70
|
-
};
|
|
71
21
|
}
|
|
22
|
+
|
|
72
23
|
/**
|
|
73
24
|
* Inserts the given text at the cursor. If the element contains a selection, the selection
|
|
74
25
|
* will be replaced by the text.
|
|
@@ -76,13 +27,13 @@ function getStateFromTextArea(textArea) {
|
|
|
76
27
|
* Copyright (c) 2018 Dmitriy Kubyshkin
|
|
77
28
|
* Copied from https://github.com/grassator/insert-text-at-cursor
|
|
78
29
|
*/
|
|
79
|
-
function
|
|
30
|
+
function insertToSelection(input, text) {
|
|
80
31
|
var _a, _b, _c, _d;
|
|
81
32
|
// Most of the used APIs only work with the field selected
|
|
82
33
|
input.focus();
|
|
83
34
|
// IE 8-10
|
|
84
35
|
if (document.selection) {
|
|
85
|
-
|
|
36
|
+
const ieRange = document.selection.createRange();
|
|
86
37
|
ieRange.text = text;
|
|
87
38
|
// Move cursor after the inserted text
|
|
88
39
|
ieRange.collapse(false /* to the end */);
|
|
@@ -90,31 +41,31 @@ function insertText(input, text) {
|
|
|
90
41
|
return;
|
|
91
42
|
}
|
|
92
43
|
// Webkit + Edge
|
|
93
|
-
|
|
44
|
+
const isSuccess = document.execCommand('insertText', false, text);
|
|
94
45
|
if (!isSuccess) {
|
|
95
|
-
|
|
96
|
-
|
|
46
|
+
const start = (_a = input.selectionStart) !== null && _a !== void 0 ? _a : 0;
|
|
47
|
+
const end = (_b = input.selectionEnd) !== null && _b !== void 0 ? _b : 0;
|
|
97
48
|
// Firefox (non-standard method)
|
|
98
49
|
if (typeof input.setRangeText === 'function') {
|
|
99
50
|
input.setRangeText(text);
|
|
100
51
|
}
|
|
101
52
|
else {
|
|
102
53
|
if (canManipulateViaTextNodes(input)) {
|
|
103
|
-
|
|
104
|
-
|
|
54
|
+
const textNode = document.createTextNode(text);
|
|
55
|
+
let node = input.firstChild;
|
|
105
56
|
// If textarea is empty, just insert the text
|
|
106
57
|
if (!node) {
|
|
107
58
|
input.appendChild(textNode);
|
|
108
59
|
}
|
|
109
60
|
else {
|
|
110
61
|
// Otherwise, we need to find a nodes for start and end
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
62
|
+
let offset = 0;
|
|
63
|
+
let startNode = null;
|
|
64
|
+
let endNode = null;
|
|
114
65
|
// To make a change we just need a Range, not a Selection
|
|
115
|
-
|
|
66
|
+
const range = document.createRange();
|
|
116
67
|
while (node && (startNode === null || endNode === null)) {
|
|
117
|
-
|
|
68
|
+
const nodeLength = (_d = (_c = node.nodeValue) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0;
|
|
118
69
|
// if start of the selection falls into current node
|
|
119
70
|
if (start >= offset && start <= offset + nodeLength) {
|
|
120
71
|
range.setStart((startNode = node), start - offset);
|
|
@@ -137,14 +88,14 @@ function insertText(input, text) {
|
|
|
137
88
|
}
|
|
138
89
|
else {
|
|
139
90
|
// For the text input the only way is to replace the whole value :(
|
|
140
|
-
|
|
91
|
+
const value = input.value;
|
|
141
92
|
input.value = value.slice(0, start) + text + value.slice(end);
|
|
142
93
|
}
|
|
143
94
|
}
|
|
144
95
|
// Correct the cursor position to be at the end of the insertion
|
|
145
96
|
input.setSelectionRange(start + text.length, start + text.length);
|
|
146
97
|
// Notify any possible listeners of the change
|
|
147
|
-
|
|
98
|
+
const e = document.createEvent('UIEvent');
|
|
148
99
|
e.initEvent('input', true, false);
|
|
149
100
|
input.dispatchEvent(e);
|
|
150
101
|
}
|
|
@@ -158,117 +109,77 @@ function canManipulateViaTextNodes(input) {
|
|
|
158
109
|
if (input.nodeName !== 'TEXTAREA') {
|
|
159
110
|
return false;
|
|
160
111
|
}
|
|
161
|
-
|
|
112
|
+
let browserSupportsTextareaTextNodes;
|
|
162
113
|
if (typeof browserSupportsTextareaTextNodes === 'undefined') {
|
|
163
|
-
|
|
114
|
+
const textarea = document.createElement('textarea');
|
|
164
115
|
textarea.value = '1';
|
|
165
116
|
browserSupportsTextareaTextNodes = !!textarea.firstChild;
|
|
166
117
|
}
|
|
167
118
|
return browserSupportsTextareaTextNodes;
|
|
168
119
|
}
|
|
169
120
|
|
|
170
|
-
var CommandsService = /** @class */ (function () {
|
|
171
|
-
function CommandsService() {
|
|
172
|
-
this.commandController = null;
|
|
173
|
-
this.textController = null;
|
|
174
|
-
}
|
|
175
|
-
CommandsService.prototype.init = function (commandController, textController) {
|
|
176
|
-
this.commandController = commandController;
|
|
177
|
-
this.textController = textController;
|
|
178
|
-
};
|
|
179
|
-
CommandsService.prototype.createCommandFn = function (command) {
|
|
180
|
-
var _this = this;
|
|
181
|
-
return function (context) {
|
|
182
|
-
if (!_this.commandController) {
|
|
183
|
-
throw new Error('Cannot execute command. CommandsService is not initialized');
|
|
184
|
-
}
|
|
185
|
-
_this.commandController.executeCommand(command, context);
|
|
186
|
-
};
|
|
187
|
-
};
|
|
188
|
-
return CommandsService;
|
|
189
|
-
}());
|
|
190
|
-
var commandsService = new CommandsService();
|
|
191
|
-
|
|
192
|
-
function useTextAreaMarkdownEditor() {
|
|
193
|
-
var textAreaRef = useRef(null);
|
|
194
|
-
var textController = useMemo(function () {
|
|
195
|
-
var textAreaController = new TextAreaTextController(textAreaRef);
|
|
196
|
-
var commandController = new CommandController(textAreaController);
|
|
197
|
-
commandsService.init(commandController, textAreaController);
|
|
198
|
-
return textAreaController;
|
|
199
|
-
}, [textAreaRef]);
|
|
200
|
-
return {
|
|
201
|
-
textController: textController,
|
|
202
|
-
ref: textAreaRef,
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
|
|
206
121
|
// A list of helpers for manipulating Markdown text.
|
|
207
122
|
// These helpers do not interface with a textarea.
|
|
208
|
-
// Check if
|
|
209
|
-
//
|
|
123
|
+
// Check if char is "space" or "new line".
|
|
124
|
+
// Char is optional because we pass a char by index,
|
|
210
125
|
// and theoretically index can be outside the string range. See text[i - 1] and text[i].
|
|
211
|
-
|
|
212
|
-
|
|
126
|
+
const isWordDelimiter = (char) => !!char && (char === ' ' || char.charCodeAt(0) === 10);
|
|
127
|
+
const getSurroundingSelection = (text, position) => {
|
|
213
128
|
if (text.length === 0)
|
|
214
129
|
throw Error("Argument 'text' should be truthy");
|
|
215
130
|
// leftIndex is initialized to 0 because if selection is 0, it won't even enter the iteration
|
|
216
|
-
|
|
131
|
+
let start = 0;
|
|
217
132
|
// rightIndex is initialized to text.length because if selection is equal to text.length it won't even enter the interation
|
|
218
|
-
|
|
133
|
+
let end = text.length;
|
|
219
134
|
// iterate to the left
|
|
220
|
-
for (
|
|
135
|
+
for (let i = position; i - 1 > -1; i--) {
|
|
221
136
|
if (isWordDelimiter(text[i - 1])) {
|
|
222
137
|
start = i;
|
|
223
138
|
break;
|
|
224
139
|
}
|
|
225
140
|
}
|
|
226
141
|
// iterate to the right
|
|
227
|
-
for (
|
|
142
|
+
for (let i = position; i < text.length; i++) {
|
|
228
143
|
if (isWordDelimiter(text[i])) {
|
|
229
144
|
end = i;
|
|
230
145
|
break;
|
|
231
146
|
}
|
|
232
147
|
}
|
|
233
|
-
return { start
|
|
234
|
-
}
|
|
148
|
+
return { start, end };
|
|
149
|
+
};
|
|
235
150
|
// If the cursor is inside a word and (selection.start === selection.end)
|
|
236
151
|
// returns a new Selection where the whole word is selected
|
|
237
|
-
function
|
|
238
|
-
var text = _a.text, selection = _a.selection;
|
|
152
|
+
function getWordSelection({ text, selection }) {
|
|
239
153
|
if (text.length !== 0 && selection.start === selection.end) {
|
|
240
154
|
// the user is pointing to a word
|
|
241
|
-
return
|
|
155
|
+
return getSurroundingSelection(text, selection.start);
|
|
242
156
|
}
|
|
243
157
|
return selection;
|
|
244
158
|
}
|
|
245
|
-
//
|
|
246
|
-
|
|
247
|
-
function selectAfterWord(_a) {
|
|
248
|
-
var text = _a.text, selection = _a.selection;
|
|
159
|
+
// Returns a new Selection where (selection.start === selection.end) but the position is after word
|
|
160
|
+
function selectAfterWord({ text, selection }) {
|
|
249
161
|
if (text.length !== 0) {
|
|
250
162
|
// the user is pointing to a word
|
|
251
|
-
|
|
163
|
+
const { end } = getSurroundingSelection(text, selection.end);
|
|
252
164
|
return {
|
|
253
165
|
start: end,
|
|
254
|
-
end
|
|
166
|
+
end,
|
|
255
167
|
};
|
|
256
168
|
}
|
|
257
169
|
return selection;
|
|
258
170
|
}
|
|
259
171
|
// Gets the number of line-breaks that would have to be inserted before the given 'startPosition'
|
|
260
172
|
// to make sure there's an empty line between 'startPosition' and the previous text
|
|
261
|
-
function getBreaksNeededForEmptyLineBefore(text, startPosition) {
|
|
262
|
-
if (text === void 0) { text = ''; }
|
|
173
|
+
function getBreaksNeededForEmptyLineBefore(text = '', startPosition) {
|
|
263
174
|
if (startPosition === 0)
|
|
264
175
|
return 0;
|
|
265
|
-
//
|
|
176
|
+
// Rules:
|
|
266
177
|
// - If we're in the first line, no breaks are needed
|
|
267
178
|
// - Otherwise there must be 2 breaks before the previous character. Depending on how many breaks exist already, we
|
|
268
179
|
// may need to insert 0, 1 or 2 breaks
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
for (
|
|
180
|
+
let neededBreaks = 2;
|
|
181
|
+
let isInFirstLine = true;
|
|
182
|
+
for (let i = startPosition - 1; i >= 0 && neededBreaks >= 0; i--) {
|
|
272
183
|
switch (text.charCodeAt(i)) {
|
|
273
184
|
case 32: // blank space
|
|
274
185
|
continue;
|
|
@@ -284,17 +195,16 @@ function getBreaksNeededForEmptyLineBefore(text, startPosition) {
|
|
|
284
195
|
}
|
|
285
196
|
// Gets the number of line-breaks that would have to be inserted after the given 'startPosition'
|
|
286
197
|
// to make sure there's an empty line between 'startPosition' and the next text
|
|
287
|
-
function getBreaksNeededForEmptyLineAfter(text, startPosition) {
|
|
288
|
-
if (text === void 0) { text = ''; }
|
|
198
|
+
function getBreaksNeededForEmptyLineAfter(text = '', startPosition) {
|
|
289
199
|
if (startPosition === text.length - 1)
|
|
290
200
|
return 0;
|
|
291
|
-
//
|
|
201
|
+
// Rules:
|
|
292
202
|
// - If we're in the first line, no breaks are needed
|
|
293
203
|
// - Otherwise there must be 2 breaks before the previous character. Depending on how many breaks exist already, we
|
|
294
204
|
// may need to insert 0, 1 or 2 breaks
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
for (
|
|
205
|
+
let neededBreaks = 2;
|
|
206
|
+
let isInLastLine = true;
|
|
207
|
+
for (let i = startPosition; i < text.length && neededBreaks >= 0; i++) {
|
|
298
208
|
switch (text.charCodeAt(i)) {
|
|
299
209
|
case 32:
|
|
300
210
|
continue;
|
|
@@ -312,438 +222,389 @@ function getBreaksNeededForEmptyLineAfter(text, startPosition) {
|
|
|
312
222
|
function getSelectedText(textSection) {
|
|
313
223
|
return textSection.text.slice(textSection.selection.start, textSection.selection.end);
|
|
314
224
|
}
|
|
315
|
-
function
|
|
225
|
+
function getStringBeforeSelection(textState, characters) {
|
|
316
226
|
return textState.text.slice(textState.selection.start - characters, textState.selection.start);
|
|
317
227
|
}
|
|
318
|
-
function
|
|
228
|
+
function getStringAfterSelection(textState, characters) {
|
|
319
229
|
return textState.text.slice(textState.selection.end, textState.selection.end + characters);
|
|
320
230
|
}
|
|
321
231
|
// Inserts insertionString before each line
|
|
322
232
|
function insertBeforeEachLine(selectedText, insertBefore) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
.map(
|
|
233
|
+
const lines = selectedText.split(/\n/);
|
|
234
|
+
let insertionLength = 0;
|
|
235
|
+
const modifiedText = lines
|
|
236
|
+
.map((item, index) => {
|
|
327
237
|
if (typeof insertBefore === 'string') {
|
|
328
238
|
insertionLength += insertBefore.length;
|
|
329
239
|
return insertBefore + item;
|
|
330
240
|
}
|
|
331
241
|
else if (typeof insertBefore === 'function') {
|
|
332
|
-
|
|
242
|
+
const insertionResult = insertBefore(item, index);
|
|
333
243
|
insertionLength += insertionResult.length;
|
|
334
244
|
return insertBefore(item, index) + item;
|
|
335
245
|
}
|
|
336
246
|
throw Error('insertion is expected to be either a string or a function');
|
|
337
247
|
})
|
|
338
248
|
.join('\n');
|
|
339
|
-
return { modifiedText
|
|
249
|
+
return { modifiedText, insertionLength };
|
|
340
250
|
}
|
|
341
251
|
|
|
342
|
-
var
|
|
252
|
+
var selectionAndText = /*#__PURE__*/Object.freeze({
|
|
343
253
|
__proto__: null,
|
|
344
|
-
|
|
345
|
-
selectWord: selectWord,
|
|
254
|
+
getWordSelection: getWordSelection,
|
|
346
255
|
selectAfterWord: selectAfterWord,
|
|
347
256
|
getBreaksNeededForEmptyLineBefore: getBreaksNeededForEmptyLineBefore,
|
|
348
257
|
getBreaksNeededForEmptyLineAfter: getBreaksNeededForEmptyLineAfter,
|
|
349
258
|
getSelectedText: getSelectedText,
|
|
350
|
-
|
|
351
|
-
|
|
259
|
+
getStringBeforeSelection: getStringBeforeSelection,
|
|
260
|
+
getStringAfterSelection: getStringAfterSelection,
|
|
352
261
|
insertBeforeEachLine: insertBeforeEachLine
|
|
353
262
|
});
|
|
354
263
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
264
|
+
function getStateFromTextArea(textArea) {
|
|
265
|
+
return {
|
|
266
|
+
selection: {
|
|
267
|
+
start: textArea.selectionStart,
|
|
268
|
+
end: textArea.selectionEnd,
|
|
269
|
+
},
|
|
270
|
+
text: textArea.value,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
class TextareaController {
|
|
274
|
+
constructor(textAreaRef) {
|
|
275
|
+
this.textAreaRef = textAreaRef;
|
|
276
|
+
}
|
|
277
|
+
get textArea() {
|
|
278
|
+
var _a;
|
|
279
|
+
const textArea = (_a = this.textAreaRef) === null || _a === void 0 ? void 0 : _a.current;
|
|
280
|
+
if (!textArea) {
|
|
281
|
+
throw new Error('No TextAreaRef');
|
|
282
|
+
}
|
|
283
|
+
return textArea;
|
|
284
|
+
}
|
|
285
|
+
selectWordByCursor() {
|
|
286
|
+
const initialState = this.getState();
|
|
362
287
|
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
363
|
-
|
|
288
|
+
const newSelectionRange = getWordSelection({
|
|
364
289
|
text: initialState.text,
|
|
365
290
|
selection: initialState.selection,
|
|
366
291
|
});
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
292
|
+
return this.setSelection(newSelectionRange);
|
|
293
|
+
}
|
|
294
|
+
setSelection({ start, end }) {
|
|
295
|
+
const textArea = this.textArea;
|
|
296
|
+
textArea.focus();
|
|
297
|
+
textArea.selectionStart = start;
|
|
298
|
+
textArea.selectionEnd = end;
|
|
299
|
+
return getStateFromTextArea(textArea);
|
|
300
|
+
}
|
|
301
|
+
replaceSelection(text) {
|
|
302
|
+
const textArea = this.textArea;
|
|
303
|
+
insertToSelection(textArea, text);
|
|
304
|
+
return getStateFromTextArea(textArea);
|
|
305
|
+
}
|
|
306
|
+
replaceText(searchString, replaceString) {
|
|
307
|
+
const textArea = this.textArea;
|
|
308
|
+
const startIndex = textArea.value.indexOf(searchString);
|
|
309
|
+
if (startIndex === -1)
|
|
310
|
+
return getStateFromTextArea(textArea);
|
|
311
|
+
this.setSelection({ start: startIndex, end: startIndex + searchString.length });
|
|
312
|
+
this.replaceSelection(replaceString);
|
|
313
|
+
return getStateFromTextArea(textArea);
|
|
314
|
+
}
|
|
315
|
+
wrapSelection(prefix, suffix) {
|
|
316
|
+
const state1 = this.getState();
|
|
317
|
+
// Replaces the current selection with new string
|
|
318
|
+
const state2 = this.replaceSelection(`${prefix}${getSelectedText(state1)}${suffix}`);
|
|
370
319
|
// Adjust the selection to not contain the **
|
|
371
|
-
|
|
372
|
-
start: state2.selection.end -
|
|
373
|
-
end: state2.selection.end -
|
|
320
|
+
return this.setSelection({
|
|
321
|
+
start: state2.selection.end - prefix.length - getSelectedText(state1).length,
|
|
322
|
+
end: state2.selection.end - suffix.length,
|
|
374
323
|
});
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
start: initialState.selection.start -
|
|
381
|
-
end: initialState.selection.end +
|
|
324
|
+
}
|
|
325
|
+
unwrapSelection(prefixLength, suffixLength) {
|
|
326
|
+
const initialState = this.getState();
|
|
327
|
+
const text = getSelectedText(initialState);
|
|
328
|
+
this.setSelection({
|
|
329
|
+
start: initialState.selection.start - prefixLength,
|
|
330
|
+
end: initialState.selection.end + suffixLength,
|
|
382
331
|
});
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
start: initialState.selection.start -
|
|
386
|
-
end: initialState.selection.end -
|
|
332
|
+
this.replaceSelection(text);
|
|
333
|
+
return this.setSelection({
|
|
334
|
+
start: initialState.selection.start - prefixLength,
|
|
335
|
+
end: initialState.selection.end - suffixLength,
|
|
387
336
|
});
|
|
337
|
+
}
|
|
338
|
+
getState() {
|
|
339
|
+
const textArea = this.textArea;
|
|
340
|
+
return getStateFromTextArea(textArea);
|
|
341
|
+
}
|
|
342
|
+
moveCursorToTheEnd() {
|
|
343
|
+
const textArea = this.textArea;
|
|
344
|
+
textArea.focus();
|
|
345
|
+
textArea.selectionEnd = textArea.selectionStart = textArea.value.length;
|
|
346
|
+
return getStateFromTextArea(textArea);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function useTextAreaMarkdownEditor(options) {
|
|
351
|
+
const textAreaRef = useRef(null);
|
|
352
|
+
return useMemo(() => {
|
|
353
|
+
const textController = new TextareaController(textAreaRef);
|
|
354
|
+
const commandController = new CommandController(textController, options.commandMap);
|
|
355
|
+
return {
|
|
356
|
+
ref: textAreaRef,
|
|
357
|
+
textController,
|
|
358
|
+
commandController,
|
|
359
|
+
};
|
|
360
|
+
}, [textAreaRef]);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function makeList(state0, textController, insertBefore) {
|
|
364
|
+
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
365
|
+
const newSelectionRange = getWordSelection({
|
|
366
|
+
text: state0.text,
|
|
367
|
+
selection: state0.selection,
|
|
368
|
+
});
|
|
369
|
+
const state1 = textController.setSelection(newSelectionRange);
|
|
370
|
+
const breaksBeforeCount = getBreaksNeededForEmptyLineBefore(state1.text, state1.selection.start);
|
|
371
|
+
const breaksBefore = Array(breaksBeforeCount + 1).join('\n');
|
|
372
|
+
const breaksAfterCount = getBreaksNeededForEmptyLineAfter(state1.text, state1.selection.end);
|
|
373
|
+
const breaksAfter = Array(breaksAfterCount + 1).join('\n');
|
|
374
|
+
const modifiedText = insertBeforeEachLine(getSelectedText(state1), insertBefore);
|
|
375
|
+
textController.replaceSelection(`${breaksBefore}${modifiedText.modifiedText}${breaksAfter}`);
|
|
376
|
+
// Specifically when the text has only one line, we can exclude the "- ", for example, from the selection
|
|
377
|
+
const oneLinerOffset = !getSelectedText(state1).includes('\n') ? modifiedText.insertionLength : 0;
|
|
378
|
+
const selectionStart = state1.selection.start + breaksBeforeCount + oneLinerOffset;
|
|
379
|
+
const selectionEnd = selectionStart + modifiedText.modifiedText.length - oneLinerOffset;
|
|
380
|
+
// Adjust the selection to not contain the **
|
|
381
|
+
textController.setSelection({
|
|
382
|
+
start: selectionStart,
|
|
383
|
+
end: selectionEnd,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
var list = /*#__PURE__*/Object.freeze({
|
|
388
|
+
__proto__: null,
|
|
389
|
+
makeList: makeList
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
function setHeader(initialState, api, prefix) {
|
|
393
|
+
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
394
|
+
const newSelectionRange = getWordSelection({
|
|
395
|
+
text: initialState.text,
|
|
396
|
+
selection: initialState.selection,
|
|
397
|
+
});
|
|
398
|
+
const state1 = api.setSelection(newSelectionRange);
|
|
399
|
+
// Add the prefix to the selection
|
|
400
|
+
const state2 = api.replaceSelection(`${prefix}${getSelectedText(state1)}`);
|
|
401
|
+
// Adjust the selection to not contain the prefix
|
|
402
|
+
api.setSelection({
|
|
403
|
+
start: state2.selection.end - getSelectedText(state1).length,
|
|
404
|
+
end: state2.selection.end,
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
var header = /*#__PURE__*/Object.freeze({
|
|
409
|
+
__proto__: null,
|
|
410
|
+
setHeader: setHeader
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
const boldCommand = {
|
|
414
|
+
shouldUndo: textCtrl => {
|
|
415
|
+
const wordSelectionState = textCtrl.selectWordByCursor();
|
|
416
|
+
return (getStringBeforeSelection(wordSelectionState, 2) === '**' &&
|
|
417
|
+
getStringAfterSelection(wordSelectionState, 2) === '**');
|
|
418
|
+
},
|
|
419
|
+
do: textCtrl => {
|
|
420
|
+
textCtrl.wrapSelection('**', '**');
|
|
421
|
+
},
|
|
422
|
+
undo: textCtrl => {
|
|
423
|
+
textCtrl.unwrapSelection(2, 2);
|
|
388
424
|
},
|
|
389
425
|
};
|
|
390
|
-
var bold = commandsService.createCommandFn(boldCommand);
|
|
391
426
|
|
|
392
|
-
|
|
393
|
-
shouldUndo:
|
|
394
|
-
|
|
395
|
-
|
|
427
|
+
const italicCommand = {
|
|
428
|
+
shouldUndo: textCtrl => {
|
|
429
|
+
const wordSelectionState = textCtrl.selectWordByCursor();
|
|
430
|
+
return (getStringBeforeSelection(wordSelectionState, 1) === '*' && getStringAfterSelection(wordSelectionState, 1) === '*');
|
|
396
431
|
},
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
400
|
-
var newSelectionRange = selectWord({
|
|
401
|
-
text: initialState.text,
|
|
402
|
-
selection: initialState.selection,
|
|
403
|
-
});
|
|
404
|
-
var state1 = textApi.setSelection(newSelectionRange);
|
|
405
|
-
// Replaces the current selection with the italic mark up
|
|
406
|
-
var state2 = textApi.replaceSelection("*".concat(getSelectedText(state1), "*"));
|
|
407
|
-
// Adjust the selection to not contain the *
|
|
408
|
-
textApi.setSelection({
|
|
409
|
-
start: state2.selection.end - 1 - getSelectedText(state1).length,
|
|
410
|
-
end: state2.selection.end - 1,
|
|
411
|
-
});
|
|
432
|
+
do(textCtrl) {
|
|
433
|
+
textCtrl.wrapSelection('*', '*');
|
|
412
434
|
},
|
|
413
|
-
undo
|
|
414
|
-
|
|
415
|
-
var text = getSelectedText(initialState);
|
|
416
|
-
textApi.setSelection({
|
|
417
|
-
start: initialState.selection.start - 1,
|
|
418
|
-
end: initialState.selection.end + 1,
|
|
419
|
-
});
|
|
420
|
-
textApi.replaceSelection(text);
|
|
421
|
-
textApi.setSelection({
|
|
422
|
-
start: initialState.selection.start - 1,
|
|
423
|
-
end: initialState.selection.end - 1,
|
|
424
|
-
});
|
|
435
|
+
undo(textCtrl) {
|
|
436
|
+
textCtrl.unwrapSelection(1, 1);
|
|
425
437
|
},
|
|
426
438
|
};
|
|
427
|
-
var italic = commandsService.createCommandFn(italicCommand);
|
|
428
439
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
// Adjust the selection to not contain the ~~
|
|
441
|
-
textApi.setSelection({
|
|
442
|
-
start: state2.selection.end - 2 - getSelectedText(state1).length,
|
|
443
|
-
end: state2.selection.end - 2,
|
|
444
|
-
});
|
|
440
|
+
const strikethroughCommand = {
|
|
441
|
+
shouldUndo(textCtrl) {
|
|
442
|
+
const wordSelectionState = textCtrl.selectWordByCursor();
|
|
443
|
+
return (getStringBeforeSelection(wordSelectionState, 2) === '~~' &&
|
|
444
|
+
getStringAfterSelection(wordSelectionState, 2) === '~~');
|
|
445
|
+
},
|
|
446
|
+
do(textCtrl) {
|
|
447
|
+
textCtrl.wrapSelection('~~', '~~');
|
|
448
|
+
},
|
|
449
|
+
undo(textCtrl) {
|
|
450
|
+
textCtrl.unwrapSelection(2, 2);
|
|
445
451
|
},
|
|
446
452
|
};
|
|
447
|
-
var strikethrough = commandsService.createCommandFn(strikethroughCommand);
|
|
448
453
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
var initialState = _a.initialState, textApi = _a.textApi;
|
|
454
|
+
const linkCommand = {
|
|
455
|
+
do: textApi => {
|
|
452
456
|
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
453
|
-
|
|
454
|
-
text: initialState.text,
|
|
455
|
-
selection: initialState.selection,
|
|
456
|
-
});
|
|
457
|
-
var state1 = textApi.setSelection(newSelectionRange);
|
|
457
|
+
const wordSelectionState = textApi.selectWordByCursor();
|
|
458
458
|
// Replaces the current selection with the bold mark up
|
|
459
|
-
|
|
459
|
+
const state2 = textApi.replaceSelection(`[${getSelectedText(wordSelectionState)}](url)`);
|
|
460
460
|
// Adjust the selection to not contain the **
|
|
461
461
|
textApi.setSelection({
|
|
462
|
-
start: state2.selection.end - 6 - getSelectedText(
|
|
462
|
+
start: state2.selection.end - 6 - getSelectedText(wordSelectionState).length,
|
|
463
463
|
end: state2.selection.end - 6,
|
|
464
464
|
});
|
|
465
465
|
},
|
|
466
466
|
};
|
|
467
|
-
var link = commandsService.createCommandFn(linkCommand);
|
|
468
467
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
468
|
+
// Todo: try to rewrite with setHeader()
|
|
469
|
+
const quoteCommand = {
|
|
470
|
+
do: textApi => {
|
|
472
471
|
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
var breaksBeforeCount = getBreaksNeededForEmptyLineBefore(state1.text, state1.selection.start);
|
|
479
|
-
var breaksBefore = Array(breaksBeforeCount + 1).join('\n');
|
|
480
|
-
var breaksAfterCount = getBreaksNeededForEmptyLineAfter(state1.text, state1.selection.end);
|
|
481
|
-
var breaksAfter = Array(breaksAfterCount + 1).join('\n');
|
|
472
|
+
const state = textApi.selectWordByCursor();
|
|
473
|
+
const breaksBeforeCount = getBreaksNeededForEmptyLineBefore(state.text, state.selection.start);
|
|
474
|
+
const breaksBefore = Array(breaksBeforeCount + 1).join('\n');
|
|
475
|
+
const breaksAfterCount = getBreaksNeededForEmptyLineAfter(state.text, state.selection.end);
|
|
476
|
+
const breaksAfter = Array(breaksAfterCount + 1).join('\n');
|
|
482
477
|
// Replaces the current selection with the quote mark up
|
|
483
|
-
textApi.replaceSelection(
|
|
484
|
-
|
|
485
|
-
|
|
478
|
+
textApi.replaceSelection(`${breaksBefore}> ${getSelectedText(state)}${breaksAfter}`);
|
|
479
|
+
const selectionStart = state.selection.start + breaksBeforeCount + 2;
|
|
480
|
+
const selectionEnd = selectionStart + getSelectedText(state).length;
|
|
486
481
|
textApi.setSelection({
|
|
487
482
|
start: selectionStart,
|
|
488
483
|
end: selectionEnd,
|
|
489
484
|
});
|
|
490
485
|
},
|
|
491
486
|
};
|
|
492
|
-
var quote = commandsService.createCommandFn(quoteCommand);
|
|
493
487
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
var state1 = textApi.setSelection(selectWord({
|
|
499
|
-
text: initialState.text,
|
|
500
|
-
selection: initialState.selection,
|
|
501
|
-
}));
|
|
502
|
-
// Replaces the current selection with the image
|
|
503
|
-
var imageTemplate = getSelectedText(state1) || 'https://example.com/your-image.png';
|
|
504
|
-
textApi.replaceSelection(""));
|
|
505
|
-
// Adjust the selection to not contain the **
|
|
506
|
-
textApi.setSelection({
|
|
507
|
-
start: state1.selection.start + 4,
|
|
508
|
-
end: state1.selection.start + 4 + imageTemplate.length,
|
|
509
|
-
});
|
|
488
|
+
const codeCommand = {
|
|
489
|
+
shouldUndo: textCtrl => {
|
|
490
|
+
const wordSelectionState = textCtrl.selectWordByCursor();
|
|
491
|
+
return (getStringBeforeSelection(wordSelectionState, 1) === '`' && getStringAfterSelection(wordSelectionState, 1) === '`');
|
|
510
492
|
},
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
var codeCommand = {
|
|
515
|
-
shouldUndo: function (options) {
|
|
516
|
-
return (getCharactersBeforeSelection(options.initialState, 1) === '`' &&
|
|
517
|
-
getCharactersAfterSelection(options.initialState, 1) === '`');
|
|
493
|
+
do(textCtrl) {
|
|
494
|
+
textCtrl.wrapSelection('`', '`');
|
|
518
495
|
},
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
522
|
-
var newSelectionRange = selectWord({
|
|
523
|
-
text: initialState.text,
|
|
524
|
-
selection: initialState.selection,
|
|
525
|
-
});
|
|
526
|
-
var state1 = textApi.setSelection(newSelectionRange);
|
|
527
|
-
// Replaces the current selection with the italic mark up
|
|
528
|
-
var state2 = textApi.replaceSelection("`".concat(getSelectedText(state1), "`"));
|
|
529
|
-
// Adjust the selection to not contain the *
|
|
530
|
-
textApi.setSelection({
|
|
531
|
-
start: state2.selection.end - 1 - getSelectedText(state1).length,
|
|
532
|
-
end: state2.selection.end - 1,
|
|
533
|
-
});
|
|
534
|
-
},
|
|
535
|
-
undo: function (_a) {
|
|
536
|
-
var initialState = _a.initialState, textApi = _a.textApi;
|
|
537
|
-
var text = getSelectedText(initialState);
|
|
538
|
-
textApi.setSelection({
|
|
539
|
-
start: initialState.selection.start - 1,
|
|
540
|
-
end: initialState.selection.end + 1,
|
|
541
|
-
});
|
|
542
|
-
textApi.replaceSelection(text);
|
|
543
|
-
textApi.setSelection({
|
|
544
|
-
start: initialState.selection.start - 1,
|
|
545
|
-
end: initialState.selection.end - 1,
|
|
546
|
-
});
|
|
496
|
+
undo(textCtrl) {
|
|
497
|
+
textCtrl.unwrapSelection(1, 1);
|
|
547
498
|
},
|
|
548
499
|
};
|
|
549
|
-
var code = commandsService.createCommandFn(codeCommand);
|
|
550
500
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
var textApi = _a.textApi, initialState = _a.initialState;
|
|
501
|
+
const codeBlockCommand = {
|
|
502
|
+
do: textApi => {
|
|
554
503
|
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
555
|
-
|
|
556
|
-
text: initialState.text,
|
|
557
|
-
selection: initialState.selection,
|
|
558
|
-
});
|
|
559
|
-
var state1 = textApi.setSelection(newSelectionRange);
|
|
504
|
+
const state1 = textApi.selectWordByCursor();
|
|
560
505
|
// when there's no breaking line
|
|
561
506
|
if (!getSelectedText(state1).includes('\n')) {
|
|
562
|
-
textApi.replaceSelection(
|
|
507
|
+
textApi.replaceSelection(`\`${getSelectedText(state1)}\``);
|
|
563
508
|
// Adjust the selection to not contain the **
|
|
564
|
-
|
|
565
|
-
|
|
509
|
+
const selectionStart = state1.selection.start + 1;
|
|
510
|
+
const selectionEnd = selectionStart + getSelectedText(state1).length;
|
|
566
511
|
textApi.setSelection({
|
|
567
|
-
start:
|
|
568
|
-
end:
|
|
512
|
+
start: selectionStart,
|
|
513
|
+
end: selectionEnd,
|
|
569
514
|
});
|
|
570
515
|
return;
|
|
571
516
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
textApi.replaceSelection(
|
|
577
|
-
|
|
578
|
-
|
|
517
|
+
const breaksBeforeCount = getBreaksNeededForEmptyLineBefore(state1.text, state1.selection.start);
|
|
518
|
+
const breaksBefore = Array(breaksBeforeCount + 1).join('\n');
|
|
519
|
+
const breaksAfterCount = getBreaksNeededForEmptyLineAfter(state1.text, state1.selection.end);
|
|
520
|
+
const breaksAfter = Array(breaksAfterCount + 1).join('\n');
|
|
521
|
+
textApi.replaceSelection(`${breaksBefore}\`\`\`\n${getSelectedText(state1)}\n\`\`\`${breaksAfter}`);
|
|
522
|
+
const selectionStart = state1.selection.start + breaksBeforeCount + 4;
|
|
523
|
+
const selectionEnd = selectionStart + getSelectedText(state1).length;
|
|
579
524
|
textApi.setSelection({
|
|
580
525
|
start: selectionStart,
|
|
581
526
|
end: selectionEnd,
|
|
582
527
|
});
|
|
583
528
|
},
|
|
584
529
|
};
|
|
585
|
-
var codeBlock = commandsService.createCommandFn(codeBlockCommand);
|
|
586
530
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
selection: state0.selection,
|
|
592
|
-
});
|
|
593
|
-
var state1 = textController.setSelection(newSelectionRange);
|
|
594
|
-
var breaksBeforeCount = getBreaksNeededForEmptyLineBefore(state1.text, state1.selection.start);
|
|
595
|
-
var breaksBefore = Array(breaksBeforeCount + 1).join('\n');
|
|
596
|
-
var breaksAfterCount = getBreaksNeededForEmptyLineAfter(state1.text, state1.selection.end);
|
|
597
|
-
var breaksAfter = Array(breaksAfterCount + 1).join('\n');
|
|
598
|
-
var modifiedText = insertBeforeEachLine(getSelectedText(state1), insertBefore);
|
|
599
|
-
textController.replaceSelection("".concat(breaksBefore).concat(modifiedText.modifiedText).concat(breaksAfter));
|
|
600
|
-
// Specifically when the text has only one line, we can exclude the "- ", for example, from the selection
|
|
601
|
-
var oneLinerOffset = !getSelectedText(state1).includes('\n') ? modifiedText.insertionLength : 0;
|
|
602
|
-
var selectionStart = state1.selection.start + breaksBeforeCount + oneLinerOffset;
|
|
603
|
-
var selectionEnd = selectionStart + modifiedText.modifiedText.length - oneLinerOffset;
|
|
604
|
-
// Adjust the selection to not contain the **
|
|
605
|
-
textController.setSelection({
|
|
606
|
-
start: selectionStart,
|
|
607
|
-
end: selectionEnd,
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
var listHelpers = /*#__PURE__*/Object.freeze({
|
|
612
|
-
__proto__: null,
|
|
613
|
-
makeList: makeList
|
|
614
|
-
});
|
|
615
|
-
|
|
616
|
-
var checkedListCommand = {
|
|
617
|
-
execute: function (_a) {
|
|
618
|
-
var initialState = _a.initialState, textApi = _a.textApi;
|
|
619
|
-
makeList(initialState, textApi, function () { return "- [ ] "; });
|
|
531
|
+
const checkedListCommand = {
|
|
532
|
+
do: textApi => {
|
|
533
|
+
const initialState = textApi.getState();
|
|
534
|
+
makeList(initialState, textApi, () => `- [ ] `);
|
|
620
535
|
},
|
|
621
536
|
};
|
|
622
|
-
var checkedList = commandsService.createCommandFn(checkedListCommand);
|
|
623
537
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
makeList(initialState, textApi,
|
|
538
|
+
const orderedListCommand = {
|
|
539
|
+
do: textApi => {
|
|
540
|
+
const initialState = textApi.getState();
|
|
541
|
+
makeList(initialState, textApi, (item, index) => `${index + 1}. `);
|
|
628
542
|
},
|
|
629
543
|
};
|
|
630
|
-
var orderedList = commandsService.createCommandFn(orderedListCommand);
|
|
631
544
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
545
|
+
const unorderedListCommand = {
|
|
546
|
+
do: textApi => {
|
|
547
|
+
const initialState = textApi.getState();
|
|
635
548
|
makeList(initialState, textApi, '- ');
|
|
636
549
|
},
|
|
637
550
|
};
|
|
638
|
-
var unorderedList = commandsService.createCommandFn(unorderedListCommand);
|
|
639
|
-
|
|
640
|
-
function setHeader(initialState, api, prefix) {
|
|
641
|
-
// Adjust the selection to encompass the whole word if the caret is inside one
|
|
642
|
-
var newSelectionRange = selectWord({
|
|
643
|
-
text: initialState.text,
|
|
644
|
-
selection: initialState.selection,
|
|
645
|
-
});
|
|
646
|
-
var state1 = api.setSelection(newSelectionRange);
|
|
647
|
-
// Add the prefix to the selection
|
|
648
|
-
var state2 = api.replaceSelection("".concat(prefix).concat(getSelectedText(state1)));
|
|
649
|
-
// Adjust the selection to not contain the prefix
|
|
650
|
-
api.setSelection({
|
|
651
|
-
start: state2.selection.end - getSelectedText(state1).length,
|
|
652
|
-
end: state2.selection.end,
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
551
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
552
|
+
const imageCommand = {
|
|
553
|
+
do: textApi => {
|
|
554
|
+
// Replaces the current selection with the whole word selected
|
|
555
|
+
const wordSelectionState = textApi.selectWordByCursor();
|
|
556
|
+
// Replaces the current selection with the image
|
|
557
|
+
const imageTemplate = getSelectedText(wordSelectionState) || 'https://example.com/your-image.png';
|
|
558
|
+
textApi.replaceSelection(``);
|
|
559
|
+
// Adjust the selection to not contain the **
|
|
560
|
+
textApi.setSelection({
|
|
561
|
+
start: wordSelectionState.selection.start + 4,
|
|
562
|
+
end: wordSelectionState.selection.start + 4 + imageTemplate.length,
|
|
563
|
+
});
|
|
665
564
|
},
|
|
666
565
|
};
|
|
667
|
-
var headingLevel1 = commandsService.createCommandFn(headingLevel1Command);
|
|
668
566
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
setHeader(initialState,
|
|
567
|
+
const headingLevel1Command = {
|
|
568
|
+
do: textCtrl => {
|
|
569
|
+
const initialState = textCtrl.getState();
|
|
570
|
+
setHeader(initialState, textCtrl, '# ');
|
|
673
571
|
},
|
|
674
572
|
};
|
|
675
|
-
var headingLevel2 = commandsService.createCommandFn(headingLevel2Command);
|
|
676
573
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
setHeader(initialState,
|
|
574
|
+
const headingLevel2Command = {
|
|
575
|
+
do: textCtrl => {
|
|
576
|
+
const initialState = textCtrl.getState();
|
|
577
|
+
setHeader(initialState, textCtrl, '## ');
|
|
681
578
|
},
|
|
682
579
|
};
|
|
683
|
-
var headingLevel3 = commandsService.createCommandFn(headingLevel3Command);
|
|
684
580
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
setHeader(initialState,
|
|
581
|
+
const headingLevel3Command = {
|
|
582
|
+
do: textCtrl => {
|
|
583
|
+
const initialState = textCtrl.getState();
|
|
584
|
+
setHeader(initialState, textCtrl, '### ');
|
|
689
585
|
},
|
|
690
586
|
};
|
|
691
|
-
var headingLevel4 = commandsService.createCommandFn(headingLevel4Command);
|
|
692
587
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
setHeader(initialState,
|
|
588
|
+
const headingLevel4Command = {
|
|
589
|
+
do: textCtrl => {
|
|
590
|
+
const initialState = textCtrl.getState();
|
|
591
|
+
setHeader(initialState, textCtrl, '#### ');
|
|
697
592
|
},
|
|
698
593
|
};
|
|
699
|
-
var headingLevel5 = commandsService.createCommandFn(headingLevel5Command);
|
|
700
594
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
setHeader(initialState,
|
|
595
|
+
const headingLevel5Command = {
|
|
596
|
+
do: textCtrl => {
|
|
597
|
+
const initialState = textCtrl.getState();
|
|
598
|
+
setHeader(initialState, textCtrl, '##### ');
|
|
705
599
|
},
|
|
706
600
|
};
|
|
707
|
-
var headingLevel6 = commandsService.createCommandFn(headingLevel6Command);
|
|
708
601
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
// or add the markdown url to the end of text
|
|
714
|
-
// 4. If request is failed delete "![Uploading test 1.jpg…]()" and console.error
|
|
715
|
-
var attachmentCommand = {
|
|
716
|
-
execute: function (_a, _b) {
|
|
717
|
-
var initialState = _a.initialState, textApi = _a.textApi;
|
|
718
|
-
var fileName = _b.fileName, fileUrlPromise = _b.fileUrlPromise;
|
|
719
|
-
// Replaces the current selection with the empty selection
|
|
720
|
-
// and sets the cursor position to the end of the word
|
|
721
|
-
textApi.setSelection(selectAfterWord({
|
|
722
|
-
text: initialState.text,
|
|
723
|
-
selection: initialState.selection,
|
|
724
|
-
}));
|
|
725
|
-
var uploadingString = "![Uploading ".concat(fileName, "\u2026]()");
|
|
726
|
-
textApi.replaceSelection(' ' + uploadingString);
|
|
727
|
-
fileUrlPromise
|
|
728
|
-
.then(function (url) {
|
|
729
|
-
var fileLinkString = ".concat(url, ")");
|
|
730
|
-
if (textApi.getState().text.includes(uploadingString)) {
|
|
731
|
-
textApi.replaceText(uploadingString, fileLinkString);
|
|
732
|
-
}
|
|
733
|
-
else {
|
|
734
|
-
textApi.moveCursorToTheEnd();
|
|
735
|
-
textApi.replaceSelection("\n".concat(fileLinkString));
|
|
736
|
-
}
|
|
737
|
-
})
|
|
738
|
-
.catch(function (error) {
|
|
739
|
-
if (textApi.getState().text.includes(uploadingString)) {
|
|
740
|
-
textApi.replaceText(uploadingString, '');
|
|
741
|
-
}
|
|
742
|
-
console.error(error);
|
|
743
|
-
});
|
|
602
|
+
const headingLevel6Command = {
|
|
603
|
+
do: textCtrl => {
|
|
604
|
+
const initialState = textCtrl.getState();
|
|
605
|
+
setHeader(initialState, textCtrl, '###### ');
|
|
744
606
|
},
|
|
745
607
|
};
|
|
746
|
-
var attachment = commandsService.createCommandFn(attachmentCommand);
|
|
747
608
|
|
|
748
|
-
export {
|
|
609
|
+
export { TextareaController, boldCommand, checkedListCommand, codeBlockCommand, codeCommand, header as headerHelpers, headingLevel1Command, headingLevel2Command, headingLevel3Command, headingLevel4Command, headingLevel5Command, headingLevel6Command, imageCommand, italicCommand, linkCommand, list as listHelpers, orderedListCommand, quoteCommand, strikethroughCommand, selectionAndText as textHelpers, unorderedListCommand, useTextAreaMarkdownEditor };
|
|
749
610
|
//# sourceMappingURL=index.js.map
|