@lexical/utils 0.7.7 → 0.7.9

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,84 +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
- const nodeMap = new Map(editorState._nodeMap);
219
+ const nodeMap = new Map();
256
220
  const activeEditorState = editor._pendingEditorState;
257
-
221
+ for (const [key, node] of editorState._nodeMap) {
222
+ const clone = selection.$cloneWithProperties(node);
223
+ if (lexical.$isTextNode(clone)) {
224
+ clone.__text = node.__text;
225
+ }
226
+ nodeMap.set(key, clone);
227
+ }
258
228
  if (activeEditorState) {
259
229
  activeEditorState._nodeMap = nodeMap;
260
230
  }
261
-
262
231
  editor._dirtyType = FULL_RECONCILE;
263
- const selection = editorState._selection;
264
- lexical.$setSelection(selection === null ? null : selection.clone());
232
+ const selection$1 = editorState._selection;
233
+ lexical.$setSelection(selection$1 === null ? null : selection$1.clone());
265
234
  }
266
235
  function $insertNodeToNearestRoot(node) {
267
236
  const selection = lexical.$getSelection();
268
-
269
237
  if (lexical.$isRangeSelection(selection)) {
270
238
  const {
271
239
  focus
272
240
  } = selection;
273
241
  const focusNode = focus.getNode();
274
242
  const focusOffset = focus.offset;
275
-
276
243
  if (lexical.$isRootOrShadowRoot(focusNode)) {
277
244
  const focusChild = focusNode.getChildAtIndex(focusOffset);
278
-
279
245
  if (focusChild == null) {
280
246
  focusNode.append(node);
281
247
  } else {
282
248
  focusChild.insertBefore(node);
283
249
  }
284
-
285
250
  node.selectNext();
286
251
  } else {
287
252
  let splitNode;
288
253
  let splitOffset;
289
-
290
254
  if (lexical.$isTextNode(focusNode)) {
291
255
  splitNode = focusNode.getParentOrThrow();
292
256
  splitOffset = focusNode.getIndexWithinParent();
293
-
294
257
  if (focusOffset > 0) {
295
258
  splitOffset += 1;
296
259
  focusNode.splitText(focusOffset);
@@ -299,8 +262,7 @@ function $insertNodeToNearestRoot(node) {
299
262
  splitNode = focusNode;
300
263
  splitOffset = focusOffset;
301
264
  }
302
-
303
- const [, rightTree] = $splitNode(splitNode, splitOffset);
265
+ const [, rightTree] = lexical.$splitNode(splitNode, splitOffset);
304
266
  rightTree.insertBefore(node);
305
267
  rightTree.selectStart();
306
268
  }
@@ -312,12 +274,10 @@ function $insertNodeToNearestRoot(node) {
312
274
  const root = lexical.$getRoot();
313
275
  root.append(node);
314
276
  }
315
-
316
277
  const paragraphNode = lexical.$createParagraphNode();
317
278
  node.insertAfter(paragraphNode);
318
279
  paragraphNode.select();
319
280
  }
320
-
321
281
  return node.getLatest();
322
282
  }
323
283
  function $wrapNodeInElement(node, createElementNode) {
@@ -326,46 +286,14 @@ function $wrapNodeInElement(node, createElementNode) {
326
286
  elementNode.append(node);
327
287
  return elementNode;
328
288
  }
329
- function $splitNode(node, offset) {
330
- let startNode = node.getChildAtIndex(offset);
331
-
332
- if (startNode == null) {
333
- startNode = node;
334
- }
335
-
336
- if (!!lexical.$isRootOrShadowRoot(node)) {
337
- throw Error(`Can not call $splitNode() on root element`);
338
- }
339
-
340
- const recurse = currentNode => {
341
- const parent = currentNode.getParentOrThrow();
342
- const isParentRoot = lexical.$isRootOrShadowRoot(parent); // The node we start split from (leaf) is moved, but its recursive
343
- // parents are copied to create separate tree
344
-
345
- const nodeToMove = currentNode === startNode && !isParentRoot ? currentNode : lexical.$copyNode(currentNode);
346
-
347
- if (isParentRoot) {
348
- currentNode.insertAfter(nodeToMove);
349
- return [currentNode, nodeToMove, nodeToMove];
350
- } else {
351
- const [leftTree, rightTree, newParent] = recurse(parent);
352
- const nextSiblings = currentNode.getNextSiblings();
353
- newParent.append(nodeToMove, ...nextSiblings);
354
- return [leftTree, rightTree, nodeToMove];
355
- }
356
- };
357
-
358
- const [leftTree, rightTree] = recurse(startNode);
359
- return [leftTree, rightTree];
360
- }
361
289
 
290
+ exports.$splitNode = lexical.$splitNode;
362
291
  exports.$dfs = $dfs;
363
292
  exports.$findMatchingParent = $findMatchingParent;
364
293
  exports.$getNearestBlockElementAncestorOrThrow = $getNearestBlockElementAncestorOrThrow;
365
294
  exports.$getNearestNodeOfType = $getNearestNodeOfType;
366
295
  exports.$insertNodeToNearestRoot = $insertNodeToNearestRoot;
367
296
  exports.$restoreEditorState = $restoreEditorState;
368
- exports.$splitNode = $splitNode;
369
297
  exports.$wrapNodeInElement = $wrapNodeInElement;
370
298
  exports.addClassNamesToElement = addClassNamesToElement;
371
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 e=f=>{const m=f.getParentOrThrow(),l=h.$isRootOrShadowRoot(m),k=f!==c||l?h.$copyNode(f):f;if(l)return f.insertAfter(k),[f,k,k];const [n,u,v]=e(m);f=f.getNextSiblings();v.append(k,...f);return[n,u,k]},[d,g]=e(c);return[d,g]}
9
- exports.$dfs=function(a,b){let c=[];a=(a||h.$getRoot()).getLatest();b=b||(h.$isElementNode(a)?a.getLastDescendant():a);for(var e=a,d=0;null!==(e=e.getParent());)d++;for(e=d;null!==a&&!a.is(b);)if(c.push({depth:e,node:a}),h.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),e++;else for(d=null;null===d&&null!==a;)d=a.getNextSibling(),null===d?(a=a.getParent(),e--):a=d;null!==a&&a.is(b)&&c.push({depth:e,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 e,d;h.$isTextNode(b)?(e=b.getParentOrThrow(),d=b.getIndexWithinParent(),0<c&&(d+=1,b.splitText(c))):(e=b,d=c);[,b]=t(e,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(b._nodeMap),e=a._pendingEditorState;e&&(e._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(e=>""!==e),a.classList.add(...c))})};exports.isMimeType=q;
14
- exports.mediaFileReader=function(a,b){let c=a[Symbol.iterator]();return new Promise((e,d)=>{let g=[],f=()=>{const {done:m,value:l}=c.next();if(m)return e(g);const k=new FileReader;k.addEventListener("error",d);k.addEventListener("load",()=>{const n=k.result;"string"===typeof n&&g.push({file:l,result:n});f()});q(l,b)?k.readAsDataURL(l):f()};f()})};exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};
15
- exports.registerNestedElementResolver=function(a,b,c,e){return a.registerNodeTransform(b,d=>{a:{var g=d.getChildren();for(var f=0;f<g.length;f++)if(g[f]instanceof b){g=null;break a}for(g=d;null!==g;)if(f=g,g=g.getParent(),g instanceof b){g={child:f,parent:g};break a}g=null}if(null!==g){const {child:m,parent:l}=g;if(m.is(d)){e(l,d);d=m.getNextSiblings();g=d.length;l.insertAfter(m);if(0!==g){f=c(l);m.insertAfter(f);for(let k=0;k<g;k++)f.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.7",
11
+ "version": "0.7.9",
12
12
  "main": "LexicalUtils.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.7.7"
14
+ "lexical": "0.7.9"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/list": "0.7.7",
18
- "@lexical/table": "0.7.7"
17
+ "@lexical/list": "0.7.9",
18
+ "@lexical/table": "0.7.9",
19
+ "@lexical/selection": "0.7.9"
19
20
  },
20
21
  "repository": {
21
22
  "type": "git",