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