Skip to content

Commit

Permalink
feat(@lexical/devtools): Added TreeView rendering instead of a simple…
Browse files Browse the repository at this point in the history
… textarea
  • Loading branch information
StyleT committed Apr 4, 2024
1 parent 1472782 commit 265eb4a
Show file tree
Hide file tree
Showing 23 changed files with 666 additions and 72 deletions.
86 changes: 86 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 17 additions & 5 deletions packages/lexical-devtools-core/src/TreeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function TreeView({
timeTravelPanelClassName: string;
timeTravelPanelSliderClassName: string;
viewClassName: string;
generateContent: (exportDOM: boolean) => string;
generateContent: (exportDOM: boolean) => Promise<string>;
setEditorState: (state: EditorState, options?: EditorSetOptions) => void;
setEditorReadOnly: (isReadonly: boolean) => void;
}): JSX.Element {
Expand All @@ -45,13 +45,25 @@ export function TreeView({
const [isPlaying, setIsPlaying] = useState(false);
const [isLimited, setIsLimited] = useState(false);
const [showLimited, setShowLimited] = useState(false);
const lastEditorStateRef = useRef<null | EditorState>(editorState);
const lastEditorStateRef = useRef<null | EditorState>(null);
const lastGenerationID = useRef(0);

const generateTree = useCallback(
(exportDOM: boolean) => {
const treeText = generateContent(exportDOM);

setContent(treeText);
const myID = ++lastGenerationID.current;
generateContent(exportDOM)
.then((treeText) => {
if (myID === lastGenerationID.current) {
setContent(treeText);
}
})
.catch((err) => {
if (myID === lastGenerationID.current) {
setContent(
`Error rendering tree: ${err.message}\n\nStack:\n${err.stack}`,
);
}
});
},
[generateContent],
);
Expand Down
4 changes: 3 additions & 1 deletion packages/lexical-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
"@vitejs/plugin-react": "^4.2.1",
"typescript": "^5.3.3",
"lexical": "0.14.2",
"@lexical/devtools-core": "0.14.2",
"wxt": "^0.17.0",
"vite": "^5.2.2"
"vite": "^5.2.2",
"@rollup/plugin-babel": "^6.0.4"
}
}
12 changes: 5 additions & 7 deletions packages/lexical-devtools/src/entrypoints/content/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@
* LICENSE file in the root directory of this source tree.
*
*/
import {allowWindowMessaging, sendMessage} from 'webext-bridge/content-script';
import {allowWindowMessaging} from 'webext-bridge/content-script';

import useExtensionStore from '../../store';
import storeReadyPromise from '../../store-sync/content-script';
import injectScript from './injectScript';

export default defineContentScript({
main(ctx) {
main(_ctx) {
allowWindowMessaging('lexical-extension');

sendMessage('getTabID', null, 'background')
.then((tabID) => {
return storeReadyPromise(useExtensionStore).then(() => {
injectScript('/injected.js');
});
storeReadyPromise(useExtensionStore)
.then(() => {
injectScript('/injected.js');
})
.catch(console.error);
},
Expand Down
80 changes: 80 additions & 0 deletions packages/lexical-devtools/src/entrypoints/devtools-panel/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
pre {
line-height: 1.1;
background: #222;
color: #fff;
margin: 0;
padding: 10px;
font-size: 12px;
overflow: auto;
max-height: 400px;
}

.tree-view-output {
display: block;
background: #222;
color: #fff;
padding: 0;
font-size: 12px;
margin: 1px auto 10px auto;
position: relative;
overflow: hidden;
border-radius: 10px;
}

.debug-timetravel-panel {
overflow: hidden;
padding: 0 0 10px 0;
margin: auto;
display: flex;
}

.debug-timetravel-panel-slider {
padding: 0;
flex: 8;
}

.debug-timetravel-panel-button {
padding: 0;
border: 0;
background: none;
flex: 1;
color: #fff;
font-size: 12px;
}

.debug-timetravel-panel-button:hover {
text-decoration: underline;
cursor: pointer;
}

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

.debug-timetravel-button:hover {
text-decoration: underline;
cursor: pointer;
}

.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;
cursor: pointer;
}
50 changes: 41 additions & 9 deletions packages/lexical-devtools/src/entrypoints/devtools-panel/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
*
*/

import './App.css';

import {TreeView} from '@lexical/devtools-core';
import * as React from 'react';
import {useState} from 'react';
import {sendMessage} from 'webext-bridge/devtools';
Expand All @@ -30,7 +33,12 @@ function App({tabID}: Props) {
<>
<div>
<a href="https://lexical.dev" target="_blank">
<img src={lexicalLogo} className="logo" alt="Lexical logo" />
<img
src={lexicalLogo}
className="logo"
width={150}
alt="Lexical logo"
/>
</a>
</div>
{errorMessage !== '' ? (
Expand All @@ -42,7 +50,7 @@ function App({tabID}: Props) {
) : (
<span>
Found <b>{lexicalCount}</b> editor{lexicalCount > 1 ? 's' : ''} on
the page
the page.
</span>
)}
<p>
Expand All @@ -54,17 +62,41 @@ function App({tabID}: Props) {
</p>
</div>
{Object.entries(states).map(([key, state]) => (
<p key={key}>
<div key={key}>
<b>ID: {key}</b>
<br />
<textarea
readOnly={true}
value={JSON.stringify(state)}
rows={5}
cols={150}
<TreeView
viewClassName="tree-view-output"
treeTypeButtonClassName="debug-treetype-button"
timeTravelPanelClassName="debug-timetravel-panel"
timeTravelButtonClassName="debug-timetravel-button"
timeTravelPanelSliderClassName="debug-timetravel-panel-slider"
timeTravelPanelButtonClassName="debug-timetravel-panel-button"
setEditorReadOnly={(isReadonly) =>
sendMessage(
'setEditorReadOnly',
{isReadonly, key},
`window@${tabID}`,
).catch((e) => setErrorMessage(e.stack))
}
editorState={state}
setEditorState={(editorState) =>
sendMessage(
'setEditorState',
{key, state: editorState},
`window@${tabID}`,
).catch((e) => setErrorMessage(e.stack))
}
generateContent={(exportDOM) =>
sendMessage(
'generateTreeViewContent',
{exportDOM, key},
`window@${tabID}`,
)
}
/>
<hr />
</p>
</div>
))}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="root"></div>
<div id="root">Loading Lexical DevTools UI...</div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React from 'react';
import ReactDOM from 'react-dom/client';

import store from '../../store.ts';
import storeReadyPromise from '../../store-sync/content-script';
import storeReadyPromise from '../../store-sync/devtools';
import App from './App.tsx';

const tabID = browser.devtools.inspectedWindow.tabId;
Expand Down
Loading

0 comments on commit 265eb4a

Please sign in to comment.