@lexical/text 0.12.2 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LexicalText.dev.js +10 -64
- package/index.d.ts +1 -1
- package/package.json +2 -2
package/LexicalText.dev.js
CHANGED
@@ -9,7 +9,6 @@
|
|
9
9
|
var lexical = require('lexical');
|
10
10
|
|
11
11
|
/** @module @lexical/text */
|
12
|
-
|
13
12
|
/**
|
14
13
|
* Finds a TextNode with a size larger than targetCharacters and returns
|
15
14
|
* the node along with the remaining length of the text.
|
@@ -20,155 +19,129 @@ var lexical = require('lexical');
|
|
20
19
|
function $findTextIntersectionFromCharacters(root, targetCharacters) {
|
21
20
|
let node = root.getFirstChild();
|
22
21
|
let currentCharacters = 0;
|
23
|
-
|
24
22
|
mainLoop: while (node !== null) {
|
25
23
|
if (lexical.$isElementNode(node)) {
|
26
24
|
const child = node.getFirstChild();
|
27
|
-
|
28
25
|
if (child !== null) {
|
29
26
|
node = child;
|
30
27
|
continue;
|
31
28
|
}
|
32
29
|
} else if (lexical.$isTextNode(node)) {
|
33
30
|
const characters = node.getTextContentSize();
|
34
|
-
|
35
31
|
if (currentCharacters + characters > targetCharacters) {
|
36
32
|
return {
|
37
33
|
node,
|
38
34
|
offset: targetCharacters - currentCharacters
|
39
35
|
};
|
40
36
|
}
|
41
|
-
|
42
37
|
currentCharacters += characters;
|
43
38
|
}
|
44
|
-
|
45
39
|
const sibling = node.getNextSibling();
|
46
|
-
|
47
40
|
if (sibling !== null) {
|
48
41
|
node = sibling;
|
49
42
|
continue;
|
50
43
|
}
|
51
|
-
|
52
44
|
let parent = node.getParent();
|
53
|
-
|
54
45
|
while (parent !== null) {
|
55
46
|
const parentSibling = parent.getNextSibling();
|
56
|
-
|
57
47
|
if (parentSibling !== null) {
|
58
48
|
node = parentSibling;
|
59
49
|
continue mainLoop;
|
60
50
|
}
|
61
|
-
|
62
51
|
parent = parent.getParent();
|
63
52
|
}
|
64
|
-
|
65
53
|
break;
|
66
54
|
}
|
67
|
-
|
68
55
|
return null;
|
69
56
|
}
|
57
|
+
|
70
58
|
/**
|
71
59
|
* Determines if the root has any text content and can trim any whitespace if it does.
|
72
60
|
* @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
|
73
61
|
* @param trim - Should the root text have its whitespaced trimmed? Defaults to true.
|
74
62
|
* @returns true if text content is empty, false if there is text or isEditorComposing is true.
|
75
63
|
*/
|
76
|
-
|
77
64
|
function $isRootTextContentEmpty(isEditorComposing, trim = true) {
|
78
65
|
if (isEditorComposing) {
|
79
66
|
return false;
|
80
67
|
}
|
81
|
-
|
82
68
|
let text = $rootTextContent();
|
83
|
-
|
84
69
|
if (trim) {
|
85
70
|
text = text.trim();
|
86
71
|
}
|
87
|
-
|
88
72
|
return text === '';
|
89
73
|
}
|
74
|
+
|
90
75
|
/**
|
91
76
|
* Returns a function that executes {@link $isRootTextContentEmpty}
|
92
77
|
* @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
|
93
78
|
* @param trim - Should the root text have its whitespaced trimmed? Defaults to true.
|
94
79
|
* @returns A function that executes $isRootTextContentEmpty based on arguments.
|
95
80
|
*/
|
96
|
-
|
97
81
|
function $isRootTextContentEmptyCurry(isEditorComposing, trim) {
|
98
82
|
return () => $isRootTextContentEmpty(isEditorComposing, trim);
|
99
83
|
}
|
84
|
+
|
100
85
|
/**
|
101
86
|
* Returns the root's text content.
|
102
87
|
* @returns The root's text content.
|
103
88
|
*/
|
104
|
-
|
105
89
|
function $rootTextContent() {
|
106
90
|
const root = lexical.$getRoot();
|
107
91
|
return root.getTextContent();
|
108
92
|
}
|
93
|
+
|
109
94
|
/**
|
110
95
|
* Determines if the input should show the placeholder. If anything is in
|
111
96
|
* in the root the placeholder should not be shown.
|
112
97
|
* @param isComposing - Is the editor in composition mode due to an active Input Method Editor?
|
113
98
|
* @returns true if the input should show the placeholder, false otherwise.
|
114
99
|
*/
|
115
|
-
|
116
100
|
function $canShowPlaceholder(isComposing) {
|
117
101
|
if (!$isRootTextContentEmpty(isComposing, false)) {
|
118
102
|
return false;
|
119
103
|
}
|
120
|
-
|
121
104
|
const root = lexical.$getRoot();
|
122
105
|
const children = root.getChildren();
|
123
106
|
const childrenLength = children.length;
|
124
|
-
|
125
107
|
if (childrenLength > 1) {
|
126
108
|
return false;
|
127
109
|
}
|
128
|
-
|
129
110
|
for (let i = 0; i < childrenLength; i++) {
|
130
111
|
const topBlock = children[i];
|
131
|
-
|
132
112
|
if (lexical.$isDecoratorNode(topBlock)) {
|
133
113
|
return false;
|
134
114
|
}
|
135
|
-
|
136
115
|
if (lexical.$isElementNode(topBlock)) {
|
137
116
|
if (!lexical.$isParagraphNode(topBlock)) {
|
138
117
|
return false;
|
139
118
|
}
|
140
|
-
|
141
119
|
if (topBlock.__indent !== 0) {
|
142
120
|
return false;
|
143
121
|
}
|
144
|
-
|
145
122
|
const topBlockChildren = topBlock.getChildren();
|
146
123
|
const topBlockChildrenLength = topBlockChildren.length;
|
147
|
-
|
148
124
|
for (let s = 0; s < topBlockChildrenLength; s++) {
|
149
125
|
const child = topBlockChildren[i];
|
150
|
-
|
151
126
|
if (!lexical.$isTextNode(child)) {
|
152
127
|
return false;
|
153
128
|
}
|
154
129
|
}
|
155
130
|
}
|
156
131
|
}
|
157
|
-
|
158
132
|
return true;
|
159
133
|
}
|
134
|
+
|
160
135
|
/**
|
161
136
|
* Returns a function that executes {@link $canShowPlaceholder}
|
162
137
|
* @param isEditorComposing - Is the editor in composition mode due to an active Input Method Editor?
|
163
138
|
* @returns A function that executes $canShowPlaceholder with arguments.
|
164
139
|
*/
|
165
|
-
|
166
140
|
function $canShowPlaceholderCurry(isEditorComposing) {
|
167
141
|
return () => $canShowPlaceholder(isEditorComposing);
|
168
142
|
}
|
169
|
-
|
170
143
|
/**
|
171
|
-
* Returns a
|
144
|
+
* Returns a tuple that can be rested (...) into mergeRegister to clean up
|
172
145
|
* node transforms listeners that transforms text into another node, eg. a HashtagNode.
|
173
146
|
* @example
|
174
147
|
* ```ts
|
@@ -190,80 +163,67 @@ function registerLexicalTextEntity(editor, getMatch, targetNode, createNode) {
|
|
190
163
|
const isTargetNode = node => {
|
191
164
|
return node instanceof targetNode;
|
192
165
|
};
|
193
|
-
|
194
166
|
const replaceWithSimpleText = node => {
|
195
167
|
const textNode = lexical.$createTextNode(node.getTextContent());
|
196
168
|
textNode.setFormat(node.getFormat());
|
197
169
|
node.replace(textNode);
|
198
170
|
};
|
199
|
-
|
200
171
|
const getMode = node => {
|
201
172
|
return node.getLatest().__mode;
|
202
173
|
};
|
203
|
-
|
204
174
|
const textNodeTransform = node => {
|
205
175
|
if (!node.isSimpleText()) {
|
206
176
|
return;
|
207
177
|
}
|
208
|
-
|
209
178
|
const prevSibling = node.getPreviousSibling();
|
210
179
|
let text = node.getTextContent();
|
211
180
|
let currentNode = node;
|
212
181
|
let match;
|
213
|
-
|
214
182
|
if (lexical.$isTextNode(prevSibling)) {
|
215
183
|
const previousText = prevSibling.getTextContent();
|
216
184
|
const combinedText = previousText + text;
|
217
185
|
const prevMatch = getMatch(combinedText);
|
218
|
-
|
219
186
|
if (isTargetNode(prevSibling)) {
|
220
187
|
if (prevMatch === null || getMode(prevSibling) !== 0) {
|
221
188
|
replaceWithSimpleText(prevSibling);
|
222
189
|
return;
|
223
190
|
} else {
|
224
191
|
const diff = prevMatch.end - previousText.length;
|
225
|
-
|
226
192
|
if (diff > 0) {
|
227
193
|
const concatText = text.slice(0, diff);
|
228
194
|
const newTextContent = previousText + concatText;
|
229
195
|
prevSibling.select();
|
230
196
|
prevSibling.setTextContent(newTextContent);
|
231
|
-
|
232
197
|
if (diff === text.length) {
|
233
198
|
node.remove();
|
234
199
|
} else {
|
235
200
|
const remainingText = text.slice(diff);
|
236
201
|
node.setTextContent(remainingText);
|
237
202
|
}
|
238
|
-
|
239
203
|
return;
|
240
204
|
}
|
241
205
|
}
|
242
206
|
} else if (prevMatch === null || prevMatch.start < previousText.length) {
|
243
207
|
return;
|
244
208
|
}
|
245
|
-
}
|
246
|
-
|
209
|
+
}
|
247
210
|
|
211
|
+
// eslint-disable-next-line no-constant-condition
|
248
212
|
while (true) {
|
249
213
|
match = getMatch(text);
|
250
214
|
let nextText = match === null ? '' : text.slice(match.end);
|
251
215
|
text = nextText;
|
252
|
-
|
253
216
|
if (nextText === '') {
|
254
217
|
const nextSibling = currentNode.getNextSibling();
|
255
|
-
|
256
218
|
if (lexical.$isTextNode(nextSibling)) {
|
257
219
|
nextText = currentNode.getTextContent() + nextSibling.getTextContent();
|
258
220
|
const nextMatch = getMatch(nextText);
|
259
|
-
|
260
221
|
if (nextMatch === null) {
|
261
222
|
if (isTargetNode(nextSibling)) {
|
262
223
|
replaceWithSimpleText(nextSibling);
|
263
224
|
} else {
|
264
225
|
nextSibling.markDirty();
|
265
226
|
}
|
266
|
-
|
267
227
|
return;
|
268
228
|
} else if (nextMatch.start !== 0) {
|
269
229
|
return;
|
@@ -271,71 +231,57 @@ function registerLexicalTextEntity(editor, getMatch, targetNode, createNode) {
|
|
271
231
|
}
|
272
232
|
} else {
|
273
233
|
const nextMatch = getMatch(nextText);
|
274
|
-
|
275
234
|
if (nextMatch !== null && nextMatch.start === 0) {
|
276
235
|
return;
|
277
236
|
}
|
278
237
|
}
|
279
|
-
|
280
238
|
if (match === null) {
|
281
239
|
return;
|
282
240
|
}
|
283
|
-
|
284
241
|
if (match.start === 0 && lexical.$isTextNode(prevSibling) && prevSibling.isTextEntity()) {
|
285
242
|
continue;
|
286
243
|
}
|
287
|
-
|
288
244
|
let nodeToReplace;
|
289
|
-
|
290
245
|
if (match.start === 0) {
|
291
246
|
[nodeToReplace, currentNode] = currentNode.splitText(match.end);
|
292
247
|
} else {
|
293
248
|
[, nodeToReplace, currentNode] = currentNode.splitText(match.start, match.end);
|
294
249
|
}
|
295
|
-
|
296
250
|
const replacementNode = createNode(nodeToReplace);
|
297
251
|
replacementNode.setFormat(nodeToReplace.getFormat());
|
298
252
|
nodeToReplace.replace(replacementNode);
|
299
|
-
|
300
253
|
if (currentNode == null) {
|
301
254
|
return;
|
302
255
|
}
|
303
256
|
}
|
304
257
|
};
|
305
|
-
|
306
258
|
const reverseNodeTransform = node => {
|
307
259
|
const text = node.getTextContent();
|
308
260
|
const match = getMatch(text);
|
309
|
-
|
310
261
|
if (match === null || match.start !== 0) {
|
311
262
|
replaceWithSimpleText(node);
|
312
263
|
return;
|
313
264
|
}
|
314
|
-
|
315
265
|
if (text.length > match.end) {
|
316
266
|
// This will split out the rest of the text as simple text
|
317
267
|
node.splitText(match.end);
|
318
268
|
return;
|
319
269
|
}
|
320
|
-
|
321
270
|
const prevSibling = node.getPreviousSibling();
|
322
|
-
|
323
271
|
if (lexical.$isTextNode(prevSibling) && prevSibling.isTextEntity()) {
|
324
272
|
replaceWithSimpleText(prevSibling);
|
325
273
|
replaceWithSimpleText(node);
|
326
274
|
}
|
327
|
-
|
328
275
|
const nextSibling = node.getNextSibling();
|
329
|
-
|
330
276
|
if (lexical.$isTextNode(nextSibling) && nextSibling.isTextEntity()) {
|
331
|
-
replaceWithSimpleText(nextSibling);
|
277
|
+
replaceWithSimpleText(nextSibling);
|
332
278
|
|
279
|
+
// This may have already been converted in the previous block
|
333
280
|
if (isTargetNode(node)) {
|
334
281
|
replaceWithSimpleText(node);
|
335
282
|
}
|
336
283
|
}
|
337
284
|
};
|
338
|
-
|
339
285
|
const removePlainTextTransform = editor.registerNodeTransform(lexical.TextNode, textNodeTransform);
|
340
286
|
const removeReverseNodeTransform = editor.registerNodeTransform(targetNode, reverseNodeTransform);
|
341
287
|
return [removePlainTextTransform, removeReverseNodeTransform];
|
package/index.d.ts
CHANGED
@@ -60,7 +60,7 @@ export type EntityMatch = {
|
|
60
60
|
start: number;
|
61
61
|
};
|
62
62
|
/**
|
63
|
-
* Returns a
|
63
|
+
* Returns a tuple that can be rested (...) into mergeRegister to clean up
|
64
64
|
* node transforms listeners that transforms text into another node, eg. a HashtagNode.
|
65
65
|
* @example
|
66
66
|
* ```ts
|
package/package.json
CHANGED