Skip to content

Commit

Permalink
ExportDOM in Debug Tree View (#4307)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivailop7 authored Apr 17, 2023
1 parent 2dc70df commit 1270716
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 32 deletions.
15 changes: 15 additions & 0 deletions packages/lexical-playground/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,21 @@ button.action-button:disabled {
text-decoration: underline;
}

.debug-treetype-button {
border: 0;
padding: 0;
font-size: 12px;
top: 10px;
right: 85px;
position: absolute;
background: none;
color: #fff;
}

.debug-treetype-button:hover {
text-decoration: underline;
}

.connecting {
font-size: 15px;
color: #999;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default function TreeViewPlugin(): JSX.Element {
return (
<TreeView
viewClassName="tree-view-output"
treeTypeButtonClassName="debug-treetype-button"
timeTravelPanelClassName="debug-timetravel-panel"
timeTravelButtonClassName="debug-timetravel-button"
timeTravelPanelSliderClassName="debug-timetravel-panel-slider"
Expand Down
97 changes: 65 additions & 32 deletions packages/lexical-react/src/LexicalTreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import type {
EditorConfig,
EditorState,
ElementNode,
GridSelection,
Expand All @@ -17,6 +16,7 @@ import type {
RangeSelection,
} from 'lexical';

import {$generateHtmlFromNodes} from '@lexical/html';
import {$isLinkNode, LinkNode} from '@lexical/link';
import {$isMarkNode} from '@lexical/mark';
import {mergeRegister} from '@lexical/utils';
Expand Down Expand Up @@ -52,6 +52,7 @@ const SYMBOLS: Record<string, string> = Object.freeze({
});

export function TreeView({
treeTypeButtonClassName,
timeTravelButtonClassName,
timeTravelPanelSliderClassName,
timeTravelPanelButtonClassName,
Expand All @@ -60,6 +61,7 @@ export function TreeView({
editor,
}: {
editor: LexicalEditor;
treeTypeButtonClassName: string;
timeTravelButtonClassName: string;
timeTravelPanelButtonClassName: string;
timeTravelPanelClassName: string;
Expand All @@ -71,6 +73,7 @@ export function TreeView({
>([]);
const [content, setContent] = useState<string>('');
const [timeTravelEnabled, setTimeTravelEnabled] = useState(false);
const [showExportDOM, setShowExportDOM] = useState(false);
const playingIndexRef = useRef(0);
const treeElementRef = useRef<HTMLPreElement | null>(null);
const inputRef = useRef<HTMLInputElement | null>(null);
Expand All @@ -83,13 +86,7 @@ export function TreeView({

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

setContent(treeText);

Expand All @@ -100,24 +97,16 @@ export function TreeView({
]);
}
},
[commandsLog, editor, timeTravelEnabled],
[commandsLog, editor, timeTravelEnabled, showExportDOM],
);

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

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

useEffect(() => {
return mergeRegister(
Expand All @@ -132,17 +121,18 @@ export function TreeView({
generateTree(editorState);
}),
editor.registerEditableListener(() => {
const treeText = generateContent(
editor.getEditorState(),
editor._config,
commandsLog,
editor._compositionKey,
editor._editable,
);
const treeText = generateContent(editor, commandsLog, showExportDOM);
setContent(treeText);
}),
);
}, [commandsLog, editor, isLimited, generateTree, showLimited]);
}, [
commandsLog,
editor,
showExportDOM,
isLimited,
generateTree,
showLimited,
]);

const totalEditorStates = timeStampedEditorStates.length;

Expand Down Expand Up @@ -224,6 +214,14 @@ export function TreeView({
</button>
</div>
) : null}
{!showLimited ? (
<button
onClick={() => setShowExportDOM(!showExportDOM)}
className={treeTypeButtonClassName}
type="button">
{showExportDOM ? 'Tree' : 'Export DOM'}
</button>
) : null}
{!timeTravelEnabled &&
(showLimited || !isLimited) &&
totalEditorStates > 2 && (
Expand Down Expand Up @@ -378,12 +376,23 @@ function printGridSelection(selection: GridSelection): string {
}

function generateContent(
editorState: EditorState,
editorConfig: EditorConfig,
editor: LexicalEditor,
commandsLog: ReadonlyArray<LexicalCommand<unknown> & {payload: unknown}>,
compositionKey: null | string,
editable: boolean,
exportDOM: boolean,
): string {
const editorState = editor.getEditorState();
const editorConfig = editor._config;
const compositionKey = editor._compositionKey;
const editable = editor._editable;

if (exportDOM) {
let htmlString = '';
editorState.read(() => {
htmlString = printPrettyHTML($generateHtmlFromNodes(editor));
});
return htmlString;
}

let res = ' root\n';

const selectionString = editorState.read(() => {
Expand Down Expand Up @@ -686,6 +695,30 @@ function printSelectedCharsLine({
);
}

function printPrettyHTML(str: string) {
const div = document.createElement('div');
div.innerHTML = str.trim();
return prettifyHTML(div, 0).innerHTML;
}

function prettifyHTML(node: Element, level: number) {
const indentBefore = new Array(level++ + 1).join(' ');
const indentAfter = new Array(level - 1).join(' ');
let textNode;

for (let i = 0; i < node.children.length; i++) {
textNode = document.createTextNode('\n' + indentBefore);
node.insertBefore(textNode, node.children[i]);
prettifyHTML(node.children[i], level);
if (node.lastElementChild === node.children[i]) {
textNode = document.createTextNode('\n' + indentAfter);
node.appendChild(textNode);
}
}

return node;
}

function $getSelectionStartEnd(
node: LexicalNode,
selection: RangeSelection | GridSelection,
Expand Down

2 comments on commit 1270716

@vercel
Copy link

@vercel vercel bot commented on 1270716 Apr 17, 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
lexical.dev
lexicaljs.org
www.lexical.dev
lexicaljs.com

@vercel
Copy link

@vercel vercel bot commented on 1270716 Apr 17, 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.vercel.app
lexical-playground-fbopensource.vercel.app
lexical-playground-git-main-fbopensource.vercel.app
playground.lexical.dev

Please sign in to comment.