@lexical/utils 0.7.8 → 0.8.0

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.
@@ -6,6 +6,7 @@
6
6
  */
7
7
  'use strict';
8
8
 
9
+ var selection = require('@lexical/selection');
9
10
  var lexical = require('lexical');
10
11
 
11
12
  /** @module @lexical/utils */
@@ -30,9 +31,9 @@ function isMimeType(file, acceptableMimeTypes) {
30
31
  return true;
31
32
  }
32
33
  }
33
-
34
34
  return false;
35
35
  }
36
+
36
37
  /**
37
38
  * Lexical File Reader with:
38
39
  * 1. MIME type support
@@ -44,44 +45,36 @@ function isMimeType(file, acceptableMimeTypes) {
44
45
  * src: file.result,
45
46
  * }));
46
47
  */
47
-
48
48
  function mediaFileReader(files, acceptableMimeTypes) {
49
49
  const filesIterator = files[Symbol.iterator]();
50
50
  return new Promise((resolve, reject) => {
51
51
  const processed = [];
52
-
53
52
  const handleNextFile = () => {
54
53
  const {
55
54
  done,
56
55
  value: file
57
56
  } = filesIterator.next();
58
-
59
57
  if (done) {
60
58
  return resolve(processed);
61
59
  }
62
-
63
60
  const fileReader = new FileReader();
64
61
  fileReader.addEventListener('error', reject);
65
62
  fileReader.addEventListener('load', () => {
66
63
  const result = fileReader.result;
67
-
68
64
  if (typeof result === 'string') {
69
65
  processed.push({
70
66
  file,
71
67
  result
72
68
  });
73
69
  }
74
-
75
70
  handleNextFile();
76
71
  });
77
-
78
72
  if (isMimeType(file, acceptableMimeTypes)) {
79
73
  fileReader.readAsDataURL(file);
80
74
  } else {
81
75
  handleNextFile();
82
76
  }
83
77
  };
84
-
85
78
  handleNextFile();
86
79
  });
87
80
  }
