@lexical/react 0.1.13 → 0.1.16

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.
Files changed (33) hide show
  1. package/DEPRECATED_useLexicalAutoFormatter.dev.js +283 -295
  2. package/DEPRECATED_useLexicalAutoFormatter.prod.js +19 -21
  3. package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +3 -72
  4. package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +1 -2
  5. package/DEPRECATED_useLexicalCharacterLimit.dev.js +11 -63
  6. package/DEPRECATED_useLexicalCharacterLimit.prod.js +6 -7
  7. package/DEPRECATED_useLexicalPlainText.dev.js +16 -41
  8. package/DEPRECATED_useLexicalPlainText.prod.js +13 -14
  9. package/DEPRECATED_useLexicalRichText.dev.js +24 -49
  10. package/DEPRECATED_useLexicalRichText.prod.js +15 -15
  11. package/LexicalAutoFormatterPlugin.dev.js +283 -295
  12. package/LexicalAutoFormatterPlugin.prod.js +19 -21
  13. package/LexicalAutoLinkPlugin.dev.js +2 -2
  14. package/LexicalAutoLinkPlugin.prod.js +2 -2
  15. package/LexicalCharacterLimitPlugin.dev.js +11 -63
  16. package/LexicalCharacterLimitPlugin.prod.js +8 -9
  17. package/LexicalCollaborationPlugin.d.ts +5 -1
  18. package/LexicalCollaborationPlugin.dev.js +77 -14
  19. package/LexicalCollaborationPlugin.js.flow +7 -2
  20. package/LexicalCollaborationPlugin.prod.js +9 -7
  21. package/LexicalHashtagPlugin.dev.js +61 -3
  22. package/LexicalHashtagPlugin.prod.js +7 -4
  23. package/LexicalOnChangePlugin.dev.js +15 -2
  24. package/LexicalOnChangePlugin.prod.js +2 -1
  25. package/LexicalPlainTextPlugin.dev.js +20 -113
  26. package/LexicalPlainTextPlugin.prod.js +11 -12
  27. package/LexicalRichTextPlugin.dev.js +28 -121
  28. package/LexicalRichTextPlugin.prod.js +12 -13
  29. package/LexicalTablePlugin.dev.js +9 -5
  30. package/LexicalTablePlugin.prod.js +2 -2
  31. package/package.json +10 -7
  32. package/useLexicalIsTextContentEmpty.dev.js +3 -32
  33. package/useLexicalIsTextContentEmpty.prod.js +1 -2
@@ -12,6 +12,7 @@ var lexical = require('lexical');
12
12
  var CodeNode = require('lexical/CodeNode');
13
13
  var react = require('react');
14
14
  var LexicalHorizontalRuleNode = require('@lexical/react/LexicalHorizontalRuleNode');
15
+ var text = require('@lexical/text');
15
16
  var HeadingNode = require('lexical/HeadingNode');
16
17
  var QuoteNode = require('lexical/QuoteNode');
17
18
 
@@ -23,108 +24,27 @@ var QuoteNode = require('lexical/QuoteNode');
23
24
  *
24
25
  *
25
26
  */
26
- // Caution, this function creates a string and should not be used within a tight loop.
27
- // Use $getNodeWithOffsetsFromJoinedTextNodesFromElementNode below to convert
28
- // indexes in the return string back into their corresponding node and offsets.
29
-
30
- function $joinTextNodesInElementNode(elementNode, separator, stopAt) {
31
- let textContent = '';
32
- const children = elementNode.getChildren();
33
- const length = children.length;
34
-
35
- for (let i = 0; i < length; ++i) {
36
- const child = children[i];
37
-
38
- if (lexical.$isTextNode(child)) {
39
- const childTextContent = child.getTextContent();
40
-
41
- if (child.is(stopAt.node)) {
42
- if (stopAt.offset > childTextContent.length) {
43
- {
44
- throw Error(`Node ${child.__key} and selection point do not match.`);
45
- }
46
- }
47
-
48
- textContent += child.getTextContent().substr(0, stopAt.offset);
49
- break;
50
- } else {
51
- textContent += childTextContent;
52
- }
53
- } else {
54
- textContent += separator;
55
- }
56
- }
57
-
58
- return textContent;
59
- } // This function converts the offsetInJoinedText to
60
- // a node and offset result or null if not found.
61
- // This function is to be used in conjunction with joinTextNodesInElementNode above.
62
- // The joinedTextContent should be return value from joinTextNodesInElementNode.
63
- //
64
- // The offsetInJoinedText is relative to the entire string which
65
- // itself is relevant to the parent ElementNode.
66
- //
67
- // Example:
68
- // Given a Paragraph with 2 TextNodes. The first is Hello, the second is World.
69
- // The joinedTextContent would be "HelloWorld"
70
- // The offsetInJoinedText might be for the letter "e" = 1 or "r" = 7.
71
- // The return values would be {TextNode1, 1} or {TextNode2,2}, respectively.
72
-
73
- function $findNodeWithOffsetFromJoinedText(elementNode, joinedTextLength, offsetInJoinedText, separatorLength) {
74
- const children = elementNode.getChildren();
75
- const childrenLength = children.length;
76
- let runningLength = 0;
77
- let isPriorNodeTextNode = false;
78
-
79
- for (let i = 0; i < childrenLength; ++i) {
80
- // We must examine the offsetInJoinedText that is located
81
- // at the length of the string.
82
- // For example, given "hello", the length is 5, yet
83
- // the caller still wants the node + offset at the
84
- // right edge of the "o".
85
- if (runningLength > joinedTextLength) {
86
- break;
87
- }
88
-
89
- const child = children[i];
90
- const isChildNodeTestNode = lexical.$isTextNode(child);
91
- const childContentLength = isChildNodeTestNode ? child.getTextContent().length : separatorLength;
92
- const newRunningLength = runningLength + childContentLength;
93
- const isJoinedOffsetWithinNode = isPriorNodeTextNode === false && runningLength === offsetInJoinedText || runningLength === 0 && runningLength === offsetInJoinedText || runningLength < offsetInJoinedText && offsetInJoinedText <= newRunningLength;
94
-
95
- if (isJoinedOffsetWithinNode && lexical.$isTextNode(child)) {
96
- // Check isTextNode again for flow.
97
- return {
98
- node: child,
99
- offset: offsetInJoinedText - runningLength
100
- };
101
- }
102
-
103
- runningLength = newRunningLength;
104
- isPriorNodeTextNode = isChildNodeTestNode;
105
- }
106
-
107
- return null;
108
- }
109
-
110
- /**
111
- * Copyright (c) Meta Platforms, Inc. and affiliates.
112
- *
113
- * This source code is licensed under the MIT license found in the
114
- * LICENSE file in the root directory of this source tree.
115
- *
116
- *
117
- */
27
+ /*
28
+ How to add a new syntax to capture and transform.
29
+ 1. Create a new enumeration by adding to AutoFormatKind.
30
+ 2. Add a new criteria with a regEx pattern. See markdownStrikethrough as an example.
31
+ 3. Add your block criteria (e.g. '# ') to allAutoFormatCriteria or
32
+ your text criteria (e.g. *MyItalic*) to allAutoFormatCriteriaForTextNodes.
33
+ 4. Add your Lexical block specific transforming code here: transformTextNodeForText.
34
+ Add your Lexical text specific transforming code here: transformTextNodeForText.
35
+ */
36
+ // The trigger state helps to capture EditorState information
118
37
  // from the prior and current EditorState.
