@lexical/markdown 0.1.19 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,9 +6,9 @@
6
6
  */
7
7
  'use strict';
8
8
 
9
- var lexical = require('lexical');
10
9
  var code = require('@lexical/code');
11
10
  var list = require('@lexical/list');
11
+ var lexical = require('lexical');
12
12
  var link = require('@lexical/link');
13
13
  var richText = require('@lexical/rich-text');
14
14
  var text = require('@lexical/text');
@@ -23,7 +23,7 @@ var text = require('@lexical/text');
23
23
  */
24
24
  /*
25
25
  How to add a new syntax to capture and transform.
26
- 1. Create a new enumeration by adding to AutoFormatKind.
26
+ 1. Create a new enumeration by adding to MarkdownFormatKind.
27
27
  2. Add a new criteria with a regEx pattern. See markdownStrikethrough as an example.
28
28
  3. Add your block criteria (e.g. '# ') to allMarkdownCriteria or
29
29
  your text criteria (e.g. *MyItalic*) to allMarkdownCriteriaForTextNodes.
@@ -41,7 +41,7 @@ const SEPARATOR_LENGTH = SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES.length;
41
41
  const spaceTrigger = {
42
42
  triggerKind: 'space_trigger',
43
43
  triggerString: '\u0020'
44
- }; // TODO: add support for ``` + carriage return either inside or not inside code block. Should toggle between.
44
+ }; // Future todo: add support for ``` + carriage return either inside or not inside code block. Should toggle between.
45
45
  // const codeBlockTrigger : AutoFormatTrigger = {
46
46
  // triggerKind: 'codeBlock_trigger',
47
47
  // triggerString: '```', // + new paragraph element or new code block element.
@@ -49,10 +49,10 @@ const spaceTrigger = {
49
49
 
50
50
  const triggers = [spaceTrigger
51
51
  /*, codeBlockTrigger*/
52
- ]; // Todo: speed up performance by having non-capture group variations of the regex.
52
+ ]; // Future Todo: speed up performance by having non-capture group variations of the regex.
53
53
 
