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