Skip to content

RangeError: Empty text nodes are not allowed (on editor.blocksToMarkdown) #184

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
empiriker opened this issue May 1, 2023 · 1 comment · Fixed by #229
Closed

RangeError: Empty text nodes are not allowed (on editor.blocksToMarkdown) #184

empiriker opened this issue May 1, 2023 · 1 comment · Fixed by #229
Assignees
Labels
bug Something isn't working

Comments

@empiriker
Copy link

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!

@YousefED
Copy link
Collaborator

Thanks. Possibly related to #216

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants