@lexical/utils 0.6.0 → 0.6.2
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/LexicalUtils.dev.js +127 -10
- package/LexicalUtils.js.flow +10 -0
- package/LexicalUtils.prod.js +11 -9
- package/index.d.ts +17 -0
- package/package.json +4 -4
package/LexicalUtils.dev.js
CHANGED
|
@@ -24,6 +24,67 @@ function removeClassNamesFromElement(element, ...classNames) {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
+
function isMimeType(file, acceptableMimeTypes) {
|
|
28
|
+
for (const acceptableType of acceptableMimeTypes) {
|
|
29
|
+
if (file.type.startsWith(acceptableType)) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Lexical File Reader with:
|
|
38
|
+
* 1. MIME type support
|
|
39
|
+
* 2. batched results (HistoryPlugin compatibility)
|
|
40
|
+
* 3. Order aware (respects the order when multiple Files are passed)
|
|
41
|
+
*
|
|
42
|
+
* const filesResult = await mediaFileReader(files, ['image/']);
|
|
43
|
+
* filesResult.forEach(file => editor.dispatchCommand('INSERT_IMAGE', {
|
|
44
|
+
* src: file.result,
|
|
45
|
+
* }));
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
function mediaFileReader(files, acceptableMimeTypes) {
|
|
49
|
+
const filesIterator = files[Symbol.iterator]();
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const processed = [];
|
|
52
|
+
|
|
53
|
+
const handleNextFile = () => {
|
|
54
|
+
const {
|
|
55
|
+
done,
|
|
56
|
+
value: file
|
|
57
|
+
} = filesIterator.next();
|
|
58
|
+
|
|
59
|
+
if (done) {
|
|
60
|
+
return resolve(processed);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const fileReader = new FileReader();
|
|
64
|
+
fileReader.addEventListener('error', reject);
|
|
65
|
+
fileReader.addEventListener('load', () => {
|
|
66
|
+
const result = fileReader.result;
|
|
67
|
+
|
|
68
|
+
if (typeof result === 'string') {
|
|
69
|
+
processed.push({
|
|
70
|
+
file,
|
|
71
|
+
result
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
handleNextFile();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (isMimeType(file, acceptableMimeTypes)) {
|
|
79
|
+
fileReader.readAsDataURL(file);
|
|
80
|
+
} else {
|
|
81
|
+
handleNextFile();
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
handleNextFile();
|
|
86
|
+
});
|
|
87
|
+
}
|
|
27
88
|
function $dfs(startingNode, endingNode) {
|
|
28
89
|
const nodes = [];
|
|
29
90
|
const start = (startingNode || lexical.$getRoot()).getLatest();
|
|
@@ -321,19 +382,44 @@ function $insertNodeToNearestRoot(node) {
|
|
|
321
382
|
const selection = lexical.$getSelection();
|
|
322
383
|
|
|
323
384
|
if (lexical.$isRangeSelection(selection)) {
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
385
|
+
const {
|
|
386
|
+
focus
|
|
387
|
+
} = selection;
|
|
388
|
+
const focusNode = focus.getNode();
|
|
389
|
+
const focusOffset = focus.offset;
|
|
390
|
+
let splitNode;
|
|
391
|
+
let splitOffset;
|
|
392
|
+
|
|
393
|
+
if (lexical.$isTextNode(focusNode)) {
|
|
394
|
+
splitNode = focusNode.getParentOrThrow();
|
|
395
|
+
splitOffset = focusNode.getIndexWithinParent();
|
|
396
|
+
|
|
397
|
+
if (focusOffset > 0) {
|
|
398
|
+
splitOffset += 1;
|
|
399
|
+
focusNode.splitText(focusOffset);
|
|
400
|
+
}
|
|
401
|
+
} else {
|
|
402
|
+
splitNode = focusNode;
|
|
403
|
+
splitOffset = focusOffset;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const [, rightTree] = $splitNode(splitNode, splitOffset);
|
|
407
|
+
rightTree.insertBefore(node);
|
|
408
|
+
rightTree.selectStart();
|
|
329
409
|
} else {
|
|
330
|
-
|
|
331
|
-
|
|
410
|
+
if (lexical.$isNodeSelection(selection) || lexical.DEPRECATED_$isGridSelection(selection)) {
|
|
411
|
+
const nodes = selection.getNodes();
|
|
412
|
+
nodes[nodes.length - 1].getTopLevelElementOrThrow().insertAfter(node);
|
|
413
|
+
} else {
|
|
414
|
+
const root = lexical.$getRoot();
|
|
415
|
+
root.append(node);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const paragraphNode = lexical.$createParagraphNode();
|
|
419
|
+
node.insertAfter(paragraphNode);
|
|
420
|
+
paragraphNode.select();
|
|
332
421
|
}
|
|
333
422
|
|
|
334
|
-
const paragraphNode = lexical.$createParagraphNode();
|
|
335
|
-
node.insertAfter(paragraphNode);
|
|
336
|
-
paragraphNode.select();
|
|
337
423
|
return node.getLatest();
|
|
338
424
|
}
|
|
339
425
|
function $wrapNodeInElement(node, createElementNode) {
|
|
@@ -342,6 +428,34 @@ function $wrapNodeInElement(node, createElementNode) {
|
|
|
342
428
|
elementNode.append(node);
|
|
343
429
|
return elementNode;
|
|
344
430
|
}
|
|
431
|
+
function $splitNode(node, offset) {
|
|
432
|
+
let startNode = node.getChildAtIndex(offset);
|
|
433
|
+
|
|
434
|
+
if (startNode == null) {
|
|
435
|
+
startNode = node;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const recurse = currentNode => {
|
|
439
|
+
const parent = currentNode.getParentOrThrow();
|
|
440
|
+
const isParentRoot = lexical.$isRootOrShadowRoot(parent); // The node we start split from (leaf) is moved, but its recursive
|
|
441
|
+
// parents are copied to create separate tree
|
|
442
|
+
|
|
443
|
+
const nodeToMove = currentNode === startNode && !isParentRoot ? currentNode : lexical.$copyNode(currentNode);
|
|
444
|
+
|
|
445
|
+
if (isParentRoot) {
|
|
446
|
+
currentNode.insertAfter(nodeToMove);
|
|
447
|
+
return [currentNode, nodeToMove, nodeToMove];
|
|
448
|
+
} else {
|
|
449
|
+
const [leftTree, rightTree, newParent] = recurse(parent);
|
|
450
|
+
const nextSiblings = currentNode.getNextSiblings();
|
|
451
|
+
newParent.append(nodeToMove, ...nextSiblings);
|
|
452
|
+
return [leftTree, rightTree, nodeToMove];
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
const [leftTree, rightTree] = recurse(startNode);
|
|
457
|
+
return [leftTree, rightTree];
|
|
458
|
+
}
|
|
345
459
|
|
|
346
460
|
exports.$dfs = $dfs;
|
|
347
461
|
exports.$findMatchingParent = $findMatchingParent;
|
|
@@ -349,8 +463,11 @@ exports.$getNearestBlockElementAncestorOrThrow = $getNearestBlockElementAncestor
|
|
|
349
463
|
exports.$getNearestNodeOfType = $getNearestNodeOfType;
|
|
350
464
|
exports.$insertNodeToNearestRoot = $insertNodeToNearestRoot;
|
|
351
465
|
exports.$restoreEditorState = $restoreEditorState;
|
|
466
|
+
exports.$splitNode = $splitNode;
|
|
352
467
|
exports.$wrapNodeInElement = $wrapNodeInElement;
|
|
353
468
|
exports.addClassNamesToElement = addClassNamesToElement;
|
|
469
|
+
exports.isMimeType = isMimeType;
|
|
470
|
+
exports.mediaFileReader = mediaFileReader;
|
|
354
471
|
exports.mergeRegister = mergeRegister;
|
|
355
472
|
exports.registerNestedElementResolver = registerNestedElementResolver;
|
|
356
473
|
exports.removeClassNamesFromElement = removeClassNamesFromElement;
|
package/LexicalUtils.js.flow
CHANGED
|
@@ -24,6 +24,14 @@ declare export function removeClassNamesFromElement(
|
|
|
24
24
|
element: HTMLElement,
|
|
25
25
|
...classNames: Array<typeof undefined | boolean | null | string>
|
|
26
26
|
): void;
|
|
27
|
+
declare export function isMimeType(
|
|
28
|
+
file: File,
|
|
29
|
+
acceptableMimeTypes: Array<string>,
|
|
30
|
+
): boolean;
|
|
31
|
+
declare export function mediaFileReader(
|
|
32
|
+
files: Array<File>,
|
|
33
|
+
acceptableMimeTypes: Array<string>,
|
|
34
|
+
): Promise<Array<$ReadOnly<{file: File, result: string}>>>;
|
|
27
35
|
declare export function $dfs(
|
|
28
36
|
startingNode?: LexicalNode,
|
|
29
37
|
endingNode?: LexicalNode,
|
|
@@ -70,3 +78,5 @@ declare export function $wrapNodeInElement(
|
|
|
70
78
|
node: LexicalNode,
|
|
71
79
|
createElementNode: () => ElementNode,
|
|
72
80
|
): ElementNode;
|
|
81
|
+
|
|
82
|
+
declare export function $splitNode<T: LexicalNode>(node: T): T;
|
package/LexicalUtils.prod.js
CHANGED
|
@@ -4,13 +4,15 @@
|
|
|
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
|
-
'use strict';var l=require("lexical");function
|
|
8
|
-
function
|
|
7
|
+
'use strict';var l=require("lexical");function p(a){throw Error(`Minified Lexical error #${a}; visit https://lexical.dev/docs/error?code=${a} for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}function q(a,b){for(let d of b)if(a.type.startsWith(d))return!0;return!1}function r(a,b){for(;a!==l.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent()}return null}
|
|
8
|
+
function t(a,b,d,g,f){var c=d._nodes.get(a.__type);void 0===c&&p(5);for(var e in a){var k=a[e];if(null!=k&&"object"===typeof k&&(k=k.editorState,null!=k)){var h=l.createEditor({namespace:k.namespace});h._nodes=d._nodes;h._parentEditor=d._parentEditor;h._pendingEditorState=u(h,k);a[e]=h}}c=c.klass;e=a.__key;a.__key=void 0;c=c.clone(a);a.__key=e;e=c.__key;f._nodeMap.set(e,c);c.__parent=g;if(l.$isElementNode(c)){g=a.__children;for(k=0;k<g.length;k++)h=b.get(g[k]),void 0!==h&&(h=t(h,b,d,e,f).__key,c.__children.push(h));
|
|
9
9
|
c.__indent=a.__indent;c.__format=a.__format;c.__dir=a.__dir}else l.$isTextNode(c)&&(c.__format=a.__format,c.__style=a.__style,c.__mode=a.__mode,c.__detail=a.__detail);return c}
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
exports.$
|
|
13
|
-
exports.$
|
|
14
|
-
exports.$
|
|
15
|
-
exports
|
|
16
|
-
exports.
|
|
10
|
+
function v(a,b){let d=b._editorState.constructor,g=new Map,f=new d(g),c=new Map(a._nodeMap),e=c.get("root");a=b._updating;try{b._updating=!1,b.update(()=>{let k=b._dirtyElements,h=b._dirtyLeaves,m=b._dirtyType;b._dirtyElements=new Map;b._dirtyLeaves=new Set;b._dirtyType=0;try{t(e,c,b,null,f)}finally{b._dirtyElements=k,b._dirtyLeaves=h,b._dirtyType=m}})}finally{b._updating=a}f._readOnly=!0;return f}function u(a,b){b="string"===typeof b?JSON.parse(b):b;return v(b,a)}
|
|
11
|
+
function w(a,b){let d=a.getChildAtIndex(b);null==d&&(d=a);let g=e=>{const k=e.getParentOrThrow(),h=l.$isRootOrShadowRoot(k),m=e!==d||h?l.$copyNode(e):e;if(h)return e.insertAfter(m),[e,m,m];const [n,x,y]=g(k);e=e.getNextSiblings();y.append(m,...e);return[n,x,m]},[f,c]=g(d);return[f,c]}
|
|
12
|
+
exports.$dfs=function(a,b){let d=[];a=(a||l.$getRoot()).getLatest();b=b||(l.$isElementNode(a)?a.getLastDescendant():a);for(var g=a,f=0;null!==(g=g.getParent());)f++;for(g=f;null!==a&&!a.is(b);)if(d.push({depth:g,node:a}),l.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),g++;else for(f=null;null===f&&null!==a;)f=a.getNextSibling(),null===f?(a=a.getParent(),g--):a=f;null!==a&&a.is(b)&&d.push({depth:g,node:a});return d};exports.$findMatchingParent=r;
|
|
13
|
+
exports.$getNearestBlockElementAncestorOrThrow=function(a){a=r(a,b=>l.$isElementNode(b)&&!b.isInline());l.$isElementNode(a)||p(4);return a};exports.$getNearestNodeOfType=function(a,b){for(;null!=a;){if(a instanceof b)return a;a=a.getParent()}return null};
|
|
14
|
+
exports.$insertNodeToNearestRoot=function(a){var b=l.$getSelection();if(l.$isRangeSelection(b)){var {focus:d}=b;b=d.getNode();d=d.offset;let g,f;l.$isTextNode(b)?(g=b.getParentOrThrow(),f=b.getIndexWithinParent(),0<d&&(f+=1,b.splitText(d))):(g=b,f=d);[,b]=w(g,f);b.insertBefore(a);b.selectStart()}else l.$isNodeSelection(b)||l.DEPRECATED_$isGridSelection(b)?(b=b.getNodes(),b[b.length-1].getTopLevelElementOrThrow().insertAfter(a)):l.$getRoot().append(a),b=l.$createParagraphNode(),a.insertAfter(b),b.select();
|
|
15
|
+
return a.getLatest()};exports.$restoreEditorState=function(a,b){let d=new Map(b._nodeMap),g=a._pendingEditorState;g&&(g._nodeMap=d);a._dirtyType=2;a=b._selection;l.$setSelection(null===a?null:a.clone())};exports.$splitNode=w;exports.$wrapNodeInElement=function(a,b){b=b();a.replace(b);b.append(a);return b};exports.addClassNamesToElement=function(a,...b){b.forEach(d=>{"string"===typeof d&&(d=d.split(" ").filter(g=>""!==g),a.classList.add(...d))})};exports.isMimeType=q;
|
|
16
|
+
exports.mediaFileReader=function(a,b){let d=a[Symbol.iterator]();return new Promise((g,f)=>{let c=[],e=()=>{const {done:k,value:h}=d.next();if(k)return g(c);const m=new FileReader;m.addEventListener("error",f);m.addEventListener("load",()=>{const n=m.result;"string"===typeof n&&c.push({file:h,result:n});e()});q(h,b)?m.readAsDataURL(h):e()};e()})};exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};
|
|
17
|
+
exports.registerNestedElementResolver=function(a,b,d,g){return a.registerNodeTransform(b,f=>{a:{var c=f.getChildren();for(var e=0;e<c.length;e++)if(c[e]instanceof b){c=null;break a}for(c=f;null!==c;)if(e=c,c=c.getParent(),c instanceof b){c={child:e,parent:c};break a}c=null}if(null!==c){const {child:k,parent:h}=c;if(k.is(f)){g(h,f);f=k.getNextSiblings();c=f.length;h.insertAfter(k);if(0!==c){e=d(h);k.insertAfter(e);for(let m=0;m<c;m++)e.append(f[m])}h.canBeEmpty()||0!==h.getChildrenSize()||h.remove()}}})};
|
|
18
|
+
exports.removeClassNamesFromElement=function(a,...b){b.forEach(d=>{"string"===typeof d&&a.classList.remove(...d.split(" "))})};exports.unstable_convertLegacyJSONEditorState=u
|
package/index.d.ts
CHANGED
|
@@ -13,6 +13,22 @@ export declare type DFSNode = Readonly<{
|
|
|
13
13
|
}>;
|
|
14
14
|
export declare function addClassNamesToElement(element: HTMLElement, ...classNames: Array<typeof undefined | boolean | null | string>): void;
|
|
15
15
|
export declare function removeClassNamesFromElement(element: HTMLElement, ...classNames: Array<typeof undefined | boolean | null | string>): void;
|
|
16
|
+
export declare function isMimeType(file: File, acceptableMimeTypes: Array<string>): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Lexical File Reader with:
|
|
19
|
+
* 1. MIME type support
|
|
20
|
+
* 2. batched results (HistoryPlugin compatibility)
|
|
21
|
+
* 3. Order aware (respects the order when multiple Files are passed)
|
|
22
|
+
*
|
|
23
|
+
* const filesResult = await mediaFileReader(files, ['image/']);
|
|
24
|
+
* filesResult.forEach(file => editor.dispatchCommand('INSERT_IMAGE', {
|
|
25
|
+
* src: file.result,
|
|
26
|
+
* }));
|
|
27
|
+
*/
|
|
28
|
+
export declare function mediaFileReader(files: Array<File>, acceptableMimeTypes: Array<string>): Promise<Array<{
|
|
29
|
+
file: File;
|
|
30
|
+
result: string;
|
|
31
|
+
}>>;
|
|
16
32
|
export declare function $dfs(startingNode?: LexicalNode, endingNode?: LexicalNode): Array<DFSNode>;
|
|
17
33
|
export declare function $getNearestNodeOfType<T extends ElementNode>(node: LexicalNode, klass: Klass<T>): T | null;
|
|
18
34
|
export declare function $getNearestBlockElementAncestorOrThrow(startNode: LexicalNode): ElementNode;
|
|
@@ -26,4 +42,5 @@ export declare function unstable_convertLegacyJSONEditorState(editor: LexicalEdi
|
|
|
26
42
|
export declare function $restoreEditorState(editor: LexicalEditor, editorState: EditorState): void;
|
|
27
43
|
export declare function $insertNodeToNearestRoot<T extends LexicalNode>(node: T): T;
|
|
28
44
|
export declare function $wrapNodeInElement(node: LexicalNode, createElementNode: () => ElementNode): ElementNode;
|
|
45
|
+
export declare function $splitNode(node: ElementNode, offset: number): [ElementNode | null, ElementNode];
|
|
29
46
|
export {};
|
package/package.json
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
"utils"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.6.
|
|
11
|
+
"version": "0.6.2",
|
|
12
12
|
"main": "LexicalUtils.js",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"lexical": "0.6.
|
|
14
|
+
"lexical": "0.6.2"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@lexical/list": "0.6.
|
|
18
|
-
"@lexical/table": "0.6.
|
|
17
|
+
"@lexical/list": "0.6.2",
|
|
18
|
+
"@lexical/table": "0.6.2"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|