@lexical/text 0.1.16 → 0.1.19
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/LICENSE +1 -1
- package/LexicalText.d.ts +53 -0
- package/LexicalText.dev.js +153 -0
- package/LexicalText.js.flow +54 -0
- package/LexicalText.prod.js +8 -5
- package/package.json +2 -6
package/LICENSE
CHANGED
package/LexicalText.d.ts
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
import type {ElementNode, LexicalEditor, RootNode, TextNode} from 'lexical';
|
9
|
+
export type TextNodeWithOffset = {
|
10
|
+
node: TextNode;
|
11
|
+
offset: number;
|
12
|
+
};
|
13
|
+
export function $findTextIntersectionFromCharacters(
|
14
|
+
root: RootNode,
|
15
|
+
targetCharacters: number,
|
16
|
+
): null | {
|
17
|
+
node: TextNode;
|
18
|
+
offset: number;
|
19
|
+
};
|
20
|
+
export function $joinTextNodesInElementNode(
|
21
|
+
elementNode: ElementNode,
|
22
|
+
separator: string,
|
23
|
+
stopAt: TextNodeWithOffset,
|
24
|
+
): string;
|
25
|
+
export function $findNodeWithOffsetFromJoinedText(
|
26
|
+
offsetInJoinedText: number,
|
27
|
+
joinedTextLength: number,
|
28
|
+
separatorLength: number,
|
29
|
+
elementNode: ElementNode,
|
30
|
+
): ?TextNodeWithOffset;
|
31
|
+
export function $isRootTextContentEmpty(
|
32
|
+
isEditorComposing: boolean,
|
33
|
+
trim?: boolean,
|
34
|
+
): boolean;
|
35
|
+
export function $isRootTextContentEmptyCurry(
|
36
|
+
isEditorComposing: boolean,
|
37
|
+
trim?: boolean,
|
38
|
+
): () => boolean;
|
39
|
+
export function $rootTextContentCurry(): string;
|
40
|
+
export function $canShowPlaceholder(isComposing: boolean): boolean;
|
41
|
+
export function $canShowPlaceholderCurry(
|
42
|
+
isEditorComposing: boolean,
|
43
|
+
): () => boolean;
|
44
|
+
export type EntityMatch = {
|
45
|
+
end: number;
|
46
|
+
start: number;
|
47
|
+
};
|
48
|
+
export function registerLexicalTextEntity<N extends TextNode>(
|
49
|
+
editor: LexicalEditor,
|
50
|
+
getMatch: (text: string) => null | EntityMatch,
|
51
|
+
targetNode: Class<N>,
|
52
|
+
createNode: (textNode: TextNode) => N,
|
53
|
+
): Array<() => void>;
|
package/LexicalText.dev.js
CHANGED
@@ -212,6 +212,158 @@ function $canShowPlaceholder(isComposing) {
|
|
212
212
|
function $canShowPlaceholderCurry(isEditorComposing) {
|
213
213
|
return () => $canShowPlaceholder(isEditorComposing);
|
214
214
|
}
|
215
|
+
function registerLexicalTextEntity(editor, getMatch, targetNode, createNode) {
|
216
|
+
const isTargetNode = node => {
|
217
|
+
return node instanceof targetNode;
|
218
|
+
};
|
219
|
+
|
220
|
+
const replaceWithSimpleText = node => {
|
221
|
+
const textNode = lexical.$createTextNode(node.getTextContent());
|
222
|
+
textNode.setFormat(node.getFormat());
|
223
|
+
node.replace(textNode);
|
224
|
+
};
|
225
|
+
|
226
|
+
const getMode = node => {
|
227
|
+
return node.getLatest().__mode;
|
228
|
+
};
|
229
|
+
|
230
|
+
const textNodeTransform = node => {
|
231
|
+
if (!node.isSimpleText()) {
|
232
|
+
return;
|
233
|
+
}
|
234
|
+
|
235
|
+
const prevSibling = node.getPreviousSibling();
|
236
|
+
let text = node.getTextContent();
|
237
|
+
let currentNode = node;
|
238
|
+
let match;
|
239
|
+
|
240
|
+
if (lexical.$isTextNode(prevSibling)) {
|
241
|
+
const previousText = prevSibling.getTextContent();
|
242
|
+
const combinedText = previousText + text;
|
243
|
+
const prevMatch = getMatch(combinedText);
|
244
|
+
|
245
|
+
if (isTargetNode(prevSibling)) {
|
246
|
+
if (prevMatch === null || getMode(prevSibling) !== 0) {
|
247
|
+
replaceWithSimpleText(prevSibling);
|
248
|
+
return;
|
249
|
+
} else {
|
250
|
+
const diff = prevMatch.end - previousText.length;
|
251
|
+
|
252
|
+
if (diff > 0) {
|
253
|
+
const concatText = text.slice(0, diff);
|
254
|
+
const newTextContent = previousText + concatText;
|
255
|
+
prevSibling.select();
|
256
|
+
prevSibling.setTextContent(newTextContent);
|
257
|
+
|
258
|
+
if (diff === text.length) {
|
259
|
+
node.remove();
|
260
|
+
} else {
|
261
|
+
const remainingText = text.slice(diff);
|
262
|
+
node.setTextContent(remainingText);
|
263
|
+
}
|
264
|
+
|
265
|
+
return;
|
266
|
+
}
|
267
|
+
}
|
268
|
+
} else if (prevMatch === null || prevMatch.start < previousText.length) {
|
269
|
+
return;
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
while (true) {
|
274
|
+
match = getMatch(text);
|
275
|
+
let nextText = match === null ? '' : text.slice(match.end);
|
276
|
+
text = nextText;
|
277
|
+
|
278
|
+
if (nextText === '') {
|
279
|
+
const nextSibling = currentNode.getNextSibling();
|
280
|
+
|
281
|
+
if (lexical.$isTextNode(nextSibling)) {
|
282
|
+
nextText = currentNode.getTextContent() + nextSibling.getTextContent();
|
283
|
+
const nextMatch = getMatch(nextText);
|
284
|
+
|
285
|
+
if (nextMatch === null) {
|
286
|
+
if (isTargetNode(nextSibling)) {
|
287
|
+
replaceWithSimpleText(nextSibling);
|
288
|
+
} else {
|
289
|
+
nextSibling.markDirty();
|
290
|
+
}
|
291
|
+
|
292
|
+
return;
|
293
|
+
} else if (nextMatch.start !== 0) {
|
294
|
+
return;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
} else {
|
298
|
+
const nextMatch = getMatch(nextText);
|
299
|
+
|
300
|
+
if (nextMatch !== null && nextMatch.start === 0) {
|
301
|
+
return;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
if (match === null) {
|
306
|
+
return;
|
307
|
+
}
|
308
|
+
|
309
|
+
if (match.start === 0 && lexical.$isTextNode(prevSibling) && prevSibling.isTextEntity()) {
|
310
|
+
continue;
|
311
|
+
}
|
312
|
+
|
313
|
+
let nodeToReplace;
|
314
|
+
|
315
|
+
if (match.start === 0) {
|
316
|
+
[nodeToReplace, currentNode] = currentNode.splitText(match.end);
|
317
|
+
} else {
|
318
|
+
[, nodeToReplace, currentNode] = currentNode.splitText(match.start, match.end);
|
319
|
+
}
|
320
|
+
|
321
|
+
const replacementNode = createNode(nodeToReplace);
|
322
|
+
nodeToReplace.replace(replacementNode);
|
323
|
+
|
324
|
+
if (currentNode == null) {
|
325
|
+
return;
|
326
|
+
}
|
327
|
+
}
|
328
|
+
};
|
329
|
+
|
330
|
+
const reverseNodeTransform = node => {
|
331
|
+
const text = node.getTextContent();
|
332
|
+
const match = getMatch(text);
|
333
|
+
|
334
|
+
if (match === null || match.start !== 0) {
|
335
|
+
replaceWithSimpleText(node);
|
336
|
+
return;
|
337
|
+
}
|
338
|
+
|
339
|
+
if (text.length > match.end) {
|
340
|
+
// This will split out the rest of the text as simple text
|
341
|
+
node.splitText(match.end);
|
342
|
+
return;
|
343
|
+
}
|
344
|
+
|
345
|
+
const prevSibling = node.getPreviousSibling();
|
346
|
+
|
347
|
+
if (lexical.$isTextNode(prevSibling) && prevSibling.isTextEntity()) {
|
348
|
+
replaceWithSimpleText(prevSibling);
|
349
|
+
replaceWithSimpleText(node);
|
350
|
+
}
|
351
|
+
|
352
|
+
const nextSibling = node.getNextSibling();
|
353
|
+
|
354
|
+
if (lexical.$isTextNode(nextSibling) && nextSibling.isTextEntity()) {
|
355
|
+
replaceWithSimpleText(nextSibling); // This may have already been converted in the previous block
|
356
|
+
|
357
|
+
if (isTargetNode(node)) {
|
358
|
+
replaceWithSimpleText(node);
|
359
|
+
}
|
360
|
+
}
|
361
|
+
};
|
362
|
+
|
363
|
+
const removePlainTextTransform = editor.registerNodeTransform(lexical.TextNode, textNodeTransform);
|
364
|
+
const removeReverseNodeTransform = editor.registerNodeTransform(targetNode, reverseNodeTransform);
|
365
|
+
return [removePlainTextTransform, removeReverseNodeTransform];
|
366
|
+
}
|
215
367
|
|
216
368
|
exports.$canShowPlaceholder = $canShowPlaceholder;
|
217
369
|
exports.$canShowPlaceholderCurry = $canShowPlaceholderCurry;
|
@@ -221,3 +373,4 @@ exports.$isRootTextContentEmpty = $isRootTextContentEmpty;
|
|
221
373
|
exports.$isRootTextContentEmptyCurry = $isRootTextContentEmptyCurry;
|
222
374
|
exports.$joinTextNodesInElementNode = $joinTextNodesInElementNode;
|
223
375
|
exports.$rootTextContentCurry = $rootTextContentCurry;
|
376
|
+
exports.registerLexicalTextEntity = registerLexicalTextEntity;
|
@@ -0,0 +1,54 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
3
|
+
*
|
4
|
+
* This source code is licensed under the MIT license found in the
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
6
|
+
*
|
7
|
+
* @flow strict
|
8
|
+
*/
|
9
|
+
import type {ElementNode, LexicalEditor, RootNode, TextNode} from 'lexical';
|
10
|
+
export type TextNodeWithOffset = {
|
11
|
+
node: TextNode,
|
12
|
+
offset: number,
|
13
|
+
};
|
14
|
+
declare export function $findTextIntersectionFromCharacters(
|
15
|
+
root: RootNode,
|
16
|
+
targetCharacters: number,
|
17
|
+
): null | {
|
18
|
+
node: TextNode,
|
19
|
+
offset: number,
|
20
|
+
};
|
21
|
+
declare export function $joinTextNodesInElementNode(
|
22
|
+
elementNode: ElementNode,
|
23
|
+
separator: string,
|
24
|
+
stopAt: TextNodeWithOffset,
|
25
|
+
): string;
|
26
|
+
declare export function $findNodeWithOffsetFromJoinedText(
|
27
|
+
offsetInJoinedText: number,
|
28
|
+
joinedTextLength: number,
|
29
|
+
separatorLength: number,
|
30
|
+
elementNode: ElementNode,
|
31
|
+
): ?TextNodeWithOffset;
|
32
|
+
declare export function $isRootTextContentEmpty(
|
33
|
+
isEditorComposing: boolean,
|
34
|
+
trim?: boolean,
|
35
|
+
): boolean;
|
36
|
+
declare export function $isRootTextContentEmptyCurry(
|
37
|
+
isEditorComposing: boolean,
|
38
|
+
trim?: boolean,
|
39
|
+
): () => boolean;
|
40
|
+
declare export function $rootTextContentCurry(): string;
|
41
|
+
declare export function $canShowPlaceholder(isComposing: boolean): boolean;
|
42
|
+
declare export function $canShowPlaceholderCurry(
|
43
|
+
isEditorComposing: boolean,
|
44
|
+
): () => boolean;
|
45
|
+
export type EntityMatch = {
|
46
|
+
end: number,
|
47
|
+
start: number,
|
48
|
+
};
|
49
|
+
declare export function registerLexicalTextEntity<N: TextNode>(
|
50
|
+
editor: LexicalEditor,
|
51
|
+
getMatch: (text: string) => null | EntityMatch,
|
52
|
+
targetNode: Class<N>,
|
53
|
+
createNode: (textNode: TextNode) => N,
|
54
|
+
): Array<() => void>;
|
package/LexicalText.prod.js
CHANGED
@@ -4,8 +4,11 @@
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
6
6
|
*/
|
7
|
-
var
|
8
|
-
exports.$canShowPlaceholderCurry=function(
|
9
|
-
exports.$findTextIntersectionFromCharacters=function(
|
10
|
-
exports.$isRootTextContentEmptyCurry=function(
|
11
|
-
exports.$joinTextNodesInElementNode=function(
|
7
|
+
var k=require("lexical");function r(b,f=!0){if(b)return!1;b=t();f&&(b=b.trim());return""===b}function t(){return k.$getRoot().getTextContent()}function u(b){if(!r(b,!1))return!1;b=k.$getRoot().getChildren();const f=b.length;if(1<f)return!1;for(let e=0;e<f;e++){var c=b[e];if(k.$isElementNode(c)){if("paragraph"!==c.__type||0!==c.__indent)return!1;c=c.getChildren();const p=c.length;for(let g=0;g<p;g++)if(!k.$isTextNode(c[e]))return!1}}return!0}exports.$canShowPlaceholder=u;
|
8
|
+
exports.$canShowPlaceholderCurry=function(b){return()=>u(b)};exports.$findNodeWithOffsetFromJoinedText=function(b,f,c,e){e=e.getChildren();const p=e.length;let g=0,a=!1;for(let l=0;l<p&&!(g>f);++l){const m=e[l],n=k.$isTextNode(m);var d=n?m.getTextContent().length:c;d=g+d;if((!1===a&&g===b||0===g&&g===b||g<b&&b<=d)&&k.$isTextNode(m))return{node:m,offset:b-g};g=d;a=n}return null};
|
9
|
+
exports.$findTextIntersectionFromCharacters=function(b,f){var c=b.getFirstChild();b=0;a:for(;null!==c;){if(k.$isElementNode(c)){var e=c.getFirstChild();if(null!==e){c=e;continue}}else if(k.$isTextNode(c)){e=c.getTextContentSize();if(b+e>f)return{node:c,offset:f-b};b+=e}e=c.getNextSibling();if(null!==e)c=e;else{for(c=c.getParent();null!==c;){e=c.getNextSibling();if(null!==e){c=e;continue a}c=c.getParent()}break}}return null};exports.$isRootTextContentEmpty=r;
|
10
|
+
exports.$isRootTextContentEmptyCurry=function(b,f){return()=>r(b,f)};
|
11
|
+
exports.$joinTextNodesInElementNode=function(b,f,c){let e="";b=b.getChildren();const p=b.length;for(let g=0;g<p;++g){const a=b[g];if(k.$isTextNode(a)){const d=a.getTextContent();if(a.is(c.node)){if(c.offset>d.length)throw Error("Minified Lexical error #50; see codes.json for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");e+=a.getTextContent().substr(0,c.offset);break}else e+=d}else e+=f}return e};exports.$rootTextContentCurry=t;
|
12
|
+
exports.registerLexicalTextEntity=function(b,f,c,e){const p=a=>{const d=k.$createTextNode(a.getTextContent());d.setFormat(a.getFormat());a.replace(d)},g=b.registerNodeTransform(k.TextNode,a=>{if(a.isSimpleText()){var d=a.getPreviousSibling(),l=a.getTextContent(),m=a;if(k.$isTextNode(d)){var n=d.getTextContent(),h=f(n+l);if(d instanceof c){if(null===h||0!==d.getLatest().__mode){p(d);return}h=h.end-n.length;if(0<h){m=l.slice(0,h);m=n+m;d.select();d.setTextContent(m);h===l.length?a.remove():(d=l.slice(h),
|
13
|
+
a.setTextContent(d));return}}else if(null===h||h.start<n.length)return}for(;;){a=f(l);l=h=null===a?"":l.slice(a.end);if(""===h){if(n=m.getNextSibling(),k.$isTextNode(n))if(h=m.getTextContent()+n.getTextContent(),h=f(h),null===h){n instanceof c?p(n):n.markDirty();break}else if(0!==h.start)break}else if(n=f(h),null!==n&&0===n.start)break;if(null===a)break;if(0===a.start&&k.$isTextNode(d)&&d.isTextEntity())continue;let q;0===a.start?[q,m]=m.splitText(a.end):[,q,m]=m.splitText(a.start,a.end);a=e(q);q.replace(a);
|
14
|
+
if(null==m)break}}});b=b.registerNodeTransform(c,a=>{var d=a.getTextContent();const l=f(d);null===l||0!==l.start?p(a):d.length>l.end?a.splitText(l.end):(d=a.getPreviousSibling(),k.$isTextNode(d)&&d.isTextEntity()&&(p(d),p(a)),d=a.getNextSibling(),k.$isTextNode(d)&&d.isTextEntity()&&(p(d),a instanceof c&&p(a)))});return[g,b]};
|
package/package.json
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lexical/text",
|
3
|
-
"author": {
|
4
|
-
"name": "Dominic Gannaway",
|
5
|
-
"email": "dg@domgan.com"
|
6
|
-
},
|
7
3
|
"description": "This package contains utilities and helpers for handling Lexical text.",
|
8
4
|
"keywords": [
|
9
5
|
"lexical",
|
@@ -13,10 +9,10 @@
|
|
13
9
|
"text"
|
14
10
|
],
|
15
11
|
"license": "MIT",
|
16
|
-
"version": "0.1.
|
12
|
+
"version": "0.1.19",
|
17
13
|
"main": "LexicalText.js",
|
18
14
|
"peerDependencies": {
|
19
|
-
"lexical": "0.1.
|
15
|
+
"lexical": "0.1.19"
|
20
16
|
},
|
21
17
|
"repository": {
|
22
18
|
"type": "git",
|