@lexical/markdown 0.2.0 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LexicalMarkdown.dev.js +276 -112
- package/LexicalMarkdown.prod.js +34 -30
- package/package.json +8 -8
package/LexicalMarkdown.dev.js
CHANGED
|
@@ -71,10 +71,20 @@ const markdownHeader2 = { ...paragraphStartBase,
|
|
|
71
71
|
regExForAutoFormatting: /^(?:## )/
|
|
72
72
|
};
|
|
73
73
|
const markdownHeader3 = { ...paragraphStartBase,
|
|
74
|
-
markdownFormatKind: '
|
|
74
|
+
markdownFormatKind: 'paragraphH3',
|
|
75
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
90
|
regEx: /^(?:> )/,
|
|
@@ -115,24 +125,24 @@ const markdownInlineCode = { ...autoFormatBase,
|
|
|
115
125
|
regEx: /(`)([^`]*)(`)/,
|
|
116
126
|
regExForAutoFormatting: /(`)(\s*\b)([^`]*)(\b\s*)(`)(\s)$/
|
|
117
127
|
};
|
|
118
|
-
const markdownItalic = { ...autoFormatBase,
|
|
119
|
-
markdownFormatKind: 'italic',
|
|
120
|
-
regEx: /(\*)([^\*]*)(\*)/,
|
|
121
|
-
regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
|
|
122
|
-
};
|
|
123
128
|
const markdownBold = { ...autoFormatBase,
|
|
124
129
|
markdownFormatKind: 'bold',
|
|
125
|
-
regEx: /(\*\*)([^\*\*]*)(\*\*)/,
|
|
130
|
+
regEx: /(\*\*)(\s*)([^\*\*]*)(\s*)(\*\*)()/,
|
|
126
131
|
regExForAutoFormatting: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
|
|
127
132
|
};
|
|
133
|
+
const markdownItalic = { ...autoFormatBase,
|
|
134
|
+
markdownFormatKind: 'italic',
|
|
135
|
+
regEx: /(\*)(\s*)([^\*]*)(\s*)(\*)()/,
|
|
136
|
+
regExForAutoFormatting: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
|
|
137
|
+
};
|
|
128
138
|
const markdownBold2 = { ...autoFormatBase,
|
|
129
139
|
markdownFormatKind: 'bold',
|
|
130
|
-
regEx: /(__)(\s*)([^__]*)(\s*)(__)/,
|
|
140
|
+
regEx: /(__)(\s*)([^__]*)(\s*)(__)()/,
|
|
131
141
|
regExForAutoFormatting: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
|
|
132
142
|
};
|
|
133
143
|
const markdownItalic2 = { ...autoFormatBase,
|
|
134
144
|
markdownFormatKind: 'italic',
|
|
135
|
-
regEx: /(_)([^_]*)(_)/,
|
|
145
|
+
regEx: /(_)()([^_]*)()(_)()/,
|
|
136
146
|
regExForAutoFormatting: /(_)()([^_]*)()(_)(\s)$/ // Maintain 7 groups.
|
|
137
147
|
|
|
138
148
|
}; // Markdown does not support underline, but we can allow folks to use
|
|
@@ -140,17 +150,17 @@ const markdownItalic2 = { ...autoFormatBase,
|
|
|
140
150
|
|
|
141
151
|
const fakeMarkdownUnderline = { ...autoFormatBase,
|
|
142
152
|
markdownFormatKind: 'underline',
|
|
143
|
-
regEx: /(\<u\>)(\s
|
|
153
|
+
regEx: /(\<u\>)(\s*)([^\<]*)(\s*)(\<\/u\>)()/,
|
|
144
154
|
regExForAutoFormatting: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)(\s)$/
|
|
145
155
|
};
|
|
146
156
|
const markdownStrikethrough = { ...autoFormatBase,
|
|
147
157
|
markdownFormatKind: 'strikethrough',
|
|
148
|
-
regEx: /(~~)([^~~]*)(~~)/,
|
|
158
|
+
regEx: /(~~)(\s*)([^~~]*)(\s*)(~~)()/,
|
|
149
159
|
regExForAutoFormatting: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
|
|
150
160
|
};
|
|
151
161
|
const markdownStrikethroughItalicBold = { ...autoFormatBase,
|
|
152
162
|
markdownFormatKind: 'strikethrough_italic_bold',
|
|
153
|
-
regEx: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)/,
|
|
163
|
+
regEx: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)()/,
|
|
154
164
|
regExForAutoFormatting: /(~~_\*\*)(\s*\b)([^~~_\*\*][^\*\*_~~]*)(\b\s*)(\*\*_~~)(\s)$/
|
|
155
165
|
};
|
|
156
166
|
const markdownItalicbold = { ...autoFormatBase,
|
|
@@ -170,15 +180,29 @@ const markdownStrikethroughBold = { ...autoFormatBase,
|
|
|
170
180
|
};
|
|
171
181
|
const markdownLink = { ...autoFormatBase,
|
|
172
182
|
markdownFormatKind: 'link',
|
|
173
|
-
regEx: /(\[)(
|
|
174
|
-
regExForAutoFormatting: /(\[)(
|
|
183
|
+
regEx: /(\[)([^\]]*)(\]\()([^)]*)(\)*)()/,
|
|
184
|
+
regExForAutoFormatting: /(\[)([^\]]*)(\]\()([^)]*)(\)*)(\s)$/
|
|
175
185
|
};
|
|
176
186
|
const allMarkdownCriteriaForTextNodes = [// Place the combination formats ahead of the individual formats.
|
|
177
187
|
// Combos
|
|
178
188
|
markdownStrikethroughItalicBold, markdownItalicbold, markdownStrikethroughItalic, markdownStrikethroughBold, // Individuals
|
|
179
|
-
markdownInlineCode,
|
|
189
|
+
markdownInlineCode, markdownBold, markdownItalic, // Must appear after markdownBold
|
|
190
|
+
markdownBold2, markdownItalic2, // Must appear after markdownBold2.
|
|
180
191
|
fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
|
|
181
|
-
const
|
|
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
|
+
}
|
|
182
206
|
function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset, triggerState) {
|
|
183
207
|
return {
|
|
184
208
|
currentElementNode: null,
|
|
@@ -202,7 +226,7 @@ function getInitialScanningContext(editor, isAutoFormatting, textNodeWithOffset,
|
|
|
202
226
|
};
|
|
203
227
|
}
|
|
204
228
|
function resetScanningContext(scanningContext) {
|
|
205
|
-
scanningContext.joinedText =
|
|
229
|
+
scanningContext.joinedText = null;
|
|
206
230
|
scanningContext.markdownCriteria = {
|
|
207
231
|
markdownFormatKind: 'noTransformation',
|
|
208
232
|
regEx: /(?:)/,
|
|
@@ -221,6 +245,13 @@ function resetScanningContext(scanningContext) {
|
|
|
221
245
|
function getCodeBlockCriteria() {
|
|
222
246
|
return markdownCodeBlock;
|
|
223
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
|
+
}
|
|
224
255
|
function getPatternMatchResultsForCodeBlock(scanningContext, text) {
|
|
225
256
|
const markdownCriteria = getCodeBlockCriteria();
|
|
226
257
|
return getPatternMatchResultsWithRegEx(text, true, false, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
|
|
@@ -270,6 +301,7 @@ function getTextNodeWithOffsetOrThrow(scanningContext) {
|
|
|
270
301
|
|
|
271
302
|
return textNodeWithOffset;
|
|
272
303
|
}
|
|
304
|
+
|
|
273
305
|
function getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext) {
|
|
274
306
|
const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext); // At start of paragraph.
|
|
275
307
|
|
|
@@ -280,23 +312,23 @@ function getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext)
|
|
|
280
312
|
|
|
281
313
|
return null;
|
|
282
314
|
}
|
|
283
|
-
function getPatternMatchResultsForText(markdownCriteria, scanningContext) {
|
|
284
|
-
if (scanningContext.joinedText == null) {
|
|
285
|
-
const parentNode = getParent(scanningContext);
|
|
286
315
|
|
|
287
|
-
|
|
316
|
+
function getPatternMatchResultsForText(markdownCriteria, scanningContext, parentElementNode) {
|
|
317
|
+
if (scanningContext.joinedText == null) {
|
|
318
|
+
if (lexical.$isElementNode(parentElementNode)) {
|
|
288
319
|
if (scanningContext.joinedText == null) {
|
|
289
320
|
// Lazy calculate the text to search.
|
|
290
|
-
scanningContext.joinedText = text.$joinTextNodesInElementNode(
|
|
321
|
+
scanningContext.joinedText = text.$joinTextNodesInElementNode(parentElementNode, SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES, getTextNodeWithOffsetOrThrow(scanningContext));
|
|
291
322
|
}
|
|
292
323
|
} else {
|
|
293
324
|
{
|
|
294
|
-
throw Error(`Expected node ${
|
|
325
|
+
throw Error(`Expected node ${parentElementNode.__key} to to be a ElementNode.`);
|
|
295
326
|
}
|
|
296
327
|
}
|
|
297
328
|
}
|
|
298
329
|
|
|
299
|
-
|
|
330
|
+
const matchMustAppearAtEndOfString = markdownCriteria.regExForAutoFormatting === true;
|
|
331
|
+
return getPatternMatchResultsWithRegEx(scanningContext.joinedText, false, matchMustAppearAtEndOfString, scanningContext.isAutoFormatting ? markdownCriteria.regExForAutoFormatting : markdownCriteria.regEx);
|
|
300
332
|
}
|
|
301
333
|
|
|
302
334
|
function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNode) {
|
|
@@ -338,6 +370,26 @@ function getNewNodeForCriteria(scanningContext, element, createHorizontalRuleNod
|
|
|
338
370
|
};
|
|
339
371
|
}
|
|
340
372
|
|
|
373
|
+
case 'paragraphH4':
|
|
374
|
+
{
|
|
375
|
+
newNode = richText.$createHeadingNode('h4');
|
|
376
|
+
newNode.append(...children);
|
|
377
|
+
return {
|
|
378
|
+
newNode,
|
|
379
|
+
shouldDelete
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
case 'paragraphH5':
|
|
384
|
+
{
|
|
385
|
+
newNode = richText.$createHeadingNode('h5');
|
|
386
|
+
newNode.append(...children);
|
|
387
|
+
return {
|
|
388
|
+
newNode,
|
|
389
|
+
shouldDelete
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
341
393
|
case 'paragraphBlockQuote':
|
|
342
394
|
{
|
|
343
395
|
newNode = richText.$createQuoteNode();
|
|
@@ -479,6 +531,14 @@ function createListOrMergeWithPrevious(element, children, patternMatchResults, t
|
|
|
479
531
|
}
|
|
480
532
|
}
|
|
481
533
|
|
|
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
|
+
|
|
482
542
|
function transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode) {
|
|
483
543
|
if (scanningContext.textNodeWithOffset != null) {
|
|
484
544
|
const textNodeWithOffset = getTextNodeWithOffsetOrThrow(scanningContext);
|
|
@@ -507,24 +567,25 @@ function transformTextNodeForElementNode(elementNode, scanningContext, createHor
|
|
|
507
567
|
elementNode.replace(newNode);
|
|
508
568
|
}
|
|
509
569
|
}
|
|
510
|
-
|
|
570
|
+
|
|
571
|
+
function transformTextNodeForText(scanningContext, parentElementNode) {
|
|
511
572
|
const markdownCriteria = scanningContext.markdownCriteria;
|
|
512
573
|
|
|
513
574
|
if (markdownCriteria.markdownFormatKind != null) {
|
|
514
575
|
const formatting = getTextFormatType(markdownCriteria.markdownFormatKind);
|
|
515
576
|
|
|
516
577
|
if (formatting != null) {
|
|
517
|
-
transformTextNodeWithFormatting(formatting, scanningContext);
|
|
578
|
+
transformTextNodeWithFormatting(formatting, scanningContext, parentElementNode);
|
|
518
579
|
return;
|
|
519
580
|
}
|
|
520
581
|
|
|
521
582
|
if (markdownCriteria.markdownFormatKind === 'link') {
|
|
522
|
-
transformTextNodeWithLink(scanningContext);
|
|
583
|
+
transformTextNodeWithLink(scanningContext, parentElementNode);
|
|
523
584
|
}
|
|
524
585
|
}
|
|
525
586
|
}
|
|
526
587
|
|
|
527
|
-
function transformTextNodeWithFormatting(formatting, scanningContext) {
|
|
588
|
+
function transformTextNodeWithFormatting(formatting, scanningContext, parentElementNode) {
|
|
528
589
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
529
590
|
const groupCount = patternMatchResults.regExCaptureGroups.length;
|
|
530
591
|
|
|
@@ -543,16 +604,16 @@ function transformTextNodeWithFormatting(formatting, scanningContext) {
|
|
|
543
604
|
// Remove group 5.
|
|
544
605
|
|
|
545
606
|
|
|
546
|
-
removeTextByCaptureGroups(5, 5, scanningContext); // Remove group 1.
|
|
607
|
+
removeTextByCaptureGroups(5, 5, scanningContext, parentElementNode); // Remove group 1.
|
|
547
608
|
|
|
548
|
-
removeTextByCaptureGroups(1, 1, scanningContext); // Apply the formatting.
|
|
609
|
+
removeTextByCaptureGroups(1, 1, scanningContext, parentElementNode); // Apply the formatting.
|
|
549
610
|
|
|
550
|
-
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.
|
|
551
612
|
|
|
552
|
-
selectAfterFinalCaptureGroup(scanningContext);
|
|
613
|
+
selectAfterFinalCaptureGroup(scanningContext, parentElementNode);
|
|
553
614
|
}
|
|
554
615
|
|
|
555
|
-
function transformTextNodeWithLink(scanningContext) {
|
|
616
|
+
function transformTextNodeWithLink(scanningContext, parentElementNode) {
|
|
556
617
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
557
618
|
const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
|
|
558
619
|
const groupCount = regExCaptureGroups.length;
|
|
@@ -578,10 +639,10 @@ function transformTextNodeWithLink(scanningContext) {
|
|
|
578
639
|
} // Remove the initial pattern through to the final pattern.
|
|
579
640
|
|
|
580
641
|
|
|
581
|
-
removeTextByCaptureGroups(1, 5, scanningContext);
|
|
642
|
+
removeTextByCaptureGroups(1, 5, scanningContext, parentElementNode);
|
|
582
643
|
insertTextPriorToCaptureGroup(1, // Insert at the beginning of the meaningful capture groups, namely index 1. Index 0 refers to the whole matched string.
|
|
583
|
-
title, scanningContext);
|
|
584
|
-
const newSelectionForLink = createSelectionWithCaptureGroups(1, 1, false, true, scanningContext);
|
|
644
|
+
title, scanningContext, parentElementNode);
|
|
645
|
+
const newSelectionForLink = createSelectionWithCaptureGroups(1, 1, false, true, scanningContext, parentElementNode);
|
|
585
646
|
|
|
586
647
|
if (newSelectionForLink == null) {
|
|
587
648
|
return;
|
|
@@ -590,11 +651,11 @@ function transformTextNodeWithLink(scanningContext) {
|
|
|
590
651
|
lexical.$setSelection(newSelectionForLink);
|
|
591
652
|
scanningContext.editor.dispatchCommand(link.TOGGLE_LINK_COMMAND, url); // Place caret at end of final capture group.
|
|
592
653
|
|
|
593
|
-
selectAfterFinalCaptureGroup(scanningContext);
|
|
654
|
+
selectAfterFinalCaptureGroup(scanningContext, parentElementNode);
|
|
594
655
|
} // Below are lower level helper functions.
|
|
595
656
|
|
|
596
657
|
|
|
597
|
-
function
|
|
658
|
+
function getParentElementNodeOrThrow(scanningContext) {
|
|
598
659
|
return getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
|
|
599
660
|
}
|
|
600
661
|
|
|
@@ -643,7 +704,7 @@ function getTextFormatType(markdownFormatKind) {
|
|
|
643
704
|
return null;
|
|
644
705
|
}
|
|
645
706
|
|
|
646
|
-
function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, startAtEndOfAnchor, finishAtEndOfFocus, scanningContext) {
|
|
707
|
+
function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, startAtEndOfAnchor, finishAtEndOfFocus, scanningContext, parentElementNode) {
|
|
647
708
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
648
709
|
const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
|
|
649
710
|
const regExCaptureGroupsCount = regExCaptureGroups.length;
|
|
@@ -652,7 +713,6 @@ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureG
|
|
|
652
713
|
return null;
|
|
653
714
|
}
|
|
654
715
|
|
|
655
|
-
const parentElementNode = getParent(scanningContext);
|
|
656
716
|
const joinedTextLength = getJoinedTextLength(patternMatchResults);
|
|
657
717
|
const anchorCaptureGroupDetail = regExCaptureGroups[anchorCaptureGroupIndex];
|
|
658
718
|
const focusCaptureGroupDetail = regExCaptureGroups[focusCaptureGroupIndex];
|
|
@@ -661,6 +721,13 @@ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureG
|
|
|
661
721
|
const anchorTextNodeWithOffset = text.$findNodeWithOffsetFromJoinedText(anchorLocation, joinedTextLength, SEPARATOR_LENGTH, parentElementNode);
|
|
662
722
|
const focusTextNodeWithOffset = text.$findNodeWithOffsetFromJoinedText(focusLocation, joinedTextLength, SEPARATOR_LENGTH, parentElementNode);
|
|
663
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
|
+
|
|
664
731
|
if (anchorTextNodeWithOffset == null || focusTextNodeWithOffset == null) {
|
|
665
732
|
return null;
|
|
666
733
|
}
|
|
@@ -671,10 +738,10 @@ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureG
|
|
|
671
738
|
return selection;
|
|
672
739
|
}
|
|
673
740
|
|
|
674
|
-
function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, scanningContext) {
|
|
741
|
+
function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, scanningContext, parentElementNode) {
|
|
675
742
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
676
743
|
const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
|
|
677
|
-
const newSelection = createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, false, true, scanningContext);
|
|
744
|
+
const newSelection = createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, false, true, scanningContext, parentElementNode);
|
|
678
745
|
|
|
679
746
|
if (newSelection != null) {
|
|
680
747
|
lexical.$setSelection(newSelection);
|
|
@@ -702,7 +769,7 @@ function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupInd
|
|
|
702
769
|
}
|
|
703
770
|
}
|
|
704
771
|
|
|
705
|
-
function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext) {
|
|
772
|
+
function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext, parentElementNode) {
|
|
706
773
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
707
774
|
const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
|
|
708
775
|
const regExCaptureGroupsCount = regExCaptureGroups.length;
|
|
@@ -716,7 +783,7 @@ function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext)
|
|
|
716
783
|
offsetInParent: captureGroupDetail.offsetInParent,
|
|
717
784
|
text
|
|
718
785
|
};
|
|
719
|
-
const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, false, scanningContext);
|
|
786
|
+
const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, false, scanningContext, parentElementNode);
|
|
720
787
|
|
|
721
788
|
if (newSelection != null) {
|
|
722
789
|
lexical.$setSelection(newSelection);
|
|
@@ -737,7 +804,7 @@ function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext)
|
|
|
737
804
|
}
|
|
738
805
|
}
|
|
739
806
|
|
|
740
|
-
function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningContext) {
|
|
807
|
+
function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningContext, parentElementNode) {
|
|
741
808
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
742
809
|
const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
|
|
743
810
|
const regExCaptureGroupsCount = regExCaptureGroups.length;
|
|
@@ -752,7 +819,7 @@ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningC
|
|
|
752
819
|
return;
|
|
753
820
|
}
|
|
754
821
|
|
|
755
|
-
const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, true, scanningContext);
|
|
822
|
+
const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, true, scanningContext, parentElementNode);
|
|
756
823
|
|
|
757
824
|
if (newSelection != null) {
|
|
758
825
|
lexical.$setSelection(newSelection);
|
|
@@ -767,7 +834,7 @@ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningC
|
|
|
767
834
|
} // Place caret at end of final capture group.
|
|
768
835
|
|
|
769
836
|
|
|
770
|
-
function selectAfterFinalCaptureGroup(scanningContext) {
|
|
837
|
+
function selectAfterFinalCaptureGroup(scanningContext, parentElementNode) {
|
|
771
838
|
const patternMatchResults = scanningContext.patternMatchResults;
|
|
772
839
|
const groupCount = patternMatchResults.regExCaptureGroups.length;
|
|
773
840
|
|
|
@@ -777,7 +844,7 @@ function selectAfterFinalCaptureGroup(scanningContext) {
|
|
|
777
844
|
}
|
|
778
845
|
|
|
779
846
|
const lastGroupIndex = groupCount - 1;
|
|
780
|
-
const newSelection = createSelectionWithCaptureGroups(lastGroupIndex, lastGroupIndex, true, true, scanningContext);
|
|
847
|
+
const newSelection = createSelectionWithCaptureGroups(lastGroupIndex, lastGroupIndex, true, true, scanningContext, parentElementNode);
|
|
781
848
|
|
|
782
849
|
if (newSelection != null) {
|
|
783
850
|
lexical.$setSelection(newSelection);
|
|
@@ -792,31 +859,6 @@ function selectAfterFinalCaptureGroup(scanningContext) {
|
|
|
792
859
|
*
|
|
793
860
|
*
|
|
794
861
|
*/
|
|
795
|
-
function getAllTriggers() {
|
|
796
|
-
return triggers;
|
|
797
|
-
}
|
|
798
|
-
function getAllMarkdownCriteriaForTextNodes() {
|
|
799
|
-
return allMarkdownCriteriaForTextNodes;
|
|
800
|
-
}
|
|
801
|
-
function getAllMarkdownCriteria() {
|
|
802
|
-
return allMarkdownCriteria;
|
|
803
|
-
}
|
|
804
|
-
function transformTextNodeForMarkdownCriteria(scanningContext, createHorizontalRuleNode) {
|
|
805
|
-
if (scanningContext.markdownCriteria.requiresParagraphStart === true) {
|
|
806
|
-
const elementNode = getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
|
|
807
|
-
transformTextNodeForElementNode(elementNode, scanningContext, createHorizontalRuleNode);
|
|
808
|
-
} else {
|
|
809
|
-
transformTextNodeForText(scanningContext);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
function getPatternMatchResultsForCriteria(markdownCriteria, scanningContext) {
|
|
814
|
-
if (markdownCriteria.requiresParagraphStart === true) {
|
|
815
|
-
return getPatternMatchResultsForParagraphs(markdownCriteria, scanningContext);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
return getPatternMatchResultsForText(markdownCriteria, scanningContext);
|
|
819
|
-
}
|
|
820
862
|
|
|
821
863
|
function getTextNodeForAutoFormatting(selection) {
|
|
822
864
|
if (!lexical.$isRangeSelection(selection)) {
|
|
@@ -837,7 +879,8 @@ function getTextNodeForAutoFormatting(selection) {
|
|
|
837
879
|
|
|
838
880
|
function updateAutoFormatting(editor, scanningContext, createHorizontalRuleNode) {
|
|
839
881
|
editor.update(() => {
|
|
840
|
-
|
|
882
|
+
const elementNode = getTextNodeWithOffsetOrThrow(scanningContext).node.getParentOrThrow();
|
|
883
|
+
transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
|
|
841
884
|
}, {
|
|
842
885
|
tag: 'history-push'
|
|
843
886
|
});
|
|
@@ -851,7 +894,7 @@ function getCriteriaWithPatternMatchResults(markdownCriteriaArray, scanningConte
|
|
|
851
894
|
const markdownCriteria = markdownCriteriaArray[i]; // Skip code block nodes, unless the autoFormatKind calls for toggling the code block.
|
|
852
895
|
|
|
853
896
|
if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || markdownCriteria.markdownFormatKind === 'paragraphCodeBlock') {
|
|
854
|
-
const patternMatchResults = getPatternMatchResultsForCriteria(markdownCriteria, scanningContext);
|
|
897
|
+
const patternMatchResults = getPatternMatchResultsForCriteria(markdownCriteria, scanningContext, getParentElementNodeOrThrow(scanningContext));
|
|
855
898
|
|
|
856
899
|
if (patternMatchResults != null) {
|
|
857
900
|
return {
|
|
@@ -935,7 +978,9 @@ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
|
|
|
935
978
|
|
|
936
979
|
const triggerStringLength = triggerString.length;
|
|
937
980
|
const currentTextContentLength = currentTriggerState.textContent.length;
|
|
938
|
-
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.
|
|
939
984
|
|
|
940
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.
|
|
941
986
|
currentTriggerState.textContent !== priorTriggerState.textContent) === false) {
|
|
@@ -980,8 +1025,61 @@ function convertStringToLexical(text, editor) {
|
|
|
980
1025
|
|
|
981
1026
|
return null;
|
|
982
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.
|
|
1034
|
+
|
|
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];
|
|
983
1042
|
|
|
984
|
-
|
|
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) {
|
|
985
1083
|
const textContent = elementNode.getTextContent(); // Handle paragraph nodes below.
|
|
986
1084
|
|
|
987
1085
|
if (lexical.$isParagraphNode(elementNode)) {
|
|
@@ -1006,74 +1104,140 @@ function convertElementNodeContainingMarkdown(scanningContext, elementNode, crea
|
|
|
1006
1104
|
|
|
1007
1105
|
scanningContext.markdownCriteria = getCodeBlockCriteria(); // Perform text transformation here.
|
|
1008
1106
|
|
|
1009
|
-
|
|
1107
|
+
transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
|
|
1010
1108
|
return;
|
|
1011
1109
|
}
|
|
1012
1110
|
|
|
1013
1111
|
if (elementNode.getChildren().length) {
|
|
1014
|
-
const allCriteria =
|
|
1112
|
+
const allCriteria = getAllMarkdownCriteriaForParagraphs();
|
|
1015
1113
|
const count = allCriteria.length;
|
|
1114
|
+
scanningContext.joinedText = paragraphNode.getTextContent();
|
|
1115
|
+
|
|
1116
|
+
if (!(firstChild != null && firstChildIsTextNode)) {
|
|
1117
|
+
throw Error(`Expect paragraph containing only text nodes.`);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
scanningContext.textNodeWithOffset = {
|
|
1121
|
+
node: firstChild,
|
|
1122
|
+
offset: 0
|
|
1123
|
+
};
|
|
1016
1124
|
|
|
1017
1125
|
for (let i = 0; i < count; i++) {
|
|
1018
1126
|
const criteria = allCriteria[i];
|
|
1019
1127
|
|
|
1020
|
-
if (criteria.requiresParagraphStart ===
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
}
|
|
1128
|
+
if (criteria.requiresParagraphStart === false) {
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1024
1131
|
|
|
1025
|
-
|
|
1026
|
-
node: firstChild,
|
|
1027
|
-
offset: 0
|
|
1028
|
-
};
|
|
1029
|
-
scanningContext.joinedText = paragraphNode.getTextContent();
|
|
1030
|
-
const patternMatchResults = getPatternMatchResultsForParagraphs(criteria, scanningContext);
|
|
1132
|
+
const patternMatchResults = getPatternMatchResultsForCriteria(criteria, scanningContext, getParentElementNodeOrThrow(scanningContext));
|
|
1031
1133
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
|
|
1134
|
+
if (patternMatchResults != null) {
|
|
1135
|
+
scanningContext.markdownCriteria = criteria;
|
|
1136
|
+
scanningContext.patternMatchResults = patternMatchResults; // Perform text transformation here.
|
|
1036
1137
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
}
|
|
1138
|
+
transformTextNodeForMarkdownCriteria(scanningContext, elementNode, createHorizontalRuleNode);
|
|
1139
|
+
return;
|
|
1040
1140
|
}
|
|
1041
1141
|
}
|
|
1042
1142
|
}
|
|
1043
1143
|
}
|
|
1044
1144
|
}
|
|
1045
1145
|
|
|
1046
|
-
function
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
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;
|
|
1051
1177
|
let startIndex = 0;
|
|
1052
1178
|
|
|
1053
1179
|
while (!done) {
|
|
1054
1180
|
done = true;
|
|
1055
|
-
const elementNodes = root.getChildren();
|
|
1056
|
-
const countOfElementNodes = elementNodes.length;
|
|
1057
1181
|
|
|
1058
|
-
for (let i = startIndex; i <
|
|
1059
|
-
const
|
|
1182
|
+
for (let i = startIndex; i < count; i++) {
|
|
1183
|
+
const criteria = allCriteria[i];
|
|
1060
1184
|
|
|
1061
|
-
if (
|
|
1062
|
-
|
|
1063
|
-
|
|
1185
|
+
if (scanningContext.textNodeWithOffset == null) {
|
|
1186
|
+
// Need to search through the very last text node in the element.
|
|
1187
|
+
const lastTextNode = getLastTextNodeInElementNode(elementNode);
|
|
1188
|
+
|
|
1189
|
+
if (lastTextNode == null) {
|
|
1190
|
+
// If we have no more text nodes, then there's nothing to search and transform.
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1064
1193
|
|
|
1194
|
+
scanningContext.textNodeWithOffset = {
|
|
1195
|
+
node: lastTextNode,
|
|
1196
|
+
offset: lastTextNode.getTextContent().length
|
|
1197
|
+
};
|
|
1198
|
+
}
|
|
1065
1199
|
|
|
1066
|
-
|
|
1200
|
+
const patternMatchResults = getPatternMatchResultsForCriteria(criteria, scanningContext, elementNode);
|
|
1067
1201
|
|
|
1068
|
-
if (
|
|
1069
|
-
|
|
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;
|
|
1070
1222
|
startIndex = i;
|
|
1071
1223
|
done = false;
|
|
1072
1224
|
break;
|
|
1073
1225
|
}
|
|
1074
1226
|
}
|
|
1075
|
-
}
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1076
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;
|
|
1077
1241
|
}
|
|
1078
1242
|
|
|
1079
1243
|
/**
|
package/LexicalMarkdown.prod.js
CHANGED
|
@@ -4,33 +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"),
|
|
8
|
-
const
|
|
9
|
-
{...
|
|
10
|
-
{...
|
|
11
|
-
regEx:/(_)([^_]*)(_)/,regExForAutoFormatting:/(_)()([^_]*)()(_)(\s)$/},{...
|
|
12
|
-
markdownFormatKind:"paragraphH1",regEx:/^(?:# )/,regExForAutoFormatting:/^(?:# )/},{...
|
|
13
|
-
regEx:/^(\s{0,10})(
|
|
14
|
-
function
|
|
15
|
-
function
|
|
16
|
-
function
|
|
17
|
-
function K(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
shouldDelete:!
|
|
21
|
-
|
|
22
|
-
function
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
f
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if(null
|
|
35
|
-
|
|
36
|
-
|
|
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.2.
|
|
11
|
+
"version": "0.2.3",
|
|
12
12
|
"main": "LexicalMarkdown.js",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"lexical": "0.2.
|
|
14
|
+
"lexical": "0.2.3"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lexical/utils": "0.2.
|
|
18
|
-
"@lexical/code": "0.2.
|
|
19
|
-
"@lexical/text": "0.2.
|
|
20
|
-
"@lexical/rich-text": "0.2.
|
|
21
|
-
"@lexical/list": "0.2.
|
|
22
|
-
"@lexical/link": "0.2.
|
|
17
|
+
"@lexical/utils": "0.2.3",
|
|
18
|
+
"@lexical/code": "0.2.3",
|
|
19
|
+
"@lexical/text": "0.2.3",
|
|
20
|
+
"@lexical/rich-text": "0.2.3",
|
|
21
|
+
"@lexical/list": "0.2.3",
|
|
22
|
+
"@lexical/link": "0.2.3"
|
|
23
23
|
},
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|