54
54
  const autoFormatBase = {
55
- autoFormatKind: null,
55
+ markdownFormatKind: null,
56
56
  regEx: /(?:)/,
57
57
  regExForAutoFormatting: /(?:)/,
58
58
  requiresParagraphStart: false
@@ -61,101 +61,133 @@ const paragraphStartBase = { ...autoFormatBase,
61
61
  requiresParagraphStart: true
62
62
  };
63
63
  const markdownHeader1 = { ...paragraphStartBase,
64
- autoFormatKind: 'paragraphH1',
65
- regEx: /^(?:#)/,
64
+ markdownFormatKind: 'paragraphH1',
65
+ regEx: /^(?:# )/,
66
66
  regExForAutoFormatting: /^(?:# )/
67
67
  };
68
68
  const markdownHeader2 = { ...paragraphStartBase,
69
- autoFormatKind: 'paragraphH2',
70
- regEx: /^(?:##)/,
69
+ markdownFormatKind: 'paragraphH2',
70
+ regEx: /^(?:## )/,
71
71
  regExForAutoFormatting: /^(?:## )/
72
72
  };
73
73
  const markdownHeader3 = { ...paragraphStartBase,
74
- autoFormatKind: 'paragraphH2',
75
- regEx: /^(?:###)/,
74
+ markdownFormatKind: 'paragraphH2',
75
+ regEx: /^(?:### )/,
76
76
  regExForAutoFormatting: /^(?:### )/
77
77
  };
78
78
  const markdownBlockQuote = { ...paragraphStartBase,
79
- autoFormatKind: 'paragraphBlockQuote',
80
- regEx: /^(?:>)/,
79
+ markdownFormatKind: 'paragraphBlockQuote',
80
+ regEx: /^(?:> )/,
81
81
  regExForAutoFormatting: /^(?:> )/
82
82
  };
83
83
  const markdownUnorderedListDash = { ...paragraphStartBase,
84
- autoFormatKind: 'paragraphUnorderedList',
85
- regEx: /^(?:- )/,
86
- regExForAutoFormatting: /^(?:- )/
84
+ markdownFormatKind: 'paragraphUnorderedList',
85
+ regEx: /^(\s{0,10})(?:- )/,
86
+ regExForAutoFormatting: /^(\s{0,10})(?:- )/
87
87
  };
88
88
  const markdownUnorderedListAsterisk = { ...paragraphStartBase,
89
- autoFormatKind: 'paragraphUnorderedList',
90
- regEx: /^(?:\* )/,
91
- regExForAutoFormatting: /^(?:\* )/
89
+ markdownFormatKind: 'paragraphUnorderedList',
90
+ regEx: /^(\s{0,10})(?:\* )/,
91
+ regExForAutoFormatting: /^(\s{0,10})(?:\* )/
92
92
  };
93
93
  const markdownCodeBlock = { ...paragraphStartBase,
94
- autoFormatKind: 'paragraphCodeBlock',
94
+ markdownFormatKind: 'paragraphCodeBlock',
95
95
  regEx: /^(```)$/,
96
96
  regExForAutoFormatting: /^(```)([a-z]*)( )/
97
97
  };
98
98
  const markdownOrderedList = { ...paragraphStartBase,
99
- autoFormatKind: 'paragraphOrderedList',
100
- regEx: /^(\d+)\.\s/,
101
- regExForAutoFormatting: /^(\d+)\.\s/
99
+ markdownFormatKind: 'paragraphOrderedList',
100
+ regEx: /^(\s{0,10})(\d+)\.\s/,
101
+ regExForAutoFormatting: /^(\s{0,10})(\d+)\.\s/
102
102
  };
103
103
  const markdownHorizontalRule = { ...paragraphStartBase,
104
- autoFormatKind: 'horizontalRule',
104
+ markdownFormatKind: 'horizontalRule',
105
105
  regEx: /^(?:\*\*\*)$/,
106
106
  regExForAutoFormatting: /^(?:\*\*\* )/
107
107
  };
108
108
  const markdownHorizontalRuleUsingDashes = { ...paragraphStartBase,
109
- autoFormatKind: 'horizontalRule',
109
+ markdownFormatKind: 'horizontalRule',
110
110
  regEx: /^(?:---)$/,
111
111
  regExForAutoFormatting: /^(?:--- )/
112
112
  };
113
+ const markdownInlineCode = { ...autoFormatBase,
114
+ markdownFormatKind: 'code',
115
+ regEx: /(`)([^`]*)(`)/,
116
+ regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/
117
+ };
113
118
  const markdownItalic = { ...autoFormatBase,
114
- autoFormatKind: 'italic',
115
- regEx: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)/,
119
+ markdownFormatKind: 'italic',
120
+ regEx: /(\*)([^\*]*)(\*)/,
116
121
  regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
117
122
  };
118
123
  const markdownBold = { ...autoFormatBase,
119
- autoFormatKind: 'bold',
120
- regEx: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)/,
124
+ markdownFormatKind: 'bold',
125
+ regEx: /(\*\*)([^\*\*]*)(\*\*)/,
121
126
  regExForAutoFormatting: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
122
127
  };
123
- const markdownBoldWithUnderlines = { ...autoFormatBase,
124
- autoFormatKind: 'bold',
128
+ const markdownBold2 = { ...autoFormatBase,
129
+ markdownFormatKind: 'bold',
125
130
  regEx: /(__)(\s*)([^__]*)(\s*)(__)/,
126
131
  regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
127
132
  };
128
- const markdownBoldItalic = { ...autoFormatBase,
129
- autoFormatKind: 'bold_italic',
130
- regEx: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)/,
131
- regExForAutoFormatting: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)(\s)$/
133
+ const markdownItalic2 = { ...autoFormatBase,
134
+ markdownFormatKind: 'italic',
135
+ regEx: /(_)([^_]*)(_)/,
136
+ regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/ // Maintain 7 groups.
137
+
132
138
  }; // Markdown does not support underline, but we can allow folks to use
133
139
  // the HTML tags for underline.
134
140
 
135
141
  const fakeMarkdownUnderline = { ...autoFormatBase,
136
- autoFormatKind: 'underline',
142
+ markdownFormatKind: 'underline',
137
143
  regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)/,
138
144
  regExForAutoFormatting: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)(\s)$/
139
145
  };
140
146
  const markdownStrikethrough = { ...autoFormatBase,
141
- autoFormatKind: 'strikethrough',
142
- regEx: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)/,
147
+ markdownFormatKind: 'strikethrough',
148
+ regEx: /(~~)([^~~]*)(~~)/,
143
149
  regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
144
150
  };
151
+ const markdownStrikethroughItalicBold = { ...autoFormatBase,
152
+ markdownFormatKind: 'strikethrough_italic_bold',
153
+ regEx: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)/,
154
+ regExForAutoFormatting: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/
155
+ };
156
+ const markdownItalicbold = { ...autoFormatBase,
157
+ markdownFormatKind: 'italic_bold',
158
+ regEx: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,
159
+ regExForAutoFormatting: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/
160
+ };
161
+ const markdownStrikethroughItalic = { ...autoFormatBase,
162
+ markdownFormatKind: 'strikethrough_italic',
163
+ regEx: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,
164
+ regExForAutoFormatting: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/
165
+ };
166
+ const markdownStrikethroughBold = { ...autoFormatBase,
167
+ markdownFormatKind: 'strikethrough_bold',
168
+ regEx: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,
169
+ regExForAutoFormatting: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/
170
+ };
145
171
  const markdownLink = { ...autoFormatBase,
146
- autoFormatKind: 'link',
172
+ markdownFormatKind: 'link',
147
173
  regEx: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))/,
148
174
  regExForAutoFormatting: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))(\s)$/
149
175
  };
150
- const allMarkdownCriteriaForTextNodes = [markdownBoldItalic, markdownItalic, markdownBold, markdownBoldWithUnderlines, fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
176
+ const allMarkdownCriteriaForTextNodes = [// Place the combination formats ahead of the individual formats.
177
+ // Combos
178
+ markdownStrikethroughItalicBold, markdownItalicbold, markdownStrikethroughItalic, markdownStrikethroughBold, // Individuals
179
+ markdownInlineCode, markdownItalic, markdownBold, markdownBold2, markdownItalic2, // Must appear after markdownBold2.
180
+ fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
151
181
  const allMarkdownCriteria = [markdownHeader1, markdownHeader2, markdownHeader3, markdownBlockQuote, markdownUnorderedListDash, markdownUnorderedListAsterisk, markdownOrderedList, markdownCodeBlock, markdownHorizontalRule, markdownHorizontalRuleUsingDashes, ...allMarkdownCriteriaForTextNodes];
152
182
  function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset, triggerState) {
153
183
  return {
184
+ currentElementNode: null,
154
185
  editor,
155
186
  isAutoFormatting,
187
+ isWithinCodeBlock: false,
156
188
  joinedText: null,
157
189
  markdownCriteria: {
158
- autoFormatKind: 'noTransformation',
190
+ markdownFormatKind: 'noTransformation',
159
191
  regEx: /(?:)/,
160
192
  // Empty reg ex.
161
193
  regExForAutoFormatting: /(?:)/,
@@ -172,7 +204,7 @@ function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset,
172
204
  function resetScanningContext(scanningContext) {
173
205
  scanningContext.joinedText = '';
174
206
  scanningContext.markdownCriteria = {
175
- autoFormatKind: 'noTransformation',
207
+ markdownFormatKind: 'noTransformation',
176
208
  regEx: /(?:)/,
177
209
  // Empty reg ex.
178
210
  regExForAutoFormatting: /(?:)/,
@@ -186,6 +218,13 @@ function resetScanningContext(scanningContext) {
186
218
  scanningContext.textNodeWithOffset = null;
187
219
  return scanningContext;
188
220
  }
221
+ function getCodeBlockCriteria() {
222
+ return markdownCodeBlock;
223
+ }
224
+ function getPatternMatchResultsForCodeBlock(scanningContext, text) {
225
+ const markdownCriteria = getCodeBlockCriteria();
226
+ return getPatternMatchResultsWithRegEx(text, true, false, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
227
+ }
189
228
 
190
229
  function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfString, matchMustAppearAtEndOfString, regEx) {
191
230
  const patternMatchResults = {
@@ -217,6 +256,9 @@ function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfS
217
256
  return null;
218
257
  }
219
258
 
259
+ function hasPatternMatchResults(scanningContext) {
260
+ return scanningContext.patternMatchResults.regExCaptureGroups.length > 0;
261
+ }
220
262
  function getTextNodeWithOffsetOrThrow(scanningContext) {
221
263
  const textNodeWithOffset = scanningContext.textNodeWithOffset;
222
264
 
@@ -233,7 +275,7 @@ function getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext)
233
275
 
234
276
  if (textNodeWithOffset.node.getPreviousSibling() === null) {
235
277
  const textToSearch = textNodeWithOffset.node.getTextContent();
236
- return getPatternMatchResultsWithRegEx(textToSearch, true, false, markdownCriteria.regExForAutoFormatting);
278
+ return getPatternMatchResultsWithRegEx(textToSearch, true, false, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
237
279
  }
238
280
 
239
281
  return null;
@@ -259,63 +301,124 @@ function getPatternMatchResultsForText(markdownCriteria, scanningContext) {
259
301
 
260
302
  function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNode) {
261
303
  let newNode = null;
304
+ const shouldDelete = false;
262
305
  const children = element.getChildren();
263
306
  const markdownCriteria = scanningContext.markdownCriteria;
264
307
  const patternMatchResults = scanningContext.patternMatchResults;
265
308
 
266
- if (markdownCriteria.autoFormatKind != null) {
267
- switch (markdownCriteria.autoFormatKind) {
309
+ if (markdownCriteria.markdownFormatKind != null) {
310
+ switch (markdownCriteria.markdownFormatKind) {
268
311
  case 'paragraphH1':
269
312
  {
270
313
  newNode = richText.$createHeadingNode('h1');
271
314
  newNode.append(...children);
272
- return newNode;
315
+ return {
316
+ newNode,
317
+ shouldDelete
318
+ };
273
319
  }
274
320
 
275
321
  case 'paragraphH2':
276
322
  {
277
323
  newNode = richText.$createHeadingNode('h2');
278
324
  newNode.append(...children);
279
- return newNode;
325
+ return {
326
+ newNode,
327
+ shouldDelete
328
+ };
280
329
  }
281
330
 
282
331
  case 'paragraphH3':
283
332
  {
284
333
  newNode = richText.$createHeadingNode('h3');
285
334
  newNode.append(...children);
286
- return newNode;
335
+ return {
336
+ newNode,
337
+ shouldDelete
338
+ };
287
339
  }
288
340
 
289
341
  case 'paragraphBlockQuote':
290
342
  {
291
343
  newNode = richText.$createQuoteNode();
292
344
  newNode.append(...children);
293
- return newNode;
345
+ return {
346
+ newNode,
347
+ shouldDelete
348
+ };
294
349
  }
295
350
 
296
351
  case 'paragraphUnorderedList':
297
352
  {
298
- newNode = list.$createListNode('ul');
299
- const listItem = list.$createListItemNode();
300
- listItem.append(...children);
301
- newNode.append(listItem);
302
- return newNode;
353
+ createListOrMergeWithPrevious(element, children, patternMatchResults, 'ul');
354
+ return {
355
+ newNode: null,
356
+ shouldDelete: false
357
+ };
303
358
  }
304
359
 
305
360
  case 'paragraphOrderedList':
306
361
  {
307
- const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1';
308
- const start = parseInt(startAsString, 10);
309
- newNode = list.$createListNode('ol', start);
310
- const listItem = list.$createListItemNode();
311
- listItem.append(...children);
312
- newNode.append(listItem);
313
- return newNode;
362
+ const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1'; // For conversion, don't use start number.
363
+ // For short-cuts aka autoFormatting, use start number.
364
+ // Later, this should be surface dependent and externalized.
365
+
366
+ const start = scanningContext.isAutoFormatting ? parseInt(startAsString, 10) : undefined;
367
+ createListOrMergeWithPrevious(element, children, patternMatchResults, 'ol', start);
368
+ return {
369
+ newNode: null,
370
+ shouldDelete: false
371
+ };
314
372
  }
315
373
 
316
374
  case 'paragraphCodeBlock':
317
375
  {
318
376
  // Toggle code and paragraph nodes.
377
+ if (scanningContext.isAutoFormatting === false) {
378
+ const shouldToggle = hasPatternMatchResults(scanningContext);
379
+
380
+ if (shouldToggle) {
381
+ scanningContext.isWithinCodeBlock = scanningContext.isWithinCodeBlock !== true; // When toggling, always clear the code block element node.
382
+
383
+ scanningContext.currentElementNode = null;
384
+ return {
385
+ newNode: null,
386
+ shouldDelete: true
387
+ };
388
+ }
389
+
390
+ if (scanningContext.isWithinCodeBlock) {
391
+ // Create the code block and return it to the caller.
392
+ if (scanningContext.currentElementNode == null) {
393
+ const newCodeBlockNode = code.$createCodeNode();
394
+ newCodeBlockNode.append(...children);
395
+ scanningContext.currentElementNode = newCodeBlockNode;
396
+ return {
397
+ newNode: newCodeBlockNode,
398
+ shouldDelete: false
399
+ };
400
+ } // Build up the code block with a line break and the children.
401
+
402
+
403
+ if (scanningContext.currentElementNode != null) {
404
+ const codeBlockNode = scanningContext.currentElementNode;
405
+ const lineBreakNode = lexical.$createLineBreakNode();
406
+ codeBlockNode.append(lineBreakNode);
407
+
408
+ if (children.length) {
409
+ codeBlockNode.append(lineBreakNode);
410
+ }
411
+
412
+ codeBlockNode.append(...children);
413
+ }
414
+ }
415
+
416
+ return {
417
+ newNode: null,
418
+ shouldDelete: true
419
+ };
420
+ }
421
+
319
422
  if (scanningContext.triggerState != null && scanningContext.triggerState.isCodeBlock) {
320
423
  newNode = lexical.$createParagraphNode();
321
424
  } else {
@@ -328,53 +431,94 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
328
431
  }
329
432
 
330
433
  newNode.append(...children);
331
- return newNode;
434
+ return {
435
+ newNode,
436
+ shouldDelete
437
+ };
332
438
  }
333
439
 
334
440
  case 'horizontalRule':
335
441
  {
336
- // return null for newNode. Insert the HR here.
337
- const horizontalRuleNode = createHorizontalRuleNode();
338
- element.insertBefore(horizontalRuleNode);
442
+ if (createHorizontalRuleNode != null) {
443
+ // return null for newNode. Insert the HR here.
444
+ const horizontalRuleNode = createHorizontalRuleNode();
445
+ element.insertBefore(horizontalRuleNode);
446
+ }
447
+
339
448
  break;
340
449
  }
341
450
  }
342
451
  }
343
452
 
344
- return newNode;
453
+ return {
454
+ newNode,
455
+ shouldDelete
456
+ };
345
457
  }
346
458
 
347
- function transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNode) {
348
- const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
349
- const element = textNodeWithOffset.node.getParentOrThrow();
350
- const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
459
+ function createListOrMergeWithPrevious(element, children, patternMatchResults, tag, start) {
460
+ const listItem = list.$createListItemNode();
461
+ const indentMatch = patternMatchResults.regExCaptureGroups[0].text.match(/^\s*/);
462
+ const indent = indentMatch ? Math.floor(indentMatch[0].length / 4) : 0;
463
+ listItem.append(...children); // Checking if previous element is a list, and if so append
464
+ // new list item inside instead of creating new list
465
+
466
+ const prevElement = element.getPreviousSibling();
467
+
468
+ if (list.$isListNode(prevElement) && prevElement.getTag() === tag) {
469
+ prevElement.append(listItem);
470
+ element.remove();
471
+ } else {
472
+ const list$1 = list.$createListNode(tag, start);
473
+ list$1.append(listItem);
474
+ element.replace(list$1);
475
+ }
476
+
477
+ if (indent) {
478
+ listItem.setIndent(indent);
479
+ }
480
+ }
481
+
482
+ function transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode) {
483
+ if (scanningContext.textNodeWithOffset != null) {
484
+ const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
485
+
486
+ if (hasPatternMatchResults(scanningContext)) {
487
+ const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
351
488
 
352
- const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
489
+ const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
353
490
 
354
- if (textNode.getTextContent() === '') {
355
- textNode.selectPrevious();
356
- textNode.remove();
491
+ if (textNode.getTextContent() === '') {
492
+ textNode.selectPrevious();
493
+ textNode.remove();
494
+ }
495
+ }
357
496
  } // Transform the current element kind to the new element kind.
358
497
 
359
498
 
360
- const elementNode = getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNode);
499
+ const {
500
+ newNode,
501
+ shouldDelete
502
+ } = getNewNodeForCriteria(scanningContext, elementNode, createHorizontalRuleNode);
361
503
 
362
- if (elementNode !== null) {
363
- element.replace(elementNode);
504
+ if (shouldDelete) {
505
+ elementNode.remove();
506
+ } else if (newNode !== null) {
507
+ elementNode.replace(newNode);
364
508
  }
365
509
  }
366
510
  function transformTextNodeForText(scanningContext) {
367
511
  const markdownCriteria = scanningContext.markdownCriteria;
368
512
 
369
- if (markdownCriteria.autoFormatKind != null) {
370
- const formatting = getTextFormatType(markdownCriteria.autoFormatKind);
513
+ if (markdownCriteria.markdownFormatKind != null) {
514
+ const formatting = getTextFormatType(markdownCriteria.markdownFormatKind);
371
515
 
372
516
  if (formatting != null) {
373
517
  transformTextNodeWithFormatting(formatting, scanningContext);
374
518
  return;
375
519
  }
376
520
 
377
- if (markdownCriteria.autoFormatKind === 'link') {
521
+ if (markdownCriteria.markdownFormatKind === 'link') {
378
522
  transformTextNodeWithLink(scanningContext);
379
523
  }
380
524
  }
@@ -466,17 +610,33 @@ function getJoinedTextLength(patternMatchResults) {
466
610
  return patternMatchResults.regExCaptureGroups[lastGroupIndex].offsetInParent + patternMatchResults.regExCaptureGroups[lastGroupIndex].text.length;
467
611
  }
468
612
 
469
- function getTextFormatType(autoFormatKind) {
470
- switch (autoFormatKind) {
613
+ function getTextFormatType(markdownFormatKind) {
614
+ switch (markdownFormatKind) {
471
615
  case 'italic':
472
616
  case 'bold':
473
617
  case 'underline':
474
618
  case 'strikethrough':
475
- return [autoFormatKind];
619
+ case 'code':
620
+ return [markdownFormatKind];
621
+
622
+ case 'strikethrough_italic_bold':
623
+ {
624
+ return ['strikethrough', 'italic', 'bold'];
625
+ }
476
626
 
477
- case 'bold_italic':
627
+ case 'italic_bold':
478
628
  {
479
- return ['bold', 'italic'];
629
+ return ['italic', 'bold'];
630
+ }
631
+
632
+ case 'strikethrough_italic':
633
+ {
634
+ return ['strikethrough', 'italic'];
635
+ }
636
+
637
+ case 'strikethrough_bold':
638
+ {
639
+ return ['strikethrough', 'bold'];
480
640
  }
481
641
  }
482
642
 
@@ -643,7 +803,8 @@ function getAllMarkdownCriteria() {
643
803
  }
644
804
  function transformTextNodeForMarkdownCriteria(scanningContext, createHorizontalRuleNode) {
645
805
  if (scanningContext.markdownCriteria.requiresParagraphStart === true) {
646
- transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNode);
806
+ const elementNode = getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
807
+ transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
647
808
  } else {
648
809
  transformTextNodeForText(scanningContext);
649
810
  }
@@ -689,7 +850,7 @@ function getCriteriaWithPatternMatchResults(markdownCriteriaArray, scanningConte
689
850
  for (let i = 0; i < count; i++) {
690
851
  const markdownCriteria = markdownCriteriaArray[i]; // Skip code block nodes, unless the autoFormatKind calls for toggling the code block.
691
852
 
692
- if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || markdownCriteria.autoFormatKind === 'paragraphCodeBlock') {
853
+ if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || markdownCriteria.markdownFormatKind === 'paragraphCodeBlock') {
693
854
  const patternMatchResults = getPatternMatchResultsForCriteria(markdownCriteria, scanningContext);
694
855
 
695
856
  if (patternMatchResults != null) {
@@ -776,7 +937,7 @@ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
776
937
  const currentTextContentLength = currentTriggerState.textContent.length;
777
938
  const triggerOffset = currentTriggerState.anchorOffset - triggerStringLength;
778
939
 
779
- if ((currentTriggerState.hasParentNode === true && currentTriggerState.isSimpleText && currentTriggerState.isSelectionCollapsed && currentTriggerState.nodeKey === priorTriggerState.nodeKey && currentTriggerState.anchorOffset !== priorTriggerState.anchorOffset && triggerOffset >= 0 && triggerOffset + triggerStringLength <= currentTextContentLength && currentTriggerState.textContent.substr(triggerOffset, triggerStringLength) === triggerString && // Some code differentiation needed if trigger kind is not a simple space character.
940
+ if ((currentTriggerState.hasParentNode === true && currentTriggerState.isSimpleText && currentTriggerState.isSelectionCollapsed && currentTriggerState.anchorOffset !== priorTriggerState.anchorOffset && triggerOffset >= 0 && triggerOffset + triggerStringLength <= currentTextContentLength && currentTriggerState.textContent.substr(triggerOffset, triggerStringLength) === triggerString && // Some code differentiation needed if trigger kind is not a simple space character.
780
941
  currentTriggerState.textContent !== priorTriggerState.textContent) === false) {
781
942
  return null;
782
943
  }
@@ -794,62 +955,125 @@ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
794
955
  *
795
956
  */
796
957
  function convertStringToLexical(text, editor) {
797
- const nodes = text.split('\n').map(splitText => lexical.$createParagraphNode().append(lexical.$createTextNode(splitText)));
798
- const root = lexical.$getRoot();
799
- root.clear();
800
- root.append(...nodes);
801
- }
958
+ if (!text.length) {
959
+ return null;
960
+ }
802
961
 
803
- function convertElementNodeContainingMarkdown(scanningContext, elementNode) {
804
- // Handle code block to be done.
805
- // Handle paragraph nodes below.
806
- if (lexical.$isParagraphNode(elementNode)) {
807
- const paragraphNode = elementNode;
808
- const allCriteria = getAllMarkdownCriteria();
809
- const count = allCriteria.length;
962
+ const nodes = [];
963
+ const splitLines = text.split('\n');
964
+ const splitLinesCount = splitLines.length;
810
965
 
811
- for (let i = 0; i < count; i++) {
812
- const criteria = allCriteria[i];
966
+ for (let i = 0; i < splitLinesCount; i++) {
967
+ if (splitLines[i].length > 0) {
968
+ nodes.push(lexical.$createParagraphNode().append(lexical.$createTextNode(splitLines[i])));
969
+ } else {
970
+ nodes.push(lexical.$createParagraphNode());
971
+ }
972
+ }
813
973
 
814
- if (criteria.requiresParagraphStart === true) {
815
- const firstChild = paragraphNode.getFirstChild();
974
+ if (nodes.length) {
975
+ const root = lexical.$getRoot();
976
+ root.clear();
977
+ root.append(...nodes);
978
+ return root;
979
+ }
816
980
 
817
- if (!lexical.$isTextNode(firstChild)) {
818
- throw Error(`Expect paragraph containing only text nodes.`);
819
- }
981
+ return null;
982
+ }
983
+
984
+ function convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode) {
985
+ const textContent = elementNode.getTextContent(); // Handle paragraph nodes below.
986
+
987
+ if (lexical.$isParagraphNode(elementNode)) {
988
+ const paragraphNode = elementNode;
989
+ const firstChild = paragraphNode.getFirstChild();
990
+ const firstChildIsTextNode = lexical.$isTextNode(firstChild); // Handle conversion to code block.
820
991
 
992
+ if (scanningContext.isWithinCodeBlock === true) {
993
+ if (firstChild != null && firstChildIsTextNode) {
994
+ // Test if we encounter ending code block.
821
995
  scanningContext.textNodeWithOffset = {
822
996
  node: firstChild,
823
997
  offset: 0
824
998
  };
825
- scanningContext.joinedText = paragraphNode.getTextContent();
826
- const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
999
+ const patternMatchResults = getPatternMatchResultsForCodeBlock(scanningContext, textContent);
827
1000
 
828
1001
  if (patternMatchResults != null) {
829
- // Lazy fill-in the particular format criteria and any matching result information.
830
- scanningContext.markdownCriteria = criteria;
831
- scanningContext.patternMatchResults = patternMatchResults; // Todo: perform text transformation here.
1002
+ // Toggle transform to or from code block.
1003
+ scanningContext.patternMatchResults = patternMatchResults;
1004
+ }
1005
+ }
1006
+
1007
+ scanningContext.markdownCriteria = getCodeBlockCriteria(); // Perform text transformation here.
1008
+
1009
+ transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
1010
+ return;
1011
+ }
1012
+
1013
+ if (elementNode.getChildren().length) {
1014
+ const allCriteria = getAllMarkdownCriteria();
1015
+ const count = allCriteria.length;
1016
+
1017
+ for (let i = 0; i < count; i++) {
1018
+ const criteria = allCriteria[i];
1019
+
1020
+ if (criteria.requiresParagraphStart === true) {
1021
+ if (!(firstChild != null && firstChildIsTextNode)) {
1022
+ throw Error(`Expect paragraph containing only text nodes.`);
1023
+ }
1024
+
1025
+ scanningContext.textNodeWithOffset = {
1026
+ node: firstChild,
1027
+ offset: 0
1028
+ };
1029
+ scanningContext.joinedText = paragraphNode.getTextContent();
1030
+ const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
1031
+
1032
+ if (patternMatchResults != null) {
1033
+ // Lazy fill-in the particular format criteria and any matching result information.
1034
+ scanningContext.markdownCriteria = criteria;
1035
+ scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
1036
+
1037
+ transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
1038
+ return;
1039
+ }
832
1040
  }
833
1041
  }
834
1042
  }
835
1043
  }
836
1044
  }
837
1045
 
838
- function convertMarkdownForElementNodes(elementNodes, editor) {
1046
+ function convertMarkdownForElementNodes(editor, createHorizontalRuleNode) {
839
1047
  // Please see the declaration of ScanningContext for a detailed explanation.
840
1048
  const scanningContext = getInitialScanningContext(editor, false, null, null);
841
- const count = elementNodes.length;
1049
+ const root = lexical.$getRoot();
1050
+ let done = false;
1051
+ let startIndex = 0;
842
1052
 
843
- for (let i = 0; i < count; i++) {
844
- const elementNode = elementNodes[i];
1053
+ while (!done) {
1054
+ done = true;
1055
+ const elementNodes = root.getChildren();
1056
+ const countOfElementNodes = elementNodes.length;
845
1057
 
846
- if (lexical.$isElementNode(elementNode) && elementNode.getTextContent().length && elementNode.getChildren().length) {
847
- convertElementNodeContainingMarkdown(scanningContext, elementNode);
848
- } // Reset the scanning information that relates to the particular element node.
1058
+ for (let i = startIndex; i < countOfElementNodes; i++) {
1059
+ const elementNode = elementNodes[i];
849
1060
 
1061
+ if (lexical.$isElementNode(elementNode)) {
1062
+ convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode);
1063
+ } // Reset the scanning information that relates to the particular element node.
1064
+
1065
+
1066
+ resetScanningContext(scanningContext);
1067
+
1068
+ if (root.getChildren().length !== countOfElementNodes) {
1069
+ // The conversion added or removed an from root's children.
1070
+ startIndex = i;
1071
+ done = false;
1072
+ break;
1073
+ }
1074
+ }
1075
+ } // while
850
1076
 
851
- resetScanningContext(scanningContext);
852
- }
853
1077
  }
854
1078
 
855
1079
  /**
@@ -885,8 +1109,9 @@ function registerMarkdownShortcuts(editor, createHorizontalRuleNode) {
885
1109
  });
886
1110
  }
887
1111
  function $convertFromMarkdownString(markdownString, editor, createHorizontalRuleNode) {
888
- convertStringToLexical(markdownString);
889
- convertMarkdownForElementNodes(lexical.$getRoot().getChildren(), editor);
1112
+ if (convertStringToLexical(markdownString) != null) {
1113
+ convertMarkdownForElementNodes(editor, createHorizontalRuleNode);
1114
+ }
890
1115
  }
891
1116
 
892
1117
  exports.$convertFromMarkdownString = $convertFromMarkdownString;
@@ -4,26 +4,33 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- var h=require("lexical"),n=require("@lexical/code"),p=require("@lexical/list"),r=require("@lexical/link"),t=require("@lexical/rich-text"),u=require("@lexical/text");function w(e){throw Error(`Minified Lexical error #${e}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
8
- const x=[{triggerKind:"space_trigger",triggerString:" "}],y={autoFormatKind:null,regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:!1},z={...y,requiresParagraphStart:!0},A=[{...y,autoFormatKind:"bold_italic",regEx:/(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)/,regExForAutoFormatting:/(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)(\s)$/},{...y,autoFormatKind:"italic",regEx:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)/,regExForAutoFormatting:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/},{...y,autoFormatKind:"bold",
9
- regEx:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)/,regExForAutoFormatting:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/},{...y,autoFormatKind:"bold",regEx:/(__)(\s*)([^__]*)(\s*)(__)/,regExForAutoFormatting:/(__)(\s*)([^__]*)(\s*)(__)(\s)$/},{...y,autoFormatKind:"underline",regEx:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)/,regExForAutoFormatting:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/},{...y,autoFormatKind:"strikethrough",regEx:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)/,regExForAutoFormatting:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/},
10
- {...y,autoFormatKind:"link",regEx:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))/,regExForAutoFormatting:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))(\s)$/}],B=[{...z,autoFormatKind:"paragraphH1",regEx:/^(?:#)/,regExForAutoFormatting:/^(?:# )/},{...z,autoFormatKind:"paragraphH2",regEx:/^(?:##)/,regExForAutoFormatting:/^(?:## )/},{...z,autoFormatKind:"paragraphH2",regEx:/^(?:###)/,regExForAutoFormatting:/^(?:### )/},{...z,autoFormatKind:"paragraphBlockQuote",regEx:/^(?:>)/,regExForAutoFormatting:/^(?:> )/},
11
- {...z,autoFormatKind:"paragraphUnorderedList",regEx:/^(?:- )/,regExForAutoFormatting:/^(?:- )/},{...z,autoFormatKind:"paragraphUnorderedList",regEx:/^(?:\* )/,regExForAutoFormatting:/^(?:\* )/},{...z,autoFormatKind:"paragraphOrderedList",regEx:/^(\d+)\.\s/,regExForAutoFormatting:/^(\d+)\.\s/},{...z,autoFormatKind:"paragraphCodeBlock",regEx:/^(```)$/,regExForAutoFormatting:/^(```)([a-z]*)( )/},{...z,autoFormatKind:"horizontalRule",regEx:/^(?:\*\*\*)$/,regExForAutoFormatting:/^(?:\*\*\* )/},{...z,autoFormatKind:"horizontalRule",
12
- regEx:/^(?:---)$/,regExForAutoFormatting:/^(?:--- )/},...A];function C(e,c,f,a){return{editor:e,isAutoFormatting:c,joinedText:null,markdownCriteria:{autoFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null},patternMatchResults:{regExCaptureGroups:[]},textNodeWithOffset:f,triggerState:a}}
13
- function D(e,c,f,a){const b={regExCaptureGroups:[]};a=e.match(a);if(null!==a&&0<a.length&&(!1===c||0===a.index)&&(!1===f||a.index+a[0].length===e.length)){e=a.length;c=a.index;for(f=0;f<e;f++){const d=a[f];b.regExCaptureGroups.push({offsetInParent:c,text:d});0<f&&(c+=d.length)}return b}return null}function E(e){e=e.textNodeWithOffset;null==e&&w(82);return e}function F(e,c){c=E(c);return null===c.node.getPreviousSibling()?(c=c.node.getTextContent(),D(c,!0,!1,e.regExForAutoFormatting)):null}
14
- function G(e,c,f,a,b){var d=b.patternMatchResults;const g=d.regExCaptureGroups;var k=g.length;if(e>=k||c>=k)return null;b=E(b).node.getParentOrThrow();k=d.regExCaptureGroups.length;2>k?d=0:(--k,d=d.regExCaptureGroups[k].offsetInParent+d.regExCaptureGroups[k].text.length);e=g[e];c=g[c];a=a?c.offsetInParent+c.text.length:c.offsetInParent;f=u.$findNodeWithOffsetFromJoinedText(f?e.offsetInParent+e.text.length:e.offsetInParent,d,1,b);a=u.$findNodeWithOffsetFromJoinedText(a,d,1,b);if(null==f||null==a)return null;
15
- b=h.$createRangeSelection();b.anchor.set(f.node.getKey(),f.offset,"text");b.focus.set(a.node.getKey(),a.offset,"text");return b}function H(e,c,f){const a=f.patternMatchResults.regExCaptureGroups;f=G(e,c,!1,!0,f);if(null!=f&&(h.$setSelection(f),f=h.$getSelection(),null!=f&&h.$isRangeSelection(f)&&!1===f.isCollapsed())){f.removeText();f=0;const b=a.length;for(let d=e;d<b;d++){const g=a[d];d>e&&(g.offsetInParent-=f);d<=c&&(f+=g.text.length,g.text="")}}}
16
- function I(e){var c=e.patternMatchResults.regExCaptureGroups.length;2>c||(--c,e=G(c,c,!0,!0,e),null!=e&&h.$setSelection(e))}
17
- function J(e,c,f){e.update(()=>{if(!0===c.markdownCriteria.requiresParagraphStart){var a=E(c),b=a.node.getParentOrThrow();a=a.node.spliceText(0,c.patternMatchResults.regExCaptureGroups[0].text.length,"",!0);""===a.getTextContent()&&(a.selectPrevious(),a.remove());var d=b;a=null;var g=d.getChildren(),k=c.markdownCriteria;const l=c.patternMatchResults;if(null!=k.autoFormatKind)switch(k.autoFormatKind){case "paragraphH1":a=t.$createHeadingNode("h1");a.append(...g);break;case "paragraphH2":a=t.$createHeadingNode("h2");
18
- a.append(...g);break;case "paragraphH3":a=t.$createHeadingNode("h3");a.append(...g);break;case "paragraphBlockQuote":a=t.$createQuoteNode();a.append(...g);break;case "paragraphUnorderedList":a=p.$createListNode("ul");d=p.$createListItemNode();d.append(...g);a.append(d);break;case "paragraphOrderedList":a=parseInt(1<l.regExCaptureGroups.length?l.regExCaptureGroups[l.regExCaptureGroups.length-1].text:"1",10);a=p.$createListNode("ol",a);d=p.$createListItemNode();d.append(...g);a.append(d);break;case "paragraphCodeBlock":null!=
19
- c.triggerState&&c.triggerState.isCodeBlock?a=h.$createParagraphNode():(a=n.$createCodeNode(),d=3<=l.regExCaptureGroups.length?l.regExCaptureGroups[2].text:null,null!=d&&0<d.length&&a.setLanguage(d));a.append(...g);break;case "horizontalRule":g=f(),d.insertBefore(g)}null!==a&&b.replace(a)}else if(b=c.markdownCriteria,null!=b.autoFormatKind){a:{a=b.autoFormatKind;switch(a){case "italic":case "bold":case "underline":case "strikethrough":a=[a];break a;case "bold_italic":a=["bold","italic"];break a}a=
20
- null}if(null!=a){if(b=a,7===c.patternMatchResults.regExCaptureGroups.length){H(5,5,c);H(1,1,c);a=c.patternMatchResults.regExCaptureGroups;3<a.length||w(65);if(0!==a[3].text.length&&(a=G(3,3,!1,!0,c),null!=a&&(h.$setSelection(a),a=h.$getSelection(),h.$isRangeSelection(a))))for(g=0;g<b.length;g++)a.formatText(b[g]);I(c)}}else if("link"===b.autoFormatKind&&(b=c.patternMatchResults.regExCaptureGroups,7===b.length&&(g=b[2].text,b=b[4].text,0!==g.length&&0!==b.length))){H(1,5,c);a=c.patternMatchResults.regExCaptureGroups;
21
- if(!(1>=a.length)&&(g={offsetInParent:a[1].offsetInParent,text:g},d=G(1,1,!1,!1,c),null!=d&&(h.$setSelection(d),d=h.$getSelection(),null!=d&&h.$isRangeSelection(d)&&d.isCollapsed())))for(d.insertText(g.text),a.splice(1,0,g),g=g.text.length,d=a.length,k=2;k<d;k++)a[k].offsetInParent+=g;a=G(1,1,!1,!0,c);null!=a&&(h.$setSelection(a),c.editor.dispatchCommand(r.TOGGLE_LINK_COMMAND,b),I(c))}}},{tag:"history-push"})}
22
- function K(e,c){let f=null;e.getEditorState().read(()=>{var a=h.$getSelection();if(h.$isRangeSelection(a)){var b=a.anchor.getNode();a=h.$isTextNode(b)?{node:b,offset:a.anchor.offset}:null}else a=null;if(null!==a){a=C(e,!0,a,c);a:{b=!1===c.isParentAListItemNode?B:A;const k=a.triggerState,l=b.length;for(let m=0;m<l;m++){const v=b[m];if(null!=k&&!1===k.isCodeBlock||"paragraphCodeBlock"===v.autoFormatKind){var d=v,g=a;if(!0===d.requiresParagraphStart)d=F(d,g);else{if(null==g.joinedText){const q=E(g).node.getParentOrThrow();
23
- h.$isElementNode(q)?null==g.joinedText&&(g.joinedText=u.$joinTextNodesInElementNode(q,"\u0004",E(g))):w(52,q.__key)}d=D(g.joinedText,!1,!0,d.regExForAutoFormatting)}if(null!=d){b={markdownCriteria:v,patternMatchResults:d};break a}}}b={markdownCriteria:null,patternMatchResults:null}}null!==b.markdownCriteria&&null!==b.patternMatchResults&&(f=a,f.markdownCriteria=b.markdownCriteria,f.patternMatchResults=b.patternMatchResults)}});return f}
24
- function L(e){let c=null;e.read(()=>{const f=h.$getSelection();if(h.$isRangeSelection(f)&&f.isCollapsed()){var a=f.anchor.getNode(),b=a.getParent(),d=p.$isListItemNode(b);c={anchorOffset:f.anchor.offset,hasParentNode:null!==b,isCodeBlock:n.$isCodeNode(a),isParentAListItemNode:d,isSelectionCollapsed:!0,isSimpleText:h.$isTextNode(a)&&a.isSimpleText(),nodeKey:a.getKey(),textContent:a.getTextContent()}}});return c}
25
- function M(e){e=e.split("\n").map(f=>h.$createParagraphNode().append(h.$createTextNode(f)));const c=h.$getRoot();c.clear();c.append(...e)}
26
- exports.$convertFromMarkdownString=function(e,c){M(e);e=h.$getRoot().getChildren();c=C(c,!1,null,null);const f=e.length;for(let g=0;g<f;g++){var a=e[g];if(h.$isElementNode(a)&&a.getTextContent().length&&a.getChildren().length){var b=c;if(h.$isParagraphNode(a)){const k=B.length;for(let l=0;l<k;l++){const m=B[l];if(!0===m.requiresParagraphStart){var d=a.getFirstChild();h.$isTextNode(d)||w(80);b.textNodeWithOffset={node:d,offset:0};b.joinedText=a.getTextContent();d=F(m,b);null!=d&&(b.markdownCriteria=
27
- m,b.patternMatchResults=d)}}}}b=c;b.joinedText="";b.markdownCriteria={autoFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null};b.patternMatchResults={regExCaptureGroups:[]};b.triggerState=null;b.textNodeWithOffset=null}};
28
- exports.registerMarkdownShortcuts=function(e,c){let f=null;return e.registerUpdateListener(({tags:a})=>{if(!1===a.has("historic")){a=L(e.getEditorState());if(null==a)var b=null;else a:{b=a;var d=f;if(null==b||null==d)b=null;else{var g=x.length;for(let k=0;k<g;k++){const l=x[k].triggerString,m=l.length,v=b.textContent.length,q=b.anchorOffset-m;if(!1===(!0===b.hasParentNode&&b.isSimpleText&&b.isSelectionCollapsed&&b.nodeKey===d.nodeKey&&b.anchorOffset!==d.anchorOffset&&0<=q&&q+m<=v&&b.textContent.substr(q,
29
- m)===l&&b.textContent!==d.textContent)){b=null;break a}}b=K(e,b)}}null!=b&&J(e,b,c);f=a}else f=null})};
7
+ var k=require("@lexical/code"),m=require("@lexical/list"),p=require("lexical"),t=require("@lexical/link"),u=require("@lexical/rich-text"),v=require("@lexical/text");function w(b){throw Error(`Minified Lexical error #${b}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
8
+ const x=[{triggerKind:"space_trigger",triggerString:" "}],y={markdownFormatKind:null,regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:!1},A={...y,requiresParagraphStart:!0},B={...A,markdownFormatKind:"paragraphCodeBlock",regEx:/^(```)$/,regExForAutoFormatting:/^(```)([a-z]*)( )/},C=[{...y,markdownFormatKind:"strikethrough_italic_bold",regEx:/(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)/,regExForAutoFormatting:/(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/},
9
+ {...y,markdownFormatKind:"italic_bold",regEx:/(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,regExForAutoFormatting:/(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/},{...y,markdownFormatKind:"strikethrough_italic",regEx:/(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,regExForAutoFormatting:/(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/},{...y,markdownFormatKind:"strikethrough_bold",regEx:/(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,regExForAutoFormatting:/(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/},
10
+ {...y,markdownFormatKind:"code",regEx:/(`)([^`]*)(`)/,regExForAutoFormatting:/(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/},{...y,markdownFormatKind:"italic",regEx:/(\*)([^\*]*)(\*)/,regExForAutoFormatting:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/},{...y,markdownFormatKind:"bold",regEx:/(\*\*)([^\*\*]*)(\*\*)/,regExForAutoFormatting:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/},{...y,markdownFormatKind:"bold",regEx:/(__)(\s*)([^__]*)(\s*)(__)/,regExForAutoFormatting:/(__)(\s*)([^__]*)(\s*)(__)(\s)$/},{...y,markdownFormatKind:"italic",
11
+ regEx:/(_)([^_]*)(_)/,regExForAutoFormatting:/(_)()([^_]*)()(_)(\s)$/},{...y,markdownFormatKind:"underline",regEx:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)/,regExForAutoFormatting:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/},{...y,markdownFormatKind:"strikethrough",regEx:/(~~)([^~~]*)(~~)/,regExForAutoFormatting:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/},{...y,markdownFormatKind:"link",regEx:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))/,regExForAutoFormatting:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))(\s)$/}],D=[{...A,
12
+ markdownFormatKind:"paragraphH1",regEx:/^(?:# )/,regExForAutoFormatting:/^(?:# )/},{...A,markdownFormatKind:"paragraphH2",regEx:/^(?:## )/,regExForAutoFormatting:/^(?:## )/},{...A,markdownFormatKind:"paragraphH2",regEx:/^(?:### )/,regExForAutoFormatting:/^(?:### )/},{...A,markdownFormatKind:"paragraphBlockQuote",regEx:/^(?:> )/,regExForAutoFormatting:/^(?:> )/},{...A,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})(?:- )/,regExForAutoFormatting:/^(\s{0,10})(?:- )/},{...A,markdownFormatKind:"paragraphUnorderedList",
13
+ regEx:/^(\s{0,10})(?:\* )/,regExForAutoFormatting:/^(\s{0,10})(?:\* )/},{...A,markdownFormatKind:"paragraphOrderedList",regEx:/^(\s{0,10})(\d+)\.\s/,regExForAutoFormatting:/^(\s{0,10})(\d+)\.\s/},B,{...A,markdownFormatKind:"horizontalRule",regEx:/^(?:\*\*\*)$/,regExForAutoFormatting:/^(?:\*\*\* )/},{...A,markdownFormatKind:"horizontalRule",regEx:/^(?:---)$/,regExForAutoFormatting:/^(?:--- )/},...C];
14
+ function E(b,d,e,a){return{currentElementNode:null,editor:b,isAutoFormatting:d,isWithinCodeBlock:!1,joinedText:null,markdownCriteria:{markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null},patternMatchResults:{regExCaptureGroups:[]},textNodeWithOffset:e,triggerState:a}}
15
+ function F(b,d,e,a){const c={regExCaptureGroups:[]};a=b.match(a);if(null!==a&&0<a.length&&(!1===d||0===a.index)&&(!1===e||a.index+a[0].length===b.length)){b=a.length;d=a.index;for(e=0;e<b;e++){const f=a[e];c.regExCaptureGroups.push({offsetInParent:d,text:f});0<e&&(d+=f.length)}return c}return null}function I(b){b=b.textNodeWithOffset;null==b&&w(82);return b}
16
+ function J(b,d){var e=I(d);return null===e.node.getPreviousSibling()?(e=e.node.getTextContent(),F(e,!0,!1,d.isAutoFormatting?b.regExForAutoFormatting:b.regEx)):null}
17
+ function K(b,d,e){var a=null,c=d.getChildren();const f=b.markdownCriteria,g=b.patternMatchResults;if(null!=f.markdownFormatKind)switch(f.markdownFormatKind){case "paragraphH1":a=u.$createHeadingNode("h1");a.append(...c);break;case "paragraphH2":a=u.$createHeadingNode("h2");a.append(...c);break;case "paragraphH3":a=u.$createHeadingNode("h3");a.append(...c);break;case "paragraphBlockQuote":a=u.$createQuoteNode();a.append(...c);break;case "paragraphUnorderedList":return L(d,c,g,"ul"),{newNode:null,shouldDelete:!1};
18
+ case "paragraphOrderedList":return a=1<g.regExCaptureGroups.length?g.regExCaptureGroups[g.regExCaptureGroups.length-1].text:"1",b=b.isAutoFormatting?parseInt(a,10):void 0,L(d,c,g,"ol",b),{newNode:null,shouldDelete:!1};case "paragraphCodeBlock":if(!1===b.isAutoFormatting){if(0<b.patternMatchResults.regExCaptureGroups.length)return b.isWithinCodeBlock=!0!==b.isWithinCodeBlock,b.currentElementNode=null,{newNode:null,shouldDelete:!0};if(b.isWithinCodeBlock){if(null==b.currentElementNode)return d=k.$createCodeNode(),
19
+ d.append(...c),b.currentElementNode=d,{newNode:d,shouldDelete:!1};null!=b.currentElementNode&&(d=b.currentElementNode,b=p.$createLineBreakNode(),d.append(b),c.length&&d.append(b),d.append(...c))}return{newNode:null,shouldDelete:!0}}null!=b.triggerState&&b.triggerState.isCodeBlock?a=p.$createParagraphNode():(a=k.$createCodeNode(),d=3<=g.regExCaptureGroups.length?g.regExCaptureGroups[2].text:null,null!=d&&0<d.length&&a.setLanguage(d));a.append(...c);break;case "horizontalRule":null!=e&&(c=e(),d.insertBefore(c))}return{newNode:a,
20
+ shouldDelete:!1}}function L(b,d,e,a,c){const f=m.$createListItemNode();e=(e=e.regExCaptureGroups[0].text.match(/^\s*/))?Math.floor(e[0].length/4):0;f.append(...d);d=b.getPreviousSibling();m.$isListNode(d)&&d.getTag()===a?(d.append(f),b.remove()):(a=m.$createListNode(a,c),a.append(f),b.replace(a));e&&f.setIndent(e)}
21
+ function M(b,d,e){if(null!=d.textNodeWithOffset){var a=I(d);0<d.patternMatchResults.regExCaptureGroups.length&&(a=a.node.spliceText(0,d.patternMatchResults.regExCaptureGroups[0].text.length,"",!0),""===a.getTextContent()&&(a.selectPrevious(),a.remove()))}const {newNode:c,shouldDelete:f}=K(d,b,e);f?b.remove():null!==c&&b.replace(c)}
22
+ function N(b){switch(b){case "italic":case "bold":case "underline":case "strikethrough":case "code":return[b];case "strikethrough_italic_bold":return["strikethrough","italic","bold"];case "italic_bold":return["italic","bold"];case "strikethrough_italic":return["strikethrough","italic"];case "strikethrough_bold":return["strikethrough","bold"]}return null}
23
+ function Q(b,d,e,a,c){var f=c.patternMatchResults;const g=f.regExCaptureGroups;var h=g.length;if(b>=h||d>=h)return null;c=I(c).node.getParentOrThrow();h=f.regExCaptureGroups.length;2>h?f=0:(--h,f=f.regExCaptureGroups[h].offsetInParent+f.regExCaptureGroups[h].text.length);b=g[b];d=g[d];a=a?d.offsetInParent+d.text.length:d.offsetInParent;e=v.$findNodeWithOffsetFromJoinedText(e?b.offsetInParent+b.text.length:b.offsetInParent,f,1,c);a=v.$findNodeWithOffsetFromJoinedText(a,f,1,c);if(null==e||null==a)return null;
24
+ c=p.$createRangeSelection();c.anchor.set(e.node.getKey(),e.offset,"text");c.focus.set(a.node.getKey(),a.offset,"text");return c}function R(b,d,e){const a=e.patternMatchResults.regExCaptureGroups;e=Q(b,d,!1,!0,e);if(null!=e&&(p.$setSelection(e),e=p.$getSelection(),null!=e&&p.$isRangeSelection(e)&&!1===e.isCollapsed())){e.removeText();e=0;const c=a.length;for(let f=b;f<c;f++){const g=a[f];f>b&&(g.offsetInParent-=e);f<=d&&(e+=g.text.length,g.text="")}}}
25
+ function S(b){var d=b.patternMatchResults.regExCaptureGroups.length;2>d||(--d,b=Q(d,d,!0,!0,b),null!=b&&p.$setSelection(b))}
26
+ function T(b,d,e){b.update(()=>{if(!0===d.markdownCriteria.requiresParagraphStart){var a=I(d).node.getParentOrThrow();M(a,d,e)}else if(a=d.markdownCriteria,null!=a.markdownFormatKind){var c=N(a.markdownFormatKind);if(null!=c){if(a=c,7===d.patternMatchResults.regExCaptureGroups.length){R(5,5,d);R(1,1,d);c=d.patternMatchResults.regExCaptureGroups;3<c.length||w(65);if(0!==c[3].text.length&&(c=Q(3,3,!1,!0,d),null!=c&&(p.$setSelection(c),c=p.$getSelection(),p.$isRangeSelection(c))))for(var f=0;f<a.length;f++)c.formatText(a[f]);
27
+ S(d)}}else if("link"===a.markdownFormatKind&&(a=d.patternMatchResults.regExCaptureGroups,7===a.length&&(f=a[2].text,a=a[4].text,0!==f.length&&0!==a.length))){R(1,5,d);c=d.patternMatchResults.regExCaptureGroups;if(!(1>=c.length)){f={offsetInParent:c[1].offsetInParent,text:f};var g=Q(1,1,!1,!1,d);if(null!=g&&(p.$setSelection(g),g=p.$getSelection(),null!=g&&p.$isRangeSelection(g)&&g.isCollapsed())){g.insertText(f.text);c.splice(1,0,f);f=f.text.length;g=c.length;for(let h=2;h<g;h++)c[h].offsetInParent+=
28
+ f}}c=Q(1,1,!1,!0,d);null!=c&&(p.$setSelection(c),d.editor.dispatchCommand(t.TOGGLE_LINK_COMMAND,a),S(d))}}},{tag:"history-push"})}
29
+ function U(b,d){let e=null;b.getEditorState().read(()=>{var a=p.$getSelection();if(p.$isRangeSelection(a)){var c=a.anchor.getNode();a=p.$isTextNode(c)?{node:c,offset:a.anchor.offset}:null}else a=null;if(null!==a){a=E(b,!0,a,d);a:{c=!1===d.isParentAListItemNode?D:C;const h=a.triggerState,r=c.length;for(let n=0;n<r;n++){const l=c[n];if(null!=h&&!1===h.isCodeBlock||"paragraphCodeBlock"===l.markdownFormatKind){var f=l,g=a;if(!0===f.requiresParagraphStart)f=J(f,g);else{if(null==g.joinedText){const q=I(g).node.getParentOrThrow();
30
+ p.$isElementNode(q)?null==g.joinedText&&(g.joinedText=v.$joinTextNodesInElementNode(q,"\u0004",I(g))):w(52,q.__key)}f=F(g.joinedText,!1,!0,f.regExForAutoFormatting)}if(null!=f){c={markdownCriteria:l,patternMatchResults:f};break a}}}c={markdownCriteria:null,patternMatchResults:null}}null!==c.markdownCriteria&&null!==c.patternMatchResults&&(e=a,e.markdownCriteria=c.markdownCriteria,e.patternMatchResults=c.patternMatchResults)}});return e}
31
+ function V(b){let d=null;b.read(()=>{const e=p.$getSelection();if(p.$isRangeSelection(e)&&e.isCollapsed()){var a=e.anchor.getNode(),c=a.getParent(),f=m.$isListItemNode(c);d={anchorOffset:e.anchor.offset,hasParentNode:null!==c,isCodeBlock:k.$isCodeNode(a),isParentAListItemNode:f,isSelectionCollapsed:!0,isSimpleText:p.$isTextNode(a)&&a.isSimpleText(),nodeKey:a.getKey(),textContent:a.getTextContent()}}});return d}
32
+ exports.$convertFromMarkdownString=function(b,d,e){if(b.length){var a=[];b=b.split("\n");var c=b.length;for(var f=0;f<c;f++)0<b[f].length?a.push(p.$createParagraphNode().append(p.$createTextNode(b[f]))):a.push(p.$createParagraphNode());a.length?(b=p.$getRoot(),b.clear(),b.append(...a),a=b):a=null}else a=null;if(null!=a)for(d=E(d,!1,null,null),a=p.$getRoot(),b=!1,c=0;!b;){b=!0;f=a.getChildren();const q=f.length;for(let z=c;z<q;z++){var g=f[z];if(p.$isElementNode(g)){var h=d,r=e,n=g.getTextContent();
33
+ if(p.$isParagraphNode(g)){var l=g.getFirstChild();const O=p.$isTextNode(l);if(!0===h.isWithinCodeBlock)null!=l&&O&&(h.textNodeWithOffset={node:l,offset:0},l=F(n,!0,!1,h.isAutoFormatting?B.regExForAutoFormatting:B.regEx),null!=l&&(h.patternMatchResults=l)),h.markdownCriteria=B,M(g,h,r);else if(g.getChildren().length){n=D.length;for(let G=0;G<n;G++){const H=D[G];if(!0===H.requiresParagraphStart){null!=l&&O||w(80);h.textNodeWithOffset={node:l,offset:0};h.joinedText=g.getTextContent();const P=J(H,h);
34
+ if(null!=P){h.markdownCriteria=H;h.patternMatchResults=P;M(g,h,r);break}}}}}}h=d;h.joinedText="";h.markdownCriteria={markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null};h.patternMatchResults={regExCaptureGroups:[]};h.triggerState=null;h.textNodeWithOffset=null;if(a.getChildren().length!==q){c=z;b=!1;break}}}};
35
+ exports.registerMarkdownShortcuts=function(b,d){let e=null;return b.registerUpdateListener(({tags:a})=>{if(!1===a.has("historic")){a=V(b.getEditorState());if(null==a)var c=null;else a:{c=a;var f=e;if(null==c||null==f)c=null;else{var g=x.length;for(let h=0;h<g;h++){const r=x[h].triggerString,n=r.length,l=c.textContent.length,q=c.anchorOffset-n;if(!1===(!0===c.hasParentNode&&c.isSimpleText&&c.isSelectionCollapsed&&c.anchorOffset!==f.anchorOffset&&0<=q&&q+n<=l&&c.textContent.substr(q,n)===r&&c.textContent!==
36
+ f.textContent)){c=null;break a}}c=U(b,c)}}null!=c&&T(b,c,d);e=a}else e=null})};
package/package.json CHANGED
@@ -8,18 +8,18 @@
8
8
  "markdown"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.1.19",
11
+ "version": "0.2.0",
12
12
  "main": "LexicalMarkdown.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.1.19"
14
+ "lexical": "0.2.0"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.1.19",
18
- "@lexical/code": "0.1.19",
19
- "@lexical/text": "0.1.19",
20
- "@lexical/rich-text": "0.1.19",
21
- "@lexical/list": "0.1.19",
22
- "@lexical/link": "0.1.19"
17
+ "@lexical/utils": "0.2.0",
18
+ "@lexical/code": "0.2.0",
19
+ "@lexical/text": "0.2.0",
20
+ "@lexical/rich-text": "0.2.0",
21
+ "@lexical/list": "0.2.0",
22
+ "@lexical/link": "0.2.0"
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",