@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.
- package/DEPRECATED_useLexicalAutoFormatter.dev.js +283 -295
- package/DEPRECATED_useLexicalAutoFormatter.prod.js +19 -21
- package/DEPRECATED_useLexicalCanShowPlaceholder.dev.js +3 -72
- package/DEPRECATED_useLexicalCanShowPlaceholder.prod.js +1 -2
- package/DEPRECATED_useLexicalCharacterLimit.dev.js +11 -63
- package/DEPRECATED_useLexicalCharacterLimit.prod.js +6 -7
- package/DEPRECATED_useLexicalPlainText.dev.js +16 -41
- package/DEPRECATED_useLexicalPlainText.prod.js +13 -14
- package/DEPRECATED_useLexicalRichText.dev.js +24 -49
- package/DEPRECATED_useLexicalRichText.prod.js +15 -15
- package/LexicalAutoFormatterPlugin.dev.js +283 -295
- package/LexicalAutoFormatterPlugin.prod.js +19 -21
- package/LexicalAutoLinkPlugin.dev.js +2 -2
- package/LexicalAutoLinkPlugin.prod.js +2 -2
- package/LexicalCharacterLimitPlugin.dev.js +11 -63
- package/LexicalCharacterLimitPlugin.prod.js +8 -9
- package/LexicalCollaborationPlugin.d.ts +3 -1
- package/LexicalCollaborationPlugin.dev.js +40 -6
- package/LexicalCollaborationPlugin.js.flow +4 -1
- package/LexicalCollaborationPlugin.prod.js +8 -7
- package/LexicalHashtagPlugin.dev.js +16 -13
- package/LexicalHashtagPlugin.prod.js +7 -7
- package/LexicalOnChangePlugin.dev.js +15 -2
- package/LexicalOnChangePlugin.prod.js +2 -1
- package/LexicalPlainTextPlugin.dev.js +20 -113
- package/LexicalPlainTextPlugin.prod.js +11 -12
- package/LexicalRichTextPlugin.dev.js +28 -121
- package/LexicalRichTextPlugin.prod.js +12 -13
- package/LexicalTablePlugin.dev.js +9 -5
- package/LexicalTablePlugin.prod.js +2 -2
- package/package.json +9 -7
- package/useLexicalIsTextContentEmpty.dev.js +3 -32
- 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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
+
autoFormatKind: 'paragraphH1',
|
|
135
55
|
regEx: /^(?:# )/
|
|
136
56
|
};
|
|
137
57
|
const markdownHeader2 = { ...paragraphStartBase,
|
|
138
|
-
|
|
58
|
+
autoFormatKind: 'paragraphH2',
|
|
139
59
|
regEx: /^(?:## )/
|
|
140
60
|
};
|
|
141
61
|
const markdownHeader3 = { ...paragraphStartBase,
|
|
142
|
-
|
|
62
|
+
autoFormatKind: 'paragraphH2',
|
|
143
63
|
regEx: /^(?:### )/
|
|
144
64
|
};
|
|
145
65
|
const markdownBlockQuote = { ...paragraphStartBase,
|
|
146
|
-
|
|
66
|
+
autoFormatKind: 'paragraphBlockQuote',
|
|
147
67
|
regEx: /^(?:> )/
|
|
148
68
|
};
|
|
149
69
|
const markdownUnorderedListDash = { ...paragraphStartBase,
|
|
150
|
-
|
|
70
|
+
autoFormatKind: 'paragraphUnorderedList',
|
|
151
71
|
regEx: /^(?:- )/
|
|
152
72
|
};
|
|
153
73
|
const markdownUnorderedListAsterisk = { ...paragraphStartBase,
|
|
154
|
-
|
|
74
|
+
autoFormatKind: 'paragraphUnorderedList',
|
|
155
75
|
regEx: /^(?:\* )/
|
|
156
76
|
};
|
|
157
77
|
const markdownCodeBlock = { ...paragraphStartBase,
|
|
158
|
-
|
|
78
|
+
autoFormatKind: 'paragraphCodeBlock',
|
|
159
79
|
regEx: /^(```)([a-z]*)( )/
|
|
160
80
|
};
|
|
161
81
|
const markdownOrderedList = { ...paragraphStartBase,
|
|
162
|
-
|
|
82
|
+
autoFormatKind: 'paragraphOrderedList',
|
|
163
83
|
regEx: /^(\d+)\.\s/
|
|
164
84
|
};
|
|
165
85
|
const markdownHorizontalRule = { ...paragraphStartBase,
|
|
166
|
-
|
|
86
|
+
autoFormatKind: 'horizontalRule',
|
|
167
87
|
regEx: /^(?:\*\*\* )/
|
|
168
88
|
};
|
|
169
89
|
const markdownHorizontalRuleUsingDashes = { ...paragraphStartBase,
|
|
170
|
-
|
|
90
|
+
autoFormatKind: 'horizontalRule',
|
|
171
91
|
regEx: /^(?:--- )/
|
|
172
92
|
};
|
|
173
93
|
const markdownItalic = { ...autoFormatBase,
|
|
174
|
-
|
|
175
|
-
regEx: /(\*)(\s*\b)([^\*]*)(\b\s*)(
|
|
94
|
+
autoFormatKind: 'italic',
|
|
95
|
+
regEx: /(\*)(\s*\b)([^\*]*)(\b\s*)(\*)(\s)$/
|
|
176
96
|
};
|
|
177
97
|
const markdownBold = { ...autoFormatBase,
|
|
178
|
-
|
|
179
|
-
regEx: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(
|
|
98
|
+
autoFormatKind: 'bold',
|
|
99
|
+
regEx: /(\*\*)(\s*\b)([^\*\*]*)(\b\s*)(\*\*)(\s)$/
|
|
180
100
|
};
|
|
181
101
|
const markdownBoldWithUnderlines = { ...autoFormatBase,
|
|
182
|
-
|
|
183
|
-
regEx: /(__)(\s*)([^__]*)(\s*)(__\s)$/
|
|
102
|
+
autoFormatKind: 'bold',
|
|
103
|
+
regEx: /(__)(\s*)([^__]*)(\s*)(__)(\s)$/
|
|
184
104
|
};
|
|
185
105
|
const markdownBoldItalic = { ...autoFormatBase,
|
|
186
|
-
|
|
187
|
-
regEx: /(\*\*\*)(\s*\b)([^\*\*\*]*)(\b\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
|
-
|
|
193
|
-
regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u
|
|
112
|
+
autoFormatKind: 'underline',
|
|
113
|
+
regEx: /(\<u\>)(\s*\b)([^\<]*)(\b\s*)(\<\/u\>)(\s)$/
|
|
194
114
|
};
|
|
195
115
|
const markdownStrikethrough = { ...autoFormatBase,
|
|
196
|
-
|
|
197
|
-
regEx: /(~~)(\s*\b)([^~~]*)(\b\s*)(
|
|
116
|
+
autoFormatKind: 'strikethrough',
|
|
117
|
+
regEx: /(~~)(\s*\b)([^~~]*)(\b\s*)(~~)(\s)$/
|
|
198
118
|
};
|
|
199
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
226
|
-
const
|
|
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
|
-
|
|
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
|
|
173
|
+
return patternMatchResults;
|
|
255
174
|
}
|
|
256
175
|
|
|
257
176
|
return null;
|
|
258
177
|
}
|
|
259
178
|
|
|
260
|
-
function
|
|
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
|
|
184
|
+
return getPatternMatchResultsWithRegEx(textToSearch, true, false, autoFormatCriteria.regEx);
|
|
266
185
|
}
|
|
267
186
|
|
|
268
187
|
return null;
|
|
269
188
|
}
|
|
270
189
|
|
|
271
|
-
function
|
|
190
|
+
function getPatternMatchResultsForText(autoFormatCriteria, scanningContext) {
|
|
272
191
|
if (scanningContext.joinedText == null) {
|
|
273
|
-
const parentNode = scanningContext
|
|
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 =
|
|
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
|
|
206
|
+
return getPatternMatchResultsWithRegEx(scanningContext.joinedText, false, true, autoFormatCriteria.regEx);
|
|
288
207
|
}
|
|
289
208
|
|
|
290
|
-
function
|
|
209
|
+
function getPatternMatchResultsForCriteria(autoFormatCriteria, scanningContext) {
|
|
291
210
|
if (autoFormatCriteria.requiresParagraphStart !== null && autoFormatCriteria.requiresParagraphStart === true) {
|
|
292
|
-
return
|
|
211
|
+
return getPatternMatchResultsForParagraphs(autoFormatCriteria, scanningContext);
|
|
293
212
|
}
|
|
294
213
|
|
|
295
|
-
return
|
|
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
|
|
221
|
+
const patternMatchResults = scanningContext.patternMatchResults;
|
|
303
222
|
|
|
304
|
-
if (autoFormatCriteria.
|
|
305
|
-
switch (autoFormatCriteria.
|
|
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 =
|
|
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 =
|
|
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.
|
|
406
|
-
|
|
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
|
|
415
|
-
|
|
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
|
-
|
|
423
|
-
|
|
424
|
-
|
|
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
|
-
|
|
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
|
|
432
|
-
const
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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
|
-
|
|
395
|
+
const title = regExCaptureGroups[2].text;
|
|
396
|
+
const url = regExCaptureGroups[4].text;
|
|
445
397
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
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
|
-
|
|
457
|
-
|
|
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
|
-
|
|
466
|
-
|
|
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
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
|
431
|
+
const lastGroupIndex = groupCount - 1;
|
|
432
|
+
return patternMatchResults.regExCaptureGroups[lastGroupIndex].offsetInParent + patternMatchResults.regExCaptureGroups[lastGroupIndex].text.length;
|
|
433
|
+
}
|
|
480
434
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
|
|
443
|
+
case 'bold_italic':
|
|
487
444
|
{
|
|
488
|
-
|
|
445
|
+
return ['bold', 'italic'];
|
|
489
446
|
}
|
|
490
|
-
}
|
|
491
447
|
}
|
|
492
448
|
|
|
493
|
-
return
|
|
449
|
+
return null;
|
|
494
450
|
}
|
|
495
451
|
|
|
496
|
-
function
|
|
497
|
-
const
|
|
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
|
-
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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
|
-
|
|
515
|
-
|
|
470
|
+
if (anchorTextNodeWithOffset == null || focusTextNodeWithOffset == null) {
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
516
473
|
|
|
517
|
-
|
|
518
|
-
|
|
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
|
-
|
|
521
|
-
|
|
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
|
-
|
|
525
|
-
|
|
526
|
-
|
|
485
|
+
if (newSelection != null) {
|
|
486
|
+
lexical.$setSelection(newSelection);
|
|
487
|
+
const currentSelection = lexical.$getSelection();
|
|
527
488
|
|
|
528
|
-
|
|
529
|
-
|
|
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
|
|
539
|
-
|
|
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 (
|
|
542
|
-
|
|
516
|
+
if (captureGroupIndex >= regExCaptureGroupsCount) {
|
|
517
|
+
return;
|
|
543
518
|
}
|
|
544
519
|
|
|
545
|
-
const
|
|
546
|
-
const
|
|
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
|
-
|
|
549
|
-
|
|
527
|
+
if (newSelection != null) {
|
|
528
|
+
lexical.$setSelection(newSelection);
|
|
529
|
+
const currentSelection = lexical.$getSelection();
|
|
550
530
|
|
|
551
|
-
if (
|
|
552
|
-
|
|
553
|
-
}
|
|
531
|
+
if (currentSelection != null && lexical.$isRangeSelection(currentSelection) && currentSelection.isCollapsed()) {
|
|
532
|
+
currentSelection.insertText(newCaptureGroupDetail.text); // Update the capture groups.
|
|
554
533
|
|
|
555
|
-
|
|
556
|
-
|
|
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,
|
|
562
|
-
const
|
|
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 (
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
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
|
|
594
|
-
const
|
|
576
|
+
function selectAfterFinalCaptureGroup(scanningContext) {
|
|
577
|
+
const patternMatchResults = scanningContext.patternMatchResults;
|
|
578
|
+
const groupCount = patternMatchResults.regExCaptureGroups.length;
|
|
595
579
|
|
|
596
|
-
if (
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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
|
|
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
|
|
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.
|
|
621
|
-
const
|
|
609
|
+
if (currentTriggerState != null && currentTriggerState.isCodeBlock === false || autoFormatCriteria.autoFormatKind === 'paragraphCodeBlock') {
|
|
610
|
+
const patternMatchResults = getPatternMatchResultsForCriteria(autoFormatCriteria, scanningContext);
|
|
622
611
|
|
|
623
|
-
if (
|
|
612
|
+
if (patternMatchResults != null) {
|
|
624
613
|
return {
|
|
625
614
|
autoFormatCriteria: autoFormatCriteria,
|
|
626
|
-
|
|
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
|
-
|
|
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(
|
|
652
|
+
function findScanningContextWithValidMatch(editor, currentTriggerState) {
|
|
664
653
|
let scanningContext = null;
|
|
665
|
-
|
|
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
|
|
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 (
|
|
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 =
|
|
684
|
-
scanningContext.
|
|
672
|
+
scanningContext.autoFormatCriteria = criteriaWithPatternMatchResults.autoFormatCriteria;
|
|
673
|
+
scanningContext.patternMatchResults = criteriaWithPatternMatchResults.patternMatchResults;
|
|
685
674
|
});
|
|
686
675
|
return scanningContext;
|
|
687
676
|
}
|
|
688
677
|
|
|
689
|
-
function findScanningContext(
|
|
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(
|
|
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
|
|
748
|
-
const
|
|
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);
|