@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.
@@ -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 touple that can be rested (...) into mergeRegister to clean up
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
- } // eslint-disable-next-line no-constant-condition
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); // This may have already been converted in the previous block
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 touple that can be rested (...) into mergeRegister to clean up
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
@@ -9,10 +9,10 @@
9
9
  "text"
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "0.12.2",
12
+ "version": "0.12.3",
13
13
  "main": "LexicalText.js",
14
14
  "peerDependencies": {
15
- "lexical": "0.12.2"
15
+ "lexical": "0.12.3"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",