-
-
Notifications
You must be signed in to change notification settings - Fork 623
Description
Hi there!
Great project! I really like the UI and the direction you're going.
I played a bit around in a NextJS project and found a couple of quirky issues that might have gone unnoticed. I'll report them in separate issues but here is the first one.
Unhandled Runtime Error
RangeError: Empty text nodes are not allowed
Source
new TextNode
node_modules/prosemirror-model/dist/index.js (1533:0)
Schema.text
node_modules/prosemirror-model/dist/index.js (2415:0)
Qt
node_modules/@blocknote/core/dist/blocknote.js (245:0)
ut
node_modules/@blocknote/core/dist/blocknote.js (258:0)
ht
node_modules/@blocknote/core/dist/blocknote.js (267:0)
R
node_modules/@blocknote/core/dist/blocknote.js (286:0)
mt
node_modules/@blocknote/core/dist/blocknote.js (498:0)
ie
node_modules/@blocknote/core/dist/blocknote.js (515:76)
No.blocksToMarkdown
node_modules/@blocknote/core/dist/blocknote.js (2801:0)
components/md-editor.tsx (68:46) @ blocksToMarkdown
66 | // saves them.
67 | const saveBlocksAsMarkdown = async () => {
> 68 | const markdown: string = await editor.blocksToMarkdown(
| ^
69 | editor.topLevelBlocks
70 | );
71 | setValue(markdown);
I followed the documentation on converting blocks to Markdown with this code snippet:
// Stores the editor's contents as Markdown.
const [markdown, setMarkdown] = useState<string>("");
// Creates a new editor instance.
const editor: BlockNoteEditor | null = useBlockNote({
// Listens for when the editor's contents change.
onEditorContentChange: (editor: BlockNoteEditor) => {
// Converts the editor's contents from Block objects to Markdown and
// saves them.
const saveBlocksAsMarkdown = async () => {
const markdown: string =
await editor.blocksToMarkdown(editor.topLevelBlocks);
setMarkdown(markdown);
};
saveBlocksAsMarkdown();
}
});
At first everything seemed to work as intended, but when copying a couple of websites to the editor (which converted the HTML to blocks in the background (excellent!)) in some cases I got the above error message.
Indeed, when investigating the block structure after pasting, I found this content block:
{
"id": "70b1274a-c071-4311-b4f2-9a854190406b",
"type": "paragraph",
"props": {
"textColor": "default",
"backgroundColor": "default",
"textAlignment": "left"
},
"content": [
{ "type": "text", "text": "sometext", "styles": { "bold": true } },
{ "type": "text", "text": "", "styles": { "bold": true } }
],
"children": []
},
I am not sure what the HTML structure looked like that caused this. However, this doesn't seem to be intended.
I could solve the issue with manually checking for empty content nodes like this:
const removeEmptyTextBlocks = (blocks: Block[]) => {
// Visit all nodes
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
// Recursively remove empty text nodes from children
if (block.children) {
removeEmptyTextBlocks(block.children);
}
// Remove empty text nodes from content
if (block.content) {
const filteredContent = block.content.filter(
(contentNode) =>
!(contentNode.type === 'text' && contentNode.text === '')
);
block.content = filteredContent.length ? filteredContent : [];
}
}
};
// Listens for when the editor's contents change.
onEditorContentChange: (editor: BlockNoteEditor) => {
// Converts the editor's contents from Block objects to Markdown and
// saves them.
const saveBlocksAsMarkdown = async () => {
const blocks = editor.topLevelBlocks;
removeEmptyTextBlocks(blocks);
const markdown: string = await editor.blocksToMarkdown(blocks);
setValue(markdown);
};
saveBlocksAsMarkdown();
}
Probably though this problem should be fixed either in the editor.blocksToMarkdown
function or whatever function is responsible for pasting HTML. Or even a check when creating new content blocks. I am not too familiar with your code base, so I am not creating a pull request myself.
Keep up the great work!