Skip to content

Commit

Permalink
Add command logging into tree view (#4022)
Browse files Browse the repository at this point in the history
  • Loading branch information
thegreatercurve authored Mar 3, 2023
1 parent 89985f7 commit ea82cb5
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 8 deletions.
3 changes: 1 addition & 2 deletions packages/lexical-playground/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pre {
padding: 10px;
font-size: 12px;
overflow: auto;
max-height: 180px;
max-height: 400px;
}

.tree-view-output {
Expand All @@ -114,7 +114,6 @@ pre {
padding: 0;
font-size: 12px;
margin: 1px auto 10px auto;
max-height: 250px;
position: relative;
overflow: hidden;
border-bottom-left-radius: 10px;
Expand Down
77 changes: 71 additions & 6 deletions packages/lexical-react/src/LexicalTreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import {
$isElementNode,
$isRangeSelection,
$isTextNode,
COMMAND_PRIORITY_HIGH,
DEPRECATED_$isGridSelection,
LexicalCommand,
} from 'lexical';
import * as React from 'react';
import {useCallback, useEffect, useRef, useState} from 'react';
import {useCallback, useEffect, useMemo, useRef, useState} from 'react';

const NON_SINGLE_WIDTH_CHARS_REPLACEMENT: Readonly<Record<string, string>> =
Object.freeze({
Expand Down Expand Up @@ -77,14 +79,18 @@ export function TreeView({
const [showLimited, setShowLimited] = useState(false);
const lastEditorStateRef = useRef<null | EditorState>(null);

const commandsLog = useLexicalCommandsLog(editor);

const generateTree = useCallback(
(editorState: EditorState) => {
const treeText = generateContent(
editor.getEditorState(),
editor._config,
commandsLog,
editor._compositionKey,
editor._editable,
);

setContent(treeText);

if (!timeTravelEnabled) {
Expand All @@ -94,22 +100,24 @@ export function TreeView({
]);
}
},
[editor, timeTravelEnabled],
[commandsLog, editor, timeTravelEnabled],
);

useEffect(() => {
const editorState = editor.getEditorState();

if (!showLimited && editorState._nodeMap.size > 1000) {
setContent(
generateContent(
editorState,
editor._config,
commandsLog,
editor._compositionKey,
editor._editable,
),
);
}
}, [editor, showLimited]);
}, [commandsLog, editor, showLimited]);

useEffect(() => {
return mergeRegister(
Expand All @@ -127,13 +135,14 @@ export function TreeView({
const treeText = generateContent(
editor.getEditorState(),
editor._config,
commandsLog,
editor._compositionKey,
editor._editable,
);
setContent(treeText);
}),
);
}, [editor, isLimited, generateTree, showLimited]);
}, [commandsLog, editor, isLimited, generateTree, showLimited]);

const totalEditorStates = timeStampedEditorStates.length;

Expand Down Expand Up @@ -293,6 +302,49 @@ export function TreeView({
);
}

function useLexicalCommandsLog(
editor: LexicalEditor,
): ReadonlyArray<LexicalCommand<unknown> & {payload: unknown}> {
const [loggedCommands, setLoggedCommands] = useState<
ReadonlyArray<LexicalCommand<unknown> & {payload: unknown}>
>([]);

useEffect(() => {
const unregisterCommandListeners = new Set<() => void>();

for (const [command] of editor._commands) {
unregisterCommandListeners.add(
editor.registerCommand(
command,
(payload) => {
setLoggedCommands((state) => {
const newState = [...state];
newState.push({
payload,
type: command.type ? command.type : 'UNKNOWN',
});

if (newState.length > 10) {
newState.shift();
}

return newState;
});

return false;
},
COMMAND_PRIORITY_HIGH,
),
);
}

return () =>
unregisterCommandListeners.forEach((unregister) => unregister());
}, [editor]);

return useMemo(() => loggedCommands, [loggedCommands]);
}

function printRangeSelection(selection: RangeSelection): string {
let res = '';

Expand All @@ -317,7 +369,7 @@ function printRangeSelection(selection: RangeSelection): string {
return res;
}

function printObjectSelection(selection: NodeSelection): string {
function printNodeSelection(selection: NodeSelection): string {
return `: node\n └ [${Array.from(selection._nodes).join(', ')}]`;
}

Expand All @@ -328,6 +380,7 @@ function printGridSelection(selection: GridSelection): string {
function generateContent(
editorState: EditorState,
editorConfig: EditorConfig,
commandsLog: ReadonlyArray<LexicalCommand<unknown> & {payload: unknown}>,
compositionKey: null | string,
editable: boolean,
): string {
Expand Down Expand Up @@ -365,11 +418,23 @@ function generateContent(
? printRangeSelection(selection)
: DEPRECATED_$isGridSelection(selection)
? printGridSelection(selection)
: printObjectSelection(selection);
: printNodeSelection(selection);
});

res += '\n selection' + selectionString;

res += '\n\n commands:';

if (commandsLog.length) {
for (const {type, payload} of commandsLog) {
res += `\n └ { type: ${type}, payload: ${
payload instanceof Event ? payload.constructor.name : payload
} }`;
}
} else {
res += '\n └ None dispatched.';
}

res += '\n\n editor:';
res += `\n └ namespace ${editorConfig.namespace}`;
if (compositionKey !== null) {
Expand Down
1 change: 1 addition & 0 deletions packages/lexical/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

export type {PasteCommandType} from './LexicalCommands';
export type {
CommandListener,
CommandListenerPriority,
CommandPayloadType,
CreateEditorArgs,
Expand Down

2 comments on commit ea82cb5

@vercel
Copy link

@vercel vercel bot commented on ea82cb5 Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lexical – ./packages/lexical-website

lexical-git-main-fbopensource.vercel.app
lexical-fbopensource.vercel.app
www.lexical.dev
lexicaljs.org
lexical.dev
lexicaljs.com

@vercel
Copy link

@vercel vercel bot commented on ea82cb5 Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

lexical-playground – ./packages/lexical-playground

lexical-playground-fbopensource.vercel.app
lexical-playground-git-main-fbopensource.vercel.app
playground.lexical.dev
lexical-playground.vercel.app

Please sign in to comment.