@lexical/devtools-core 0.14.4 → 0.15.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/LexicalDevtoolsCore.dev.js +42 -20
- package/LexicalDevtoolsCore.dev.mjs +18 -9
- package/LexicalDevtoolsCore.js +2 -0
- package/LexicalDevtoolsCore.js.flow +29 -0
- package/LexicalDevtoolsCore.mjs +2 -0
- package/LexicalDevtoolsCore.node.mjs +2 -0
- package/LexicalDevtoolsCore.prod.js +21 -19
- package/LexicalDevtoolsCore.prod.mjs +3 -1
- package/generateContent.d.ts +1 -1
- package/package.json +7 -7
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
8
|
+
|
|
7
9
|
'use strict';
|
|
8
10
|
|
|
9
11
|
var html = require('@lexical/html');
|
|
@@ -13,6 +15,19 @@ var table = require('@lexical/table');
|
|
|
13
15
|
var lexical = require('lexical');
|
|
14
16
|
var React = require('react');
|
|
15
17
|
|
|
18
|
+
function _interopNamespaceDefault(e) {
|
|
19
|
+
var n = Object.create(null);
|
|
20
|
+
if (e) {
|
|
21
|
+
for (var k in e) {
|
|
22
|
+
n[k] = e[k];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return n;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
30
|
+
|
|
16
31
|
/**
|
|
17
32
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
18
33
|
*
|
|
@@ -20,6 +35,7 @@ var React = require('react');
|
|
|
20
35
|
* LICENSE file in the root directory of this source tree.
|
|
21
36
|
*
|
|
22
37
|
*/
|
|
38
|
+
|
|
23
39
|
const NON_SINGLE_WIDTH_CHARS_REPLACEMENT = Object.freeze({
|
|
24
40
|
'\t': '\\t',
|
|
25
41
|
'\n': '\\n'
|
|
@@ -37,7 +53,7 @@ const FORMAT_PREDICATES = [node => node.hasFormat('bold') && 'Bold', node => nod
|
|
|
37
53
|
const FORMAT_PREDICATES_PARAGRAPH = [node => node.hasTextFormat('bold') && 'Bold', node => node.hasTextFormat('code') && 'Code', node => node.hasTextFormat('italic') && 'Italic', node => node.hasTextFormat('strikethrough') && 'Strikethrough', node => node.hasTextFormat('subscript') && 'Subscript', node => node.hasTextFormat('superscript') && 'Superscript', node => node.hasTextFormat('underline') && 'Underline'];
|
|
38
54
|
const DETAIL_PREDICATES = [node => node.isDirectionless() && 'Directionless', node => node.isUnmergeable() && 'Unmergeable'];
|
|
39
55
|
const MODE_PREDICATES = [node => node.isToken() && 'Token', node => node.isSegmented() && 'Segmented'];
|
|
40
|
-
function generateContent(editor, commandsLog, exportDOM) {
|
|
56
|
+
function generateContent(editor, commandsLog, exportDOM, obfuscateText = false) {
|
|
41
57
|
const editorState = editor.getEditorState();
|
|
42
58
|
const editorConfig = editor._config;
|
|
43
59
|
const compositionKey = editor._compositionKey;
|
|
@@ -58,8 +74,8 @@ function generateContent(editor, commandsLog, exportDOM) {
|
|
|
58
74
|
const typeDisplay = node.getType() || '';
|
|
59
75
|
const isSelected = node.isSelected();
|
|
60
76
|
const idsDisplay = mark.$isMarkNode(node) ? ` id: [ ${node.getIDs().join(', ')} ] ` : '';
|
|
61
|
-
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node)}\n`;
|
|
62
|
-
res += printSelectedCharsLine({
|
|
77
|
+
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node, obfuscateText)}\n`;
|
|
78
|
+
res += $printSelectedCharsLine({
|
|
63
79
|
indent,
|
|
64
80
|
isSelected,
|
|
65
81
|
node,
|
|
@@ -121,20 +137,24 @@ function visitTree(currentNode, visitor, indent = []) {
|
|
|
121
137
|
}
|
|
122
138
|
});
|
|
123
139
|
}
|
|
124
|
-
function normalize(text) {
|
|
125
|
-
|
|
140
|
+
function normalize(text, obfuscateText = false) {
|
|
141
|
+
const textToPrint = Object.entries(NON_SINGLE_WIDTH_CHARS_REPLACEMENT).reduce((acc, [key, value]) => acc.replace(new RegExp(key, 'g'), String(value)), text);
|
|
142
|
+
if (obfuscateText) {
|
|
143
|
+
return textToPrint.replace(/[^\s]/g, '*');
|
|
144
|
+
}
|
|
145
|
+
return textToPrint;
|
|
126
146
|
}
|
|
127
147
|
|
|
128
148
|
// TODO Pass via props to allow customizability
|
|
129
|
-
function printNode(node) {
|
|
149
|
+
function printNode(node, obfuscateText = false) {
|
|
130
150
|
if (lexical.$isTextNode(node)) {
|
|
131
151
|
const text = node.getTextContent();
|
|
132
|
-
const title = text.length === 0 ? '(empty)' : `"${normalize(text)}"`;
|
|
152
|
+
const title = text.length === 0 ? '(empty)' : `"${normalize(text, obfuscateText)}"`;
|
|
133
153
|
const properties = printAllTextNodeProperties(node);
|
|
134
154
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
135
155
|
} else if (link.$isLinkNode(node)) {
|
|
136
156
|
const link = node.getURL();
|
|
137
|
-
const title = link.length === 0 ? '(empty)' : `"${normalize(link)}"`;
|
|
157
|
+
const title = link.length === 0 ? '(empty)' : `"${normalize(link, obfuscateText)}"`;
|
|
138
158
|
const properties = printAllLinkNodeProperties(node);
|
|
139
159
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
140
160
|
} else if (lexical.$isParagraphNode(node)) {
|
|
@@ -202,7 +222,7 @@ function printTitleProperties(node) {
|
|
|
202
222
|
}
|
|
203
223
|
return str;
|
|
204
224
|
}
|
|
205
|
-
function printSelectedCharsLine({
|
|
225
|
+
function $printSelectedCharsLine({
|
|
206
226
|
indent,
|
|
207
227
|
isSelected,
|
|
208
228
|
node,
|
|
@@ -294,6 +314,7 @@ function $getSelectionStartEnd(node, selection) {
|
|
|
294
314
|
* LICENSE file in the root directory of this source tree.
|
|
295
315
|
*
|
|
296
316
|
*/
|
|
317
|
+
|
|
297
318
|
const LARGE_EDITOR_STATE_SIZE = 1000;
|
|
298
319
|
const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
299
320
|
treeTypeButtonClassName,
|
|
@@ -381,17 +402,17 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
381
402
|
generateTree(!showExportDOM);
|
|
382
403
|
setShowExportDOM(!showExportDOM);
|
|
383
404
|
};
|
|
384
|
-
return /*#__PURE__*/
|
|
405
|
+
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
385
406
|
className: viewClassName
|
|
386
|
-
}, !showLimited && isLimited ? /*#__PURE__*/
|
|
407
|
+
}, !showLimited && isLimited ? /*#__PURE__*/React__namespace.createElement("div", {
|
|
387
408
|
style: {
|
|
388
409
|
padding: 20
|
|
389
410
|
}
|
|
390
|
-
}, /*#__PURE__*/
|
|
411
|
+
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
391
412
|
style: {
|
|
392
413
|
marginRight: 20
|
|
393
414
|
}
|
|
394
|
-
}, "Detected large EditorState, this can impact debugging performance."), /*#__PURE__*/
|
|
415
|
+
}, "Detected large EditorState, this can impact debugging performance."), /*#__PURE__*/React__namespace.createElement("button", {
|
|
395
416
|
onClick: () => {
|
|
396
417
|
setShowLimited(true);
|
|
397
418
|
},
|
|
@@ -402,11 +423,11 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
402
423
|
cursor: 'pointer',
|
|
403
424
|
padding: 5
|
|
404
425
|
}
|
|
405
|
-
}, "Show full tree")) : null, !showLimited ? /*#__PURE__*/
|
|
426
|
+
}, "Show full tree")) : null, !showLimited ? /*#__PURE__*/React__namespace.createElement("button", {
|
|
406
427
|
onClick: () => handleExportModeToggleClick(),
|
|
407
428
|
className: treeTypeButtonClassName,
|
|
408
429
|
type: "button"
|
|
409
|
-
}, showExportDOM ? 'Tree' : 'Export DOM') : null, !timeTravelEnabled && (showLimited || !isLimited) && totalEditorStates > 2 && /*#__PURE__*/
|
|
430
|
+
}, showExportDOM ? 'Tree' : 'Export DOM') : null, !timeTravelEnabled && (showLimited || !isLimited) && totalEditorStates > 2 && /*#__PURE__*/React__namespace.createElement("button", {
|
|
410
431
|
onClick: () => {
|
|
411
432
|
setEditorReadOnly(true);
|
|
412
433
|
playingIndexRef.current = totalEditorStates - 1;
|
|
@@ -414,11 +435,11 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
414
435
|
},
|
|
415
436
|
className: timeTravelButtonClassName,
|
|
416
437
|
type: "button"
|
|
417
|
-
}, "Time Travel"), (showLimited || !isLimited) && /*#__PURE__*/
|
|
438
|
+
}, "Time Travel"), (showLimited || !isLimited) && /*#__PURE__*/React__namespace.createElement("pre", {
|
|
418
439
|
ref: ref
|
|
419
|
-
}, content), timeTravelEnabled && (showLimited || !isLimited) && /*#__PURE__*/
|
|
440
|
+
}, content), timeTravelEnabled && (showLimited || !isLimited) && /*#__PURE__*/React__namespace.createElement("div", {
|
|
420
441
|
className: timeTravelPanelClassName
|
|
421
|
-
}, /*#__PURE__*/
|
|
442
|
+
}, /*#__PURE__*/React__namespace.createElement("button", {
|
|
422
443
|
className: timeTravelPanelButtonClassName,
|
|
423
444
|
onClick: () => {
|
|
424
445
|
if (playingIndexRef.current === totalEditorStates - 1) {
|
|
@@ -427,7 +448,7 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
427
448
|
setIsPlaying(!isPlaying);
|
|
428
449
|
},
|
|
429
450
|
type: "button"
|
|
430
|
-
}, isPlaying ? 'Pause' : 'Play'), /*#__PURE__*/
|
|
451
|
+
}, isPlaying ? 'Pause' : 'Play'), /*#__PURE__*/React__namespace.createElement("input", {
|
|
431
452
|
className: timeTravelPanelSliderClassName,
|
|
432
453
|
ref: inputRef,
|
|
433
454
|
onChange: event => {
|
|
@@ -441,7 +462,7 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
441
462
|
type: "range",
|
|
442
463
|
min: "1",
|
|
443
464
|
max: totalEditorStates - 1
|
|
444
|
-
}), /*#__PURE__*/
|
|
465
|
+
}), /*#__PURE__*/React__namespace.createElement("button", {
|
|
445
466
|
className: timeTravelPanelButtonClassName,
|
|
446
467
|
onClick: () => {
|
|
447
468
|
setEditorReadOnly(false);
|
|
@@ -466,6 +487,7 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
466
487
|
* LICENSE file in the root directory of this source tree.
|
|
467
488
|
*
|
|
468
489
|
*/
|
|
490
|
+
|
|
469
491
|
function registerLexicalCommandLogger(editor, setLoggedCommands) {
|
|
470
492
|
const unregisterCommandListeners = new Set();
|
|
471
493
|
for (const [command] of editor._commands) {
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
8
|
+
|
|
7
9
|
import { $generateHtmlFromNodes } from '@lexical/html';
|
|
8
10
|
import { $isLinkNode } from '@lexical/link';
|
|
9
11
|
import { $isMarkNode } from '@lexical/mark';
|
|
@@ -19,6 +21,7 @@ import { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'r
|
|
|
19
21
|
* LICENSE file in the root directory of this source tree.
|
|
20
22
|
*
|
|
21
23
|
*/
|
|
24
|
+
|
|
22
25
|
const NON_SINGLE_WIDTH_CHARS_REPLACEMENT = Object.freeze({
|
|
23
26
|
'\t': '\\t',
|
|
24
27
|
'\n': '\\n'
|
|
@@ -36,7 +39,7 @@ const FORMAT_PREDICATES = [node => node.hasFormat('bold') && 'Bold', node => nod
|
|
|
36
39
|
const FORMAT_PREDICATES_PARAGRAPH = [node => node.hasTextFormat('bold') && 'Bold', node => node.hasTextFormat('code') && 'Code', node => node.hasTextFormat('italic') && 'Italic', node => node.hasTextFormat('strikethrough') && 'Strikethrough', node => node.hasTextFormat('subscript') && 'Subscript', node => node.hasTextFormat('superscript') && 'Superscript', node => node.hasTextFormat('underline') && 'Underline'];
|
|
37
40
|
const DETAIL_PREDICATES = [node => node.isDirectionless() && 'Directionless', node => node.isUnmergeable() && 'Unmergeable'];
|
|
38
41
|
const MODE_PREDICATES = [node => node.isToken() && 'Token', node => node.isSegmented() && 'Segmented'];
|
|
39
|
-
function generateContent(editor, commandsLog, exportDOM) {
|
|
42
|
+
function generateContent(editor, commandsLog, exportDOM, obfuscateText = false) {
|
|
40
43
|
const editorState = editor.getEditorState();
|
|
41
44
|
const editorConfig = editor._config;
|
|
42
45
|
const compositionKey = editor._compositionKey;
|
|
@@ -57,8 +60,8 @@ function generateContent(editor, commandsLog, exportDOM) {
|
|
|
57
60
|
const typeDisplay = node.getType() || '';
|
|
58
61
|
const isSelected = node.isSelected();
|
|
59
62
|
const idsDisplay = $isMarkNode(node) ? ` id: [ ${node.getIDs().join(', ')} ] ` : '';
|
|
60
|
-
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node)}\n`;
|
|
61
|
-
res += printSelectedCharsLine({
|
|
63
|
+
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node, obfuscateText)}\n`;
|
|
64
|
+
res += $printSelectedCharsLine({
|
|
62
65
|
indent,
|
|
63
66
|
isSelected,
|
|
64
67
|
node,
|
|
@@ -120,20 +123,24 @@ function visitTree(currentNode, visitor, indent = []) {
|
|
|
120
123
|
}
|
|
121
124
|
});
|
|
122
125
|
}
|
|
123
|
-
function normalize(text) {
|
|
124
|
-
|
|
126
|
+
function normalize(text, obfuscateText = false) {
|
|
127
|
+
const textToPrint = Object.entries(NON_SINGLE_WIDTH_CHARS_REPLACEMENT).reduce((acc, [key, value]) => acc.replace(new RegExp(key, 'g'), String(value)), text);
|
|
128
|
+
if (obfuscateText) {
|
|
129
|
+
return textToPrint.replace(/[^\s]/g, '*');
|
|
130
|
+
}
|
|
131
|
+
return textToPrint;
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
// TODO Pass via props to allow customizability
|
|
128
|
-
function printNode(node) {
|
|
135
|
+
function printNode(node, obfuscateText = false) {
|
|
129
136
|
if ($isTextNode(node)) {
|
|
130
137
|
const text = node.getTextContent();
|
|
131
|
-
const title = text.length === 0 ? '(empty)' : `"${normalize(text)}"`;
|
|
138
|
+
const title = text.length === 0 ? '(empty)' : `"${normalize(text, obfuscateText)}"`;
|
|
132
139
|
const properties = printAllTextNodeProperties(node);
|
|
133
140
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
134
141
|
} else if ($isLinkNode(node)) {
|
|
135
142
|
const link = node.getURL();
|
|
136
|
-
const title = link.length === 0 ? '(empty)' : `"${normalize(link)}"`;
|
|
143
|
+
const title = link.length === 0 ? '(empty)' : `"${normalize(link, obfuscateText)}"`;
|
|
137
144
|
const properties = printAllLinkNodeProperties(node);
|
|
138
145
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
139
146
|
} else if ($isParagraphNode(node)) {
|
|
@@ -201,7 +208,7 @@ function printTitleProperties(node) {
|
|
|
201
208
|
}
|
|
202
209
|
return str;
|
|
203
210
|
}
|
|
204
|
-
function printSelectedCharsLine({
|
|
211
|
+
function $printSelectedCharsLine({
|
|
205
212
|
indent,
|
|
206
213
|
isSelected,
|
|
207
214
|
node,
|
|
@@ -293,6 +300,7 @@ function $getSelectionStartEnd(node, selection) {
|
|
|
293
300
|
* LICENSE file in the root directory of this source tree.
|
|
294
301
|
*
|
|
295
302
|
*/
|
|
303
|
+
|
|
296
304
|
const LARGE_EDITOR_STATE_SIZE = 1000;
|
|
297
305
|
const TreeView = /*#__PURE__*/forwardRef(function TreeViewWrapped({
|
|
298
306
|
treeTypeButtonClassName,
|
|
@@ -465,6 +473,7 @@ const TreeView = /*#__PURE__*/forwardRef(function TreeViewWrapped({
|
|
|
465
473
|
* LICENSE file in the root directory of this source tree.
|
|
466
474
|
*
|
|
467
475
|
*/
|
|
476
|
+
|
|
468
477
|
function registerLexicalCommandLogger(editor, setLoggedCommands) {
|
|
469
478
|
const unregisterCommandListeners = new Set();
|
|
470
479
|
for (const [command] of editor._commands) {
|
package/LexicalDevtoolsCore.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
8
|
+
|
|
7
9
|
'use strict'
|
|
8
10
|
const LexicalDevtoolsCore = process.env.NODE_ENV === 'development' ? require('./LexicalDevtoolsCore.dev.js') : require('./LexicalDevtoolsCore.prod.js');
|
|
9
11
|
module.exports = LexicalDevtoolsCore;
|
|
@@ -6,3 +6,32 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* LexicalDevtoolsCore
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type {
|
|
15
|
+
LexicalEditor,
|
|
16
|
+
LexicalCommand
|
|
17
|
+
} from 'lexical';
|
|
18
|
+
|
|
19
|
+
export type LexicalCommandLog = $ReadOnlyArray<LexicalCommand<mixed> | {payload: mixed}>;
|
|
20
|
+
|
|
21
|
+
declare export function generateContent(
|
|
22
|
+
editor: LexicalEditor,
|
|
23
|
+
commandsLog: $ReadOnlyArray<LexicalCommandLog>,
|
|
24
|
+
exportDOM: boolean,
|
|
25
|
+
obfuscateText?: boolean,
|
|
26
|
+
): string;
|
|
27
|
+
|
|
28
|
+
declare export function registerLexicalCommandLogger(
|
|
29
|
+
editor: LexicalEditor,
|
|
30
|
+
setLoggedCommands: (
|
|
31
|
+
v: (oldValue: LexicalCommandLog) => LexicalCommandLog,
|
|
32
|
+
) => void,
|
|
33
|
+
): () => void;
|
|
34
|
+
|
|
35
|
+
declare export function useLexicalCommandsLog(
|
|
36
|
+
editor: LexicalEditor,
|
|
37
|
+
): LexicalCommandLog;
|
package/LexicalDevtoolsCore.mjs
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
8
|
+
|
|
7
9
|
import * as modDev from './LexicalDevtoolsCore.dev.mjs';
|
|
8
10
|
import * as modProd from './LexicalDevtoolsCore.prod.mjs';
|
|
9
11
|
const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
8
|
+
|
|
7
9
|
const mod = await (process.env.NODE_ENV === 'development' ? import('./LexicalDevtoolsCore.dev.mjs') : import('./LexicalDevtoolsCore.prod.mjs'));
|
|
8
10
|
export const TreeView = mod.TreeView;
|
|
9
11
|
export const generateContent = mod.generateContent;
|
|
@@ -3,23 +3,25 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
function
|
|
12
|
-
function
|
|
13
|
-
(a=ja(a),""!==a?`{ ${a} }`:"")
|
|
14
|
-
function
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
null
|
|
8
|
+
|
|
9
|
+
'use strict';var f=require("@lexical/html"),r=require("@lexical/link"),t=require("@lexical/mark"),aa=require("@lexical/table"),v=require("lexical"),L=require("react"),M=Object.create(null);if(L)for(var N in L)M[N]=L[N];M.default=L;
|
|
10
|
+
let O=Object.freeze({"\t":"\\t","\n":"\\n"}),P=new RegExp(Object.keys(O).join("|"),"g"),Q=Object.freeze({ancestorHasNextSibling:"|",ancestorIsLastChild:" ",hasNextSibling:"\u251c",isLastChild:"\u2514",selectedChar:"^",selectedLine:">"}),ba=[a=>a.hasFormat("bold")&&"Bold",a=>a.hasFormat("code")&&"Code",a=>a.hasFormat("italic")&&"Italic",a=>a.hasFormat("strikethrough")&&"Strikethrough",a=>a.hasFormat("subscript")&&"Subscript",a=>a.hasFormat("superscript")&&"Superscript",a=>a.hasFormat("underline")&&
|
|
11
|
+
"Underline"],ca=[a=>a.hasTextFormat("bold")&&"Bold",a=>a.hasTextFormat("code")&&"Code",a=>a.hasTextFormat("italic")&&"Italic",a=>a.hasTextFormat("strikethrough")&&"Strikethrough",a=>a.hasTextFormat("subscript")&&"Subscript",a=>a.hasTextFormat("superscript")&&"Superscript",a=>a.hasTextFormat("underline")&&"Underline"],da=[a=>a.isDirectionless()&&"Directionless",a=>a.isUnmergeable()&&"Unmergeable"],ea=[a=>a.isToken()&&"Token",a=>a.isSegmented()&&"Segmented"];
|
|
12
|
+
function fa(a){let b="";var c=R(a);b+=`: range ${""!==c?`{ ${c} }`:""} ${""!==a.style?`{ style: ${a.style} } `:""}`;c=a.anchor;a=a.focus;let e=c.offset,d=a.offset;b+=`\n \u251c anchor { key: ${c.key}, offset: ${null===e?"null":e}, type: ${c.type} }`;return b+=`\n \u2514 focus { key: ${a.key}, offset: ${null===d?"null":d}, type: ${a.type} }`}function ha(a){return v.$isNodeSelection(a)?`: node\n \u2514 [${Array.from(a._nodes).join(", ")}]`:""}
|
|
13
|
+
function W(a,b,c=[]){a=a.getChildren();let e=a.length;a.forEach((d,h)=>{b(d,c.concat(h===e-1?Q.isLastChild:Q.hasNextSibling));v.$isElementNode(d)&&W(d,b,c.concat(h===e-1?Q.ancestorIsLastChild:Q.ancestorHasNextSibling))})}function X(a,b=!1){a=Object.entries(O).reduce((c,[e,d])=>c.replace(new RegExp(e,"g"),String(d)),a);return b?a.replace(/[^\s]/g,"*"):a}
|
|
14
|
+
function ia(a,b=!1){if(v.$isTextNode(a)){var c=a.getTextContent();b=0===c.length?"(empty)":`"${X(c,b)}"`;a=[R(a),ja(a),ka(a)].filter(Boolean).join(", ");return[b,0!==a.length?`{ ${a} }`:null].filter(Boolean).join(" ").trim()}if(r.$isLinkNode(a)){c=a.getURL();b=0===c.length?"(empty)":`"${X(c,b)}"`;c=a.getTarget();null!=c&&(c="target: "+c);var e=Boolean;var d=a.getRel();null!=d&&(d="rel: "+d);a=a.getTitle();null!=a&&(a="title: "+a);a=[c,d,a].filter(e).join(", ");return[b,0!==a.length?`{ ${a} }`:null].filter(Boolean).join(" ").trim()}return v.$isParagraphNode(a)?
|
|
15
|
+
(a=la(a),""!==a?`{ ${a} }`:""):""}function la(a){let b=ca.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="format: "+b);return b}function ja(a){let b=da.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="detail: "+b);return b}function ka(a){let b=ea.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="mode: "+b);return b}
|
|
16
|
+
function R(a){let b=ba.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="format: "+b);return b}
|
|
17
|
+
function ma({indent:a,isSelected:b,node:c,nodeKeyDisplay:e,selection:d,typeDisplay:h}){if(!v.$isTextNode(c)||!v.$isRangeSelection(d)||!b||v.$isElementNode(c))return"";b=d.anchor;var n=d.focus;if(""===c.getTextContent()||b.getNode()===d.focus.getNode()&&b.offset===n.offset)return"";b=d.getStartEndPoints();if(v.$isNodeSelection(d)||null===b)c=[-1,-1];else{var [p,g]=b;n=c.getTextContent();var k=n.length;b=d=-1;if("text"===p.type&&"text"===g.type){let w=p.getNode(),x=g.getNode();w===x&&c===w&&p.offset!==
|
|
18
|
+
g.offset?[d,b]=p.offset<g.offset?[p.offset,g.offset]:[g.offset,p.offset]:c===w?[d,b]=w.isBefore(x)?[p.offset,k]:[0,p.offset]:c===x?[d,b]=x.isBefore(w)?[g.offset,k]:[0,g.offset]:[d,b]=[0,k]}c=(n.slice(0,d).match(P)||[]).length;n=(n.slice(d,b).match(P)||[]).length;c=[d+c,b+c+n]}let [l,m]=c;if(l===m)return"";c=a[a.length-1]===Q.hasNextSibling?Q.ancestorHasNextSibling:Q.ancestorIsLastChild;a=[...a.slice(0,a.length-1),c];c=Array(l+1).fill(" ");d=Array(m-l).fill(Q.selectedChar);e=Array(e.length+(h.length+
|
|
19
|
+
3)).fill(" ");return[Q.selectedLine,a.join(" "),[...e,...c,...d].join("")].join(" ")+"\n"}function Y(a,b){let c=Array(b++ +1).join(" "),e=Array(b-1).join(" "),d;for(let h=0;h<a.children.length;h++)d=document.createTextNode("\n"+c),a.insertBefore(d,a.children[h]),Y(a.children[h],b),a.lastElementChild===a.children[h]&&(d=document.createTextNode("\n"+e),a.appendChild(d));return a}
|
|
20
|
+
let qa=L.forwardRef(function({treeTypeButtonClassName:a,timeTravelButtonClassName:b,timeTravelPanelSliderClassName:c,timeTravelPanelButtonClassName:e,viewClassName:d,timeTravelPanelClassName:h,editorState:n,setEditorState:p,setEditorReadOnly:g,generateContent:k},l){const [m,w]=L.useState([]),[x,D]=L.useState(""),[B,S]=L.useState(!1),[E,na]=L.useState(!1),A=L.useRef(0),H=L.useRef(null),[F,I]=L.useState(!1),[G,oa]=L.useState(!1),[y,pa]=L.useState(!1),T=L.useRef(),J=L.useRef(0),K=L.useCallback(q=>{const u=
|
|
21
|
+
++J.current;k(q).then(z=>{u===J.current&&D(z)}).catch(z=>{u===J.current&&D(`Error rendering tree: ${z.message}\n\nStack:\n${z.stack}`)})},[k]);L.useEffect(()=>{if(!y&&1E3<n._nodeMap.size&&(oa(!0),!y))return;T.current!==n&&(T.current=n,K(E),B||w(q=>[...q,[Date.now(),n]]))},[n,K,E,y,B]);const C=m.length;L.useEffect(()=>{if(F){let q;const u=()=>{const z=A.current;z===C-1?I(!1):q=setTimeout(()=>{A.current++;const U=A.current,V=H.current;null!==V&&(V.value=String(U));p(m[U][1]);u()},m[z+1][0]-m[z][0])};
|
|
22
|
+
u();return()=>{clearTimeout(q)}}},[m,F,C,p]);return M.createElement("div",{className:d},!y&&G?M.createElement("div",{style:{padding:20}},M.createElement("span",{style:{marginRight:20}},"Detected large EditorState, this can impact debugging performance."),M.createElement("button",{onClick:()=>{pa(!0)},style:{background:"transparent",border:"1px solid white",color:"white",cursor:"pointer",padding:5}},"Show full tree")):null,y?null:M.createElement("button",{onClick:()=>{K(!E);na(!E)},className:a,type:"button"},
|
|
23
|
+
E?"Tree":"Export DOM"),!B&&(y||!G)&&2<C&&M.createElement("button",{onClick:()=>{g(!0);A.current=C-1;S(!0)},className:b,type:"button"},"Time Travel"),(y||!G)&&M.createElement("pre",{ref:l},x),B&&(y||!G)&&M.createElement("div",{className:h},M.createElement("button",{className:e,onClick:()=>{A.current===C-1&&(A.current=1);I(!F)},type:"button"},F?"Pause":"Play"),M.createElement("input",{className:c,ref:H,onChange:q=>{q=Number(q.target.value);const u=m[q];u&&(A.current=q,p(u[1]))},type:"range",min:"1",
|
|
24
|
+
max:C-1}),M.createElement("button",{className:e,onClick:()=>{g(!1);const q=m.length-1;p(m[q][1]);const u=H.current;null!==u&&(u.value=String(q));S(!1);I(!1)},type:"button"},"Exit")))});function Z(a,b){let c=new Set;for(let [e]of a._commands)c.add(a.registerCommand(e,d=>{b(h=>{h=[...h];h.push({payload:d,type:e.type?e.type:"UNKNOWN"});10<h.length&&h.shift();return h});return!1},v.COMMAND_PRIORITY_CRITICAL));return()=>c.forEach(e=>e())}exports.TreeView=qa;
|
|
25
|
+
exports.generateContent=function(a,b,c,e=!1){let d=a.getEditorState(),h=a._config,n=a._compositionKey,p=a._editable;if(c){let k="";d.read(()=>{var l=f.$generateHtmlFromNodes(a);let m=document.createElement("div");m.innerHTML=l.trim();k=Y(m,0).innerHTML});return k}let g=" root\n";c=d.read(()=>{const k=v.$getSelection();W(v.$getRoot(),(l,m)=>{const w=`(${l.getKey()})`,x=l.getType()||"",D=l.isSelected(),B=t.$isMarkNode(l)?` id: [ ${l.getIDs().join(", ")} ] `:"";g+=`${D?Q.selectedLine:" "} ${m.join(" ")} ${w} ${x} ${B} ${ia(l,
|
|
26
|
+
e)}\n`;g+=ma({indent:m,isSelected:D,node:l,nodeKeyDisplay:w,selection:k,typeDisplay:x})});return null===k?": null":v.$isRangeSelection(k)?fa(k):aa.$isTableSelection(k)?`: table\n \u2514 { table: ${k.tableKey}, anchorCell: ${k.anchor.key}, focusCell: ${k.focus.key} }`:ha(k)});g+="\n selection"+c;g+="\n\n commands:";if(b.length)for(let {type:k,payload:l}of b)g+=`\n \u2514 { type: ${k}, payload: ${l instanceof Event?l.constructor.name:l} }`;else g+="\n \u2514 None dispatched.";g+="\n\n editor:";g+=
|
|
27
|
+
`\n \u2514 namespace ${h.namespace}`;null!==n&&(g+=`\n \u2514 compositionKey ${n}`);return g+=`\n \u2514 editable ${String(p)}`};exports.registerLexicalCommandLogger=Z;exports.useLexicalCommandsLog=function(a){let [b,c]=L.useState([]);L.useEffect(()=>Z(a,c),[a]);return L.useMemo(()=>b,[b])}
|
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
*
|
|
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
|
*/
|
|
7
|
-
|
|
8
|
+
|
|
9
|
+
import{$generateHtmlFromNodes as e}from"@lexical/html";import{$isLinkNode as t}from"@lexical/link";import{$isMarkNode as n}from"@lexical/mark";import{$isTableSelection as r}from"@lexical/table";import{$getSelection as o,$getRoot as l,$isRangeSelection as i,$isNodeSelection as a,$isElementNode as s,$isTextNode as c,$isParagraphNode as u,COMMAND_PRIORITY_CRITICAL as f}from"lexical";import*as m from"react";import{forwardRef as d,useState as g,useRef as h,useCallback as p,useEffect as y,useMemo as b}from"react";const C=Object.freeze({"\t":"\\t","\n":"\\n"}),$=new RegExp(Object.keys(C).join("|"),"g"),x=Object.freeze({ancestorHasNextSibling:"|",ancestorIsLastChild:" ",hasNextSibling:"├",isLastChild:"└",selectedChar:"^",selectedLine:">"}),N=[e=>e.hasFormat("bold")&&"Bold",e=>e.hasFormat("code")&&"Code",e=>e.hasFormat("italic")&&"Italic",e=>e.hasFormat("strikethrough")&&"Strikethrough",e=>e.hasFormat("subscript")&&"Subscript",e=>e.hasFormat("superscript")&&"Superscript",e=>e.hasFormat("underline")&&"Underline"],S=[e=>e.hasTextFormat("bold")&&"Bold",e=>e.hasTextFormat("code")&&"Code",e=>e.hasTextFormat("italic")&&"Italic",e=>e.hasTextFormat("strikethrough")&&"Strikethrough",e=>e.hasTextFormat("subscript")&&"Subscript",e=>e.hasTextFormat("superscript")&&"Superscript",e=>e.hasTextFormat("underline")&&"Underline"],T=[e=>e.isDirectionless()&&"Directionless",e=>e.isUnmergeable()&&"Unmergeable"],E=[e=>e.isToken()&&"Token",e=>e.isSegmented()&&"Segmented"];function k(f,m,d,g=!1){const h=f.getEditorState(),p=f._config,y=f._compositionKey,b=f._editable;if(d){let t="";return h.read((()=>{t=function(e){const t=document.createElement("div");return t.innerHTML=e.trim(),O(t,0).innerHTML}(e(f))})),t}let C=" root\n";const N=h.read((()=>{const e=o();return j(l(),((r,o)=>{const l=`(${r.getKey()})`,f=r.getType()||"",m=r.isSelected(),d=n(r)?` id: [ ${r.getIDs().join(", ")} ] `:"";C+=`${m?x.selectedLine:" "} ${o.join(" ")} ${l} ${f} ${d} ${function(e,n=!1){if(c(e)){const t=e.getTextContent(),r=0===t.length?"(empty)":`"${L(t,n)}"`,o=function(e){return[w(e),v(e),B(e)].filter(Boolean).join(", ")}(e);return[r,0!==o.length?`{ ${o} }`:null].filter(Boolean).join(" ").trim()}if(t(e)){const t=e.getURL(),r=0===t.length?"(empty)":`"${L(t,n)}"`,o=function(e){return[F(e),D(e),K(e)].filter(Boolean).join(", ")}(e);return[r,0!==o.length?`{ ${o} }`:null].filter(Boolean).join(" ").trim()}if(u(e)){const t=function(e){let t=S.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();""!==t&&(t="format: "+t);return t}(e);return""!==t?`{ ${t} }`:""}return""}(r,g)}\n`,C+=function({indent:e,isSelected:t,node:n,nodeKeyDisplay:r,selection:o,typeDisplay:l}){if(!c(n)||!i(o)||!t||s(n))return"";const u=o.anchor,f=o.focus;if(""===n.getTextContent()||u.getNode()===o.focus.getNode()&&u.offset===f.offset)return"";const[m,d]=function(e,t){const n=t.getStartEndPoints();if(a(t)||null===n)return[-1,-1];const[r,o]=n,l=e.getTextContent(),i=l.length;let s=-1,c=-1;if("text"===r.type&&"text"===o.type){const t=r.getNode(),n=o.getNode();t===n&&e===t&&r.offset!==o.offset?[s,c]=r.offset<o.offset?[r.offset,o.offset]:[o.offset,r.offset]:[s,c]=e===t?t.isBefore(n)?[r.offset,i]:[0,r.offset]:e===n?n.isBefore(t)?[o.offset,i]:[0,o.offset]:[0,i]}const u=(l.slice(0,s).match($)||[]).length,f=(l.slice(s,c).match($)||[]).length;return[s+u,c+u+f]}(n,o);if(m===d)return"";const g=e[e.length-1]===x.hasNextSibling?x.ancestorHasNextSibling:x.ancestorIsLastChild,h=[...e.slice(0,e.length-1),g],p=Array(m+1).fill(" "),y=Array(d-m).fill(x.selectedChar),b=l.length+3,C=Array(r.length+b).fill(" ");return[x.selectedLine,h.join(" "),[...C,...p,...y].join("")].join(" ")+"\n"}({indent:o,isSelected:m,node:r,nodeKeyDisplay:l,selection:e,typeDisplay:f})})),null===e?": null":i(e)?function(e){let t="";const n=w(e);t+=`: range ${""!==n?`{ ${n} }`:""} ${""!==e.style?`{ style: ${e.style} } `:""}`;const r=e.anchor,o=e.focus,l=r.offset,i=o.offset;return t+=`\n ├ anchor { key: ${r.key}, offset: ${null===l?"null":l}, type: ${r.type} }`,t+=`\n └ focus { key: ${o.key}, offset: ${null===i?"null":i}, type: ${o.type} }`,t}(e):r(e)?function(e){return`: table\n └ { table: ${e.tableKey}, anchorCell: ${e.anchor.key}, focusCell: ${e.focus.key} }`}(e):function(e){if(!a(e))return"";return`: node\n └ [${Array.from(e._nodes).join(", ")}]`}(e)}));if(C+="\n selection"+N,C+="\n\n commands:",m.length)for(const{type:e,payload:t}of m)C+=`\n └ { type: ${e}, payload: ${t instanceof Event?t.constructor.name:t} }`;else C+="\n └ None dispatched.";return C+="\n\n editor:",C+=`\n └ namespace ${p.namespace}`,null!==y&&(C+=`\n └ compositionKey ${y}`),C+=`\n └ editable ${String(b)}`,C}function j(e,t,n=[]){const r=e.getChildren(),o=r.length;r.forEach(((e,r)=>{t(e,n.concat(r===o-1?x.isLastChild:x.hasNextSibling)),s(e)&&j(e,t,n.concat(r===o-1?x.ancestorIsLastChild:x.ancestorHasNextSibling))}))}function L(e,t=!1){const n=Object.entries(C).reduce(((e,[t,n])=>e.replace(new RegExp(t,"g"),String(n))),e);return t?n.replace(/[^\s]/g,"*"):n}function v(e){let t=T.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="detail: "+t),t}function B(e){let t=E.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="mode: "+t),t}function w(e){let t=N.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="format: "+t),t}function F(e){let t=e.getTarget();return null!=t&&(t="target: "+t),t}function D(e){let t=e.getRel();return null!=t&&(t="rel: "+t),t}function K(e){let t=e.getTitle();return null!=t&&(t="title: "+t),t}function O(e,t){const n=new Array(1+t++).join(" "),r=new Array(t-1).join(" ");let o;for(let l=0;l<e.children.length;l++)o=document.createTextNode("\n"+n),e.insertBefore(o,e.children[l]),O(e.children[l],t),e.lastElementChild===e.children[l]&&(o=document.createTextNode("\n"+r),e.appendChild(o));return e}const A=d((function({treeTypeButtonClassName:e,timeTravelButtonClassName:t,timeTravelPanelSliderClassName:n,timeTravelPanelButtonClassName:r,viewClassName:o,timeTravelPanelClassName:l,editorState:i,setEditorState:a,setEditorReadOnly:s,generateContent:c},u){const[f,d]=g([]),[b,C]=g(""),[$,x]=g(!1),[N,S]=g(!1),T=h(0),E=h(null),[k,j]=g(!1),[L,v]=g(!1),[B,w]=g(!1),F=h(),D=h(0),K=p((e=>{const t=++D.current;c(e).then((e=>{t===D.current&&C(e)})).catch((e=>{t===D.current&&C(`Error rendering tree: ${e.message}\n\nStack:\n${e.stack}`)}))}),[c]);y((()=>{!B&&i._nodeMap.size>1e3&&(v(!0),!B)||F.current!==i&&(F.current=i,K(N),$||d((e=>[...e,[Date.now(),i]])))}),[i,K,N,B,$]);const O=f.length;y((()=>{if(k){let e;const t=()=>{const n=T.current;if(n===O-1)return void j(!1);const r=f[n][0],o=f[n+1][0];e=setTimeout((()=>{T.current++;const e=T.current,n=E.current;null!==n&&(n.value=String(e)),a(f[e][1]),t()}),o-r)};return t(),()=>{clearTimeout(e)}}}),[f,k,O,a]);return m.createElement("div",{className:o},!B&&L?m.createElement("div",{style:{padding:20}},m.createElement("span",{style:{marginRight:20}},"Detected large EditorState, this can impact debugging performance."),m.createElement("button",{onClick:()=>{w(!0)},style:{background:"transparent",border:"1px solid white",color:"white",cursor:"pointer",padding:5}},"Show full tree")):null,B?null:m.createElement("button",{onClick:()=>(K(!N),void S(!N)),className:e,type:"button"},N?"Tree":"Export DOM"),!$&&(B||!L)&&O>2&&m.createElement("button",{onClick:()=>{s(!0),T.current=O-1,x(!0)},className:t,type:"button"},"Time Travel"),(B||!L)&&m.createElement("pre",{ref:u},b),$&&(B||!L)&&m.createElement("div",{className:l},m.createElement("button",{className:r,onClick:()=>{T.current===O-1&&(T.current=1),j(!k)},type:"button"},k?"Pause":"Play"),m.createElement("input",{className:n,ref:E,onChange:e=>{const t=Number(e.target.value),n=f[t];n&&(T.current=t,a(n[1]))},type:"range",min:"1",max:O-1}),m.createElement("button",{className:r,onClick:()=>{s(!1);const e=f.length-1,t=f[e];a(t[1]);const n=E.current;null!==n&&(n.value=String(e)),x(!1),j(!1)},type:"button"},"Exit")))}));function I(e,t){const n=new Set;for(const[r]of e._commands)n.add(e.registerCommand(r,(e=>(t((t=>{const n=[...t];return n.push({payload:e,type:r.type?r.type:"UNKNOWN"}),n.length>10&&n.shift(),n})),!1)),f));return()=>n.forEach((e=>e()))}function P(e){const[t,n]=g([]);return y((()=>I(e,n)),[e]),b((()=>t),[t])}export{A as TreeView,k as generateContent,I as registerLexicalCommandLogger,P as useLexicalCommandsLog};
|
package/generateContent.d.ts
CHANGED
|
@@ -9,4 +9,4 @@ import type { LexicalEditor } from 'lexical';
|
|
|
9
9
|
import { LexicalCommand } from 'lexical';
|
|
10
10
|
export declare function generateContent(editor: LexicalEditor, commandsLog: ReadonlyArray<LexicalCommand<unknown> & {
|
|
11
11
|
payload: unknown;
|
|
12
|
-
}>, exportDOM: boolean): string;
|
|
12
|
+
}>, exportDOM: boolean, obfuscateText?: boolean): string;
|
package/package.json
CHANGED
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
"utils"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.15.0",
|
|
12
12
|
"main": "LexicalDevtoolsCore.js",
|
|
13
13
|
"types": "index.d.ts",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@lexical/html": "0.
|
|
16
|
-
"@lexical/link": "0.
|
|
17
|
-
"@lexical/mark": "0.
|
|
18
|
-
"@lexical/table": "0.
|
|
19
|
-
"@lexical/utils": "0.
|
|
20
|
-
"lexical": "0.
|
|
15
|
+
"@lexical/html": "0.15.0",
|
|
16
|
+
"@lexical/link": "0.15.0",
|
|
17
|
+
"@lexical/mark": "0.15.0",
|
|
18
|
+
"@lexical/table": "0.15.0",
|
|
19
|
+
"@lexical/utils": "0.15.0",
|
|
20
|
+
"lexical": "0.15.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"react": ">=17.x",
|