@lexical/text 0.12.2 → 0.12.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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",