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