@lexical/utils 0.2.8 → 0.3.1

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.d.ts CHANGED
@@ -5,13 +5,21 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
+
8
9
  import {Class} from 'utility-types';
9
10
 
10
- import type {LexicalNode, ElementNode, LexicalEditor} from 'lexical';
11
+ import type {
12
+ EditorState,
13
+ LexicalNode,
14
+ ElementNode,
15
+ LexicalEditor,
16
+ } from 'lexical';
17
+
11
18
  export type DFSNode = Readonly<{
12
19
  depth: number;
13
20
  node: LexicalNode;
14
21
  }>;
22
+
15
23
  declare function addClassNamesToElement(
16
24
  element: HTMLElement,
17
25
  ...classNames: Array<typeof undefined | boolean | null | string>
@@ -29,7 +37,9 @@ declare function $getNearestNodeOfType<T extends LexicalNode>(
29
37
  node: LexicalNode,
30
38
  klass: Class<T>,
31
39
  ): T | null;
40
+
32
41
  export type DOMNodeToLexicalConversion = (element: Node) => LexicalNode;
42
+
33
43
  export type DOMNodeToLexicalConversionMap = Record<
34
44
  string,
35
45
  DOMNodeToLexicalConversion
@@ -43,10 +53,19 @@ declare function mergeRegister(...func: Array<Func>): () => void;
43
53
  declare function $getNearestBlockElementAncestorOrThrow(
44
54
  startNode: LexicalNode,
45
55
  ): ElementNode;
46
-
47
56
  declare function registerNestedElementResolver<N>(
48
57
  editor: LexicalEditor,
49
58
  targetNode: Class<N>,
50
59
  cloneNode: (from: N) => N,
51
60
  handleOverlap: (from: N, to: N) => void,
52
61
  ): () => void;
62
+
63
+ export declare function unstable_convertLegacyJSONEditorState(
64
+ editor: LexicalEditor,
65
+ maybeStringifiedEditorState: string,
66
+ ): EditorState;
67
+
68
+ export declare function $restoreEditorState(
69
+ editor: LexicalEditor,
70
+ editorState: EditorState,
71
+ ): void;
@@ -14,7 +14,6 @@ var lexical = require('lexical');
14
14
  * This source code is licensed under the MIT license found in the
15
15
  * LICENSE file in the root directory of this source tree.
16
16
  *
17
- *
18
17
  */
19
18
  function addClassNamesToElement(element, ...classNames) {
20
19
  classNames.forEach(className => {
@@ -194,13 +193,138 @@ function registerNestedElementResolver(editor, targetNode, cloneNode, handleOver
194
193
  };
195
194
 
196
195
  return editor.registerNodeTransform(targetNode, elementNodeTransform);
196
+ } // eslint-disable-next-line @typescript-eslint/no-explicit-any
197
+
198
+ function unstable_internalCreateNodeFromParse(parsedNode, parsedNodeMap, editor, parentKey, activeEditorState) {
199
+ const nodeType = parsedNode.__type;
200
+
201
+ const registeredNode = editor._nodes.get(nodeType);
202
+
203
+ if (registeredNode === undefined) {
204
+ {
205
+ throw Error(`createNodeFromParse: type "${nodeType}" + not found`);
206
+ }
207
+ } // Check for properties that are editors
208
+
209
+
210
+ for (const property in parsedNode) {
211
+ const value = parsedNode[property];
212
+
213
+ if (value != null && typeof value === 'object') {
214
+ const parsedEditorState = value.editorState;
215
+
216
+ if (parsedEditorState != null) {
217
+ const nestedEditor = lexical.createEditor();
218
+ nestedEditor._nodes = editor._nodes;
219
+ nestedEditor._parentEditor = editor._parentEditor;
220
+ nestedEditor._pendingEditorState = unstable_convertLegacyJSONEditorState(nestedEditor, parsedEditorState);
221
+ parsedNode[property] = nestedEditor;
222
+ }
223
+ }
224
+ }
225
+
226
+ const NodeKlass = registeredNode.klass;
227
+ const parsedKey = parsedNode.__key; // We set the parsedKey to undefined before calling clone() so that
228
+ // we get a new random key assigned.
229
+
230
+ parsedNode.__key = undefined; // @ts-expect-error TODO Replace Class utility type with InstanceType
231
+
232
+ const node = NodeKlass.clone(parsedNode);
233
+ parsedNode.__key = parsedKey;
234
+ const key = node.__key;
235
+
236
+ activeEditorState._nodeMap.set(key, node);
237
+
238
+ node.__parent = parentKey; // We will need to recursively handle the children in the case
239
+ // of a ElementNode.
240
+
241
+ if (lexical.$isElementNode(node)) {
242
+ const children = parsedNode.__children;
243
+
244
+ for (let i = 0; i < children.length; i++) {
245
+ const childKey = children[i];
246
+ const parsedChild = parsedNodeMap.get(childKey);
247
+
248
+ if (parsedChild !== undefined) {
249
+ const child = unstable_internalCreateNodeFromParse(parsedChild, parsedNodeMap, editor, key, activeEditorState);
250
+ const newChildKey = child.__key;
251
+
252
+ node.__children.push(newChildKey);
253
+ }
254
+ }
255
+
256
+ node.__indent = parsedNode.__indent;
257
+ node.__format = parsedNode.__format;
258
+ node.__dir = parsedNode.__dir;
259
+ } else if (lexical.$isTextNode(node)) {
260
+ node.__format = parsedNode.__format;
261
+ node.__style = parsedNode.__style;
262
+ node.__mode = parsedNode.__mode;
263
+ node.__detail = parsedNode.__detail;
264
+ }
265
+
266
+ return node;
267
+ }
268
+
269
+ function unstable_parseEditorState(parsedEditorState, editor) {
270
+ // This is hacky, do not do this!
271
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
272
+ const EditorStateClass = editor._editorState.constructor;
273
+ const nodeMap = new Map();
274
+ const editorState = new EditorStateClass(nodeMap);
275
+ const parsedNodeMap = new Map(parsedEditorState._nodeMap); // root always exists in Map
276
+
277
+ const parsedRoot = parsedNodeMap.get('root');
278
+ const isUpdating = editor._updating;
279
+
280
+ try {
281
+ editor._updating = false;
282
+ editor.update(() => {
283
+ const dirtyElements = editor._dirtyElements;
284
+ const dirtyLeaves = editor._dirtyLeaves;
285
+ const dirtyType = editor._dirtyType;
286
+ editor._dirtyElements = new Map();
287
+ editor._dirtyLeaves = new Set();
288
+ editor._dirtyType = 0;
289
+
290
+ try {
291
+ unstable_internalCreateNodeFromParse(parsedRoot, parsedNodeMap, editor, null, editorState);
292
+ } finally {
293
+ editor._dirtyElements = dirtyElements;
294
+ editor._dirtyLeaves = dirtyLeaves;
295
+ editor._dirtyType = dirtyType;
296
+ }
297
+ });
298
+ } finally {
299
+ editor._updating = isUpdating;
300
+ }
301
+
302
+ editorState._readOnly = true;
303
+ return editorState;
304
+ } // TODO: remove this function in version 0.4
305
+
306
+
307
+ function unstable_convertLegacyJSONEditorState(editor, maybeStringifiedEditorState) {
308
+ const parsedEditorState = typeof maybeStringifiedEditorState === 'string' ? JSON.parse(maybeStringifiedEditorState) : maybeStringifiedEditorState;
309
+ return unstable_parseEditorState(parsedEditorState, editor);
310
+ }
311
+ function $restoreEditorState(editor, editorState) {
312
+ const FULL_RECONCILE = 2;
313
+ const nodeMap = new Map(editorState._nodeMap);
314
+ const activeEditorState = editor._pendingEditorState;
315
+ activeEditorState._nodeMap = nodeMap;
316
+ editor._dirtyType = FULL_RECONCILE;
317
+ const selection = editorState._selection;
318
+ lexical.$setSelection(selection === null ? null : selection.clone());
197
319
  }
198
320
 
199
321
  exports.$dfs = $dfs;
200
322
  exports.$findMatchingParent = $findMatchingParent;
201
323
  exports.$getNearestBlockElementAncestorOrThrow = $getNearestBlockElementAncestorOrThrow;
202
324
  exports.$getNearestNodeOfType = $getNearestNodeOfType;
325
+ exports.$restoreEditorState = $restoreEditorState;
203
326
  exports.addClassNamesToElement = addClassNamesToElement;
204
327
  exports.mergeRegister = mergeRegister;
205
328
  exports.registerNestedElementResolver = registerNestedElementResolver;
206
329
  exports.removeClassNamesFromElement = removeClassNamesFromElement;
330
+ exports.unstable_convertLegacyJSONEditorState = unstable_convertLegacyJSONEditorState;
@@ -6,7 +6,12 @@
6
6
  *
7
7
  * @flow strict
8
8
  */
9
- import type {LexicalEditor, LexicalNode, ElementNode} from 'lexical';
9
+ import type {
10
+ EditorState,
11
+ LexicalEditor,
12
+ LexicalNode,
13
+ ElementNode,
14
+ } from 'lexical';
10
15
  export type DFSNode = $ReadOnly<{
11
16
  depth: number,
12
17
  node: LexicalNode,
@@ -48,3 +53,13 @@ declare export function registerNestedElementResolver<N: ElementNode>(
48
53
  cloneNode: (from: N) => N,
49
54
  handleOverlap: (from: N, to: N) => void,
50
55
  ): () => void;
56
+
57
+ declare export function unstable_convertLegacyJSONEditorState(
58
+ editor: LexicalEditor,
59
+ maybeStringifiedEditorState: string,
60
+ ): EditorState;
61
+
62
+ declare export function $restoreEditorState(
63
+ editor: LexicalEditor,
64
+ editorState: EditorState,
65
+ ): void;
@@ -4,9 +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
- var h=require("lexical");function n(a,b){for(;a!==h.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent()}return null}
8
- exports.$dfs=function(a,b){const e=[];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(e.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)&&e.push({depth:f,node:a});return e};exports.$findMatchingParent=n;
9
- exports.$getNearestBlockElementAncestorOrThrow=function(a){a=n(a,b=>h.$isElementNode(b)&&!b.isInline());if(!h.$isElementNode(a))throw Error("Minified Lexical error #3; see codes.json 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&&!(a instanceof b);)a=a.getParent();return a};exports.addClassNamesToElement=function(a,...b){b.forEach(e=>{"string"===typeof e&&a.classList.add(...e.split(" "))})};
10
- exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};
11
- exports.registerNestedElementResolver=function(a,b,e,f){return a.registerNodeTransform(b,d=>{a:{var c=d.getChildren();for(var g=0;g<c.length;g++)if(c[g]instanceof b){c=null;break a}for(c=d;null!==c;)if(g=c,c=c.getParent(),c instanceof b){c={child:g,parent:c};break a}c=null}if(null!==c){const {child:l,parent:k}=c;if(l.is(d)){f(k,d);d=l.getNextSiblings();c=d.length;k.insertAfter(l);if(0!==c){g=e(k);l.insertAfter(g);for(let m=0;m<c;m++)g.append(d[m])}k.canBeEmpty()||0!==k.getChildrenSize()||k.remove()}}})};
12
- exports.removeClassNamesFromElement=function(a,...b){b.forEach(e=>{"string"===typeof e&&a.classList.remove(...e.split(" "))})};
7
+ 'use strict';var l=require("lexical");function n(a){throw Error(`Minified Lexical error #${a}; see codes.json for the full message or `+"use the non-minified dev environment for full errors and additional helpful warnings.");}function p(a,b){for(;a!==l.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent()}return null}
8
+ function q(a,b,e,h,f){var c=a.__type,d=e._nodes.get(c);void 0===d&&n(5,c);for(var k in a)if(c=a[k],null!=c&&"object"===typeof c&&(c=c.editorState,null!=c)){var g=l.createEditor();g._nodes=e._nodes;g._parentEditor=e._parentEditor;g._pendingEditorState=r(g,c);a[k]=g}d=d.klass;k=a.__key;a.__key=void 0;d=d.clone(a);a.__key=k;k=d.__key;f._nodeMap.set(k,d);d.__parent=h;if(l.$isElementNode(d)){h=a.__children;for(c=0;c<h.length;c++)g=b.get(h[c]),void 0!==g&&(g=q(g,b,e,k,f).__key,d.__children.push(g));d.__indent=
9
+ a.__indent;d.__format=a.__format;d.__dir=a.__dir}else l.$isTextNode(d)&&(d.__format=a.__format,d.__style=a.__style,d.__mode=a.__mode,d.__detail=a.__detail);return d}
10
+ function t(a,b){let e=b._editorState.constructor,h=new Map,f=new e(h),c=new Map(a._nodeMap),d=c.get("root");a=b._updating;try{b._updating=!1,b.update(()=>{let k=b._dirtyElements,g=b._dirtyLeaves,m=b._dirtyType;b._dirtyElements=new Map;b._dirtyLeaves=new Set;b._dirtyType=0;try{q(d,c,b,null,f)}finally{b._dirtyElements=k,b._dirtyLeaves=g,b._dirtyType=m}})}finally{b._updating=a}f._readOnly=!0;return f}function r(a,b){b="string"===typeof b?JSON.parse(b):b;return t(b,a)}
11
+ exports.$dfs=function(a,b){let e=[];a=(a||l.$getRoot()).getLatest();b=b||(l.$isElementNode(a)?a.getLastDescendant():a);for(var h=a,f=0;null!==(h=h.getParent());)f++;for(h=f;null!==a&&!a.is(b);)if(e.push({depth:h,node:a}),l.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),h++;else for(f=null;null===f&&null!==a;)f=a.getNextSibling(),null===f?(a=a.getParent(),h--):a=f;null!==a&&a.is(b)&&e.push({depth:h,node:a});return e};exports.$findMatchingParent=p;
12
+ exports.$getNearestBlockElementAncestorOrThrow=function(a){let b=p(a,e=>l.$isElementNode(e)&&!e.isInline());l.$isElementNode(b)||n(4,a.__key);return b};exports.$getNearestNodeOfType=function(a,b){for(;null!=a&&!(a instanceof b);)a=a.getParent();return a};exports.$restoreEditorState=function(a,b){let e=new Map(b._nodeMap);a._pendingEditorState._nodeMap=e;a._dirtyType=2;a=b._selection;l.$setSelection(null===a?null:a.clone())};
13
+ exports.addClassNamesToElement=function(a,...b){b.forEach(e=>{"string"===typeof e&&a.classList.add(...e.split(" "))})};exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};
14
+ exports.registerNestedElementResolver=function(a,b,e,h){return a.registerNodeTransform(b,f=>{a:{var c=f.getChildren();for(var d=0;d<c.length;d++)if(c[d]instanceof b){c=null;break a}for(c=f;null!==c;)if(d=c,c=c.getParent(),c instanceof b){c={child:d,parent:c};break a}c=null}if(null!==c){const {child:k,parent:g}=c;if(k.is(f)){h(g,f);f=k.getNextSiblings();c=f.length;g.insertAfter(k);if(0!==c){d=e(g);k.insertAfter(d);for(let m=0;m<c;m++)d.append(f[m])}g.canBeEmpty()||0!==g.getChildrenSize()||g.remove()}}})};
15
+ exports.removeClassNamesFromElement=function(a,...b){b.forEach(e=>{"string"===typeof e&&a.classList.remove(...e.split(" "))})};exports.unstable_convertLegacyJSONEditorState=r
package/package.json CHANGED
@@ -8,14 +8,14 @@
8
8
  "utils"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.2.8",
11
+ "version": "0.3.1",
12
12
  "main": "LexicalUtils.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.2.8"
14
+ "lexical": "0.3.1"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/list": "0.2.8",
18
- "@lexical/table": "0.2.8"
17
+ "@lexical/list": "0.3.1",
18
+ "@lexical/table": "0.3.1"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",