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