@lexical/utils 0.2.5 → 0.2.8

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,8 +5,10 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  */
8
- import type {LexicalNode, ElementNode} from 'lexical';
9
- export type DFSNode = $ReadOnly<{
8
+ import {Class} from 'utility-types';
9
+
10
+ import type {LexicalNode, ElementNode, LexicalEditor} from 'lexical';
11
+ export type DFSNode = Readonly<{
10
12
  depth: number;
11
13
  node: LexicalNode;
12
14
  }>;
@@ -16,7 +18,7 @@ declare function addClassNamesToElement(
16
18
  ): void;
17
19
  declare function removeClassNamesFromElement(
18
20
  element: HTMLElement,
19
- ...classNames: Array<string>
21
+ ...classNames: Array<typeof undefined | boolean | null | string>
20
22
  ): void;
21
23
  declare function $dfs(
22
24
  startingNode?: LexicalNode,
@@ -28,15 +30,23 @@ declare function $getNearestNodeOfType<T extends LexicalNode>(
28
30
  klass: Class<T>,
29
31
  ): T | null;
30
32
  export type DOMNodeToLexicalConversion = (element: Node) => LexicalNode;
31
- export type DOMNodeToLexicalConversionMap = {
32
- [string]: DOMNodeToLexicalConversion;
33
- };
33
+ export type DOMNodeToLexicalConversionMap = Record<
34
+ string,
35
+ DOMNodeToLexicalConversion
36
+ >;
34
37
  declare function $findMatchingParent(
35
38
  startingNode: LexicalNode,
36
- findFn: (LexicalNode) => boolean,
39
+ findFn: (node: LexicalNode) => boolean,
37
40
  ): LexicalNode | null;
38
41
  type Func = () => void;
39
42
  declare function mergeRegister(...func: Array<Func>): () => void;
40
43
  declare function $getNearestBlockElementAncestorOrThrow(
41
44
  startNode: LexicalNode,
42
45
  ): ElementNode;
46
+
47
+ declare function registerNestedElementResolver<N>(
48
+ editor: LexicalEditor,
49
+ targetNode: Class<N>,
50
+ cloneNode: (from: N) => N,
51
+ handleOverlap: (from: N, to: N) => void,
52
+ ): () => void;
@@ -18,14 +18,16 @@ var lexical = require('lexical');
18
18
  */
19
19
  function addClassNamesToElement(element, ...classNames) {
20
20
  classNames.forEach(className => {
21
- if (className != null && typeof className === 'string') {
21
+ if (typeof className === 'string') {
22
22
  element.classList.add(...className.split(' '));
23
23
  }
24
24
  });
25
25
  }
26
26
  function removeClassNamesFromElement(element, ...classNames) {
27
27
  classNames.forEach(className => {
28
- element.classList.remove(...className.split(' '));
28
+ if (typeof className === 'string') {
29
+ element.classList.remove(...className.split(' '));
30
+ }
29
31
  });
30
32
  }
31
33
  function $dfs(startingNode, endingNode) {
@@ -124,6 +126,75 @@ function mergeRegister(...func) {
124
126
  func.forEach(f => f());
125
127
  };
126
128
  }
129
+ function registerNestedElementResolver(editor, targetNode, cloneNode, handleOverlap) {
130
+ const $isTargetNode = node => {
131
+ return node instanceof targetNode;
132
+ };
133
+
134
+ const $findMatch = node => {
135
+ // First validate we don't have any children that are of the target,
136
+ // as we need to handle them first.
137
+ const children = node.getChildren();
138
+
139
+ for (let i = 0; i < children.length; i++) {
140
+ const child = children[i];
141
+
142
+ if ($isTargetNode(child)) {
143
+ return null;
144
+ }
145
+ }
146
+
147
+ let parentNode = node;
148
+ let childNode = node;
149
+
150
+ while (parentNode !== null) {
151
+ childNode = parentNode;
152
+ parentNode = parentNode.getParent();
153
+
154
+ if ($isTargetNode(parentNode)) {
155
+ return {
156
+ child: childNode,
157
+ parent: parentNode
158
+ };
159
+ }
160
+ }
161
+
162
+ return null;
163
+ };
164
+
165
+ const elementNodeTransform = node => {
166
+ const match = $findMatch(node);
167
+
168
+ if (match !== null) {
169
+ const {
170
+ child,
171
+ parent
172
+ } = match; // Simple path, we can move child out and siblings into a new parent.
173
+
174
+ if (child.is(node)) {
175
+ handleOverlap(parent, node);
176
+ const nextSiblings = child.getNextSiblings();
177
+ const nextSiblingsLength = nextSiblings.length;
178
+ parent.insertAfter(child);
179
+
180
+ if (nextSiblingsLength !== 0) {
181
+ const newParent = cloneNode(parent);
182
+ child.insertAfter(newParent);
183
+
184
+ for (let i = 0; i < nextSiblingsLength; i++) {
185
+ newParent.append(nextSiblings[i]);
186
+ }
187
+ }
188
+
189
+ if (!parent.canBeEmpty() && parent.getChildrenSize() === 0) {
190
+ parent.remove();
191
+ }
192
+ }
193
+ }
194
+ };
195
+
196
+ return editor.registerNodeTransform(targetNode, elementNodeTransform);
197
+ }
127
198
 
128
199
  exports.$dfs = $dfs;
129
200
  exports.$findMatchingParent = $findMatchingParent;
@@ -131,4 +202,5 @@ exports.$getNearestBlockElementAncestorOrThrow = $getNearestBlockElementAncestor
131
202
  exports.$getNearestNodeOfType = $getNearestNodeOfType;
132
203
  exports.addClassNamesToElement = addClassNamesToElement;
133
204
  exports.mergeRegister = mergeRegister;
205
+ exports.registerNestedElementResolver = registerNestedElementResolver;
134
206
  exports.removeClassNamesFromElement = removeClassNamesFromElement;
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @flow strict
8
8
  */
9
- import type {LexicalNode, ElementNode} from 'lexical';
9
+ import type {LexicalEditor, LexicalNode, ElementNode} from 'lexical';
10
10
  export type DFSNode = $ReadOnly<{
11
11
  depth: number,
12
12
  node: LexicalNode,
@@ -17,7 +17,7 @@ declare export function addClassNamesToElement(
17
17
  ): void;
18
18
  declare export function removeClassNamesFromElement(
19
19
  element: HTMLElement,
20
- ...classNames: Array<string>
20
+ ...classNames: Array<typeof undefined | boolean | null | string>
21
21
  ): void;
22
22
  declare export function $dfs(
23
23
  startingNode?: LexicalNode,
@@ -41,3 +41,10 @@ declare export function mergeRegister(...func: Array<Func>): () => void;
41
41
  declare export function $getNearestBlockElementAncestorOrThrow(
42
42
  startNode: LexicalNode,
43
43
  ): ElementNode;
44
+
45
+ declare export function registerNestedElementResolver<N: ElementNode>(
46
+ editor: LexicalEditor,
47
+ targetNode: Class<N>,
48
+ cloneNode: (from: N) => N,
49
+ handleOverlap: (from: N, to: N) => void,
50
+ ): () => void;
@@ -4,7 +4,9 @@
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 f=require("lexical");function g(a,b){for(;a!==f.$getRoot()&&null!=a;){if(b(a))return a;a=a.getParent()}return null}
8
- exports.$dfs=function(a,b){const c=[];a=(a||f.$getRoot()).getLatest();b=b||(f.$isElementNode(a)?a.getLastDescendant():a);for(var d=a,e=0;null!==(d=d.getParent());)e++;for(d=e;null!==a&&!a.is(b);)if(c.push({depth:d,node:a}),f.$isElementNode(a)&&0<a.getChildrenSize())a=a.getFirstChild(),d++;else for(e=null;null===e&&null!==a;)e=a.getNextSibling(),null===e?(a=a.getParent(),d--):a=e;null!==a&&a.is(b)&&c.push({depth:d,node:a});return c};exports.$findMatchingParent=g;
9
- exports.$getNearestBlockElementAncestorOrThrow=function(a){const b=g(a,c=>f.$isElementNode(c)&&!c.isInline());if(!f.$isElementNode(b))throw Error(`Expected node ${a.__key} to have closest block element node.`);return b};exports.$getNearestNodeOfType=function(a,b){for(;null!=a&&!(a instanceof b);)a=a.getParent();return a};exports.addClassNamesToElement=function(a,...b){b.forEach(c=>{null!=c&&"string"===typeof c&&a.classList.add(...c.split(" "))})};
10
- exports.mergeRegister=function(...a){return()=>{a.forEach(b=>b())}};exports.removeClassNamesFromElement=function(a,...b){b.forEach(c=>{a.classList.remove(...c.split(" "))})};
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(" "))})};
package/package.json CHANGED
@@ -8,14 +8,14 @@
8
8
  "utils"
9
9
  ],
10
10
  "license": "MIT",
11
- "version": "0.2.5",
11
+ "version": "0.2.8",
12
12
  "main": "LexicalUtils.js",
13
13
  "peerDependencies": {
14
- "lexical": "0.2.5"
14
+ "lexical": "0.2.8"
15
15
  },
16
16
  "dependencies": {
17
- "@lexical/list": "0.2.5",
18
- "@lexical/table": "0.2.5"
17
+ "@lexical/list": "0.2.8",
18
+ "@lexical/table": "0.2.8"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",