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