@@ -91,23 +84,19 @@ function $dfs(startingNode, endingNode) {
91
84
  const end = endingNode || (lexical.$isElementNode(start) ? start.getLastDescendant() : start);
92
85
  let node = start;
93
86
  let depth = $getDepth(node);
94
-
95
87
  while (node !== null && !node.is(end)) {
96
88
  nodes.push({
97
89
  depth,
98
90
  node
99
91
  });
100
-
101
92
  if (lexical.$isElementNode(node) && node.getChildrenSize() > 0) {
102
93
  node = node.getFirstChild();
103
94
  depth++;
104
95
  } else {
105
96
  // Find immediate sibling or nearest parent sibling
106
97
  let sibling = null;
107
-
108
98
  while (sibling === null && node !== null) {
109
99
  sibling = node.getNextSibling();
110
-
111
100
  if (sibling === null) {
112
101
  node = node.getParent();
113
102
  depth--;
@@ -117,63 +106,49 @@ function $dfs(startingNode, endingNode) {
117
106
  }
118
107
  }
119
108
  }
120
-
121
109
  if (node !== null && node.is(end)) {
122
110
  nodes.push({
123
111
  depth,
124
112
  node
125
113
  });
126
114
  }
127
-
128
115
  return nodes;
129
116
  }
130
-
131
117
  function $getDepth(node) {
132
118
  let innerNode = node;
133
119
  let depth = 0;
134
-
135
120
  while ((innerNode = innerNode.getParent()) !== null) {
136
121
  depth++;
137
122
  }
138
-
139
123
  return depth;
140
124
  }
141
-
142
125
  function $getNearestNodeOfType(node, klass) {
143
126
  let parent = node;
144
-
145
127
  while (parent != null) {
146
128
  if (parent instanceof klass) {
147
129
  return parent;
148
130
  }
149
-
150
131
  parent = parent.getParent();
151
132
  }
152
-
153
133
  return null;
154
134
  }
155
135
  function $getNearestBlockElementAncestorOrThrow(startNode) {
156
136
  const blockNode = $findMatchingParent(startNode, node => lexical.$isElementNode(node) && !node.isInline());
157
-
158
137
  if (!lexical.$isElementNode(blockNode)) {
159
138
  {
160
139
  throw Error(`Expected node ${startNode.__key} to have closest block element node.`);
161
140
  }
162
141
  }
163
-
164
142
  return blockNode;
165
143
  }
166
144
  function $findMatchingParent(startingNode, findFn) {
167
145
  let curr = startingNode;
168
-
169
146
  while (curr !== lexical.$getRoot() && curr != null) {
170
147
  if (findFn(curr)) {
171
148
  return curr;
172
149
  }
173
-
174
150
  curr = curr.getParent();
175
151
  }
176
-
177
152
  return null;
178
153
  }
179
154
  function mergeRegister(...func) {
@@ -185,27 +160,21 @@ function registerNestedElementResolver(editor, targetNode, cloneNode, handleOver
185
160
  const $isTargetNode = node => {
186
161
  return node instanceof targetNode;
187
162
  };
188
-
189
163
  const $findMatch = node => {
190
164
  // First validate we don't have any children that are of the target,
191
165
  // as we need to handle them first.
192
166
  const children = node.getChildren();
193
-
194
167
  for (let i = 0; i < children.length; i++) {
195
168
  const child = children[i];
196
-
197
169
  if ($isTargetNode(child)) {
198
170
  return null;
199
171
  }
200
172
  }
201
-
202
173
  let parentNode = node;
203
174
  let childNode = node;
204
-
205
175
  while (parentNode !== null) {
206
176
  childNode = parentNode;
207
177
  parentNode = parentNode.getParent();
208
-
209
178
  if ($isTargetNode(parentNode)) {
210
179
  return {
211
180
  child: childNode,
@@ -213,89 +182,78 @@ function registerNestedElementResolver(editor, targetNode, cloneNode, handleOver
213
182
  };
214
183
  }
215
184
  }
216
-
217
185
  return null;
218
186
  };
219
-
220
187
  const elementNodeTransform = node => {
221
188
  const match = $findMatch(node);
222
-
223
189
  if (match !== null) {
224
190
  const {
225
191
  child,
226
192
  parent
227
- } = match; // Simple path, we can move child out and siblings into a new parent.
193
+ } = match;
194
+
195
+ // Simple path, we can move child out and siblings into a new parent.
228
196
 
229
197
  if (child.is(node)) {
230
198
  handleOverlap(parent, node);
231
199
  const nextSiblings = child.getNextSiblings();
232
200
  const nextSiblingsLength = nextSiblings.length;
233
201
  parent.insertAfter(child);
234
-
235
202
  if (nextSiblingsLength !== 0) {
236
203
  const newParent = cloneNode(parent);
237
204
  child.insertAfter(newParent);
238
-
239
205
  for (let i = 0; i < nextSiblingsLength; i++) {
240
206
  newParent.append(nextSiblings[i]);
241
207
  }
242
208
  }
243
-
244
209
  if (!parent.canBeEmpty() && parent.getChildrenSize() === 0) {
245
210
  parent.remove();
246
211
  }
247
212
  }
248
213
  }
249
214
  };
250
-
251
215
  return editor.registerNodeTransform(targetNode, elementNodeTransform);
252
216
  }
253
217
  function $restoreEditorState(editor, editorState) {
254
218
  const FULL_RECONCILE = 2;
255
219
  const nodeMap = new Map();
256
220
  const activeEditorState = editor._pendingEditorState;
257
-
258
221
  for (const [key, node] of editorState._nodeMap) {
259
- // @ts-ignore
260
- nodeMap.set(key, node.constructor.clone(node));
222
+ const clone = selection.$cloneWithProperties(node);
223
+ if (lexical.$isTextNode(clone)) {
224
+ clone.__text = node.__text;
225
+ }
226
+ nodeMap.set(key, clone);
261
227
  }
262
-
263
228
  if (activeEditorState) {
264
229
  activeEditorState._nodeMap = nodeMap;
265
230
  }
266
-
267
231
  editor._dirtyType = FULL_RECONCILE;
268
- const selection = editorState._selection;
269
- lexical.$setSelection(selection === null ? null : selection.clone());
232
+ const selection$1 = editorState._selection;
233
+ lexical.$setSelection(selection$1 === null ? null : selection$1.clone());
270
234
  }
271
235
  function $insertNodeToNearestRoot(node) {
272
236
  const selection = lexical.$getSelection();
273
-
274
237
  if (lexical.$isRangeSelection(selection)) {
275
238
  const {
276
239
  focus
277
240
  } = selection;
278
241
  const focusNode = focus.getNode();
279
242
  const focusOffset = focus.offset;
280
-
281
243
  if (lexical.$isRootOrShadowRoot(focusNode)) {
282
244
  const focusChild = focusNode.getChildAtIndex(focusOffset);
283
-
284
245
  if (focusChild == null) {
285
246
  focusNode.append(node);
286
247
  } else {
287
248
  focusChild.insertBefore(node);
288
249
  }
289
-
290
250
  node.selectNext();
291
251
  } else {
292
252
  let splitNode;
293
253
  let splitOffset;
294
-
295
254
  if (lexical.$isTextNode(focusNode)) {
296
255
  splitNode = focusNode.getParentOrThrow();
297
256
  splitOffset = focusNode.getIndexWithinParent();
298
-
299
257
  if (focusOffset > 0) {
300
258
  splitOffset += 1;
301
259
  focusNode.splitText(focusOffset);
@@ -304,8 +262,7 @@ function $insertNodeToNearestRoot(node) {
304
262
  splitNode = focusNode;
305
263
  splitOffset = focusOffset;
306
264
  }
307
-
308
- const [, rightTree] = $splitNode(splitNode, splitOffset);
265
+ const [, rightTree] = lexical.$splitNode(splitNode, splitOffset);
309
266
  rightTree.insertBefore(node);
310
267
  rightTree.selectStart();
311
268
  }
@@ -317,12 +274,10 @@ function $insertNodeToNearestRoot(node) {
317
274
  const root = lexical.$getRoot();
318
275
  root.append(node);
319
276
  }
320
-
321
277
  const paragraphNode = lexical.$createParagraphNode();
322
278
  node.insertAfter(paragraphNode);
323
279
  paragraphNode.select();
324
280
  }
325
-
326
281
  return node.getLatest();
327
282
  }
328
283
  function $wrapNodeInElement(node, createElementNode) {
@@ -331,46 +286,14 @@ function $wrapNodeInElement(node, createElementNode) {
331
286
  elementNode.append(node);
332
287
  return elementNode;
333
288
  }
334
- function $splitNode(node, offset) {
335
- let startNode = node.getChildAtIndex(offset);
336
-
337
- if (startNode == null) {
338
- startNode = node;
339
- }
340
-
341
- if (!!lexical.$isRootOrShadowRoot(node)) {
342
- throw Error(`Can not call $splitNode() on root element`);
343
- }
344
-
345
- const recurse = currentNode => {
346
- const parent = currentNode.getParentOrThrow();
347
- const isParentRoot = lexical.$isRootOrShadowRoot(parent); // The node we start split from (leaf) is moved, but its recursive
348
- // parents are copied to create separate tree
349
-
350
- const nodeToMove = currentNode === startNode && !isParentRoot ? currentNode : lexical.$copyNode(currentNode);
351
-
352
- if (isParentRoot) {
353
- currentNode.insertAfter(nodeToMove);
354
- return [currentNode, nodeToMove, nodeToMove];
355
- } else {
356
- const [leftTree, rightTree, newParent] = recurse(parent);
357
- const nextSiblings = currentNode.getNextSiblings();
358
- newParent.append(nodeToMove, ...nextSiblings);
359
- return [leftTree, rightTree, nodeToMove];
360
- }
361
- };
362
-
363
- const [leftTree, rightTree] = recurse(startNode);
364
- return [leftTree, rightTree];
365
- }
366
289
 
290
+ exports.$splitNode = lexical.$splitNode;
367
291
  exports.$dfs = $dfs;
368
292
  exports.$findMatchingParent = $findMatchingParent;
369
293
  exports.$getNearestBlockElementAncestorOrThrow = $getNearestBlockElementAncestorOrThrow;
370
294
  exports.$getNearestNodeOfType = $getNearestNodeOfType;
371
295
  exports.$insertNodeToNearestRoot = $insertNodeToNearestRoot;
372
296
  exports.$restoreEditorState = $restoreEditorState;
373
- exports.$splitNode = $splitNode;
374
297
  exports.$wrapNodeInElement = $wrapNodeInElement;
375
298
  exports.addClassNamesToElement = addClassNamesToElement;
376
299
  exports.isMimeType = isMimeType;
@@ -4,13 +4,12 @@
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 h=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 c of b)if(a.type.startsWith(c))return!0;return!1}function r(a,b){for(;a!==h.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent()}return null}
8
- function t(a,b){let c=a.getChildAtIndex(b);null==c&&(c=a);h.$isRootOrShadowRoot(a)&&p(102);let f=g=>{const m=g.getParentOrThrow(),l=h.$isRootOrShadowRoot(m),k=g!==c||l?h.$copyNode(g):g;if(l)return g.insertAfter(k),[g,k,k];const [n,u,v]=f(m);g=g.getNextSiblings();v.append(k,...g);return[n,u,k]},[d,e]=f(c);return[d,e]}
9
- exports.$dfs=function(a,b){let c=[];a=(a||h.$getRoot()).getLatest();b=b||(h.$isElementNode(a)?a.getLastDescendant():a);for(var f=a,d=0;null!==(f=f.getParent());)d++;for(f=d;null!==a&&!a.is(b);)if(c.push({depth:f,node:a}),h.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),f++;else for(d=null;null===d&&null!==a;)d=a.getNextSibling(),null===d?(a=a.getParent(),f--):a=d;null!==a&&a.is(b)&&c.push({depth:f,node:a});return c};exports.$findMatchingParent=r;
10
- exports.$getNearestBlockElementAncestorOrThrow=function(a){a=r(a,b=>h.$isElementNode(b)&&!b.isInline());h.$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};
11
- exports.$insertNodeToNearestRoot=function(a){var b=h.$getSelection();if(h.$isRangeSelection(b)){var {focus:c}=b;b=c.getNode();c=c.offset;if(h.$isRootOrShadowRoot(b))c=b.getChildAtIndex(c),null==c?b.append(a):c.insertBefore(a),a.selectNext();else{let f,d;h.$isTextNode(b)?(f=b.getParentOrThrow(),d=b.getIndexWithinParent(),0<c&&(d+=1,b.splitText(c))):(f=b,d=c);[,b]=t(f,d);b.insertBefore(a);b.selectStart()}}else h.$isNodeSelection(b)||h.DEPRECATED_$isGridSelection(b)?(b=b.getNodes(),b[b.length-1].getTopLevelElementOrThrow().insertAfter(a)):
12
- h.$getRoot().append(a),b=h.$createParagraphNode(),a.insertAfter(b),b.select();return a.getLatest()};exports.$restoreEditorState=function(a,b){let c=new Map,f=a._pendingEditorState;for(let [d,e]of b._nodeMap)c.set(d,e.constructor.clone(e));f&&(f._nodeMap=c);a._dirtyType=2;a=b._selection;h.$setSelection(null===a?null:a.clone())};exports.$splitNode=t;exports.$wrapNodeInElement=function(a,b){b=b();a.replace(b);b.append(a);return b};
13
- exports.addClassNamesToElement=function(a,...b){b.forEach(c=>{"string"===typeof c&&(c=c.split(" ").filter(f=>""!==f),a.classList.add(...c))})};exports.isMimeType=q;
14
- exports.mediaFileReader=function(a,b){let c=a[Symbol.iterator]();return new Promise((f,d)=>{let e=[],g=()=>{const {done:m,value:l}=c.next();if(m)return f(e);const k=new FileReader;k.addEventListener("error",d);k.addEventListener("load",()=>{const n=k.result;"string"===typeof n&&e.push({file:l,result:n});g()});q(l,b)?k.readAsDataURL(l):g()};g()})};exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};
15
- exports.registerNestedElementResolver=function(a,b,c,f){return a.registerNodeTransform(b,d=>{a:{var e=d.getChildren();for(var g=0;g<e.length;g++)if(e[g]instanceof b){e=null;break a}for(e=d;null!==e;)if(g=e,e=e.getParent(),e instanceof b){e={child:g,parent:e};break a}e=null}if(null!==e){const {child:m,parent:l}=e;if(m.is(d)){f(l,d);d=m.getNextSiblings();e=d.length;l.insertAfter(m);if(0!==e){g=c(l);m.insertAfter(g);for(let k=0;k<e;k++)g.append(d[k])}l.canBeEmpty()||0!==l.getChildrenSize()||l.remove()}}})};
7
+ 'use strict';var g=require("@lexical/selection"),n=require("lexical");function p(a,b){for(let c of b)if(a.type.startsWith(c))return!0;return!1}function r(a,b){for(;a!==n.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent()}return null}exports.$splitNode=n.$splitNode;
8
+ exports.$dfs=function(a,b){let c=[];a=(a||n.$getRoot()).getLatest();b=b||(n.$isElementNode(a)?a.getLastDescendant():a);for(var f=a,d=0;null!==(f=f.getParent());)d++;for(f=d;null!==a&&!a.is(b);)if(c.push({depth:f,node:a}),n.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),f++;else for(d=null;null===d&&null!==a;)d=a.getNextSibling(),null===d?(a=a.getParent(),f--):a=d;null!==a&&a.is(b)&&c.push({depth:f,node:a});return c};exports.$findMatchingParent=r;
9
+ exports.$getNearestBlockElementAncestorOrThrow=function(a){a=r(a,b=>n.$isElementNode(b)&&!b.isInline());if(!n.$isElementNode(a))throw Error("Minified Lexical error #4; visit https://lexical.dev/docs/error?code=4 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");return a};exports.$getNearestNodeOfType=function(a,b){for(;null!=a;){if(a instanceof b)return a;a=a.getParent()}return null};
10
+ exports.$insertNodeToNearestRoot=function(a){var b=n.$getSelection();if(n.$isRangeSelection(b)){var {focus:c}=b;b=c.getNode();c=c.offset;if(n.$isRootOrShadowRoot(b))c=b.getChildAtIndex(c),null==c?b.append(a):c.insertBefore(a),a.selectNext();else{let f,d;n.$isTextNode(b)?(f=b.getParentOrThrow(),d=b.getIndexWithinParent(),0<c&&(d+=1,b.splitText(c))):(f=b,d=c);[,b]=n.$splitNode(f,d);b.insertBefore(a);b.selectStart()}}else n.$isNodeSelection(b)||n.DEPRECATED_$isGridSelection(b)?(b=b.getNodes(),b[b.length-
11
+ 1].getTopLevelElementOrThrow().insertAfter(a)):n.$getRoot().append(a),b=n.$createParagraphNode(),a.insertAfter(b),b.select();return a.getLatest()};exports.$restoreEditorState=function(a,b){let c=new Map,f=a._pendingEditorState;for(let [d,e]of b._nodeMap){let h=g.$cloneWithProperties(e);n.$isTextNode(h)&&(h.__text=e.__text);c.set(d,h)}f&&(f._nodeMap=c);a._dirtyType=2;a=b._selection;n.$setSelection(null===a?null:a.clone())};exports.$wrapNodeInElement=function(a,b){b=b();a.replace(b);b.append(a);return b};
12
+ exports.addClassNamesToElement=function(a,...b){b.forEach(c=>{"string"===typeof c&&(c=c.split(" ").filter(f=>""!==f),a.classList.add(...c))})};exports.isMimeType=p;
13
+ exports.mediaFileReader=function(a,b){let c=a[Symbol.iterator]();return new Promise((f,d)=>{let e=[],h=()=>{const {done:m,value:k}=c.next();if(m)return f(e);const l=new FileReader;l.addEventListener("error",d);l.addEventListener("load",()=>{const q=l.result;"string"===typeof q&&e.push({file:k,result:q});h()});p(k,b)?l.readAsDataURL(k):h()};h()})};exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};
14
+ exports.registerNestedElementResolver=function(a,b,c,f){return a.registerNodeTransform(b,d=>{a:{var e=d.getChildren();for(var h=0;h<e.length;h++)if(e[h]instanceof b){e=null;break a}for(e=d;null!==e;)if(h=e,e=e.getParent(),e instanceof b){e={child:h,parent:e};break a}e=null}if(null!==e){const {child:m,parent:k}=e;if(m.is(d)){f(k,d);d=m.getNextSiblings();e=d.length;k.insertAfter(m);if(0!==e){h=c(k);m.insertAfter(h);for(let l=0;l<e;l++)h.append(d[l])}k.canBeEmpty()||0!==k.getChildrenSize()||k.remove()}}})};
16
15
  exports.removeClassNamesFromElement=function(a,...b){b.forEach(c=>{"string"===typeof c&&a.classList.remove(...c.split(" "))})}
package/index.d.ts CHANGED
@@ -6,7 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  *
8
8
  */
9
- import { EditorState, ElementNode, Klass, LexicalEditor, LexicalNode } from 'lexical';
9
+ import { $splitNode, EditorState, ElementNode, Klass, LexicalEditor, LexicalNode } from 'lexical';
10
+ export { $splitNode };
10
11
  export declare type DFSNode = Readonly<{
11
12
  depth: number;
12
13
  node: LexicalNode;
@@ -41,5 +42,3 @@ export declare function registerNestedElementResolver<N extends ElementNode>(edi
41
42
  export declare function $restoreEditorState(editor: LexicalEditor, editorState: EditorState): void;
42
43
  export declare function $insertNodeToNearestRoot<T extends LexicalNode>(node: T): T;
43
44
  export declare function $wrapNodeInElement(node: LexicalNode, createElementNode: () => ElementNode): ElementNode;
44
- export declare function $splitNode(node: ElementNode, offset: number): [ElementNode | null, ElementNode];
45
- export {};
package/package.json CHANGED
@@ -8,14 +8,15 @@
8
8
  "utils"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.7.8",
11
+ "version": "0.8.0",
12
12
  "main": "LexicalUtils.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.7.8"
14
+ "lexical": "0.8.0"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/list": "0.7.8",
18
- "@lexical/table": "0.7.8"
17
+ "@lexical/list": "0.8.0",
18
+ "@lexical/table": "0.8.0",
19
+ "@lexical/selection": "0.8.0"
19
20
  },
20
21
  "repository": {
21
22
  "type": "git",