@lexical/react 0.1.14 → 0.1.15

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