@lexical/markdown 0.1.21 → 0.2.2

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.
@@ -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,7 +49,7 @@ 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
55
  markdownFormatKind: null,
@@ -62,33 +62,43 @@ const paragraphStartBase = { ...autoFormatBase,
62
62
  };
63
63
  const markdownHeader1 = { ...paragraphStartBase,
64
64
  markdownFormatKind: 'paragraphH1',
65
- regEx: /^(?:#)/,
65
+ regEx: /^(?:# )/,
66
66
  regExForAutoFormatting: /^(?:# )/
67
67
  };
68
68
  const markdownHeader2 = { ...paragraphStartBase,
69
69
  markdownFormatKind: 'paragraphH2',
70
- regEx: /^(?:##)/,
70
+ regEx: /^(?:## )/,
71
71
  regExForAutoFormatting: /^(?:## )/
72
72
  };
73
73
  const markdownHeader3 = { ...paragraphStartBase,
74
- markdownFormatKind: 'paragraphH2',
75
- regEx: /^(?:###)/,
74
+ markdownFormatKind: 'paragraphH3',
75
+ regEx: /^(?:### )/,
76
76
  regExForAutoFormatting: /^(?:### )/
77
77
  };
78
+ const markdownHeader4 = { ...paragraphStartBase,
79
+ markdownFormatKind: 'paragraphH4',
80
+ regEx: /^(?:#### )/,
81
+ regExForAutoFormatting: /^(?:#### )/
82
+ };
83
+ const markdownHeader5 = { ...paragraphStartBase,
84
+ markdownFormatKind: 'paragraphH5',
85
+ regEx: /^(?:##### )/,
86
+ regExForAutoFormatting: /^(?:##### )/
87
+ };
78
88
  const markdownBlockQuote = { ...paragraphStartBase,
79
89
  markdownFormatKind: 'paragraphBlockQuote',
80
- regEx: /^(?:>)/,
90
+ regEx: /^(?:> )/,
81
91
  regExForAutoFormatting: /^(?:> )/
82
92
  };
83
93
  const markdownUnorderedListDash = { ...paragraphStartBase,
84
94
  markdownFormatKind: 'paragraphUnorderedList',
85
- regEx: /^(?:- )/,
86
- regExForAutoFormatting: /^(?:- )/
95
+ regEx: /^(\s{0,10})(?:- )/,
96
+ regExForAutoFormatting: /^(\s{0,10})(?:- )/
87
97
  };
88
98
  const markdownUnorderedListAsterisk = { ...paragraphStartBase,
89
99
  markdownFormatKind: 'paragraphUnorderedList',
90
- regEx: /^(?:\* )/,
91
- regExForAutoFormatting: /^(?:\* )/
100
+ regEx: /^(\s{0,10})(?:\* )/,
101
+ regExForAutoFormatting: /^(\s{0,10})(?:\* )/
92
102
  };
93
103
  const markdownCodeBlock = { ...paragraphStartBase,
94
104
  markdownFormatKind: 'paragraphCodeBlock',
@@ -97,8 +107,8 @@ const markdownCodeBlock = { ...paragraphStartBase,
97
107
  };
98
108
  const markdownOrderedList = { ...paragraphStartBase,
99
109
  markdownFormatKind: 'paragraphOrderedList',
100
- regEx: /^(\d+)\.\s/,
101
- regExForAutoFormatting: /^(\d+)\.\s/
110
+ regEx: /^(\s{0,10})(\d+)\.\s/,
111
+ regExForAutoFormatting: /^(\s{0,10})(\d+)\.\s/
102
112
  };
103
113
  const markdownHorizontalRule = { ...paragraphStartBase,
104
114
  markdownFormatKind: 'horizontalRule',
@@ -110,45 +120,89 @@ const markdownHorizontalRuleUsingDashes = { ...paragraphStartBase,
110
120
  regEx: /^(?:---)$/,
111
121
  regExForAutoFormatting: /^(?:--- )/
112
122
  };
113
- const markdownItalic = { ...autoFormatBase,
114
- markdownFormatKind: 'italic',
115
- regEx: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)/,
116
- regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
123
+ const markdownInlineCode = { ...autoFormatBase,
124
+ markdownFormatKind: 'code',
125
+ regEx: /(`)([^`]*)(`)/,
126
+ regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/
117
127
  };
118
128
  const markdownBold = { ...autoFormatBase,
119
129
  markdownFormatKind: 'bold',
120
- regEx: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)/,
130
+ regEx: /(\*\*)(\s*)([^\*\*]*)(\s*)(\*\*)()/,
121
131
  regExForAutoFormatting: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
122
132
  };
123
- const markdownBoldWithUnderlines = { ...autoFormatBase,
133
+ const markdownItalic = { ...autoFormatBase,
134
+ markdownFormatKind: 'italic',
135
+ regEx: /(\*)(\s*)([^\*]*)(\s*)(\*)()/,
136
+ regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
137
+ };
138
+ const markdownBold2 = { ...autoFormatBase,
124
139
  markdownFormatKind: 'bold',
125
- regEx: /(__)(\s*)([^__]*)(\s*)(__)/,
140
+ regEx: /(__)(\s*)([^__]*)(\s*)(__)()/,
126
141
  regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
127
142
  };
128
- const markdownBoldItalic = { ...autoFormatBase,
129
- markdownFormatKind: 'bold_italic',
130
- regEx: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)/,
131
- regExForAutoFormatting: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)(\s)$/
143
+ const markdownItalic2 = { ...autoFormatBase,
144
+ markdownFormatKind: 'italic',
145
+ regEx: /(_)()([^_]*)()(_)()/,
146
+ regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/ // Maintain 7 groups.
147
+
132
148
  }; // Markdown does not support underline, but we can allow folks to use
133
149
  // the HTML tags for underline.
134
150
 
135
151
  const fakeMarkdownUnderline = { ...autoFormatBase,
136
152
  markdownFormatKind: 'underline',
137
- regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)/,
153
+ regEx: /(\<u\>)(\s*)([^\<]*)(\s*)(\<\/u\>)()/,
138
154
  regExForAutoFormatting: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)(\s)$/
139
155
  };
140
156
  const markdownStrikethrough = { ...autoFormatBase,
141
157
  markdownFormatKind: 'strikethrough',
142
- regEx: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)/,
158
+ regEx: /(~~)(\s*)([^~~]*)(\s*)(~~)()/,
143
159
  regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
144
160
  };
161
+ const markdownStrikethroughItalicBold = { ...autoFormatBase,
162
+ markdownFormatKind: 'strikethrough_italic_bold',
163
+ regEx: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)()/,
164
+ regExForAutoFormatting: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/
165
+ };
166
+ const markdownItalicbold = { ...autoFormatBase,
167
+ markdownFormatKind: 'italic_bold',
168
+ regEx: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,
169
+ regExForAutoFormatting: /(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/
170
+ };
171
+ const markdownStrikethroughItalic = { ...autoFormatBase,
172
+ markdownFormatKind: 'strikethrough_italic',
173
+ regEx: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,
174
+ regExForAutoFormatting: /(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/
175
+ };
176
+ const markdownStrikethroughBold = { ...autoFormatBase,
177
+ markdownFormatKind: 'strikethrough_bold',
178
+ regEx: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,
179
+ regExForAutoFormatting: /(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/
180
+ };
145
181
  const markdownLink = { ...autoFormatBase,
146
182
  markdownFormatKind: 'link',
147
- regEx: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))/,
148
- regExForAutoFormatting: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))(\s)$/
183
+ regEx: /(\[)([^\]]*)(\]\()([^)]*)(\)*)()/,
184
+ regExForAutoFormatting: /(\[)([^\]]*)(\]\()([^)]*)(\)*)(\s)$/
149
185
  };
150
- const allMarkdownCriteriaForTextNodes = [markdownBoldItalic, markdownItalic, markdownBold, markdownBoldWithUnderlines, fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
151
- const allMarkdownCriteria = [markdownHeader1, markdownHeader2, markdownHeader3, markdownBlockQuote, markdownUnorderedListDash, markdownUnorderedListAsterisk, markdownOrderedList, markdownCodeBlock, markdownHorizontalRule, markdownHorizontalRuleUsingDashes, ...allMarkdownCriteriaForTextNodes];
186
+ const allMarkdownCriteriaForTextNodes = [// Place the combination formats ahead of the individual formats.
187
+ // Combos
188
+ markdownStrikethroughItalicBold, markdownItalicbold, markdownStrikethroughItalic, markdownStrikethroughBold, // Individuals
189
+ markdownInlineCode, markdownBold, markdownItalic, // Must appear after markdownBold
190
+ markdownBold2, markdownItalic2, // Must appear after markdownBold2.
191
+ fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
192
+ const allMarkdownCriteriaForParagraphs = [markdownHeader1, markdownHeader2, markdownHeader3, markdownHeader4, markdownHeader5, markdownBlockQuote, markdownUnorderedListDash, markdownUnorderedListAsterisk, markdownOrderedList, markdownCodeBlock, markdownHorizontalRule, markdownHorizontalRuleUsingDashes];
193
+ const allMarkdownCriteria = [...allMarkdownCriteriaForParagraphs, ...allMarkdownCriteriaForTextNodes];
194
+ function getAllTriggers() {
195
+ return triggers;
196
+ }
197
+ function getAllMarkdownCriteriaForParagraphs() {
198
+ return allMarkdownCriteriaForParagraphs;
199
+ }
200
+ function getAllMarkdownCriteriaForTextNodes() {
201
+ return allMarkdownCriteriaForTextNodes;
202
+ }
203
+ function getAllMarkdownCriteria() {
204
+ return allMarkdownCriteria;
205
+ }
152
206
  function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset, triggerState) {
153
207
  return {
154
208
  currentElementNode: null,
@@ -172,7 +226,7 @@ function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset,
172
226
  };
173
227
  }
174
228
  function resetScanningContext(scanningContext) {
175
- scanningContext.joinedText = '';
229
+ scanningContext.joinedText = null;
176
230
  scanningContext.markdownCriteria = {
177
231
  markdownFormatKind: 'noTransformation',
178
232
  regEx: /(?:)/,
@@ -191,6 +245,13 @@ function resetScanningContext(scanningContext) {
191
245
  function getCodeBlockCriteria() {
192
246
  return markdownCodeBlock;
193
247
  }
248
+ function getPatternMatchResultsForCriteria(markdownCriteria, scanningContext, parentElementNode) {
249
+ if (markdownCriteria.requiresParagraphStart === true) {
250
+ return getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext);
251
+ }
252
+
253
+ return getPatternMatchResultsForText(markdownCriteria, scanningContext, parentElementNode);
254
+ }
194
255
  function getPatternMatchResultsForCodeBlock(scanningContext, text) {
195
256
  const markdownCriteria = getCodeBlockCriteria();
196
257
  return getPatternMatchResultsWithRegEx(text, true, false, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
@@ -226,6 +287,9 @@ function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfS
226
287
  return null;
227
288
  }
228
289
 
290
+ function hasPatternMatchResults(scanningContext) {
291
+ return scanningContext.patternMatchResults.regExCaptureGroups.length > 0;
292
+ }
229
293
  function getTextNodeWithOffsetOrThrow(scanningContext) {
230
294
  const textNodeWithOffset = scanningContext.textNodeWithOffset;
231
295
 
@@ -237,6 +301,7 @@ function getTextNodeWithOffsetOrThrow(scanningContext) {
237
301
 
238
302
  return textNodeWithOffset;
239
303
  }
304
+
240
305
  function getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext) {
241
306
  const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext); // At start of paragraph.
242
307
 
@@ -247,23 +312,23 @@ function getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext)
247
312
 
248
313
  return null;
249
314
  }
250
- function getPatternMatchResultsForText(markdownCriteria, scanningContext) {
251
- if (scanningContext.joinedText == null) {
252
- const parentNode = getParent(scanningContext);
253
315
 
254
- if (lexical.$isElementNode(parentNode)) {
316
+ function getPatternMatchResultsForText(markdownCriteria, scanningContext, parentElementNode) {
317
+ if (scanningContext.joinedText == null) {
318
+ if (lexical.$isElementNode(parentElementNode)) {
255
319
  if (scanningContext.joinedText == null) {
256
320
  // Lazy calculate the text to search.
257
- scanningContext.joinedText = text.$joinTextNodesInElementNode(parentNode, SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES, getTextNodeWithOffsetOrThrow(scanningContext));
321
+ scanningContext.joinedText = text.$joinTextNodesInElementNode(parentElementNode, SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES, getTextNodeWithOffsetOrThrow(scanningContext));
258
322
  }
259
323
  } else {
260
324
  {
261
- throw Error(`Expected node ${parentNode.__key} to to be a ElementNode.`);
325
+ throw Error(`Expected node ${parentElementNode.__key} to to be a ElementNode.`);
262
326
  }
263
327
  }
264
328
  }
265
329
 
266
- return getPatternMatchResultsWithRegEx(scanningContext.joinedText, false, true, markdownCriteria.regExForAutoFormatting);
330
+ const matchMustAppearAtEndOfString = markdownCriteria.regExForAutoFormatting === true;
331
+ return getPatternMatchResultsWithRegEx(scanningContext.joinedText, false, matchMustAppearAtEndOfString, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
267
332
  }
268
333
 
269
334
  function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNode) {
@@ -305,9 +370,9 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
305
370
  };
306
371
  }
307
372
 
308
- case 'paragraphBlockQuote':
373
+ case 'paragraphH4':
309
374
  {
310
- newNode = richText.$createQuoteNode();
375
+ newNode = richText.$createHeadingNode('h4');
311
376
  newNode.append(...children);
312
377
  return {
313
378
  newNode,
@@ -315,37 +380,54 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
315
380
  };
316
381
  }
317
382
 
318
- case 'paragraphUnorderedList':
383
+ case 'paragraphH5':
319
384
  {
320
- newNode = list.$createListNode('ul');
321
- const listItem = list.$createListItemNode();
322
- listItem.append(...children);
323
- newNode.append(listItem);
385
+ newNode = richText.$createHeadingNode('h5');
386
+ newNode.append(...children);
324
387
  return {
325
388
  newNode,
326
389
  shouldDelete
327
390
  };
328
391
  }
329
392
 
330
- case 'paragraphOrderedList':
393
+ case 'paragraphBlockQuote':
331
394
  {
332
- const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1';
333
- const start = parseInt(startAsString, 10);
334
- newNode = list.$createListNode('ol', start);
335
- const listItem = list.$createListItemNode();
336
- listItem.append(...children);
337
- newNode.append(listItem);
395
+ newNode = richText.$createQuoteNode();
396
+ newNode.append(...children);
338
397
  return {
339
398
  newNode,
340
399
  shouldDelete
341
400
  };
342
401
  }
343
402
 
403
+ case 'paragraphUnorderedList':
404
+ {
405
+ createListOrMergeWithPrevious(element, children, patternMatchResults, 'ul');
406
+ return {
407
+ newNode: null,
408
+ shouldDelete: false
409
+ };
410
+ }
411
+
412
+ case 'paragraphOrderedList':
413
+ {
414
+ const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1'; // For conversion, don't use start number.
415
+ // For short-cuts aka autoFormatting, use start number.
416
+ // Later, this should be surface dependent and externalized.
417
+
418
+ const start = scanningContext.isAutoFormatting ? parseInt(startAsString, 10) : undefined;
419
+ createListOrMergeWithPrevious(element, children, patternMatchResults, 'ol', start);
420
+ return {
421
+ newNode: null,
422
+ shouldDelete: false
423
+ };
424
+ }
425
+
344
426
  case 'paragraphCodeBlock':
345
427
  {
346
428
  // Toggle code and paragraph nodes.
347
429
  if (scanningContext.isAutoFormatting === false) {
348
- const shouldToggle = scanningContext.patternMatchResults.regExCaptureGroups.length > 0;
430
+ const shouldToggle = hasPatternMatchResults(scanningContext);
349
431
 
350
432
  if (shouldToggle) {
351
433
  scanningContext.isWithinCodeBlock = scanningContext.isWithinCodeBlock !== true; // When toggling, always clear the code block element node.
@@ -374,6 +456,11 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
374
456
  const codeBlockNode = scanningContext.currentElementNode;
375
457
  const lineBreakNode = lexical.$createLineBreakNode();
376
458
  codeBlockNode.append(lineBreakNode);
459
+
460
+ if (children.length) {
461
+ codeBlockNode.append(lineBreakNode);
462
+ }
463
+
377
464
  codeBlockNode.append(...children);
378
465
  }
379
466
  }
@@ -421,18 +508,50 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
421
508
  };
422
509
  }
423
510
 
424
- function transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNode) {
425
- const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
426
- const element = textNodeWithOffset.node.getParentOrThrow();
511
+ function createListOrMergeWithPrevious(element, children, patternMatchResults, tag, start) {
512
+ const listItem = list.$createListItemNode();
513
+ const indentMatch = patternMatchResults.regExCaptureGroups[0].text.match(/^\s*/);
514
+ const indent = indentMatch ? Math.floor(indentMatch[0].length / 4) : 0;
515
+ listItem.append(...children); // Checking if previous element is a list, and if so append
516
+ // new list item inside instead of creating new list
427
517
 
428
- if (scanningContext.patternMatchResults.regExCaptureGroups.length > 0) {
429
- const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
518
+ const prevElement = element.getPreviousSibling();
430
519
 
431
- const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
520
+ if (list.$isListNode(prevElement) && prevElement.getTag() === tag) {
521
+ prevElement.append(listItem);
522
+ element.remove();
523
+ } else {
524
+ const list$1 = list.$createListNode(tag, start);
525
+ list$1.append(listItem);
526
+ element.replace(list$1);
527
+ }
528
+
529
+ if (indent) {
530
+ listItem.setIndent(indent);
531
+ }
532
+ }
432
533
 
433
- if (textNode.getTextContent() === '') {
434
- textNode.selectPrevious();
435
- textNode.remove();
534
+ function transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode) {
535
+ if (scanningContext.markdownCriteria.requiresParagraphStart === true) {
536
+ transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
537
+ } else {
538
+ transformTextNodeForText(scanningContext, elementNode);
539
+ }
540
+ }
541
+
542
+ function transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode) {
543
+ if (scanningContext.textNodeWithOffset != null) {
544
+ const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
545
+
546
+ if (hasPatternMatchResults(scanningContext)) {
547
+ const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
548
+
549
+ const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
550
+
551
+ if (textNode.getTextContent() === '') {
552
+ textNode.selectPrevious();
553
+ textNode.remove();
554
+ }
436
555
  }
437
556
  } // Transform the current element kind to the new element kind.
438
557
 
@@ -440,32 +559,33 @@ function transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNod
440
559
  const {
441
560
  newNode,
442
561
  shouldDelete
443
- } = getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNode);
562
+ } = getNewNodeForCriteria(scanningContext, elementNode, createHorizontalRuleNode);
444
563
 
445
564
  if (shouldDelete) {
446
- element.remove();
565
+ elementNode.remove();
447
566
  } else if (newNode !== null) {
448
- element.replace(newNode);
567
+ elementNode.replace(newNode);
449
568
  }
450
569
  }
451
- function transformTextNodeForText(scanningContext) {
570
+
571
+ function transformTextNodeForText(scanningContext, parentElementNode) {
452
572
  const markdownCriteria = scanningContext.markdownCriteria;
453
573
 
454
574
  if (markdownCriteria.markdownFormatKind != null) {
455
575
  const formatting = getTextFormatType(markdownCriteria.markdownFormatKind);
456
576
 
457
577
  if (formatting != null) {
458
- transformTextNodeWithFormatting(formatting, scanningContext);
578
+ transformTextNodeWithFormatting(formatting, scanningContext, parentElementNode);
459
579
  return;
460
580
  }
461
581
 
462
582
  if (markdownCriteria.markdownFormatKind === 'link') {
463
- transformTextNodeWithLink(scanningContext);
583
+ transformTextNodeWithLink(scanningContext, parentElementNode);
464
584
  }
465
585
  }
466
586
  }
467
587
 
468
- function transformTextNodeWithFormatting(formatting, scanningContext) {
588
+ function transformTextNodeWithFormatting(formatting, scanningContext, parentElementNode) {
469
589
  const patternMatchResults = scanningContext.patternMatchResults;
470
590
  const groupCount = patternMatchResults.regExCaptureGroups.length;
471
591
 
@@ -484,16 +604,16 @@ function transformTextNodeWithFormatting(formatting, scanningContext) {
484
604
  // Remove group 5.
485
605
 
486
606
 
487
- removeTextByCaptureGroups(5, 5, scanningContext); // Remove group 1.
607
+ removeTextByCaptureGroups(5, 5, scanningContext, parentElementNode); // Remove group 1.
488
608
 
489
- removeTextByCaptureGroups(1, 1, scanningContext); // Apply the formatting.
609
+ removeTextByCaptureGroups(1, 1, scanningContext, parentElementNode); // Apply the formatting.
490
610
 
491
- formatTextInCaptureGroupIndex(formatting, 3, scanningContext); // Place caret at end of final capture group.
611
+ formatTextInCaptureGroupIndex(formatting, 3, scanningContext, parentElementNode); // Place caret at end of final capture group.
492
612
 
493
- selectAfterFinalCaptureGroup(scanningContext);
613
+ selectAfterFinalCaptureGroup(scanningContext, parentElementNode);
494
614
  }
495
615
 
496
- function transformTextNodeWithLink(scanningContext) {
616
+ function transformTextNodeWithLink(scanningContext, parentElementNode) {
497
617
  const patternMatchResults = scanningContext.patternMatchResults;
498
618
  const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
499
619
  const groupCount = regExCaptureGroups.length;
@@ -519,10 +639,10 @@ function transformTextNodeWithLink(scanningContext) {
519
639
  } // Remove the initial pattern through to the final pattern.
520
640
 
521
641
 
522
- removeTextByCaptureGroups(1, 5, scanningContext);
642
+ removeTextByCaptureGroups(1, 5, scanningContext, parentElementNode);
523
643
  insertTextPriorToCaptureGroup(1, // Insert at the beginning of the meaningful capture groups, namely index 1. Index 0 refers to the whole matched string.
524
- title, scanningContext);
525
- const newSelectionForLink = createSelectionWithCaptureGroups(1, 1, false, true, scanningContext);
644
+ title, scanningContext, parentElementNode);
645
+ const newSelectionForLink = createSelectionWithCaptureGroups(1, 1, false, true, scanningContext, parentElementNode);
526
646
 
527
647
  if (newSelectionForLink == null) {
528
648
  return;
@@ -531,11 +651,11 @@ function transformTextNodeWithLink(scanningContext) {
531
651
  lexical.$setSelection(newSelectionForLink);
532
652
  scanningContext.editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, url); // Place caret at end of final capture group.
533
653
 
534
- selectAfterFinalCaptureGroup(scanningContext);
654
+ selectAfterFinalCaptureGroup(scanningContext, parentElementNode);
535
655
  } // Below are lower level helper functions.
536
656
 
537
657
 
538
- function getParent(scanningContext) {
658
+ function getParentElementNodeOrThrow(scanningContext) {
539
659
  return getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
540
660
  }
541
661
 
@@ -557,18 +677,34 @@ function getTextFormatType(markdownFormatKind) {
557
677
  case 'bold':
558
678
  case 'underline':
559
679
  case 'strikethrough':
680
+ case 'code':
560
681
  return [markdownFormatKind];
561
682
 
562
- case 'bold_italic':
683
+ case 'strikethrough_italic_bold':
684
+ {
685
+ return ['strikethrough', 'italic', 'bold'];
686
+ }
687
+
688
+ case 'italic_bold':
689
+ {
690
+ return ['italic', 'bold'];
691
+ }
692
+
693
+ case 'strikethrough_italic':
694
+ {
695
+ return ['strikethrough', 'italic'];
696
+ }
697
+
698
+ case 'strikethrough_bold':
563
699
  {
564
- return ['bold', 'italic'];
700
+ return ['strikethrough', 'bold'];
565
701
  }
566
702
  }
567
703
 
568
704
  return null;
569
705
  }
570
706
 
571
- function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, startAtEndOfAnchor, finishAtEndOfFocus, scanningContext) {
707
+ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, startAtEndOfAnchor, finishAtEndOfFocus, scanningContext, parentElementNode) {
572
708
  const patternMatchResults = scanningContext.patternMatchResults;
573
709
  const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
574
710
  const regExCaptureGroupsCount = regExCaptureGroups.length;
@@ -577,7 +713,6 @@ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureG
577
713
  return null;
578
714
  }
579
715
 
580
- const parentElementNode = getParent(scanningContext);
581
716
  const joinedTextLength = getJoinedTextLength(patternMatchResults);
582
717
  const anchorCaptureGroupDetail = regExCaptureGroups[anchorCaptureGroupIndex];
583
718
  const focusCaptureGroupDetail = regExCaptureGroups[focusCaptureGroupIndex];
@@ -586,6 +721,13 @@ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureG
586
721
  const anchorTextNodeWithOffset = text.$findNodeWithOffsetFromJoinedText(anchorLocation, joinedTextLength, SEPARATOR_LENGTH, parentElementNode);
587
722
  const focusTextNodeWithOffset = text.$findNodeWithOffsetFromJoinedText(focusLocation, joinedTextLength, SEPARATOR_LENGTH, parentElementNode);
588
723
 
724
+ if (anchorTextNodeWithOffset == null && focusTextNodeWithOffset == null && parentElementNode.getChildren().length === 0) {
725
+ const emptyElementSelection = lexical.$createRangeSelection();
726
+ emptyElementSelection.anchor.set(parentElementNode.getKey(), 0, 'element');
727
+ emptyElementSelection.focus.set(parentElementNode.getKey(), 0, 'element');
728
+ return emptyElementSelection;
729
+ }
730
+
589
731
  if (anchorTextNodeWithOffset == null || focusTextNodeWithOffset == null) {
590
732
  return null;
591
733
  }
@@ -596,10 +738,10 @@ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureG
596
738
  return selection;
597
739
  }
598
740
 
599
- function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, scanningContext) {
741
+ function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, scanningContext, parentElementNode) {
600
742
  const patternMatchResults = scanningContext.patternMatchResults;
601
743
  const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
602
- const newSelection = createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, false, true, scanningContext);
744
+ const newSelection = createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, false, true, scanningContext, parentElementNode);
603
745
 
604
746
  if (newSelection != null) {
605
747
  lexical.$setSelection(newSelection);
@@ -627,7 +769,7 @@ function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupInd
627
769
  }
628
770
  }
629
771
 
630
- function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext) {
772
+ function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext, parentElementNode) {
631
773
  const patternMatchResults = scanningContext.patternMatchResults;
632
774
  const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
633
775
  const regExCaptureGroupsCount = regExCaptureGroups.length;
@@ -641,7 +783,7 @@ function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext)
641
783
  offsetInParent: captureGroupDetail.offsetInParent,
642
784
  text
643
785
  };
644
- const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, false, scanningContext);
786
+ const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, false, scanningContext, parentElementNode);
645
787
 
646
788
  if (newSelection != null) {
647
789
  lexical.$setSelection(newSelection);
@@ -662,7 +804,7 @@ function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext)
662
804
  }
663
805
  }
664
806
 
665
- function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningContext) {
807
+ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningContext, parentElementNode) {
666
808
  const patternMatchResults = scanningContext.patternMatchResults;
667
809
  const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
668
810
  const regExCaptureGroupsCount = regExCaptureGroups.length;
@@ -677,7 +819,7 @@ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningC
677
819
  return;
678
820
  }
679
821
 
680
- const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, true, scanningContext);
822
+ const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, true, scanningContext, parentElementNode);
681
823
 
682
824
  if (newSelection != null) {
683
825
  lexical.$setSelection(newSelection);
@@ -692,7 +834,7 @@ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningC
692
834
  } // Place caret at end of final capture group.
693
835
 
694
836
 
695
- function selectAfterFinalCaptureGroup(scanningContext) {
837
+ function selectAfterFinalCaptureGroup(scanningContext, parentElementNode) {
696
838
  const patternMatchResults = scanningContext.patternMatchResults;
697
839
  const groupCount = patternMatchResults.regExCaptureGroups.length;
698
840
 
@@ -702,7 +844,7 @@ function selectAfterFinalCaptureGroup(scanningContext) {
702
844
  }
703
845
 
704
846
  const lastGroupIndex = groupCount - 1;
705
- const newSelection = createSelectionWithCaptureGroups(lastGroupIndex, lastGroupIndex, true, true, scanningContext);
847
+ const newSelection = createSelectionWithCaptureGroups(lastGroupIndex, lastGroupIndex, true, true, scanningContext, parentElementNode);
706
848
 
707
849
  if (newSelection != null) {
708
850
  lexical.$setSelection(newSelection);
@@ -717,30 +859,6 @@ function selectAfterFinalCaptureGroup(scanningContext) {
717
859
  *
718
860
  *
719
861
  */
720
- function getAllTriggers() {
721
- return triggers;
722
- }
723
- function getAllMarkdownCriteriaForTextNodes() {
724
- return allMarkdownCriteriaForTextNodes;
725
- }
726
- function getAllMarkdownCriteria() {
727
- return allMarkdownCriteria;
728
- }
729
- function transformTextNodeForMarkdownCriteria(scanningContext, createHorizontalRuleNode) {
730
- if (scanningContext.markdownCriteria.requiresParagraphStart === true) {
731
- transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNode);
732
- } else {
733
- transformTextNodeForText(scanningContext);
734
- }
735
- }
736
-
737
- function getPatternMatchResultsForCriteria(markdownCriteria, scanningContext) {
738
- if (markdownCriteria.requiresParagraphStart === true) {
739
- return getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext);
740
- }
741
-
742
- return getPatternMatchResultsForText(markdownCriteria, scanningContext);
743
- }
744
862
 
745
863
  function getTextNodeForAutoFormatting(selection) {
746
864
  if (!lexical.$isRangeSelection(selection)) {
@@ -761,7 +879,8 @@ function getTextNodeForAutoFormatting(selection) {
761
879
 
762
880
  function updateAutoFormatting(editor, scanningContext, createHorizontalRuleNode) {
763
881
  editor.update(() => {
764
- transformTextNodeForMarkdownCriteria(scanningContext, createHorizontalRuleNode);
882
+ const elementNode = getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
883
+ transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
765
884
  }, {
766
885
  tag: 'history-push'
767
886
  });
@@ -775,7 +894,7 @@ function getCriteriaWithPatternMatchResults(markdownCriteriaArray, scanningConte
775
894
  const markdownCriteria = markdownCriteriaArray[i]; // Skip code block nodes, unless the autoFormatKind calls for toggling the code block.
776
895
 
777
896
  if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || markdownCriteria.markdownFormatKind === 'paragraphCodeBlock') {
778
- const patternMatchResults = getPatternMatchResultsForCriteria(markdownCriteria, scanningContext);
897
+ const patternMatchResults = getPatternMatchResultsForCriteria(markdownCriteria, scanningContext, getParentElementNodeOrThrow(scanningContext));
779
898
 
780
899
  if (patternMatchResults != null) {
781
900
  return {
@@ -859,7 +978,9 @@ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
859
978
 
860
979
  const triggerStringLength = triggerString.length;
861
980
  const currentTextContentLength = currentTriggerState.textContent.length;
862
- const triggerOffset = currentTriggerState.anchorOffset - triggerStringLength;
981
+ const triggerOffset = currentTriggerState.anchorOffset - triggerStringLength; // Todo: these checks help w/ performance, yet we can do more.
982
+ // We might consider looking for ** + space or __ + space and so on to boost performance
983
+ // even further. Make sure the patter is driven from the trigger state type.
863
984
 
864
985
  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.
865
986
  currentTriggerState.textContent !== priorTriggerState.textContent) === false) {
@@ -904,61 +1025,117 @@ function convertStringToLexical(text, editor) {
904
1025
 
905
1026
  return null;
906
1027
  }
1028
+ function convertMarkdownForElementNodes(editor, createHorizontalRuleNode) {
1029
+ // Please see the declaration of ScanningContext for a detailed explanation.
1030
+ const scanningContext = getInitialScanningContext(editor, false, null, null);
1031
+ const root = lexical.$getRoot();
1032
+ let done = false;
1033
+ let startIndex = 0; // Handle the paragraph level markdown.
907
1034
 
908
- function convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode) {
1035
+ while (!done) {
1036
+ done = true;
1037
+ const elementNodes = root.getChildren();
1038
+ const countOfElementNodes = elementNodes.length;
1039
+
1040
+ for (let i = startIndex; i < countOfElementNodes; i++) {
1041
+ const elementNode = elementNodes[i];
1042
+
1043
+ if (lexical.$isElementNode(elementNode)) {
1044
+ convertParagraphLevelMarkdown(scanningContext, elementNode, createHorizontalRuleNode);
1045
+ } // Reset the scanning information that relates to the particular element node.
1046
+
1047
+
1048
+ resetScanningContext(scanningContext);
1049
+
1050
+ if (root.getChildren().length !== countOfElementNodes) {
1051
+ // The conversion added or removed an from root's children.
1052
+ startIndex = i;
1053
+ done = false;
1054
+ break;
1055
+ }
1056
+ }
1057
+ } // while
1058
+
1059
+
1060
+ done = false;
1061
+ startIndex = 0; // Handle the text level markdown.
1062
+
1063
+ while (!done) {
1064
+ done = true;
1065
+ const elementNodes = root.getChildren();
1066
+ const countOfElementNodes = elementNodes.length;
1067
+
1068
+ for (let i = startIndex; i < countOfElementNodes; i++) {
1069
+ const elementNode = elementNodes[i];
1070
+
1071
+ if (lexical.$isElementNode(elementNode)) {
1072
+ convertTextLevelMarkdown(scanningContext, elementNode, createHorizontalRuleNode);
1073
+ } // Reset the scanning information that relates to the particular element node.
1074
+
1075
+
1076
+ resetScanningContext(scanningContext);
1077
+ }
1078
+ } // while
1079
+
1080
+ }
1081
+
1082
+ function convertParagraphLevelMarkdown(scanningContext, elementNode, createHorizontalRuleNode) {
909
1083
  const textContent = elementNode.getTextContent(); // Handle paragraph nodes below.
910
1084
 
911
- if (lexical.$isParagraphNode(elementNode) && elementNode.getChildren().length) {
1085
+ if (lexical.$isParagraphNode(elementNode)) {
912
1086
  const paragraphNode = elementNode;
913
1087
  const firstChild = paragraphNode.getFirstChild();
914
1088
  const firstChildIsTextNode = lexical.$isTextNode(firstChild); // Handle conversion to code block.
915
1089
 
916
1090
  if (scanningContext.isWithinCodeBlock === true) {
917
- if (!(firstChild != null && firstChildIsTextNode)) {
918
- throw Error(`Expect paragraph containing only text nodes.`);
919
- }
920
-
921
- scanningContext.textNodeWithOffset = {
922
- node: firstChild,
923
- offset: 0
924
- };
925
- const patternMatchResults = getPatternMatchResultsForCodeBlock(scanningContext, textContent);
1091
+ if (firstChild != null && firstChildIsTextNode) {
1092
+ // Test if we encounter ending code block.
1093
+ scanningContext.textNodeWithOffset = {
1094
+ node: firstChild,
1095
+ offset: 0
1096
+ };
1097
+ const patternMatchResults = getPatternMatchResultsForCodeBlock(scanningContext, textContent);
926
1098
 
927
- if (patternMatchResults != null) {
928
- // Toggle transform to or from code block.
929
- scanningContext.patternMatchResults = patternMatchResults;
1099
+ if (patternMatchResults != null) {
1100
+ // Toggle transform to or from code block.
1101
+ scanningContext.patternMatchResults = patternMatchResults;
1102
+ }
930
1103
  }
931
1104
 
932
1105
  scanningContext.markdownCriteria = getCodeBlockCriteria(); // Perform text transformation here.
933
1106
 
934
- transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNode);
1107
+ transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
935
1108
  return;
936
1109
  }
937
1110
 
938
- const allCriteria = getAllMarkdownCriteria();
939
- const count = allCriteria.length;
1111
+ if (elementNode.getChildren().length) {
1112
+ const allCriteria = getAllMarkdownCriteriaForParagraphs();
1113
+ const count = allCriteria.length;
1114
+ scanningContext.joinedText = paragraphNode.getTextContent();
940
1115
 
941
- for (let i = 0; i < count; i++) {
942
- const criteria = allCriteria[i];
1116
+ if (!(firstChild != null && firstChildIsTextNode)) {
1117
+ throw Error(`Expect paragraph containing only text nodes.`);
1118
+ }
943
1119
 
944
- if (criteria.requiresParagraphStart === true) {
945
- if (!(firstChild != null && firstChildIsTextNode)) {
946
- throw Error(`Expect paragraph containing only text nodes.`);
1120
+ scanningContext.textNodeWithOffset = {
1121
+ node: firstChild,
1122
+ offset: 0
1123
+ };
1124
+
1125
+ for (let i = 0; i < count; i++) {
1126
+ const criteria = allCriteria[i];
1127
+
1128
+ if (criteria.requiresParagraphStart === false) {
1129
+ return;
947
1130
  }
948
1131
 
949
- scanningContext.textNodeWithOffset = {
950
- node: firstChild,
951
- offset: 0
952
- };
953
- scanningContext.joinedText = paragraphNode.getTextContent();
954
- const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
1132
+ const patternMatchResults = getPatternMatchResultsForCriteria(criteria, scanningContext, getParentElementNodeOrThrow(scanningContext));
955
1133
 
956
1134
  if (patternMatchResults != null) {
957
- // Lazy fill-in the particular format criteria and any matching result information.
958
1135
  scanningContext.markdownCriteria = criteria;
959
1136
  scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
960
1137
 
961
- transformTextNodeForParagraphs(scanningContext, createHorizontalRuleNode);
1138
+ transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
962
1139
  return;
963
1140
  }
964
1141
  }
@@ -966,37 +1143,101 @@ function convertElementNodeContainingMarkdown(scanningContext, elementNode, crea
966
1143
  }
967
1144
  }
968
1145
 
969
- function convertMarkdownForElementNodes(editor, createHorizontalRuleNode) {
970
- // Please see the declaration of ScanningContext for a detailed explanation.
971
- const scanningContext = getInitialScanningContext(editor, false, null, null);
972
- const root = lexical.$getRoot();
973
- let done = false;
1146
+ function convertTextLevelMarkdown(scanningContext, elementNode, createHorizontalRuleNode) {
1147
+ const firstChild = elementNode.getFirstChild();
1148
+
1149
+ if (lexical.$isTextNode(firstChild)) {
1150
+ // This function will convert all text nodes within the elementNode.
1151
+ convertMarkdownForTextCriteria(scanningContext, elementNode, createHorizontalRuleNode);
1152
+ return;
1153
+ } // Handle the case where the elementNode has child elementNodes like lists.
1154
+ // Since we started at a text import, we don't need to worry about anything but textNodes.
1155
+
1156
+
1157
+ const children = elementNode.getChildren();
1158
+ const countOfChildren = children.length;
1159
+
1160
+ for (let i = 0; i < countOfChildren; i++) {
1161
+ const node = children[i];
1162
+
1163
+ if (lexical.$isElementNode(node)) {
1164
+ // Recurse down until we find a text node.
1165
+ convertTextLevelMarkdown(scanningContext, node, createHorizontalRuleNode);
1166
+ }
1167
+ }
1168
+ }
1169
+
1170
+ function convertMarkdownForTextCriteria(scanningContext, elementNode, createHorizontalRuleNode) {
1171
+ resetScanningContext(scanningContext); // Cycle through all the criteria and convert all text patterns in the parent element.
1172
+
1173
+ const allCriteria = getAllMarkdownCriteriaForTextNodes();
1174
+ const count = allCriteria.length;
1175
+ let textContent = elementNode.getTextContent();
1176
+ let done = textContent.length === 0;
974
1177
  let startIndex = 0;
975
1178
 
976
1179
  while (!done) {
977
1180
  done = true;
978
- const elementNodes = root.getChildren();
979
- const countOfElementNodes = elementNodes.length;
980
1181
 
981
- for (let i = startIndex; i < countOfElementNodes; i++) {
982
- const elementNode = elementNodes[i];
1182
+ for (let i = startIndex; i < count; i++) {
1183
+ const criteria = allCriteria[i];
983
1184
 
984
- if (lexical.$isElementNode(elementNode)) {
985
- convertElementNodeContainingMarkdown(scanningContext, elementNode, createHorizontalRuleNode);
986
- } // Reset the scanning information that relates to the particular element node.
1185
+ if (scanningContext.textNodeWithOffset == null) {
1186
+ // Need to search through the very last text node in the element.
1187
+ const lastTextNode = getLastTextNodeInElementNode(elementNode);
987
1188
 
1189
+ if (lastTextNode == null) {
1190
+ // If we have no more text nodes, then there's nothing to search and transform.
1191
+ return;
1192
+ }
988
1193
 
989
- resetScanningContext(scanningContext);
1194
+ scanningContext.textNodeWithOffset = {
1195
+ node: lastTextNode,
1196
+ offset: lastTextNode.getTextContent().length
1197
+ };
1198
+ }
990
1199
 
991
- if (root.getChildren().length !== countOfElementNodes) {
992
- // The conversion added or removed an from root's children.
1200
+ const patternMatchResults = getPatternMatchResultsForCriteria(criteria, scanningContext, elementNode);
1201
+
1202
+ if (patternMatchResults != null) {
1203
+ scanningContext.markdownCriteria = criteria;
1204
+ scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
1205
+
1206
+ transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
1207
+ resetScanningContext(scanningContext);
1208
+ const currentTextContent = elementNode.getTextContent();
1209
+
1210
+ if (currentTextContent.length === 0) {
1211
+ // Nothing left to convert.
1212
+ return;
1213
+ }
1214
+
1215
+ if (currentTextContent === textContent) {
1216
+ // Nothing was changed by this transformation, so move on to the next crieteria.
1217
+ continue;
1218
+ } // The text was changed. Perhaps there is another hit for the same criteria.
1219
+
1220
+
1221
+ textContent = currentTextContent;
993
1222
  startIndex = i;
994
1223
  done = false;
995
1224
  break;
996
1225
  }
997
1226
  }
998
- } // while
1227
+ }
1228
+ }
999
1229
 
1230
+ function getLastTextNodeInElementNode(elementNode) {
1231
+ const children = elementNode.getChildren();
1232
+ const countOfChildren = children.length;
1233
+
1234
+ for (let i = countOfChildren - 1; i >= 0; i--) {
1235
+ if (lexical.$isTextNode(children[i])) {
1236
+ return children[i];
1237
+ }
1238
+ }
1239
+
1240
+ return null;
1000
1241
  }
1001
1242
 
1002
1243
  /**
@@ -4,29 +4,37 @@
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 k=require("@lexical/code"),p=require("@lexical/list"),q=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 y=[{triggerKind:"space_trigger",triggerString:" "}],z={markdownFormatKind:null,regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:!1},A={...z,requiresParagraphStart:!0},B={...A,markdownFormatKind:"paragraphCodeBlock",regEx:/^(```)$/,regExForAutoFormatting:/^(```)([a-z]*)( )/},C=[{...z,markdownFormatKind:"bold_italic",regEx:/(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)/,regExForAutoFormatting:/(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)(\s)$/},{...z,markdownFormatKind:"italic",regEx:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)/,
9
- regExForAutoFormatting:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/},{...z,markdownFormatKind:"bold",regEx:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)/,regExForAutoFormatting:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/},{...z,markdownFormatKind:"bold",regEx:/(__)(\s*)([^__]*)(\s*)(__)/,regExForAutoFormatting:/(__)(\s*)([^__]*)(\s*)(__)(\s)$/},{...z,markdownFormatKind:"underline",regEx:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)/,regExForAutoFormatting:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/},{...z,markdownFormatKind:"strikethrough",
10
- regEx:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)/,regExForAutoFormatting:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/},{...z,markdownFormatKind:"link",regEx:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))/,regExForAutoFormatting:/(\[)(.+)(\]\()([^ ]+)(?: "(?:.+)")?(\))(\s)$/}],D=[{...A,markdownFormatKind:"paragraphH1",regEx:/^(?:#)/,regExForAutoFormatting:/^(?:# )/},{...A,markdownFormatKind:"paragraphH2",regEx:/^(?:##)/,regExForAutoFormatting:/^(?:## )/},{...A,markdownFormatKind:"paragraphH2",regEx:/^(?:###)/,regExForAutoFormatting:/^(?:### )/},
11
- {...A,markdownFormatKind:"paragraphBlockQuote",regEx:/^(?:>)/,regExForAutoFormatting:/^(?:> )/},{...A,markdownFormatKind:"paragraphUnorderedList",regEx:/^(?:- )/,regExForAutoFormatting:/^(?:- )/},{...A,markdownFormatKind:"paragraphUnorderedList",regEx:/^(?:\* )/,regExForAutoFormatting:/^(?:\* )/},{...A,markdownFormatKind:"paragraphOrderedList",regEx:/^(\d+)\.\s/,regExForAutoFormatting:/^(\d+)\.\s/},B,{...A,markdownFormatKind:"horizontalRule",regEx:/^(?:\*\*\*)$/,regExForAutoFormatting:/^(?:\*\*\* )/},
12
- {...A,markdownFormatKind:"horizontalRule",regEx:/^(?:---)$/,regExForAutoFormatting:/^(?:--- )/},...C];function E(b,e,d,c){return{currentElementNode:null,editor:b,isAutoFormatting:e,isWithinCodeBlock:!1,joinedText:null,markdownCriteria:{markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null},patternMatchResults:{regExCaptureGroups:[]},textNodeWithOffset:d,triggerState:c}}
13
- function F(b,e,d,c){const a={regExCaptureGroups:[]};c=b.match(c);if(null!==c&&0<c.length&&(!1===e||0===c.index)&&(!1===d||c.index+c[0].length===b.length)){b=c.length;e=c.index;for(d=0;d<b;d++){const f=c[d];a.regExCaptureGroups.push({offsetInParent:e,text:f});0<d&&(e+=f.length)}return a}return null}function I(b){b=b.textNodeWithOffset;null==b&&w(82);return b}
14
- function J(b,e){var d=I(e);return null===d.node.getPreviousSibling()?(d=d.node.getTextContent(),F(d,!0,!1,e.isAutoFormatting?b.regExForAutoFormatting:b.regEx)):null}
15
- function K(b,e){var d=I(b);const c=d.node.getParentOrThrow();0<b.patternMatchResults.regExCaptureGroups.length&&(d=d.node.spliceText(0,b.patternMatchResults.regExCaptureGroups[0].text.length,"",!0),""===d.getTextContent()&&(d.selectPrevious(),d.remove()));a:{var a=null;d=c.getChildren();const g=b.markdownCriteria,l=b.patternMatchResults;if(null!=g.markdownFormatKind)switch(g.markdownFormatKind){case "paragraphH1":a=u.$createHeadingNode("h1");a.append(...d);break;case "paragraphH2":a=u.$createHeadingNode("h2");
16
- a.append(...d);break;case "paragraphH3":a=u.$createHeadingNode("h3");a.append(...d);break;case "paragraphBlockQuote":a=u.$createQuoteNode();a.append(...d);break;case "paragraphUnorderedList":a=p.$createListNode("ul");b=p.$createListItemNode();b.append(...d);a.append(b);break;case "paragraphOrderedList":a=parseInt(1<l.regExCaptureGroups.length?l.regExCaptureGroups[l.regExCaptureGroups.length-1].text:"1",10);a=p.$createListNode("ol",a);b=p.$createListItemNode();b.append(...d);a.append(b);break;case "paragraphCodeBlock":if(!1===
17
- b.isAutoFormatting){if(0<b.patternMatchResults.regExCaptureGroups.length){b.isWithinCodeBlock=!0!==b.isWithinCodeBlock;b.currentElementNode=null;d={newNode:null,shouldDelete:!0};break a}if(b.isWithinCodeBlock){if(null==b.currentElementNode){a=k.$createCodeNode();a.append(...d);b.currentElementNode=a;d={newNode:a,shouldDelete:!1};break a}null!=b.currentElementNode&&(a=b.currentElementNode,b=q.$createLineBreakNode(),a.append(b),a.append(...d))}d={newNode:null,shouldDelete:!0};break a}null!=b.triggerState&&
18
- b.triggerState.isCodeBlock?a=q.$createParagraphNode():(a=k.$createCodeNode(),b=3<=l.regExCaptureGroups.length?l.regExCaptureGroups[2].text:null,null!=b&&0<b.length&&a.setLanguage(b));a.append(...d);break;case "horizontalRule":null!=e&&(d=e(),c.insertBefore(d))}d={newNode:a,shouldDelete:!1}}const {newNode:f,shouldDelete:h}=d;h?c.remove():null!==f&&c.replace(f)}
19
- function L(b,e,d,c,a){var f=a.patternMatchResults;const h=f.regExCaptureGroups;var g=h.length;if(b>=g||e>=g)return null;a=I(a).node.getParentOrThrow();g=f.regExCaptureGroups.length;2>g?f=0:(--g,f=f.regExCaptureGroups[g].offsetInParent+f.regExCaptureGroups[g].text.length);b=h[b];e=h[e];c=c?e.offsetInParent+e.text.length:e.offsetInParent;d=v.$findNodeWithOffsetFromJoinedText(d?b.offsetInParent+b.text.length:b.offsetInParent,f,1,a);c=v.$findNodeWithOffsetFromJoinedText(c,f,1,a);if(null==d||null==c)return null;
20
- a=q.$createRangeSelection();a.anchor.set(d.node.getKey(),d.offset,"text");a.focus.set(c.node.getKey(),c.offset,"text");return a}function M(b,e,d){const c=d.patternMatchResults.regExCaptureGroups;d=L(b,e,!1,!0,d);if(null!=d&&(q.$setSelection(d),d=q.$getSelection(),null!=d&&q.$isRangeSelection(d)&&!1===d.isCollapsed())){d.removeText();d=0;const a=c.length;for(let f=b;f<a;f++){const h=c[f];f>b&&(h.offsetInParent-=d);f<=e&&(d+=h.text.length,h.text="")}}}
21
- function P(b){var e=b.patternMatchResults.regExCaptureGroups.length;2>e||(--e,b=L(e,e,!0,!0,b),null!=b&&q.$setSelection(b))}
22
- function Q(b,e,d){b.update(()=>{if(!0===e.markdownCriteria.requiresParagraphStart)K(e,d);else{var c=e.markdownCriteria;if(null!=c.markdownFormatKind){a:{var a=c.markdownFormatKind;switch(a){case "italic":case "bold":case "underline":case "strikethrough":a=[a];break a;case "bold_italic":a=["bold","italic"];break a}a=null}if(null!=a){if(c=a,7===e.patternMatchResults.regExCaptureGroups.length){M(5,5,e);M(1,1,e);a=e.patternMatchResults.regExCaptureGroups;3<a.length||w(65);if(0!==a[3].text.length&&(a=
23
- L(3,3,!1,!0,e),null!=a&&(q.$setSelection(a),a=q.$getSelection(),q.$isRangeSelection(a))))for(var f=0;f<c.length;f++)a.formatText(c[f]);P(e)}}else if("link"===c.markdownFormatKind&&(c=e.patternMatchResults.regExCaptureGroups,7===c.length&&(f=c[2].text,c=c[4].text,0!==f.length&&0!==c.length))){M(1,5,e);a=e.patternMatchResults.regExCaptureGroups;if(!(1>=a.length)){f={offsetInParent:a[1].offsetInParent,text:f};var h=L(1,1,!1,!1,e);if(null!=h&&(q.$setSelection(h),h=q.$getSelection(),null!=h&&q.$isRangeSelection(h)&&
24
- h.isCollapsed())){h.insertText(f.text);a.splice(1,0,f);f=f.text.length;h=a.length;for(let g=2;g<h;g++)a[g].offsetInParent+=f}}a=L(1,1,!1,!0,e);null!=a&&(q.$setSelection(a),e.editor.dispatchCommand(t.TOGGLE_LINK_COMMAND,c),P(e))}}}},{tag:"history-push"})}
25
- function R(b,e){let d=null;b.getEditorState().read(()=>{var c=q.$getSelection();if(q.$isRangeSelection(c)){var a=c.anchor.getNode();c=q.$isTextNode(a)?{node:a,offset:c.anchor.offset}:null}else c=null;if(null!==c){c=E(b,!0,c,e);a:{a=!1===e.isParentAListItemNode?D:C;const g=c.triggerState,l=a.length;for(let n=0;n<l;n++){const r=a[n];if(null!=g&&!1===g.isCodeBlock||"paragraphCodeBlock"===r.markdownFormatKind){var f=r,h=c;if(!0===f.requiresParagraphStart)f=J(f,h);else{if(null==h.joinedText){const m=I(h).node.getParentOrThrow();
26
- q.$isElementNode(m)?null==h.joinedText&&(h.joinedText=v.$joinTextNodesInElementNode(m,"\u0004",I(h))):w(52,m.__key)}f=F(h.joinedText,!1,!0,f.regExForAutoFormatting)}if(null!=f){a={markdownCriteria:r,patternMatchResults:f};break a}}}a={markdownCriteria:null,patternMatchResults:null}}null!==a.markdownCriteria&&null!==a.patternMatchResults&&(d=c,d.markdownCriteria=a.markdownCriteria,d.patternMatchResults=a.patternMatchResults)}});return d}
27
- function S(b){let e=null;b.read(()=>{const d=q.$getSelection();if(q.$isRangeSelection(d)&&d.isCollapsed()){var c=d.anchor.getNode(),a=c.getParent(),f=p.$isListItemNode(a);e={anchorOffset:d.anchor.offset,hasParentNode:null!==a,isCodeBlock:k.$isCodeNode(c),isParentAListItemNode:f,isSelectionCollapsed:!0,isSimpleText:q.$isTextNode(c)&&c.isSimpleText(),nodeKey:c.getKey(),textContent:c.getTextContent()}}});return e}
28
- exports.$convertFromMarkdownString=function(b,e,d){if(b.length){var c=[];b=b.split("\n");var a=b.length;for(var f=0;f<a;f++)0<b[f].length?c.push(q.$createParagraphNode().append(q.$createTextNode(b[f]))):c.push(q.$createParagraphNode());c.length?(b=q.$getRoot(),b.clear(),b.append(...c),c=b):c=null}else c=null;if(null!=c)for(e=E(e,!1,null,null),c=q.$getRoot(),b=!1,a=0;!b;){b=!0;f=c.getChildren();const r=f.length;for(let m=a;m<r;m++){var h=f[m];if(q.$isElementNode(h)){var g=e,l=h;h=d;var n=l.getTextContent();
29
- if(q.$isParagraphNode(l)&&l.getChildren().length){const x=l.getFirstChild(),N=q.$isTextNode(x);if(!0===g.isWithinCodeBlock)null!=x&&N||w(80),g.textNodeWithOffset={node:x,offset:0},l=F(n,!0,!1,g.isAutoFormatting?B.regExForAutoFormatting:B.regEx),null!=l&&(g.patternMatchResults=l),g.markdownCriteria=B,K(g,h);else{n=D.length;for(let G=0;G<n;G++){const H=D[G];if(!0===H.requiresParagraphStart){null!=x&&N||w(80);g.textNodeWithOffset={node:x,offset:0};g.joinedText=l.getTextContent();const O=J(H,g);if(null!=
30
- O){g.markdownCriteria=H;g.patternMatchResults=O;K(g,h);break}}}}}}g=e;g.joinedText="";g.markdownCriteria={markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null};g.patternMatchResults={regExCaptureGroups:[]};g.triggerState=null;g.textNodeWithOffset=null;if(c.getChildren().length!==r){a=m;b=!1;break}}}};
31
- exports.registerMarkdownShortcuts=function(b,e){let d=null;return b.registerUpdateListener(({tags:c})=>{if(!1===c.has("historic")){c=S(b.getEditorState());if(null==c)var a=null;else a:{a=c;var f=d;if(null==a||null==f)a=null;else{var h=y.length;for(let g=0;g<h;g++){const l=y[g].triggerString,n=l.length,r=a.textContent.length,m=a.anchorOffset-n;if(!1===(!0===a.hasParentNode&&a.isSimpleText&&a.isSelectionCollapsed&&a.anchorOffset!==f.anchorOffset&&0<=m&&m+n<=r&&a.textContent.substr(m,n)===l&&a.textContent!==
32
- f.textContent)){a=null;break a}}a=R(b,a)}}null!=a&&Q(b,a,e);d=c}else d=null})};
7
+ var k=require("@lexical/code"),n=require("@lexical/list"),p=require("lexical"),u=require("@lexical/link"),v=require("@lexical/rich-text"),x=require("@lexical/text");function y(a){throw Error(`Minified Lexical error #${a}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}
8
+ const z=[{triggerKind:"space_trigger",triggerString:" "}],A={markdownFormatKind:null,regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:!1},B={...A,requiresParagraphStart:!0},C={...B,markdownFormatKind:"paragraphCodeBlock",regEx:/^(```)$/,regExForAutoFormatting:/^(```)([a-z]*)( )/},D=[{...A,markdownFormatKind:"strikethrough_italic_bold",regEx:/(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)()/,regExForAutoFormatting:/(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/},
9
+ {...A,markdownFormatKind:"italic_bold",regEx:/(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)/,regExForAutoFormatting:/(_\*\*)(\s*\b)([^_\*\*][^\*\*_]*)(\b\s*)(\*\*_)(\s)$/},{...A,markdownFormatKind:"strikethrough_italic",regEx:/(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)/,regExForAutoFormatting:/(~~_)(\s*)([^~~_][^_~~]*)(\s*)(_~~)(\s)$/},{...A,markdownFormatKind:"strikethrough_bold",regEx:/(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)/,regExForAutoFormatting:/(~~\*\*)(\s*\b)([^~~\*\*][^\*\*~~]*)(\b\s*)(\*\*~~)(\s)$/},
10
+ {...A,markdownFormatKind:"code",regEx:/(`)([^`]*)(`)/,regExForAutoFormatting:/(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/},{...A,markdownFormatKind:"bold",regEx:/(\*\*)(\s*)([^\*\*]*)(\s*)(\*\*)()/,regExForAutoFormatting:/(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/},{...A,markdownFormatKind:"italic",regEx:/(\*)(\s*)([^\*]*)(\s*)(\*)()/,regExForAutoFormatting:/(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/},{...A,markdownFormatKind:"bold",regEx:/(__)(\s*)([^__]*)(\s*)(__)()/,regExForAutoFormatting:/(__)(\s*)([^__]*)(\s*)(__)(\s)$/},
11
+ {...A,markdownFormatKind:"italic",regEx:/(_)()([^_]*)()(_)()/,regExForAutoFormatting:/(_)()([^_]*)()(_)(\s)$/},{...A,markdownFormatKind:"underline",regEx:/(<u>)(\s*)([^<]*)(\s*)(<\/u>)()/,regExForAutoFormatting:/(<u>)(\s*\b)([^<]*)(\b\s*)(<\/u>)(\s)$/},{...A,markdownFormatKind:"strikethrough",regEx:/(~~)(\s*)([^~~]*)(\s*)(~~)()/,regExForAutoFormatting:/(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/},{...A,markdownFormatKind:"link",regEx:/(\[)([^\]]*)(\]\()([^)]*)(\)*)()/,regExForAutoFormatting:/(\[)([^\]]*)(\]\()([^)]*)(\)*)(\s)$/}],
12
+ E=[{...B,markdownFormatKind:"paragraphH1",regEx:/^(?:# )/,regExForAutoFormatting:/^(?:# )/},{...B,markdownFormatKind:"paragraphH2",regEx:/^(?:## )/,regExForAutoFormatting:/^(?:## )/},{...B,markdownFormatKind:"paragraphH3",regEx:/^(?:### )/,regExForAutoFormatting:/^(?:### )/},{...B,markdownFormatKind:"paragraphH4",regEx:/^(?:#### )/,regExForAutoFormatting:/^(?:#### )/},{...B,markdownFormatKind:"paragraphH5",regEx:/^(?:##### )/,regExForAutoFormatting:/^(?:##### )/},{...B,markdownFormatKind:"paragraphBlockQuote",
13
+ regEx:/^(?:> )/,regExForAutoFormatting:/^(?:> )/},{...B,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})(?:- )/,regExForAutoFormatting:/^(\s{0,10})(?:- )/},{...B,markdownFormatKind:"paragraphUnorderedList",regEx:/^(\s{0,10})(?:\* )/,regExForAutoFormatting:/^(\s{0,10})(?:\* )/},{...B,markdownFormatKind:"paragraphOrderedList",regEx:/^(\s{0,10})(\d+)\.\s/,regExForAutoFormatting:/^(\s{0,10})(\d+)\.\s/},C,{...B,markdownFormatKind:"horizontalRule",regEx:/^(?:\*\*\*)$/,regExForAutoFormatting:/^(?:\*\*\* )/},
14
+ {...B,markdownFormatKind:"horizontalRule",regEx:/^(?:---)$/,regExForAutoFormatting:/^(?:--- )/}],F=[...E,...D];function G(a,d,c,b){return{currentElementNode:null,editor:a,isAutoFormatting:d,isWithinCodeBlock:!1,joinedText:null,markdownCriteria:{markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null},patternMatchResults:{regExCaptureGroups:[]},textNodeWithOffset:c,triggerState:b}}
15
+ function H(a){a.joinedText=null;a.markdownCriteria={markdownFormatKind:"noTransformation",regEx:/(?:)/,regExForAutoFormatting:/(?:)/,requiresParagraphStart:null};a.patternMatchResults={regExCaptureGroups:[]};a.triggerState=null;a.textNodeWithOffset=null;return a}
16
+ function I(a,d,c){if(!0===a.requiresParagraphStart)return c=J(d),null===c.node.getPreviousSibling()?(c=c.node.getTextContent(),a=K(c,!0,!1,d.isAutoFormatting?a.regExForAutoFormatting:a.regEx)):a=null,a;null==d.joinedText&&(p.$isElementNode(c)?null==d.joinedText&&(d.joinedText=x.$joinTextNodesInElementNode(c,"\u0004",J(d))):y(52,c.__key));return K(d.joinedText,!1,!0===a.regExForAutoFormatting,d.isAutoFormatting?a.regExForAutoFormatting:a.regEx)}
17
+ function K(a,d,c,b){const e={regExCaptureGroups:[]};b=a.match(b);if(null!==b&&0<b.length&&(!1===d||0===b.index)&&(!1===c||b.index+b[0].length===a.length)){a=b.length;d=b.index;for(c=0;c<a;c++){const f=b[c];e.regExCaptureGroups.push({offsetInParent:d,text:f});0<c&&(d+=f.length)}return e}return null}function J(a){a=a.textNodeWithOffset;null==a&&y(82);return a}
18
+ function L(a,d,c){var b=null,e=d.getChildren();const f=a.markdownCriteria,g=a.patternMatchResults;if(null!=f.markdownFormatKind)switch(f.markdownFormatKind){case "paragraphH1":b=v.$createHeadingNode("h1");b.append(...e);break;case "paragraphH2":b=v.$createHeadingNode("h2");b.append(...e);break;case "paragraphH3":b=v.$createHeadingNode("h3");b.append(...e);break;case "paragraphH4":b=v.$createHeadingNode("h4");b.append(...e);break;case "paragraphH5":b=v.$createHeadingNode("h5");b.append(...e);break;
19
+ case "paragraphBlockQuote":b=v.$createQuoteNode();b.append(...e);break;case "paragraphUnorderedList":return M(d,e,g,"ul"),{newNode:null,shouldDelete:!1};case "paragraphOrderedList":return b=1<g.regExCaptureGroups.length?g.regExCaptureGroups[g.regExCaptureGroups.length-1].text:"1",a=a.isAutoFormatting?parseInt(b,10):void 0,M(d,e,g,"ol",a),{newNode:null,shouldDelete:!1};case "paragraphCodeBlock":if(!1===a.isAutoFormatting){if(0<a.patternMatchResults.regExCaptureGroups.length)return a.isWithinCodeBlock=
20
+ !0!==a.isWithinCodeBlock,a.currentElementNode=null,{newNode:null,shouldDelete:!0};if(a.isWithinCodeBlock){if(null==a.currentElementNode)return d=k.$createCodeNode(),d.append(...e),a.currentElementNode=d,{newNode:d,shouldDelete:!1};null!=a.currentElementNode&&(d=a.currentElementNode,a=p.$createLineBreakNode(),d.append(a),e.length&&d.append(a),d.append(...e))}return{newNode:null,shouldDelete:!0}}null!=a.triggerState&&a.triggerState.isCodeBlock?b=p.$createParagraphNode():(b=k.$createCodeNode(),d=3<=
21
+ g.regExCaptureGroups.length?g.regExCaptureGroups[2].text:null,null!=d&&0<d.length&&b.setLanguage(d));b.append(...e);break;case "horizontalRule":null!=c&&(e=c(),d.insertBefore(e))}return{newNode:b,shouldDelete:!1}}
22
+ function M(a,d,c,b,e){const f=n.$createListItemNode();c=(c=c.regExCaptureGroups[0].text.match(/^\s*/))?Math.floor(c[0].length/4):0;f.append(...d);d=a.getPreviousSibling();n.$isListNode(d)&&d.getTag()===b?(d.append(f),a.remove()):(b=n.$createListNode(b,e),b.append(f),a.replace(b));c&&f.setIndent(c)}
23
+ function N(a,d,c){if(!0===a.markdownCriteria.requiresParagraphStart){if(null!=a.textNodeWithOffset){var b=J(a);0<a.patternMatchResults.regExCaptureGroups.length&&(b=b.node.spliceText(0,a.patternMatchResults.regExCaptureGroups[0].text.length,"",!0),""===b.getTextContent()&&(b.selectPrevious(),b.remove()))}const {newNode:g,shouldDelete:h}=L(a,d,c);h?d.remove():null!==g&&d.replace(g)}else if(c=a.markdownCriteria,null!=c.markdownFormatKind)if(b=O(c.markdownFormatKind),null!=b){if(c=b,7===a.patternMatchResults.regExCaptureGroups.length){Q(5,
24
+ 5,a,d);Q(1,1,a,d);b=a.patternMatchResults.regExCaptureGroups;3<b.length||y(65);if(0!==b[3].text.length&&(b=R(3,3,!1,!0,a,d),null!=b&&(p.$setSelection(b),b=p.$getSelection(),p.$isRangeSelection(b))))for(var e=0;e<c.length;e++)b.formatText(c[e]);S(a,d)}}else if("link"===c.markdownFormatKind&&(c=a.patternMatchResults.regExCaptureGroups,7===c.length&&(e=c[2].text,c=c[4].text,0!==e.length&&0!==c.length))){Q(1,5,a,d);b=a.patternMatchResults.regExCaptureGroups;if(!(1>=b.length)){e={offsetInParent:b[1].offsetInParent,
25
+ text:e};var f=R(1,1,!1,!1,a,d);if(null!=f&&(p.$setSelection(f),f=p.$getSelection(),null!=f&&p.$isRangeSelection(f)&&f.isCollapsed())){f.insertText(e.text);b.splice(1,0,e);e=e.text.length;f=b.length;for(let g=2;g<f;g++)b[g].offsetInParent+=e}}b=R(1,1,!1,!0,a,d);null!=b&&(p.$setSelection(b),a.editor.dispatchCommand(u.TOGGLE_LINK_COMMAND,c),S(a,d))}}
26
+ function O(a){switch(a){case "italic":case "bold":case "underline":case "strikethrough":case "code":return[a];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}
27
+ function R(a,d,c,b,e,f){var g=e.patternMatchResults;e=g.regExCaptureGroups;var h=e.length;if(a>=h||d>=h)return null;h=g.regExCaptureGroups.length;2>h?g=0:(--h,g=g.regExCaptureGroups[h].offsetInParent+g.regExCaptureGroups[h].text.length);a=e[a];d=e[d];b=b?d.offsetInParent+d.text.length:d.offsetInParent;c=x.$findNodeWithOffsetFromJoinedText(c?a.offsetInParent+a.text.length:a.offsetInParent,g,1,f);b=x.$findNodeWithOffsetFromJoinedText(b,g,1,f);if(null==c&&null==b&&0===f.getChildren().length)return c=
28
+ p.$createRangeSelection(),c.anchor.set(f.getKey(),0,"element"),c.focus.set(f.getKey(),0,"element"),c;if(null==c||null==b)return null;f=p.$createRangeSelection();f.anchor.set(c.node.getKey(),c.offset,"text");f.focus.set(b.node.getKey(),b.offset,"text");return f}
29
+ function Q(a,d,c,b){const e=c.patternMatchResults.regExCaptureGroups;c=R(a,d,!1,!0,c,b);if(null!=c&&(p.$setSelection(c),c=p.$getSelection(),null!=c&&p.$isRangeSelection(c)&&!1===c.isCollapsed())){c.removeText();c=0;b=e.length;for(let f=a;f<b;f++){const g=e[f];f>a&&(g.offsetInParent-=c);f<=d&&(c+=g.text.length,g.text="")}}}function S(a,d){var c=a.patternMatchResults.regExCaptureGroups.length;2>c||(--c,a=R(c,c,!0,!0,a,d),null!=a&&p.$setSelection(a))}
30
+ function T(a,d,c){a.update(()=>{const b=J(d).node.getParentOrThrow();N(d,b,c)},{tag:"history-push"})}
31
+ function U(a,d){let c=null;a.getEditorState().read(()=>{var b=p.$getSelection();if(p.$isRangeSelection(b)){var e=b.anchor.getNode();b=p.$isTextNode(e)?{node:e,offset:b.anchor.offset}:null}else b=null;if(null!==b){b=G(a,!0,b,d);a:{e=!1===d.isParentAListItemNode?F:D;const f=b.triggerState,g=e.length;for(let h=0;h<g;h++){const l=e[h];if(null!=f&&!1===f.isCodeBlock||"paragraphCodeBlock"===l.markdownFormatKind){const m=I(l,b,J(b).node.getParentOrThrow());if(null!=m){e={markdownCriteria:l,patternMatchResults:m};
32
+ break a}}}e={markdownCriteria:null,patternMatchResults:null}}null!==e.markdownCriteria&&null!==e.patternMatchResults&&(c=b,c.markdownCriteria=e.markdownCriteria,c.patternMatchResults=e.patternMatchResults)}});return c}
33
+ function V(a){let d=null;a.read(()=>{const c=p.$getSelection();if(p.$isRangeSelection(c)&&c.isCollapsed()){var b=c.anchor.getNode(),e=b.getParent(),f=n.$isListItemNode(e);d={anchorOffset:c.anchor.offset,hasParentNode:null!==e,isCodeBlock:k.$isCodeNode(b),isParentAListItemNode:f,isSelectionCollapsed:!0,isSimpleText:p.$isTextNode(b)&&b.isSimpleText(),nodeKey:b.getKey(),textContent:b.getTextContent()}}});return d}
34
+ function W(a,d,c){var b=d.getFirstChild();if(p.$isTextNode(b))a:{H(a);b=D.length;var e=d.getTextContent(),f=0===e.length;let m=0;for(;!f;){f=!0;for(let t=m;t<b;t++){var g=D[t];if(null==a.textNodeWithOffset){b:{var h=d.getChildren();var l=h.length;for(--l;0<=l;l--)if(p.$isTextNode(h[l])){h=h[l];break b}h=null}if(null==h)break a;a.textNodeWithOffset={node:h,offset:h.getTextContent().length}}h=I(g,a,d);if(null!=h){a.markdownCriteria=g;a.patternMatchResults=h;N(a,d,c);H(a);g=d.getTextContent();if(0===
35
+ g.length)break a;if(g!==e){e=g;m=t;f=!1;break}}}}}else for(d=d.getChildren(),b=d.length,e=0;e<b;e++)f=d[e],p.$isElementNode(f)&&W(a,f,c)}
36
+ exports.$convertFromMarkdownString=function(a,d,c){if(a.length){var b=[];a=a.split("\n");var e=a.length;for(var f=0;f<e;f++)0<a[f].length?b.push(p.$createParagraphNode().append(p.$createTextNode(a[f]))):b.push(p.$createParagraphNode());b.length?(a=p.$getRoot(),a.clear(),a.append(...b),b=a):b=null}else b=null;if(null!=b){d=G(d,!1,null,null);b=p.$getRoot();a=!1;for(e=0;!a;){a=!0;var g=b.getChildren(),h=g.length;for(var l=e;l<h;l++){var m=g[l];if(p.$isElementNode(m)){f=d;var t=c;var r=m.getTextContent();
37
+ if(p.$isParagraphNode(m)){var q=m.getFirstChild(),w=p.$isTextNode(q);if(!0===f.isWithinCodeBlock)null!=q&&w&&(f.textNodeWithOffset={node:q,offset:0},q=C,r=K(r,!0,!1,f.isAutoFormatting?q.regExForAutoFormatting:q.regEx),null!=r&&(f.patternMatchResults=r)),f.markdownCriteria=C,N(f,m,t);else if(m.getChildren().length)for(r=E.length,f.joinedText=m.getTextContent(),null!=q&&w||y(80),f.textNodeWithOffset={node:q,offset:0},q=0;q<r;q++){w=E[q];if(!1===w.requiresParagraphStart)break;const P=I(w,f,J(f).node.getParentOrThrow());
38
+ if(null!=P){f.markdownCriteria=w;f.patternMatchResults=P;N(f,m,t);break}}}}H(d);if(b.getChildren().length!==h){e=l;a=!1;break}}}a=!1;for(e=0;!a;)for(a=!0,f=b.getChildren(),g=f.length,h=e;h<g;h++)l=f[h],p.$isElementNode(l)&&W(d,l,c),H(d)}};
39
+ exports.registerMarkdownShortcuts=function(a,d){let c=null;return a.registerUpdateListener(({tags:b})=>{if(!1===b.has("historic")){b=V(a.getEditorState());if(null==b)var e=null;else a:{e=b;var f=c;if(null==e||null==f)e=null;else{var g=z.length;for(let h=0;h<g;h++){const l=z[h].triggerString,m=l.length,t=e.textContent.length,r=e.anchorOffset-m;if(!1===(!0===e.hasParentNode&&e.isSimpleText&&e.isSelectionCollapsed&&e.anchorOffset!==f.anchorOffset&&0<=r&&r+m<=t&&e.textContent.substr(r,m)===l&&e.textContent!==
40
+ f.textContent)){e=null;break a}}e=U(a,e)}}null!=e&&T(a,e,d);c=b}else c=null})};
package/package.json CHANGED
@@ -8,18 +8,18 @@
8
8
  "markdown"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.1.21",
11
+ "version": "0.2.2",
12
12
  "main": "LexicalMarkdown.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.1.21"
14
+ "lexical": "0.2.2"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/utils": "0.1.21",
18
- "@lexical/code": "0.1.21",
19
- "@lexical/text": "0.1.21",
20
- "@lexical/rich-text": "0.1.21",
21
- "@lexical/list": "0.1.21",
22
- "@lexical/link": "0.1.21"
17
+ "@lexical/utils": "0.2.2",
18
+ "@lexical/code": "0.2.2",
19
+ "@lexical/text": "0.2.2",
20
+ "@lexical/rich-text": "0.2.2",
21
+ "@lexical/list": "0.2.2",
22
+ "@lexical/link": "0.2.2"
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",