119
38
  // This is then used to determined if an auto format has been triggered.
120
39
 
121
40
  const TRIGGER_STRING = '\u0020'; // The space key triggers markdown.
122
41
 
123
- const TRIGGER_STRING_LENGTH = TRIGGER_STRING.length;
124
42
  const SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES = '\u0004'; // Select an unused unicode character to separate text and non-text nodes.
125
43
 
44
+ const SEPARATOR_LENGTH = SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES.length; // Todo: speed up performance by having non-capture group variations of the regex.
45
+
126
46
  const autoFormatBase = {
127
- nodeTransformationKind: null,
47
+ autoFormatKind: null,
128
48
  regEx: /(?:)/,
129
49
  requiresParagraphStart: false
130
50
  };
@@ -132,72 +52,76 @@ const paragraphStartBase = { ...autoFormatBase,
132
52
  requiresParagraphStart: true
133
53
  };
134
54
  const markdownHeader1 = { ...paragraphStartBase,
135
- nodeTransformationKind: 'paragraphH1',
55
+ autoFormatKind: 'paragraphH1',
136
56
  regEx: /^(?:# )/
137
57
  };
138
58
  const markdownHeader2 = { ...paragraphStartBase,
139
- nodeTransformationKind: 'paragraphH2',
59
+ autoFormatKind: 'paragraphH2',
140
60
  regEx: /^(?:## )/
141
61
  };
142
62
  const markdownHeader3 = { ...paragraphStartBase,
143
- nodeTransformationKind: 'paragraphH2',
63
+ autoFormatKind: 'paragraphH2',
144
64
  regEx: /^(?:### )/
145
65
  };
146
66
  const markdownBlockQuote = { ...paragraphStartBase,
147
- nodeTransformationKind: 'paragraphBlockQuote',
67
+ autoFormatKind: 'paragraphBlockQuote',
148
68
  regEx: /^(?:> )/
149
69
  };
150
70
  const markdownUnorderedListDash = { ...paragraphStartBase,
151
- nodeTransformationKind: 'paragraphUnorderedList',
71
+ autoFormatKind: 'paragraphUnorderedList',
152
72
  regEx: /^(?:- )/
153
73
  };
154
74
  const markdownUnorderedListAsterisk = { ...paragraphStartBase,
155
- nodeTransformationKind: 'paragraphUnorderedList',
75
+ autoFormatKind: 'paragraphUnorderedList',
156
76
  regEx: /^(?:\* )/
157
77
  };
158
78
  const markdownCodeBlock = { ...paragraphStartBase,
159
- nodeTransformationKind: 'paragraphCodeBlock',
79
+ autoFormatKind: 'paragraphCodeBlock',
160
80
  regEx: /^(```)([a-z]*)( )/
161
81
  };
162
82
  const markdownOrderedList = { ...paragraphStartBase,
163
- nodeTransformationKind: 'paragraphOrderedList',
83
+ autoFormatKind: 'paragraphOrderedList',
164
84
  regEx: /^(\d+)\.\s/
165
85
  };
166
86
  const markdownHorizontalRule = { ...paragraphStartBase,
167
- nodeTransformationKind: 'horizontalRule',
87
+ autoFormatKind: 'horizontalRule',
168
88
  regEx: /^(?:\*\*\* )/
169
89
  };
170
90
  const markdownHorizontalRuleUsingDashes = { ...paragraphStartBase,
171
- nodeTransformationKind: 'horizontalRule',
91
+ autoFormatKind: 'horizontalRule',
172
92
  regEx: /^(?:--- )/
173
93
  };
174
94
  const markdownItalic = { ...autoFormatBase,
175
- nodeTransformationKind: 'italic',
176
- regEx: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*\s)$/
95
+ autoFormatKind: 'italic',
96
+ regEx: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
177
97
  };
178
98
  const markdownBold = { ...autoFormatBase,
179
- nodeTransformationKind: 'bold',
180
- regEx: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*\s)$/
99
+ autoFormatKind: 'bold',
100
+ regEx: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
181
101
  };
182
102
  const markdownBoldWithUnderlines = { ...autoFormatBase,
183
- nodeTransformationKind: 'bold',
184
- regEx: /(__)(\s*)([^__]*)(\s*)(__\s)$/
103
+ autoFormatKind: 'bold',
104
+ regEx: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
185
105
  };
186
106
  const markdownBoldItalic = { ...autoFormatBase,
187
- nodeTransformationKind: 'bold_italic',
188
- regEx: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*\s)$/
107
+ autoFormatKind: 'bold_italic',
108
+ regEx: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\s*)(\*\*\*)(\s)$/
189
109
  }; // Markdown does not support underline, but we can allow folks to use
190
110
  // the HTML tags for underline.
191
111
 
192
112
  const fakeMarkdownUnderline = { ...autoFormatBase,
193
- nodeTransformationKind: 'underline',
194
- regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>\s)$/
113
+ autoFormatKind: 'underline',
114
+ regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)(\s)$/
195
115
  };
196
116
  const markdownStrikethrough = { ...autoFormatBase,
197
- nodeTransformationKind: 'strikethrough',
198
- regEx: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~\s)$/
117
+ autoFormatKind: 'strikethrough',
118
+ regEx: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
199
119
  };
200
- const allAutoFormatCriteriaForTextNodes = [markdownBoldItalic, markdownItalic, markdownBold, markdownBoldWithUnderlines, fakeMarkdownUnderline, markdownStrikethrough];
120
+ const markdownLink = { ...autoFormatBase,
121
+ autoFormatKind: 'link',
122
+ regEx: /(\[)(.+)(\]\()([^ ]+)(?: \"(?:.+)\")?(\))(\s)$/
123
+ };
124
+ const allAutoFormatCriteriaForTextNodes = [markdownBoldItalic, markdownItalic, markdownBold, markdownBoldWithUnderlines, fakeMarkdownUnderline, markdownStrikethrough, markdownLink];
201
125
  const allAutoFormatCriteria = [markdownHeader1, markdownHeader2, markdownHeader3, markdownBlockQuote, markdownUnorderedListDash, markdownUnorderedListAsterisk, markdownOrderedList, markdownCodeBlock, markdownHorizontalRule, markdownHorizontalRuleUsingDashes, ...allAutoFormatCriteriaForTextNodes];
202
126
  function getAllAutoFormatCriteriaForTextNodes() {
203
127
  return allAutoFormatCriteriaForTextNodes;
@@ -205,17 +129,17 @@ function getAllAutoFormatCriteriaForTextNodes() {
205
129
  function getAllAutoFormatCriteria() {
206
130
  return allAutoFormatCriteria;
207
131
  }
208
- function getInitialScanningContext(textNodeWithOffset, triggerState) {
132
+ function getInitialScanningContext(editor, textNodeWithOffset, triggerState) {
209
133
  return {
210
134
  autoFormatCriteria: {
211
- nodeTransformationKind: 'noTransformation',
135
+ autoFormatKind: 'noTransformation',
212
136
  regEx: /(?:)/,
213
137
  // Empty reg ex will do until the precise criteria is discovered.
214
138
  requiresParagraphStart: null
215
139
  },
140
+ editor,
216
141
  joinedText: null,
217
- matchResultContext: {
218
- offsetInJoinedTextForCollapsedSelection: 0,
142
+ patternMatchResults: {
219
143
  regExCaptureGroups: []
220
144
  },
221
145
  textNodeWithOffset,
@@ -223,26 +147,21 @@ function getInitialScanningContext(textNodeWithOffset, triggerState) {
223
147
  };
224
148
  }
225
149
 
226
- function getMatchResultContextWithRegEx(textToSearch, matchMustAppearAtStartOfString, matchMustAppearAtEndOfString, regEx) {
227
- const matchResultContext = {
228
- offsetInJoinedTextForCollapsedSelection: 0,
150
+ function getPatternMatchResultsWithRegEx(textToSearch, matchMustAppearAtStartOfString, matchMustAppearAtEndOfString, regEx) {
151
+ const patternMatchResults = {
229
152
  regExCaptureGroups: []
230
153
  };
231
154
  const regExMatches = textToSearch.match(regEx);
232
155
 
233
156
  if (regExMatches !== null && regExMatches.length > 0 && (matchMustAppearAtStartOfString === false || regExMatches.index === 0) && (matchMustAppearAtEndOfString === false || regExMatches.index + regExMatches[0].length === textToSearch.length)) {
234
- matchResultContext.offsetInJoinedTextForCollapsedSelection = textToSearch.length;
235
157
  const captureGroupsCount = regExMatches.length;
236
158
  let runningLength = regExMatches.index;
237
159
 
238
160
  for (let captureGroupIndex = 0; captureGroupIndex < captureGroupsCount; captureGroupIndex++) {
239
161
  const textContent = regExMatches[captureGroupIndex];
240
- matchResultContext.regExCaptureGroups.push({
241
- anchorTextNodeWithOffset: null,
242
- focusTextNodeWithOffset: null,
162
+ patternMatchResults.regExCaptureGroups.push({
243
163
  offsetInParent: runningLength,
244
- text: textContent,
245
- textLength: textContent.length - (captureGroupIndex + 1 === captureGroupsCount ? TRIGGER_STRING_LENGTH : 0)
164
+ text: textContent
246
165
  }); // The 0th capture group is special in that it's text contents is
247
166
  // a join of all subsequent capture groups. So, skip this group
248
167
  // when calculating the runningLength.
@@ -252,31 +171,31 @@ function getMatchResultContextWithRegEx(textToSearch, matchMustAppearAtStartOfSt
252
171
  }
253
172
  }
254
173
 
255
- return matchResultContext;
174
+ return patternMatchResults;
256
175
  }
257
176
 
258
177
  return null;
259
178
  }
260
179
 
261
- function getMatchResultContextForParagraphs(autoFormatCriteria, scanningContext) {
180
+ function getPatternMatchResultsForParagraphs(autoFormatCriteria, scanningContext) {
262
181
  const textNodeWithOffset = scanningContext.textNodeWithOffset; // At start of paragraph.
263
182
 
264
183
  if (textNodeWithOffset.node.getPreviousSibling() === null) {
265
184
  const textToSearch = scanningContext.textNodeWithOffset.node.getTextContent();
266
- return getMatchResultContextWithRegEx(textToSearch, true, false, autoFormatCriteria.regEx);
185
+ return getPatternMatchResultsWithRegEx(textToSearch, true, false, autoFormatCriteria.regEx);
267
186
  }
268
187
 
269
188
  return null;
270
189
  }
271
190
 
272
- function getMatchResultContextForText(autoFormatCriteria, scanningContext) {
191
+ function getPatternMatchResultsForText(autoFormatCriteria, scanningContext) {
273
192
  if (scanningContext.joinedText == null) {
274
- const parentNode = scanningContext.textNodeWithOffset.node.getParentOrThrow();
193
+ const parentNode = getParent(scanningContext);
275
194
 
276
195
  if (lexical.$isElementNode(parentNode)) {
277
196
  if (scanningContext.joinedText == null) {
278
197
  // Lazy calculate the text to search.
279
- scanningContext.joinedText = $joinTextNodesInElementNode(parentNode, SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES, scanningContext.textNodeWithOffset);
198
+ scanningContext.joinedText = text.$joinTextNodesInElementNode(parentNode, SEPARATOR_BETWEEN_TEXT_AND_NON_TEXT_NODES, scanningContext.textNodeWithOffset);
280
199
  }
281
200
  } else {
282
201
  {
@@ -285,25 +204,25 @@ function getMatchResultContextForText(autoFormatCriteria, scanningContext) {
285
204
  }
286
205
  }
287
206
 
288
- return getMatchResultContextWithRegEx(scanningContext.joinedText, false, true, autoFormatCriteria.regEx);
207
+ return getPatternMatchResultsWithRegEx(scanningContext.joinedText, false, true, autoFormatCriteria.regEx);
289
208
  }
290
209
 
291
- function getMatchResultContextForCriteria(autoFormatCriteria, scanningContext) {
210
+ function getPatternMatchResultsForCriteria(autoFormatCriteria, scanningContext) {
292
211
  if (autoFormatCriteria.requiresParagraphStart !== null && autoFormatCriteria.requiresParagraphStart === true) {
293
- return getMatchResultContextForParagraphs(autoFormatCriteria, scanningContext);
212
+ return getPatternMatchResultsForParagraphs(autoFormatCriteria, scanningContext);
294
213
  }
295
214
 
296
- return getMatchResultContextForText(autoFormatCriteria, scanningContext);
215
+ return getPatternMatchResultsForText(autoFormatCriteria, scanningContext);
297
216
  }
298
217
 
299
218
  function getNewNodeForCriteria(scanningContext, element) {
300
219
  let newNode = null;
301
220
  const children = element.getChildren();
302
221
  const autoFormatCriteria = scanningContext.autoFormatCriteria;
303
- const matchResultContext = scanningContext.matchResultContext;
222
+ const patternMatchResults = scanningContext.patternMatchResults;
304
223
 
305
- if (autoFormatCriteria.nodeTransformationKind != null) {
306
- switch (autoFormatCriteria.nodeTransformationKind) {
224
+ if (autoFormatCriteria.autoFormatKind != null) {
225
+ switch (autoFormatCriteria.autoFormatKind) {
307
226
  case 'paragraphH1':
308
227
  {
309
228
  newNode = HeadingNode.$createHeadingNode('h1');
@@ -343,7 +262,7 @@ function getNewNodeForCriteria(scanningContext, element) {
343
262
 
344
263
  case 'paragraphOrderedList':
345
264
  {
346
- const startAsString = matchResultContext.regExCaptureGroups.length > 1 ? matchResultContext.regExCaptureGroups[matchResultContext.regExCaptureGroups.length - 1].text : '1';
265
+ const startAsString = patternMatchResults.regExCaptureGroups.length > 1 ? patternMatchResults.regExCaptureGroups[patternMatchResults.regExCaptureGroups.length - 1].text : '1';
347
266
  const start = parseInt(startAsString, 10);
348
267
  newNode = list.$createListNode('ol', start);
349
268
  const listItem = list.$createListItemNode();
@@ -359,7 +278,7 @@ function getNewNodeForCriteria(scanningContext, element) {
359
278
  newNode = lexical.$createParagraphNode();
360
279
  } else {
361
280
  newNode = CodeNode.$createCodeNode();
362
- const codingLanguage = matchResultContext.regExCaptureGroups.length >= 3 ? matchResultContext.regExCaptureGroups[2].text : null;
281
+ const codingLanguage = patternMatchResults.regExCaptureGroups.length >= 3 ? patternMatchResults.regExCaptureGroups[2].text : null;
363
282
 
364
283
  if (codingLanguage != null && codingLanguage.length > 0) {
365
284
  newNode.setLanguage(codingLanguage);
@@ -383,15 +302,6 @@ function getNewNodeForCriteria(scanningContext, element) {
383
302
  return newNode;
384
303
  }
385
304
 
386
- function updateTextNode(node, count) {
387
- const textNode = node.spliceText(0, count, '', true);
388
-
389
- if (textNode.getTextContent() === '') {
390
- textNode.selectPrevious();
391
- textNode.remove();
392
- }
393
- }
394
-
395
305
  function transformTextNodeForAutoFormatCriteria(scanningContext) {
396
306
  if (scanningContext.autoFormatCriteria.requiresParagraphStart) {
397
307
  transformTextNodeForParagraphs(scanningContext);
@@ -403,8 +313,16 @@ function transformTextNodeForAutoFormatCriteria(scanningContext) {
403
313
  function transformTextNodeForParagraphs(scanningContext) {
404
314
  const textNodeWithOffset = scanningContext.textNodeWithOffset;
405
315
  const element = textNodeWithOffset.node.getParentOrThrow();
406
- const text = scanningContext.matchResultContext.regExCaptureGroups[0].text;
407
- updateTextNode(textNodeWithOffset.node, text.length);
316
+ const text = scanningContext.patternMatchResults.regExCaptureGroups[0].text; // Remove the text which we matched.
317
+
318
+ const textNode = textNodeWithOffset.node.spliceText(0, text.length, '', true);
319
+
320
+ if (textNode.getTextContent() === '') {
321
+ textNode.selectPrevious();
322
+ textNode.remove();
323
+ } // Transform the current element kind to the new element kind.
324
+
325
+
408
326
  const elementNode = getNewNodeForCriteria(scanningContext, element);
409
327
 
410
328
  if (elementNode !== null) {
@@ -412,155 +330,223 @@ function transformTextNodeForParagraphs(scanningContext) {
412
330
  }
413
331
  }
414
332
 
415
- function getTextFormatType(nodeTransformationKind) {
416
- switch (nodeTransformationKind) {
417
- case 'italic':
418
- case 'bold':
419
- case 'underline':
420
- case 'strikethrough':
421
- return [nodeTransformationKind];
333
+ function transformTextNodeForText(scanningContext) {
334
+ const autoFormatCriteria = scanningContext.autoFormatCriteria;
422
335
 
423
- case 'bold_italic':
424
- {
425
- return ['bold', 'italic'];
426
- }
336
+ if (autoFormatCriteria.autoFormatKind != null) {
337
+ const formatting = getTextFormatType(autoFormatCriteria.autoFormatKind);
338
+
339
+ if (formatting != null) {
340
+ transformTextNodeWithFormatting(formatting, scanningContext);
341
+ return;
342
+ }
343
+
344
+ if (autoFormatCriteria.autoFormatKind === 'link') {
345
+ transformTextNodeWithLink(scanningContext);
346
+ }
427
347
  }
348
+ }
428
349
 
429
- return null;
350
+ function transformTextNodeWithFormatting(formatting, scanningContext) {
351
+ const patternMatchResults = scanningContext.patternMatchResults;
352
+ const groupCount = patternMatchResults.regExCaptureGroups.length;
353
+
354
+ if (groupCount !== 7) {
355
+ // For BIUS and similar formats which have a pattern + text + pattern:
356
+ // given '*italic* ' below are the capture groups by index:
357
+ // 0. '*italic* '
358
+ // 1. '*'
359
+ // 2. whitespace // typically this is "".
360
+ // 3. 'italic'
361
+ // 4. whitespace // typicallly this is "".
362
+ // 5. '*'
363
+ // 6. ' '
364
+ return;
365
+ } // Remove unwanted text in reg ex pattern.
366
+ // Remove group 5.
367
+
368
+
369
+ removeTextByCaptureGroups(5, 5, scanningContext); // Remove group 1.
370
+
371
+ removeTextByCaptureGroups(1, 1, scanningContext); // Apply the formatting.
372
+
373
+ formatTextInCaptureGroupIndex(formatting, 3, scanningContext); // Place caret at end of final capture group.
374
+
375
+ selectAfterFinalCaptureGroup(scanningContext);
430
376
  }
431
377
 
432
- function transformTextNodeForText(scanningContext) {
433
- const autoFormatCriteria = scanningContext.autoFormatCriteria;
434
- const matchResultContext = scanningContext.matchResultContext;
435
-
436
- if (autoFormatCriteria.nodeTransformationKind != null) {
437
- if (matchResultContext.regExCaptureGroups.length !== 6) {
438
- // For BIUS and other formatts which have a pattern + text + pattern,
439
- // the expected reg ex pattern should have 6 groups.
440
- // If it does not, then break and fail silently.
441
- // e2e tests validate the regEx pattern.
442
- return;
443
- }
378
+ function transformTextNodeWithLink(scanningContext) {
379
+ const patternMatchResults = scanningContext.patternMatchResults;
380
+ const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
381
+ const groupCount = regExCaptureGroups.length;
382
+
383
+ if (groupCount !== 7) {
384
+ // For links and similar formats which have: pattern + text + pattern + pattern2 text2 + pattern2:
385
+ // Given '[title](url) ', below are the capture groups by index:
386
+ // 0. '[title](url) '
387
+ // 1. '['
388
+ // 2. 'title'
389
+ // 3. ']('
390
+ // 4. 'url'
391
+ // 5. ')'
392
+ // 6. ' '
393
+ return;
394
+ }
444
395
 
445
- const formatting = getTextFormatType(autoFormatCriteria.nodeTransformationKind);
396
+ const title = regExCaptureGroups[2].text;
397
+ const url = regExCaptureGroups[4].text;
446
398
 
447
- if (formatting != null) {
448
- const captureGroupsToDelete = [1, 5];
449
- const formatCaptureGroup = 3;
450
- matchResultContext.regExCaptureGroups = getCaptureGroupsByResolvingAllDetails(scanningContext);
399
+ if (title.length === 0 || url.length === 0) {
400
+ return;
401
+ } // Remove the initial pattern through to the final pattern.
451
402
 
452
- if (captureGroupsToDelete.length > 0) {
453
- // Remove unwanted text in reg ex pattern.
454
- removeTextInCaptureGroups(captureGroupsToDelete, matchResultContext);
455
- }
456
403
 
457
- formatTextInCaptureGroupIndex(formatting, formatCaptureGroup, matchResultContext);
458
- makeCollapsedSelectionAtOffsetInJoinedText(matchResultContext.offsetInJoinedTextForCollapsedSelection, matchResultContext.offsetInJoinedTextForCollapsedSelection + 1, scanningContext.textNodeWithOffset.node.getParentOrThrow());
459
- }
404
+ removeTextByCaptureGroups(1, 5, scanningContext);
405
+ insertTextPriorToCaptureGroup(1, // Insert at the beginning of the meaningful capture groups, namely index 1. Index 0 refers to the whole matched string.
406
+ title, scanningContext);
407
+ const newSelectionForLink = createSelectionWithCaptureGroups(1, 1, false, true, scanningContext);
408
+
409
+ if (newSelectionForLink == null) {
410
+ return;
460
411
  }
461
- } // Some Capture Group Details were left lazily unresolved as their calculation
462
- // was not necessary during the scanning phase. Now that the nodeTransformationKind is
463
- // known, the details may be fully resolved without incurring unwasted performance cost.
464
412
 
413
+ lexical.$setSelection(newSelectionForLink);
414
+ scanningContext.editor.execCommand('toggleLink', url); // Place caret at end of final capture group.
465
415
 
466
- function getCaptureGroupsByResolvingAllDetails(scanningContext) {
467
- const autoFormatCriteria = scanningContext.autoFormatCriteria;
468
- const matchResultContext = scanningContext.matchResultContext;
469
- const textNodeWithOffset = scanningContext.textNodeWithOffset;
470
- const regExCaptureGroups = matchResultContext.regExCaptureGroups;
471
- const captureGroupsCount = regExCaptureGroups.length;
472
- const parentElementNode = textNodeWithOffset.node.getParentOrThrow();
416
+ selectAfterFinalCaptureGroup(scanningContext);
417
+ } // Below are lower level helper functions.
473
418
 
474
- if (scanningContext.joinedText == null) {
475
- {
476
- throw Error(`joinedText was not calculated`);
477
- }
419
+
420
+ function getParent(scanningContext) {
421
+ return scanningContext.textNodeWithOffset.node.getParentOrThrow();
422
+ }
423
+
424
+ function getJoinedTextLength(patternMatchResults) {
425
+ const groupCount = patternMatchResults.regExCaptureGroups.length;
426
+
427
+ if (groupCount < 2) {
428
+ // Ignore capture group 0, as regEx defaults the 0th one to the entire matched string.
429
+ return 0;
478
430
  }
479
431
 
480
- const joinedTextLength = scanningContext.joinedText.length;
432
+ const lastGroupIndex = groupCount - 1;
433
+ return patternMatchResults.regExCaptureGroups[lastGroupIndex].offsetInParent + patternMatchResults.regExCaptureGroups[lastGroupIndex].text.length;
434
+ }
481
435
 
482
- for (let captureGroupIndex = 1; captureGroupIndex < captureGroupsCount; captureGroupIndex++) {
483
- const captureGroupDetail = regExCaptureGroups[captureGroupIndex];
484
- captureGroupDetail.anchorTextNodeWithOffset = $findNodeWithOffsetFromJoinedText(parentElementNode, joinedTextLength, captureGroupDetail.offsetInParent, TRIGGER_STRING_LENGTH);
485
- captureGroupDetail.focusTextNodeWithOffset = $findNodeWithOffsetFromJoinedText(parentElementNode, joinedTextLength, captureGroupDetail.offsetInParent + captureGroupDetail.textLength, TRIGGER_STRING_LENGTH);
436
+ function getTextFormatType(autoFormatKind) {
437
+ switch (autoFormatKind) {
438
+ case 'italic':
439
+ case 'bold':
440
+ case 'underline':
441
+ case 'strikethrough':
442
+ return [autoFormatKind];
486
443
 
487
- if (captureGroupDetail.textLength < 0) {
444
+ case 'bold_italic':
488
445
  {
489
- throw Error(`Bad regEx pattern found for ${autoFormatCriteria.nodeTransformationKind}`);
446
+ return ['bold', 'italic'];
490
447
  }
491
- }
492
448
  }
493
449
 
494
- return regExCaptureGroups;
450
+ return null;
495
451
  }
496
452
 
497
- function removeTextInCaptureGroups(regExCaptureGroupsToDelete, matchResultContext) {
498
- const regExCaptureGroups = matchResultContext.regExCaptureGroups;
453
+ function createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, startAtEndOfAnchor, finishAtEndOfFocus, scanningContext) {
454
+ const patternMatchResults = scanningContext.patternMatchResults;
455
+ const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
499
456
  const regExCaptureGroupsCount = regExCaptureGroups.length;
500
457
 
501
- for (let i = regExCaptureGroupsToDelete.length - 1; i >= 0; i--) {
502
- if (i < regExCaptureGroupsCount) {
503
- const captureGroupIndex = regExCaptureGroupsToDelete[i];
504
- const captureGroupDetail = regExCaptureGroups[captureGroupIndex];
505
- const anchorTextNodeWithOffset = captureGroupDetail.anchorTextNodeWithOffset;
506
- const focusTextNodeWithOffset = captureGroupDetail.focusTextNodeWithOffset;
458
+ if (anchorCaptureGroupIndex >= regExCaptureGroupsCount || focusCaptureGroupIndex >= regExCaptureGroupsCount) {
459
+ return null;
460
+ }
507
461
 
508
- if (anchorTextNodeWithOffset != null && focusTextNodeWithOffset != null && captureGroupDetail.textLength > 0) {
509
- const newSelection = lexical.$createRangeSelection();
510
- newSelection.anchor.set(anchorTextNodeWithOffset.node.getKey(), anchorTextNodeWithOffset.offset, 'text');
511
- newSelection.focus.set(focusTextNodeWithOffset.node.getKey(), focusTextNodeWithOffset.offset, 'text');
512
- lexical.$setSelection(newSelection);
513
- const currentSelection = lexical.$getSelection();
462
+ const parentElementNode = getParent(scanningContext);
463
+ const joinedTextLength = getJoinedTextLength(patternMatchResults);
464
+ const anchorCaptureGroupDetail = regExCaptureGroups[anchorCaptureGroupIndex];
465
+ const focusCaptureGroupDetail = regExCaptureGroups[focusCaptureGroupIndex];
466
+ const anchorLocation = startAtEndOfAnchor ? anchorCaptureGroupDetail.offsetInParent + anchorCaptureGroupDetail.text.length : anchorCaptureGroupDetail.offsetInParent;
467
+ const focusLocation = finishAtEndOfFocus ? focusCaptureGroupDetail.offsetInParent + focusCaptureGroupDetail.text.length : focusCaptureGroupDetail.offsetInParent;
468
+ const anchorTextNodeWithOffset = text.$findNodeWithOffsetFromJoinedText(anchorLocation, joinedTextLength, SEPARATOR_LENGTH, parentElementNode);
469
+ const focusTextNodeWithOffset = text.$findNodeWithOffsetFromJoinedText(focusLocation, joinedTextLength, SEPARATOR_LENGTH, parentElementNode);
514
470
 
515
- if (lexical.$isRangeSelection(currentSelection)) {
516
- currentSelection.removeText(); // Shift offsets for capture groups which are within the same node
471
+ if (anchorTextNodeWithOffset == null || focusTextNodeWithOffset == null) {
472
+ return null;
473
+ }
517
474
 
518
- if (anchorTextNodeWithOffset.node.getKey() === focusTextNodeWithOffset.node.getKey()) {
519
- const delta = focusTextNodeWithOffset.offset - anchorTextNodeWithOffset.offset;
475
+ const selection = lexical.$createRangeSelection();
476
+ selection.anchor.set(anchorTextNodeWithOffset.node.getKey(), anchorTextNodeWithOffset.offset, 'text');
477
+ selection.focus.set(focusTextNodeWithOffset.node.getKey(), focusTextNodeWithOffset.offset, 'text');
478
+ return selection;
479
+ }
520
480
 
521
- if (!(delta > 0)) {
522
- throw Error(`Expected anchor and focus offsets to have ascending character order.`);
523
- }
481
+ function removeTextByCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, scanningContext) {
482
+ const patternMatchResults = scanningContext.patternMatchResults;
483
+ const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
484
+ const newSelection = createSelectionWithCaptureGroups(anchorCaptureGroupIndex, focusCaptureGroupIndex, false, true, scanningContext);
524
485
 
525
- shiftCaptureGroupOffsets(-delta, focusTextNodeWithOffset.offset, anchorTextNodeWithOffset.node, captureGroupIndex, matchResultContext);
526
- } else {
527
- const focusDelta = focusTextNodeWithOffset.offset;
486
+ if (newSelection != null) {
487
+ lexical.$setSelection(newSelection);
488
+ const currentSelection = lexical.$getSelection();
528
489
 
529
- if (focusDelta > 0) {
530
- shiftCaptureGroupOffsets(-focusDelta, focusDelta, focusTextNodeWithOffset.node, captureGroupIndex, matchResultContext);
531
- }
532
- }
490
+ if (currentSelection != null && lexical.$isRangeSelection(currentSelection) && currentSelection.isCollapsed() === false) {
491
+ currentSelection.removeText(); // Shift all group offsets and clear out group text.
492
+
493
+ let runningLength = 0;
494
+ const groupCount = regExCaptureGroups.length;
495
+
496
+ for (let i = anchorCaptureGroupIndex; i < groupCount; i++) {
497
+ const captureGroupDetail = regExCaptureGroups[i];
498
+
499
+ if (i > anchorCaptureGroupIndex) {
500
+ captureGroupDetail.offsetInParent -= runningLength;
501
+ }
502
+
503
+ if (i <= focusCaptureGroupIndex) {
504
+ runningLength += captureGroupDetail.text.length;
505
+ captureGroupDetail.text = '';
533
506
  }
534
507
  }
535
508
  }
536
509
  }
537
510
  }
538
511
 
539
- function shiftCaptureGroupOffsets(delta, applyAtOrAfterOffset, node, startingCaptureGroupIndex, matchResultContext) {
540
- matchResultContext.offsetInJoinedTextForCollapsedSelection += delta;
512
+ function insertTextPriorToCaptureGroup(captureGroupIndex, text, scanningContext) {
513
+ const patternMatchResults = scanningContext.patternMatchResults;
514
+ const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
515
+ const regExCaptureGroupsCount = regExCaptureGroups.length;
541
516
 
542
- if (!(matchResultContext.offsetInJoinedTextForCollapsedSelection > 0)) {
543
- throw Error(`The text content string length does not correlate with insertions/deletions of new text.`);
517
+ if (captureGroupIndex >= regExCaptureGroupsCount) {
518
+ return;
544
519
  }
545
520
 
546
- const regExCaptureGroups = matchResultContext.regExCaptureGroups;
547
- const regExCaptureGroupsCount = regExCaptureGroups.length;
521
+ const captureGroupDetail = regExCaptureGroups[captureGroupIndex];
522
+ const newCaptureGroupDetail = {
523
+ offsetInParent: captureGroupDetail.offsetInParent,
524
+ text
525
+ };
526
+ const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, false, scanningContext);
548
527
 
549
- for (let captureGroupIndex = startingCaptureGroupIndex + 1; captureGroupIndex < regExCaptureGroupsCount; captureGroupIndex++) {
550
- const captureGroupDetail = regExCaptureGroups[captureGroupIndex];
528
+ if (newSelection != null) {
529
+ lexical.$setSelection(newSelection);
530
+ const currentSelection = lexical.$getSelection();
551
531
 
552
- if (captureGroupDetail.anchorTextNodeWithOffset != null && captureGroupDetail.anchorTextNodeWithOffset.offset >= applyAtOrAfterOffset && captureGroupDetail.anchorTextNodeWithOffset.node.is(node)) {
553
- captureGroupDetail.anchorTextNodeWithOffset.offset += delta;
554
- }
532
+ if (currentSelection != null && lexical.$isRangeSelection(currentSelection) && currentSelection.isCollapsed()) {
533
+ currentSelection.insertText(newCaptureGroupDetail.text); // Update the capture groups.
555
534
 
556
- if (captureGroupDetail.focusTextNodeWithOffset != null && captureGroupDetail.focusTextNodeWithOffset.offset >= applyAtOrAfterOffset && captureGroupDetail.focusTextNodeWithOffset.node.is(node)) {
557
- captureGroupDetail.focusTextNodeWithOffset.offset += delta;
535
+ regExCaptureGroups.splice(captureGroupIndex, 0, newCaptureGroupDetail);
536
+ const textLength = newCaptureGroupDetail.text.length;
537
+ const newGroupCount = regExCaptureGroups.length;
538
+
539
+ for (let i = captureGroupIndex + 1; i < newGroupCount; i++) {
540
+ const currentCaptureGroupDetail = regExCaptureGroups[i];
541
+ currentCaptureGroupDetail.offsetInParent += textLength;
542
+ }
558
543
  }
559
544
  }
560
545
  }
561
546
 
562
- function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, matchResultContext) {
563
- const regExCaptureGroups = matchResultContext.regExCaptureGroups;
547
+ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, scanningContext) {
548
+ const patternMatchResults = scanningContext.patternMatchResults;
549
+ const regExCaptureGroups = patternMatchResults.regExCaptureGroups;
564
550
  const regExCaptureGroupsCount = regExCaptureGroups.length;
565
551
 
566
552
  if (!(captureGroupIndex < regExCaptureGroupsCount)) {
@@ -568,13 +554,14 @@ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, matchResu
568
554
  }
569
555
 
570
556
  const captureGroupDetail = regExCaptureGroups[captureGroupIndex];
571
- const anchorTextNodeWithOffset = captureGroupDetail.anchorTextNodeWithOffset;
572
- const focusTextNodeWithOffset = captureGroupDetail.focusTextNodeWithOffset;
573
557
 
574
- if (anchorTextNodeWithOffset != null && focusTextNodeWithOffset != null && captureGroupDetail.textLength > 0) {
575
- const newSelection = lexical.$createRangeSelection();
576
- newSelection.anchor.set(anchorTextNodeWithOffset.node.getKey(), anchorTextNodeWithOffset.offset, 'text');
577
- newSelection.focus.set(focusTextNodeWithOffset.node.getKey(), focusTextNodeWithOffset.offset, 'text');
558
+ if (captureGroupDetail.text.length === 0) {
559
+ return;
560
+ }
561
+
562
+ const newSelection = createSelectionWithCaptureGroups(captureGroupIndex, captureGroupIndex, false, true, scanningContext);
563
+
564
+ if (newSelection != null) {
578
565
  lexical.$setSelection(newSelection);
579
566
  const currentSelection = lexical.$getSelection();
580
567
 
@@ -582,22 +569,24 @@ function formatTextInCaptureGroupIndex(formatTypes, captureGroupIndex, matchResu
582
569
  for (let i = 0; i < formatTypes.length; i++) {
583
570
  currentSelection.formatText(formatTypes[i]);
584
571
  }
585
-
586
- const finalSelection = lexical.$createRangeSelection();
587
- finalSelection.anchor.set(focusTextNodeWithOffset.node.getKey(), focusTextNodeWithOffset.offset + 1, 'text');
588
- finalSelection.focus.set(focusTextNodeWithOffset.node.getKey(), focusTextNodeWithOffset.offset + 1, 'text');
589
- lexical.$setSelection(finalSelection);
590
572
  }
591
573
  }
592
- }
574
+ } // Place caret at end of final capture group.
575
+
593
576
 
594
- function makeCollapsedSelectionAtOffsetInJoinedText(offsetInJoinedText, joinedTextLength, parentElementNode) {
595
- const textNodeWithOffset = $findNodeWithOffsetFromJoinedText(parentElementNode, joinedTextLength, offsetInJoinedText, TRIGGER_STRING_LENGTH);
577
+ function selectAfterFinalCaptureGroup(scanningContext) {
578
+ const patternMatchResults = scanningContext.patternMatchResults;
579
+ const groupCount = patternMatchResults.regExCaptureGroups.length;
596
580
 
597
- if (textNodeWithOffset != null) {
598
- const newSelection = lexical.$createRangeSelection();
599
- newSelection.anchor.set(textNodeWithOffset.node.getKey(), textNodeWithOffset.offset, 'text');
600
- newSelection.focus.set(textNodeWithOffset.node.getKey(), textNodeWithOffset.offset, 'text');
581
+ if (groupCount < 2) {
582
+ // Ignore capture group 0, as regEx defaults the 0th one to the entire matched string.
583
+ return;
584
+ }
585
+
586
+ const lastGroupIndex = groupCount - 1;
587
+ const newSelection = createSelectionWithCaptureGroups(lastGroupIndex, lastGroupIndex, true, true, scanningContext);
588
+
589
+ if (newSelection != null) {
601
590
  lexical.$setSelection(newSelection);
602
591
  }
603
592
  }
@@ -611,20 +600,20 @@ function makeCollapsedSelectionAtOffsetInJoinedText(offsetInJoinedText, joinedTe
611
600
  *
612
601
  */
613
602
 
614
- function getCriteriaWithMatchResultContext(autoFormatCriteriaArray, scanningContext) {
603
+ function getCriteriaWithPatternMatchResults(autoFormatCriteriaArray, scanningContext) {
615
604
  const currentTriggerState = scanningContext.triggerState;
616
605
  const count = autoFormatCriteriaArray.length;
617
606
 
618
607
  for (let i = 0; i < count; i++) {
619
- const autoFormatCriteria = autoFormatCriteriaArray[i]; // Skip code block nodes, unless the nodeTransformationKind calls for toggling the code block.
608
+ const autoFormatCriteria = autoFormatCriteriaArray[i]; // Skip code block nodes, unless the autoFormatKind calls for toggling the code block.
620
609
 
621
- if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || autoFormatCriteria.nodeTransformationKind === 'paragraphCodeBlock') {
622
- const matchResultContext = getMatchResultContextForCriteria(autoFormatCriteria, scanningContext);
610
+ if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || autoFormatCriteria.autoFormatKind === 'paragraphCodeBlock') {
611
+ const patternMatchResults = getPatternMatchResultsForCriteria(autoFormatCriteria, scanningContext);
623
612
 
624
- if (matchResultContext != null) {
613
+ if (patternMatchResults != null) {
625
614
  return {
626
615
  autoFormatCriteria: autoFormatCriteria,
627
- matchResultContext
616
+ patternMatchResults
628
617
  };
629
618
  }
630
619
  }
@@ -632,7 +621,7 @@ function getCriteriaWithMatchResultContext(autoFormatCriteriaArray, scanningCont
632
621
 
633
622
  return {
634
623
  autoFormatCriteria: null,
635
- matchResultContext: null
624
+ patternMatchResults: null
636
625
  };
637
626
  }
638
627
 
@@ -661,9 +650,9 @@ function updateAutoFormatting(editor, scanningContext) {
661
650
  });
662
651
  }
663
652
 
664
- function findScanningContextWithValidMatch(editorState, currentTriggerState) {
653
+ function findScanningContextWithValidMatch(editor, currentTriggerState) {
665
654
  let scanningContext = null;
666
- editorState.read(() => {
655
+ editor.getEditorState().read(() => {
667
656
  const textNodeWithOffset = getTextNodeForAutoFormatting(lexical.$getSelection());
668
657
 
669
658
  if (textNodeWithOffset === null) {
@@ -671,23 +660,23 @@ function findScanningContextWithValidMatch(editorState, currentTriggerState) {
671
660
  } // Please see the declaration of ScanningContext for a detailed explanation.
672
661
 
673
662
 
674
- const initialScanningContext = getInitialScanningContext(textNodeWithOffset, currentTriggerState);
675
- const criteriaWithMatchResultContext = getCriteriaWithMatchResultContext( // Do not apply paragraph node changes like blockQuote or H1 to listNodes. Also, do not attempt to transform a list into a list using * or -.
663
+ const initialScanningContext = getInitialScanningContext(editor, textNodeWithOffset, currentTriggerState);
664
+ const criteriaWithPatternMatchResults = getCriteriaWithPatternMatchResults( // Do not apply paragraph node changes like blockQuote or H1 to listNodes. Also, do not attempt to transform a list into a list using * or -.
676
665
  currentTriggerState.isParentAListItemNode === false ? getAllAutoFormatCriteria() : getAllAutoFormatCriteriaForTextNodes(), initialScanningContext);
677
666
 
678
- if (criteriaWithMatchResultContext.autoFormatCriteria === null || criteriaWithMatchResultContext.matchResultContext === null) {
667
+ if (criteriaWithPatternMatchResults.autoFormatCriteria === null || criteriaWithPatternMatchResults.patternMatchResults === null) {
679
668
  return;
680
669
  }
681
670
 
682
671
  scanningContext = initialScanningContext; // Lazy fill-in the particular format criteria and any matching result information.
683
672
 
684
- scanningContext.autoFormatCriteria = criteriaWithMatchResultContext.autoFormatCriteria;
685
- scanningContext.matchResultContext = criteriaWithMatchResultContext.matchResultContext;
673
+ scanningContext.autoFormatCriteria = criteriaWithPatternMatchResults.autoFormatCriteria;
674
+ scanningContext.patternMatchResults = criteriaWithPatternMatchResults.patternMatchResults;
686
675
  });
687
676
  return scanningContext;
688
677
  }
689
678
 
690
- function findScanningContext(editorState, currentTriggerState, priorTriggerState) {
679
+ function findScanningContext(editor, currentTriggerState, priorTriggerState) {
691
680
  if (currentTriggerState == null || priorTriggerState == null) {
692
681
  return null;
693
682
  } // The below checks needs to execute relativey quickly, so perform the light-weight ones first.
@@ -703,7 +692,7 @@ function findScanningContext(editorState, currentTriggerState, priorTriggerState
703
692
  return null;
704
693
  }
705
694
 
706
- return findScanningContextWithValidMatch(editorState, currentTriggerState);
695
+ return findScanningContextWithValidMatch(editor, currentTriggerState);
707
696
  }
708
697
 
709
698
  function getTriggerState(editorState) {
@@ -745,9 +734,8 @@ function useAutoFormatter(editor) {
745
734
  }) => {
746
735
  // Examine historic so that we are not running autoformatting within markdown.
747
736
  if (tags.has('historic') === false) {
748
- const editorState = editor.getEditorState();
749
- const currentTriggerState = getTriggerState(editorState);
750
- const scanningContext = currentTriggerState == null ? null : findScanningContext(editorState, currentTriggerState, priorTriggerState);
737
+ const currentTriggerState = getTriggerState(editor.getEditorState());
738
+ const scanningContext = currentTriggerState == null ? null : findScanningContext(editor, currentTriggerState, priorTriggerState);
751
739
 
752
740
  if (scanningContext != null) {
753
741
  updateAutoFormatting(editor, scanningContext);