@lexical/devtools-core 0.15.0 → 0.16.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 +120 -115
- package/LexicalDevtoolsCore.dev.mjs +101 -84
- package/LexicalDevtoolsCore.js.flow +18 -13
- package/LexicalDevtoolsCore.prod.js +19 -19
- package/LexicalDevtoolsCore.prod.mjs +1 -1
- package/generateContent.d.ts +4 -5
- package/package.json +7 -7
- package/useLexicalCommandsLog.d.ts +3 -1
|
@@ -13,20 +13,8 @@ var link = require('@lexical/link');
|
|
|
13
13
|
var mark = require('@lexical/mark');
|
|
14
14
|
var table = require('@lexical/table');
|
|
15
15
|
var lexical = require('lexical');
|
|
16
|
-
var
|
|
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);
|
|
16
|
+
var react = require('react');
|
|
17
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
30
18
|
|
|
31
19
|
/**
|
|
32
20
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -53,7 +41,7 @@ const FORMAT_PREDICATES = [node => node.hasFormat('bold') && 'Bold', node => nod
|
|
|
53
41
|
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'];
|
|
54
42
|
const DETAIL_PREDICATES = [node => node.isDirectionless() && 'Directionless', node => node.isUnmergeable() && 'Unmergeable'];
|
|
55
43
|
const MODE_PREDICATES = [node => node.isToken() && 'Token', node => node.isSegmented() && 'Segmented'];
|
|
56
|
-
function generateContent(editor, commandsLog, exportDOM, obfuscateText = false) {
|
|
44
|
+
function generateContent(editor, commandsLog, exportDOM, customPrintNode, obfuscateText = false) {
|
|
57
45
|
const editorState = editor.getEditorState();
|
|
58
46
|
const editorConfig = editor._config;
|
|
59
47
|
const compositionKey = editor._compositionKey;
|
|
@@ -73,8 +61,7 @@ function generateContent(editor, commandsLog, exportDOM, obfuscateText = false)
|
|
|
73
61
|
const nodeKeyDisplay = `(${nodeKey})`;
|
|
74
62
|
const typeDisplay = node.getType() || '';
|
|
75
63
|
const isSelected = node.isSelected();
|
|
76
|
-
|
|
77
|
-
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node, obfuscateText)}\n`;
|
|
64
|
+
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${printNode(node, customPrintNode, obfuscateText)}\n`;
|
|
78
65
|
res += $printSelectedCharsLine({
|
|
79
66
|
indent,
|
|
80
67
|
isSelected,
|
|
@@ -90,10 +77,11 @@ function generateContent(editor, commandsLog, exportDOM, obfuscateText = false)
|
|
|
90
77
|
res += '\n\n commands:';
|
|
91
78
|
if (commandsLog.length) {
|
|
92
79
|
for (const {
|
|
80
|
+
index,
|
|
93
81
|
type,
|
|
94
82
|
payload
|
|
95
83
|
} of commandsLog) {
|
|
96
|
-
res += `\n └ { type: ${type}, payload: ${payload instanceof Event ? payload.constructor.name : payload} }`;
|
|
84
|
+
res += `\n └ ${index}. { type: ${type}, payload: ${payload instanceof Event ? payload.constructor.name : payload} }`;
|
|
97
85
|
}
|
|
98
86
|
} else {
|
|
99
87
|
res += '\n └ None dispatched.';
|
|
@@ -144,9 +132,11 @@ function normalize(text, obfuscateText = false) {
|
|
|
144
132
|
}
|
|
145
133
|
return textToPrint;
|
|
146
134
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
135
|
+
function printNode(node, customPrintNode, obfuscateText = false) {
|
|
136
|
+
const customPrint = customPrintNode ? customPrintNode(node, obfuscateText) : undefined;
|
|
137
|
+
if (customPrint !== undefined && customPrint.length > 0) {
|
|
138
|
+
return customPrint;
|
|
139
|
+
}
|
|
150
140
|
if (lexical.$isTextNode(node)) {
|
|
151
141
|
const text = node.getTextContent();
|
|
152
142
|
const title = text.length === 0 ? '(empty)' : `"${normalize(text, obfuscateText)}"`;
|
|
@@ -157,6 +147,8 @@ function printNode(node, obfuscateText = false) {
|
|
|
157
147
|
const title = link.length === 0 ? '(empty)' : `"${normalize(link, obfuscateText)}"`;
|
|
158
148
|
const properties = printAllLinkNodeProperties(node);
|
|
159
149
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
150
|
+
} else if (mark.$isMarkNode(node)) {
|
|
151
|
+
return `ids: [ ${node.getIDs().join(', ')} ]`;
|
|
160
152
|
} else if (lexical.$isParagraphNode(node)) {
|
|
161
153
|
const formatText = printTextFormatProperties(node);
|
|
162
154
|
return formatText !== '' ? `{ ${formatText} }` : '';
|
|
@@ -316,7 +308,7 @@ function $getSelectionStartEnd(node, selection) {
|
|
|
316
308
|
*/
|
|
317
309
|
|
|
318
310
|
const LARGE_EDITOR_STATE_SIZE = 1000;
|
|
319
|
-
const TreeView = /*#__PURE__*/
|
|
311
|
+
const TreeView = /*#__PURE__*/react.forwardRef(function TreeViewWrapped({
|
|
320
312
|
treeTypeButtonClassName,
|
|
321
313
|
timeTravelButtonClassName,
|
|
322
314
|
timeTravelPanelSliderClassName,
|
|
@@ -328,18 +320,18 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
328
320
|
setEditorReadOnly,
|
|
329
321
|
generateContent
|
|
330
322
|
}, ref) {
|
|
331
|
-
const [timeStampedEditorStates, setTimeStampedEditorStates] =
|
|
332
|
-
const [content, setContent] =
|
|
333
|
-
const [timeTravelEnabled, setTimeTravelEnabled] =
|
|
334
|
-
const [showExportDOM, setShowExportDOM] =
|
|
335
|
-
const playingIndexRef =
|
|
336
|
-
const inputRef =
|
|
337
|
-
const [isPlaying, setIsPlaying] =
|
|
338
|
-
const [isLimited, setIsLimited] =
|
|
339
|
-
const [showLimited, setShowLimited] =
|
|
340
|
-
const lastEditorStateRef =
|
|
341
|
-
const lastGenerationID =
|
|
342
|
-
const generateTree =
|
|
323
|
+
const [timeStampedEditorStates, setTimeStampedEditorStates] = react.useState([]);
|
|
324
|
+
const [content, setContent] = react.useState('');
|
|
325
|
+
const [timeTravelEnabled, setTimeTravelEnabled] = react.useState(false);
|
|
326
|
+
const [showExportDOM, setShowExportDOM] = react.useState(false);
|
|
327
|
+
const playingIndexRef = react.useRef(0);
|
|
328
|
+
const inputRef = react.useRef(null);
|
|
329
|
+
const [isPlaying, setIsPlaying] = react.useState(false);
|
|
330
|
+
const [isLimited, setIsLimited] = react.useState(false);
|
|
331
|
+
const [showLimited, setShowLimited] = react.useState(false);
|
|
332
|
+
const lastEditorStateRef = react.useRef();
|
|
333
|
+
const lastGenerationID = react.useRef(0);
|
|
334
|
+
const generateTree = react.useCallback(exportDOM => {
|
|
343
335
|
const myID = ++lastGenerationID.current;
|
|
344
336
|
generateContent(exportDOM).then(treeText => {
|
|
345
337
|
if (myID === lastGenerationID.current) {
|
|
@@ -351,7 +343,7 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
351
343
|
}
|
|
352
344
|
});
|
|
353
345
|
}, [generateContent]);
|
|
354
|
-
|
|
346
|
+
react.useEffect(() => {
|
|
355
347
|
if (!showLimited && editorState._nodeMap.size > LARGE_EDITOR_STATE_SIZE) {
|
|
356
348
|
setIsLimited(true);
|
|
357
349
|
if (!showLimited) {
|
|
@@ -369,7 +361,7 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
369
361
|
}
|
|
370
362
|
}, [editorState, generateTree, showExportDOM, showLimited, timeTravelEnabled]);
|
|
371
363
|
const totalEditorStates = timeStampedEditorStates.length;
|
|
372
|
-
|
|
364
|
+
react.useEffect(() => {
|
|
373
365
|
if (isPlaying) {
|
|
374
366
|
let timeoutId;
|
|
375
367
|
const play = () => {
|
|
@@ -402,82 +394,92 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
402
394
|
generateTree(!showExportDOM);
|
|
403
395
|
setShowExportDOM(!showExportDOM);
|
|
404
396
|
};
|
|
405
|
-
return /*#__PURE__*/
|
|
406
|
-
className: viewClassName
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
397
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
398
|
+
className: viewClassName,
|
|
399
|
+
children: [!showLimited && isLimited ? /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
400
|
+
style: {
|
|
401
|
+
padding: 20
|
|
402
|
+
},
|
|
403
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
404
|
+
style: {
|
|
405
|
+
marginRight: 20
|
|
406
|
+
},
|
|
407
|
+
children: "Detected large EditorState, this can impact debugging performance."
|
|
408
|
+
}), /*#__PURE__*/jsxRuntime.jsx("button", {
|
|
409
|
+
onClick: () => {
|
|
410
|
+
setShowLimited(true);
|
|
411
|
+
},
|
|
412
|
+
style: {
|
|
413
|
+
background: 'transparent',
|
|
414
|
+
border: '1px solid white',
|
|
415
|
+
color: 'white',
|
|
416
|
+
cursor: 'pointer',
|
|
417
|
+
padding: 5
|
|
418
|
+
},
|
|
419
|
+
children: "Show full tree"
|
|
420
|
+
})]
|
|
421
|
+
}) : null, !showLimited ? /*#__PURE__*/jsxRuntime.jsx("button", {
|
|
422
|
+
onClick: () => handleExportModeToggleClick(),
|
|
423
|
+
className: treeTypeButtonClassName,
|
|
424
|
+
type: "button",
|
|
425
|
+
children: showExportDOM ? 'Tree' : 'Export DOM'
|
|
426
|
+
}) : null, !timeTravelEnabled && (showLimited || !isLimited) && totalEditorStates > 2 && /*#__PURE__*/jsxRuntime.jsx("button", {
|
|
427
|
+
onClick: () => {
|
|
428
|
+
setEditorReadOnly(true);
|
|
429
|
+
playingIndexRef.current = totalEditorStates - 1;
|
|
430
|
+
setTimeTravelEnabled(true);
|
|
431
|
+
},
|
|
432
|
+
className: timeTravelButtonClassName,
|
|
433
|
+
type: "button",
|
|
434
|
+
children: "Time Travel"
|
|
435
|
+
}), (showLimited || !isLimited) && /*#__PURE__*/jsxRuntime.jsx("pre", {
|
|
436
|
+
ref: ref,
|
|
437
|
+
children: content
|
|
438
|
+
}), timeTravelEnabled && (showLimited || !isLimited) && /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
439
|
+
className: timeTravelPanelClassName,
|
|
440
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("button", {
|
|
441
|
+
className: timeTravelPanelButtonClassName,
|
|
442
|
+
onClick: () => {
|
|
443
|
+
if (playingIndexRef.current === totalEditorStates - 1) {
|
|
444
|
+
playingIndexRef.current = 1;
|
|
445
|
+
}
|
|
446
|
+
setIsPlaying(!isPlaying);
|
|
447
|
+
},
|
|
448
|
+
type: "button",
|
|
449
|
+
children: isPlaying ? 'Pause' : 'Play'
|
|
450
|
+
}), /*#__PURE__*/jsxRuntime.jsx("input", {
|
|
451
|
+
className: timeTravelPanelSliderClassName,
|
|
452
|
+
ref: inputRef,
|
|
453
|
+
onChange: event => {
|
|
454
|
+
const editorStateIndex = Number(event.target.value);
|
|
455
|
+
const timeStampedEditorState = timeStampedEditorStates[editorStateIndex];
|
|
456
|
+
if (timeStampedEditorState) {
|
|
457
|
+
playingIndexRef.current = editorStateIndex;
|
|
458
|
+
setEditorState(timeStampedEditorState[1]);
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
type: "range",
|
|
462
|
+
min: "1",
|
|
463
|
+
max: totalEditorStates - 1
|
|
464
|
+
}), /*#__PURE__*/jsxRuntime.jsx("button", {
|
|
465
|
+
className: timeTravelPanelButtonClassName,
|
|
466
|
+
onClick: () => {
|
|
467
|
+
setEditorReadOnly(false);
|
|
468
|
+
const index = timeStampedEditorStates.length - 1;
|
|
469
|
+
const timeStampedEditorState = timeStampedEditorStates[index];
|
|
470
|
+
setEditorState(timeStampedEditorState[1]);
|
|
471
|
+
const input = inputRef.current;
|
|
472
|
+
if (input !== null) {
|
|
473
|
+
input.value = String(index);
|
|
474
|
+
}
|
|
475
|
+
setTimeTravelEnabled(false);
|
|
476
|
+
setIsPlaying(false);
|
|
477
|
+
},
|
|
478
|
+
type: "button",
|
|
479
|
+
children: "Exit"
|
|
480
|
+
})]
|
|
481
|
+
})]
|
|
482
|
+
});
|
|
481
483
|
});
|
|
482
484
|
|
|
483
485
|
/**
|
|
@@ -490,11 +492,14 @@ const TreeView = /*#__PURE__*/React.forwardRef(function TreeViewWrapped({
|
|
|
490
492
|
|
|
491
493
|
function registerLexicalCommandLogger(editor, setLoggedCommands) {
|
|
492
494
|
const unregisterCommandListeners = new Set();
|
|
495
|
+
let i = 0;
|
|
493
496
|
for (const [command] of editor._commands) {
|
|
494
497
|
unregisterCommandListeners.add(editor.registerCommand(command, payload => {
|
|
495
498
|
setLoggedCommands(state => {
|
|
499
|
+
i += 1;
|
|
496
500
|
const newState = [...state];
|
|
497
501
|
newState.push({
|
|
502
|
+
index: i,
|
|
498
503
|
payload,
|
|
499
504
|
type: command.type ? command.type : 'UNKNOWN'
|
|
500
505
|
});
|
|
@@ -509,11 +514,11 @@ function registerLexicalCommandLogger(editor, setLoggedCommands) {
|
|
|
509
514
|
return () => unregisterCommandListeners.forEach(unregister => unregister());
|
|
510
515
|
}
|
|
511
516
|
function useLexicalCommandsLog(editor) {
|
|
512
|
-
const [loggedCommands, setLoggedCommands] =
|
|
513
|
-
|
|
517
|
+
const [loggedCommands, setLoggedCommands] = react.useState([]);
|
|
518
|
+
react.useEffect(() => {
|
|
514
519
|
return registerLexicalCommandLogger(editor, setLoggedCommands);
|
|
515
520
|
}, [editor]);
|
|
516
|
-
return
|
|
521
|
+
return react.useMemo(() => loggedCommands, [loggedCommands]);
|
|
517
522
|
}
|
|
518
523
|
|
|
519
524
|
exports.TreeView = TreeView;
|
|
@@ -11,8 +11,8 @@ import { $isLinkNode } from '@lexical/link';
|
|
|
11
11
|
import { $isMarkNode } from '@lexical/mark';
|
|
12
12
|
import { $isTableSelection } from '@lexical/table';
|
|
13
13
|
import { $getSelection, $getRoot, $isRangeSelection, $isNodeSelection, $isElementNode, $isTextNode, $isParagraphNode, COMMAND_PRIORITY_CRITICAL } from 'lexical';
|
|
14
|
-
import * as React from 'react';
|
|
15
14
|
import { forwardRef, useState, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
15
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -39,7 +39,7 @@ const FORMAT_PREDICATES = [node => node.hasFormat('bold') && 'Bold', node => nod
|
|
|
39
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'];
|
|
40
40
|
const DETAIL_PREDICATES = [node => node.isDirectionless() && 'Directionless', node => node.isUnmergeable() && 'Unmergeable'];
|
|
41
41
|
const MODE_PREDICATES = [node => node.isToken() && 'Token', node => node.isSegmented() && 'Segmented'];
|
|
42
|
-
function generateContent(editor, commandsLog, exportDOM, obfuscateText = false) {
|
|
42
|
+
function generateContent(editor, commandsLog, exportDOM, customPrintNode, obfuscateText = false) {
|
|
43
43
|
const editorState = editor.getEditorState();
|
|
44
44
|
const editorConfig = editor._config;
|
|
45
45
|
const compositionKey = editor._compositionKey;
|
|
@@ -59,8 +59,7 @@ function generateContent(editor, commandsLog, exportDOM, obfuscateText = false)
|
|
|
59
59
|
const nodeKeyDisplay = `(${nodeKey})`;
|
|
60
60
|
const typeDisplay = node.getType() || '';
|
|
61
61
|
const isSelected = node.isSelected();
|
|
62
|
-
|
|
63
|
-
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${idsDisplay} ${printNode(node, obfuscateText)}\n`;
|
|
62
|
+
res += `${isSelected ? SYMBOLS.selectedLine : ' '} ${indent.join(' ')} ${nodeKeyDisplay} ${typeDisplay} ${printNode(node, customPrintNode, obfuscateText)}\n`;
|
|
64
63
|
res += $printSelectedCharsLine({
|
|
65
64
|
indent,
|
|
66
65
|
isSelected,
|
|
@@ -76,10 +75,11 @@ function generateContent(editor, commandsLog, exportDOM, obfuscateText = false)
|
|
|
76
75
|
res += '\n\n commands:';
|
|
77
76
|
if (commandsLog.length) {
|
|
78
77
|
for (const {
|
|
78
|
+
index,
|
|
79
79
|
type,
|
|
80
80
|
payload
|
|
81
81
|
} of commandsLog) {
|
|
82
|
-
res += `\n └ { type: ${type}, payload: ${payload instanceof Event ? payload.constructor.name : payload} }`;
|
|
82
|
+
res += `\n └ ${index}. { type: ${type}, payload: ${payload instanceof Event ? payload.constructor.name : payload} }`;
|
|
83
83
|
}
|
|
84
84
|
} else {
|
|
85
85
|
res += '\n └ None dispatched.';
|
|
@@ -130,9 +130,11 @@ function normalize(text, obfuscateText = false) {
|
|
|
130
130
|
}
|
|
131
131
|
return textToPrint;
|
|
132
132
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
function printNode(node, customPrintNode, obfuscateText = false) {
|
|
134
|
+
const customPrint = customPrintNode ? customPrintNode(node, obfuscateText) : undefined;
|
|
135
|
+
if (customPrint !== undefined && customPrint.length > 0) {
|
|
136
|
+
return customPrint;
|
|
137
|
+
}
|
|
136
138
|
if ($isTextNode(node)) {
|
|
137
139
|
const text = node.getTextContent();
|
|
138
140
|
const title = text.length === 0 ? '(empty)' : `"${normalize(text, obfuscateText)}"`;
|
|
@@ -143,6 +145,8 @@ function printNode(node, obfuscateText = false) {
|
|
|
143
145
|
const title = link.length === 0 ? '(empty)' : `"${normalize(link, obfuscateText)}"`;
|
|
144
146
|
const properties = printAllLinkNodeProperties(node);
|
|
145
147
|
return [title, properties.length !== 0 ? `{ ${properties} }` : null].filter(Boolean).join(' ').trim();
|
|
148
|
+
} else if ($isMarkNode(node)) {
|
|
149
|
+
return `ids: [ ${node.getIDs().join(', ')} ]`;
|
|
146
150
|
} else if ($isParagraphNode(node)) {
|
|
147
151
|
const formatText = printTextFormatProperties(node);
|
|
148
152
|
return formatText !== '' ? `{ ${formatText} }` : '';
|
|
@@ -388,82 +392,92 @@ const TreeView = /*#__PURE__*/forwardRef(function TreeViewWrapped({
|
|
|
388
392
|
generateTree(!showExportDOM);
|
|
389
393
|
setShowExportDOM(!showExportDOM);
|
|
390
394
|
};
|
|
391
|
-
return /*#__PURE__*/
|
|
392
|
-
className: viewClassName
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
395
|
+
return /*#__PURE__*/jsxs("div", {
|
|
396
|
+
className: viewClassName,
|
|
397
|
+
children: [!showLimited && isLimited ? /*#__PURE__*/jsxs("div", {
|
|
398
|
+
style: {
|
|
399
|
+
padding: 20
|
|
400
|
+
},
|
|
401
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
402
|
+
style: {
|
|
403
|
+
marginRight: 20
|
|
404
|
+
},
|
|
405
|
+
children: "Detected large EditorState, this can impact debugging performance."
|
|
406
|
+
}), /*#__PURE__*/jsx("button", {
|
|
407
|
+
onClick: () => {
|
|
408
|
+
setShowLimited(true);
|
|
409
|
+
},
|
|
410
|
+
style: {
|
|
411
|
+
background: 'transparent',
|
|
412
|
+
border: '1px solid white',
|
|
413
|
+
color: 'white',
|
|
414
|
+
cursor: 'pointer',
|
|
415
|
+
padding: 5
|
|
416
|
+
},
|
|
417
|
+
children: "Show full tree"
|
|
418
|
+
})]
|
|
419
|
+
}) : null, !showLimited ? /*#__PURE__*/jsx("button", {
|
|
420
|
+
onClick: () => handleExportModeToggleClick(),
|
|
421
|
+
className: treeTypeButtonClassName,
|
|
422
|
+
type: "button",
|
|
423
|
+
children: showExportDOM ? 'Tree' : 'Export DOM'
|
|
424
|
+
}) : null, !timeTravelEnabled && (showLimited || !isLimited) && totalEditorStates > 2 && /*#__PURE__*/jsx("button", {
|
|
425
|
+
onClick: () => {
|
|
426
|
+
setEditorReadOnly(true);
|
|
427
|
+
playingIndexRef.current = totalEditorStates - 1;
|
|
428
|
+
setTimeTravelEnabled(true);
|
|
429
|
+
},
|
|
430
|
+
className: timeTravelButtonClassName,
|
|
431
|
+
type: "button",
|
|
432
|
+
children: "Time Travel"
|
|
433
|
+
}), (showLimited || !isLimited) && /*#__PURE__*/jsx("pre", {
|
|
434
|
+
ref: ref,
|
|
435
|
+
children: content
|
|
436
|
+
}), timeTravelEnabled && (showLimited || !isLimited) && /*#__PURE__*/jsxs("div", {
|
|
437
|
+
className: timeTravelPanelClassName,
|
|
438
|
+
children: [/*#__PURE__*/jsx("button", {
|
|
439
|
+
className: timeTravelPanelButtonClassName,
|
|
440
|
+
onClick: () => {
|
|
441
|
+
if (playingIndexRef.current === totalEditorStates - 1) {
|
|
442
|
+
playingIndexRef.current = 1;
|
|
443
|
+
}
|
|
444
|
+
setIsPlaying(!isPlaying);
|
|
445
|
+
},
|
|
446
|
+
type: "button",
|
|
447
|
+
children: isPlaying ? 'Pause' : 'Play'
|
|
448
|
+
}), /*#__PURE__*/jsx("input", {
|
|
449
|
+
className: timeTravelPanelSliderClassName,
|
|
450
|
+
ref: inputRef,
|
|
451
|
+
onChange: event => {
|
|
452
|
+
const editorStateIndex = Number(event.target.value);
|
|
453
|
+
const timeStampedEditorState = timeStampedEditorStates[editorStateIndex];
|
|
454
|
+
if (timeStampedEditorState) {
|
|
455
|
+
playingIndexRef.current = editorStateIndex;
|
|
456
|
+
setEditorState(timeStampedEditorState[1]);
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
type: "range",
|
|
460
|
+
min: "1",
|
|
461
|
+
max: totalEditorStates - 1
|
|
462
|
+
}), /*#__PURE__*/jsx("button", {
|
|
463
|
+
className: timeTravelPanelButtonClassName,
|
|
464
|
+
onClick: () => {
|
|
465
|
+
setEditorReadOnly(false);
|
|
466
|
+
const index = timeStampedEditorStates.length - 1;
|
|
467
|
+
const timeStampedEditorState = timeStampedEditorStates[index];
|
|
468
|
+
setEditorState(timeStampedEditorState[1]);
|
|
469
|
+
const input = inputRef.current;
|
|
470
|
+
if (input !== null) {
|
|
471
|
+
input.value = String(index);
|
|
472
|
+
}
|
|
473
|
+
setTimeTravelEnabled(false);
|
|
474
|
+
setIsPlaying(false);
|
|
475
|
+
},
|
|
476
|
+
type: "button",
|
|
477
|
+
children: "Exit"
|
|
478
|
+
})]
|
|
479
|
+
})]
|
|
480
|
+
});
|
|
467
481
|
});
|
|
468
482
|
|
|
469
483
|
/**
|
|
@@ -476,11 +490,14 @@ const TreeView = /*#__PURE__*/forwardRef(function TreeViewWrapped({
|
|
|
476
490
|
|
|
477
491
|
function registerLexicalCommandLogger(editor, setLoggedCommands) {
|
|
478
492
|
const unregisterCommandListeners = new Set();
|
|
493
|
+
let i = 0;
|
|
479
494
|
for (const [command] of editor._commands) {
|
|
480
495
|
unregisterCommandListeners.add(editor.registerCommand(command, payload => {
|
|
481
496
|
setLoggedCommands(state => {
|
|
497
|
+
i += 1;
|
|
482
498
|
const newState = [...state];
|
|
483
499
|
newState.push({
|
|
500
|
+
index: i,
|
|
484
501
|
payload,
|
|
485
502
|
type: command.type ? command.type : 'UNKNOWN'
|
|
486
503
|
});
|
|
@@ -12,26 +12,31 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
LexicalCommand,
|
|
16
|
+
LexicalEditor,
|
|
17
|
+
LexicalNode,
|
|
17
18
|
} from 'lexical';
|
|
18
19
|
|
|
19
|
-
export type LexicalCommandLog = $ReadOnlyArray<
|
|
20
|
+
export type LexicalCommandLog = $ReadOnlyArray<
|
|
21
|
+
{index: number} | LexicalCommand<mixed> | {payload: mixed}
|
|
22
|
+
>;
|
|
23
|
+
export type CustomPrintNodeFn = (node: LexicalNode, obfuscateText?: boolean) => string;
|
|
20
24
|
|
|
21
25
|
declare export function generateContent(
|
|
22
|
-
editor: LexicalEditor,
|
|
23
|
-
commandsLog: $ReadOnlyArray<LexicalCommandLog>,
|
|
24
|
-
exportDOM: boolean,
|
|
25
|
-
|
|
26
|
+
editor: LexicalEditor,
|
|
27
|
+
commandsLog: $ReadOnlyArray<LexicalCommandLog>,
|
|
28
|
+
exportDOM: boolean,
|
|
29
|
+
customPrintNode?: CustomPrintNodeFn,
|
|
30
|
+
obfuscateText?: boolean,
|
|
26
31
|
): string;
|
|
27
32
|
|
|
28
33
|
declare export function registerLexicalCommandLogger(
|
|
29
|
-
editor: LexicalEditor,
|
|
30
|
-
setLoggedCommands: (
|
|
31
|
-
|
|
32
|
-
) => void,
|
|
34
|
+
editor: LexicalEditor,
|
|
35
|
+
setLoggedCommands: (
|
|
36
|
+
v: (oldValue: LexicalCommandLog) => LexicalCommandLog,
|
|
37
|
+
) => void,
|
|
33
38
|
): () => void;
|
|
34
39
|
|
|
35
40
|
declare export function useLexicalCommandsLog(
|
|
36
|
-
editor: LexicalEditor,
|
|
37
|
-
): LexicalCommandLog;
|
|
41
|
+
editor: LexicalEditor,
|
|
42
|
+
): LexicalCommandLog;
|
|
@@ -6,22 +6,22 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
'use strict';var
|
|
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:">"}),
|
|
11
|
-
"Underline"],
|
|
12
|
-
function
|
|
13
|
-
function W(a,b,c=[]){a=a.getChildren();let e=a.length;a.forEach((d,
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
function
|
|
17
|
-
function
|
|
18
|
-
|
|
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
|
|
20
|
-
let
|
|
21
|
-
++J.current;
|
|
22
|
-
|
|
23
|
-
E?"Tree":"Export DOM"),!
|
|
24
|
-
|
|
25
|
-
exports.generateContent=function(a,b,c,e=!1){let
|
|
26
|
-
|
|
27
|
-
|
|
9
|
+
'use strict';var k=require("@lexical/html"),t=require("@lexical/link"),u=require("@lexical/mark"),w=require("@lexical/table"),L=require("lexical"),M=require("react"),N=require("react/jsx-runtime");
|
|
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:">"}),aa=[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"],ba=[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"],ca=[a=>a.isDirectionless()&&"Directionless",a=>a.isUnmergeable()&&"Unmergeable"],da=[a=>a.isToken()&&"Token",a=>a.isSegmented()&&"Segmented"];
|
|
12
|
+
function ea(a){let b="";var c=V(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 fa(a){return L.$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,l)=>{b(d,c.concat(l===e-1?Q.isLastChild:Q.hasNextSibling));L.$isElementNode(d)&&W(d,b,c.concat(l===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 ha(a,b,c=!1){b=b?b(a,c):void 0;if(void 0!==b&&0<b.length)return b;if(L.$isTextNode(a))return b=a.getTextContent(),c=0===b.length?"(empty)":`"${X(b,c)}"`,a=[V(a),ia(a),ja(a)].filter(Boolean).join(", "),[c,0!==a.length?`{ ${a} }`:null].filter(Boolean).join(" ").trim();if(t.$isLinkNode(a)){b=a.getURL();c=0===b.length?"(empty)":`"${X(b,c)}"`;b=a.getTarget();null!=b&&(b="target: "+b);var e=Boolean;var d=a.getRel();null!=d&&(d="rel: "+d);a=a.getTitle();null!=a&&(a="title: "+a);a=[b,d,a].filter(e).join(", ");
|
|
15
|
+
return[c,0!==a.length?`{ ${a} }`:null].filter(Boolean).join(" ").trim()}return u.$isMarkNode(a)?`ids: [ ${a.getIDs().join(", ")} ]`:L.$isParagraphNode(a)?(a=ka(a),""!==a?`{ ${a} }`:""):""}function ka(a){let b=ba.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="format: "+b);return b}function ia(a){let b=ca.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="detail: "+b);return b}
|
|
16
|
+
function ja(a){let b=da.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="mode: "+b);return b}function V(a){let b=aa.map(c=>c(a)).filter(Boolean).join(", ").toLocaleLowerCase();""!==b&&(b="format: "+b);return b}
|
|
17
|
+
function la({indent:a,isSelected:b,node:c,nodeKeyDisplay:e,selection:d,typeDisplay:l}){if(!L.$isTextNode(c)||!L.$isRangeSelection(d)||!b||L.$isElementNode(c))return"";b=d.anchor;var f=d.focus;if(""===c.getTextContent()||b.getNode()===d.focus.getNode()&&b.offset===f.offset)return"";b=d.getStartEndPoints();if(L.$isNodeSelection(d)||null===b)c=[-1,-1];else{var [p,r]=b;f=c.getTextContent();var m=f.length;b=d=-1;if("text"===p.type&&"text"===r.type){let n=p.getNode(),x=r.getNode();n===x&&c===n&&p.offset!==
|
|
18
|
+
r.offset?[d,b]=p.offset<r.offset?[p.offset,r.offset]:[r.offset,p.offset]:c===n?[d,b]=n.isBefore(x)?[p.offset,m]:[0,p.offset]:c===x?[d,b]=x.isBefore(n)?[r.offset,m]:[0,r.offset]:[d,b]=[0,m]}c=(f.slice(0,d).match(P)||[]).length;f=(f.slice(d,b).match(P)||[]).length;c=[d+c,b+c+f]}let [h,g]=c;if(h===g)return"";c=a[a.length-1]===Q.hasNextSibling?Q.ancestorHasNextSibling:Q.ancestorIsLastChild;a=[...a.slice(0,a.length-1),c];c=Array(h+1).fill(" ");d=Array(g-h).fill(Q.selectedChar);e=Array(e.length+(l.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 l=0;l<a.children.length;l++)d=document.createTextNode("\n"+c),a.insertBefore(d,a.children[l]),Y(a.children[l],b),a.lastElementChild===a.children[l]&&(d=document.createTextNode("\n"+e),a.appendChild(d));return a}
|
|
20
|
+
let pa=M.forwardRef(function({treeTypeButtonClassName:a,timeTravelButtonClassName:b,timeTravelPanelSliderClassName:c,timeTravelPanelButtonClassName:e,viewClassName:d,timeTravelPanelClassName:l,editorState:f,setEditorState:p,setEditorReadOnly:r,generateContent:m},h){const [g,n]=M.useState([]),[x,D]=M.useState(""),[A,R]=M.useState(!1),[E,ma]=M.useState(!1),B=M.useRef(0),H=M.useRef(null),[F,I]=M.useState(!1),[G,na]=M.useState(!1),[y,oa]=M.useState(!1),S=M.useRef(),J=M.useRef(0),K=M.useCallback(q=>{const v=
|
|
21
|
+
++J.current;m(q).then(z=>{v===J.current&&D(z)}).catch(z=>{v===J.current&&D(`Error rendering tree: ${z.message}\n\nStack:\n${z.stack}`)})},[m]);M.useEffect(()=>{if(!y&&1E3<f._nodeMap.size&&(na(!0),!y))return;S.current!==f&&(S.current=f,K(E),A||n(q=>[...q,[Date.now(),f]]))},[f,K,E,y,A]);const C=g.length;M.useEffect(()=>{if(F){let q;const v=()=>{const z=B.current;z===C-1?I(!1):q=setTimeout(()=>{B.current++;const T=B.current,U=H.current;null!==U&&(U.value=String(T));p(g[T][1]);v()},g[z+1][0]-g[z][0])};
|
|
22
|
+
v();return()=>{clearTimeout(q)}}},[g,F,C,p]);return N.jsxs("div",{className:d,children:[!y&&G?N.jsxs("div",{style:{padding:20},children:[N.jsx("span",{style:{marginRight:20},children:"Detected large EditorState, this can impact debugging performance."}),N.jsx("button",{onClick:()=>{oa(!0)},style:{background:"transparent",border:"1px solid white",color:"white",cursor:"pointer",padding:5},children:"Show full tree"})]}):null,y?null:N.jsx("button",{onClick:()=>{K(!E);ma(!E)},className:a,type:"button",
|
|
23
|
+
children:E?"Tree":"Export DOM"}),!A&&(y||!G)&&2<C&&N.jsx("button",{onClick:()=>{r(!0);B.current=C-1;R(!0)},className:b,type:"button",children:"Time Travel"}),(y||!G)&&N.jsx("pre",{ref:h,children:x}),A&&(y||!G)&&N.jsxs("div",{className:l,children:[N.jsx("button",{className:e,onClick:()=>{B.current===C-1&&(B.current=1);I(!F)},type:"button",children:F?"Pause":"Play"}),N.jsx("input",{className:c,ref:H,onChange:q=>{q=Number(q.target.value);const v=g[q];v&&(B.current=q,p(v[1]))},type:"range",min:"1",max:C-
|
|
24
|
+
1}),N.jsx("button",{className:e,onClick:()=>{r(!1);const q=g.length-1;p(g[q][1]);const v=H.current;null!==v&&(v.value=String(q));R(!1);I(!1)},type:"button",children:"Exit"})]})]})});function Z(a,b){let c=new Set,e=0;for(let [d]of a._commands)c.add(a.registerCommand(d,l=>{b(f=>{e+=1;f=[...f];f.push({index:e,payload:l,type:d.type?d.type:"UNKNOWN"});10<f.length&&f.shift();return f});return!1},L.COMMAND_PRIORITY_CRITICAL));return()=>c.forEach(d=>d())}exports.TreeView=pa;
|
|
25
|
+
exports.generateContent=function(a,b,c,e,d=!1){let l=a.getEditorState(),f=a._config,p=a._compositionKey,r=a._editable;if(c){let h="";l.read(()=>{var g=k.$generateHtmlFromNodes(a);let n=document.createElement("div");n.innerHTML=g.trim();h=Y(n,0).innerHTML});return h}let m=" root\n";c=l.read(()=>{const h=L.$getSelection();W(L.$getRoot(),(g,n)=>{const x=`(${g.getKey()})`,D=g.getType()||"",A=g.isSelected();m+=`${A?Q.selectedLine:" "} ${n.join(" ")} ${x} ${D} ${ha(g,e,d)}\n`;m+=la({indent:n,isSelected:A,
|
|
26
|
+
node:g,nodeKeyDisplay:x,selection:h,typeDisplay:D})});return null===h?": null":L.$isRangeSelection(h)?ea(h):w.$isTableSelection(h)?`: table\n \u2514 { table: ${h.tableKey}, anchorCell: ${h.anchor.key}, focusCell: ${h.focus.key} }`:fa(h)});m+="\n selection"+c;m+="\n\n commands:";if(b.length)for(let {index:h,type:g,payload:n}of b)m+=`\n \u2514 ${h}. { type: ${g}, payload: ${n instanceof Event?n.constructor.name:n} }`;else m+="\n \u2514 None dispatched.";m+="\n\n editor:";m+=`\n \u2514 namespace ${f.namespace}`;
|
|
27
|
+
null!==p&&(m+=`\n \u2514 compositionKey ${p}`);return m+=`\n \u2514 editable ${String(r)}`};exports.registerLexicalCommandLogger=Z;exports.useLexicalCommandsLog=function(a){let [b,c]=M.useState([]);M.useEffect(()=>Z(a,c),[a]);return M.useMemo(()=>b,[b])}
|
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
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
|
|
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 i,$isRangeSelection as l,$isNodeSelection as s,$isElementNode as a,$isTextNode as c,$isParagraphNode as u,COMMAND_PRIORITY_CRITICAL as f}from"lexical";import{forwardRef as d,useState as m,useRef as h,useCallback as g,useEffect as p,useMemo as y}from"react";import{jsxs as b,jsx as x}from"react/jsx-runtime";const C=Object.freeze({"\t":"\\t","\n":"\\n"}),$=new RegExp(Object.keys(C).join("|"),"g"),N=Object.freeze({ancestorHasNextSibling:"|",ancestorIsLastChild:" ",hasNextSibling:"├",isLastChild:"└",selectedChar:"^",selectedLine:">"}),S=[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"],T=[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"],k=[e=>e.isDirectionless()&&"Directionless",e=>e.isUnmergeable()&&"Unmergeable"],j=[e=>e.isToken()&&"Token",e=>e.isSegmented()&&"Segmented"];function L(f,d,m,h,g=!1){const p=f.getEditorState(),y=f._config,b=f._compositionKey,x=f._editable;if(m){let t="";return p.read((()=>{t=function(e){const t=document.createElement("div");return t.innerHTML=e.trim(),A(t,0).innerHTML}(e(f))})),t}let C=" root\n";const S=p.read((()=>{const e=o();return v(i(),((r,o)=>{const i=`(${r.getKey()})`,f=r.getType()||"",d=r.isSelected();C+=`${d?N.selectedLine:" "} ${o.join(" ")} ${i} ${f} ${function(e,r,o=!1){const i=r?r(e,o):void 0;if(void 0!==i&&i.length>0)return i;if(c(e)){const t=e.getTextContent(),n=0===t.length?"(empty)":`"${B(t,o)}"`,r=function(e){return[F(e),E(e),w(e)].filter(Boolean).join(", ")}(e);return[n,0!==r.length?`{ ${r} }`:null].filter(Boolean).join(" ").trim()}if(t(e)){const t=e.getURL(),n=0===t.length?"(empty)":`"${B(t,o)}"`,r=function(e){return[D(e),K(e),O(e)].filter(Boolean).join(", ")}(e);return[n,0!==r.length?`{ ${r} }`:null].filter(Boolean).join(" ").trim()}if(n(e))return`ids: [ ${e.getIDs().join(", ")} ]`;if(u(e)){const t=function(e){let t=T.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();""!==t&&(t="format: "+t);return t}(e);return""!==t?`{ ${t} }`:""}return""}(r,h,g)}\n`,C+=function({indent:e,isSelected:t,node:n,nodeKeyDisplay:r,selection:o,typeDisplay:i}){if(!c(n)||!l(o)||!t||a(n))return"";const u=o.anchor,f=o.focus;if(""===n.getTextContent()||u.getNode()===o.focus.getNode()&&u.offset===f.offset)return"";const[d,m]=function(e,t){const n=t.getStartEndPoints();if(s(t)||null===n)return[-1,-1];const[r,o]=n,i=e.getTextContent(),l=i.length;let a=-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?[a,c]=r.offset<o.offset?[r.offset,o.offset]:[o.offset,r.offset]:[a,c]=e===t?t.isBefore(n)?[r.offset,l]:[0,r.offset]:e===n?n.isBefore(t)?[o.offset,l]:[0,o.offset]:[0,l]}const u=(i.slice(0,a).match($)||[]).length,f=(i.slice(a,c).match($)||[]).length;return[a+u,c+u+f]}(n,o);if(d===m)return"";const h=e[e.length-1]===N.hasNextSibling?N.ancestorHasNextSibling:N.ancestorIsLastChild,g=[...e.slice(0,e.length-1),h],p=Array(d+1).fill(" "),y=Array(m-d).fill(N.selectedChar),b=i.length+3,x=Array(r.length+b).fill(" ");return[N.selectedLine,g.join(" "),[...x,...p,...y].join("")].join(" ")+"\n"}({indent:o,isSelected:d,node:r,nodeKeyDisplay:i,selection:e,typeDisplay:f})})),null===e?": null":l(e)?function(e){let t="";const n=F(e);t+=`: range ${""!==n?`{ ${n} }`:""} ${""!==e.style?`{ style: ${e.style} } `:""}`;const r=e.anchor,o=e.focus,i=r.offset,l=o.offset;return t+=`\n ├ anchor { key: ${r.key}, offset: ${null===i?"null":i}, type: ${r.type} }`,t+=`\n └ focus { key: ${o.key}, offset: ${null===l?"null":l}, 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(!s(e))return"";return`: node\n └ [${Array.from(e._nodes).join(", ")}]`}(e)}));if(C+="\n selection"+S,C+="\n\n commands:",d.length)for(const{index:e,type:t,payload:n}of d)C+=`\n └ ${e}. { type: ${t}, payload: ${n instanceof Event?n.constructor.name:n} }`;else C+="\n └ None dispatched.";return C+="\n\n editor:",C+=`\n └ namespace ${y.namespace}`,null!==b&&(C+=`\n └ compositionKey ${b}`),C+=`\n └ editable ${String(x)}`,C}function v(e,t,n=[]){const r=e.getChildren(),o=r.length;r.forEach(((e,r)=>{t(e,n.concat(r===o-1?N.isLastChild:N.hasNextSibling)),a(e)&&v(e,t,n.concat(r===o-1?N.ancestorIsLastChild:N.ancestorHasNextSibling))}))}function B(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 E(e){let t=k.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="detail: "+t),t}function w(e){let t=j.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="mode: "+t),t}function F(e){let t=S.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="format: "+t),t}function D(e){let t=e.getTarget();return null!=t&&(t="target: "+t),t}function K(e){let t=e.getRel();return null!=t&&(t="rel: "+t),t}function O(e){let t=e.getTitle();return null!=t&&(t="title: "+t),t}function A(e,t){const n=new Array(1+t++).join(" "),r=new Array(t-1).join(" ");let o;for(let i=0;i<e.children.length;i++)o=document.createTextNode("\n"+n),e.insertBefore(o,e.children[i]),A(e.children[i],t),e.lastElementChild===e.children[i]&&(o=document.createTextNode("\n"+r),e.appendChild(o));return e}const I=d((function({treeTypeButtonClassName:e,timeTravelButtonClassName:t,timeTravelPanelSliderClassName:n,timeTravelPanelButtonClassName:r,viewClassName:o,timeTravelPanelClassName:i,editorState:l,setEditorState:s,setEditorReadOnly:a,generateContent:c},u){const[f,d]=m([]),[y,C]=m(""),[$,N]=m(!1),[S,T]=m(!1),k=h(0),j=h(null),[L,v]=m(!1),[B,E]=m(!1),[w,F]=m(!1),D=h(),K=h(0),O=g((e=>{const t=++K.current;c(e).then((e=>{t===K.current&&C(e)})).catch((e=>{t===K.current&&C(`Error rendering tree: ${e.message}\n\nStack:\n${e.stack}`)}))}),[c]);p((()=>{!w&&l._nodeMap.size>1e3&&(E(!0),!w)||D.current!==l&&(D.current=l,O(S),$||d((e=>[...e,[Date.now(),l]])))}),[l,O,S,w,$]);const A=f.length;p((()=>{if(L){let e;const t=()=>{const n=k.current;if(n===A-1)return void v(!1);const r=f[n][0],o=f[n+1][0];e=setTimeout((()=>{k.current++;const e=k.current,n=j.current;null!==n&&(n.value=String(e)),s(f[e][1]),t()}),o-r)};return t(),()=>{clearTimeout(e)}}}),[f,L,A,s]);return b("div",{className:o,children:[!w&&B?b("div",{style:{padding:20},children:[x("span",{style:{marginRight:20},children:"Detected large EditorState, this can impact debugging performance."}),x("button",{onClick:()=>{F(!0)},style:{background:"transparent",border:"1px solid white",color:"white",cursor:"pointer",padding:5},children:"Show full tree"})]}):null,w?null:x("button",{onClick:()=>(O(!S),void T(!S)),className:e,type:"button",children:S?"Tree":"Export DOM"}),!$&&(w||!B)&&A>2&&x("button",{onClick:()=>{a(!0),k.current=A-1,N(!0)},className:t,type:"button",children:"Time Travel"}),(w||!B)&&x("pre",{ref:u,children:y}),$&&(w||!B)&&b("div",{className:i,children:[x("button",{className:r,onClick:()=>{k.current===A-1&&(k.current=1),v(!L)},type:"button",children:L?"Pause":"Play"}),x("input",{className:n,ref:j,onChange:e=>{const t=Number(e.target.value),n=f[t];n&&(k.current=t,s(n[1]))},type:"range",min:"1",max:A-1}),x("button",{className:r,onClick:()=>{a(!1);const e=f.length-1,t=f[e];s(t[1]);const n=j.current;null!==n&&(n.value=String(e)),N(!1),v(!1)},type:"button",children:"Exit"})]})]})}));function P(e,t){const n=new Set;let r=0;for(const[o]of e._commands)n.add(e.registerCommand(o,(e=>(t((t=>{r+=1;const n=[...t];return n.push({index:r,payload:e,type:o.type?o.type:"UNKNOWN"}),n.length>10&&n.shift(),n})),!1)),f));return()=>n.forEach((e=>e()))}function R(e){const[t,n]=m([]);return p((()=>P(e,n)),[e]),y((()=>t),[t])}export{I as TreeView,L as generateContent,P as registerLexicalCommandLogger,R as useLexicalCommandsLog};
|
package/generateContent.d.ts
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
import type { LexicalEditor } from 'lexical';
|
|
9
|
-
import {
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
}>, exportDOM: boolean, obfuscateText?: boolean): string;
|
|
8
|
+
import type { LexicalEditor, LexicalNode } from 'lexical';
|
|
9
|
+
import { LexicalCommandLog } from './useLexicalCommandsLog';
|
|
10
|
+
export type CustomPrintNodeFn = (node: LexicalNode, obfuscateText?: boolean) => string;
|
|
11
|
+
export declare function generateContent(editor: LexicalEditor, commandsLog: LexicalCommandLog, exportDOM: boolean, customPrintNode?: CustomPrintNodeFn, 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.16.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.16.0",
|
|
16
|
+
"@lexical/link": "0.16.0",
|
|
17
|
+
"@lexical/mark": "0.16.0",
|
|
18
|
+
"@lexical/table": "0.16.0",
|
|
19
|
+
"@lexical/utils": "0.16.0",
|
|
20
|
+
"lexical": "0.16.0"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"react": ">=17.x",
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { LexicalEditor } from 'lexical';
|
|
9
9
|
import { LexicalCommand } from 'lexical';
|
|
10
|
-
export type LexicalCommandLog = ReadonlyArray<
|
|
10
|
+
export type LexicalCommandLog = ReadonlyArray<{
|
|
11
|
+
index: number;
|
|
12
|
+
} & LexicalCommand<unknown> & {
|
|
11
13
|
payload: unknown;
|
|
12
14
|
}>;
|
|
13
15
|
export declare function registerLexicalCommandLogger(editor: LexicalEditor, setLoggedCommands: (v: (oldValue: LexicalCommandLog) => LexicalCommandLog) => void): () => void;
|