Skip to content

Conversation

@reteps
Copy link

@reteps reteps commented Sep 16, 2025

Changes Overview

This PR serves as an issue report for #4792. I wanted to discuss implementation strategy before I implement this. Currently, whitespace is trimmed before the document is parsed by ProseMirror. This means that the whitespace: pre option isn't correctly respected. You can see the failing test attached to this PR.

I noticed this bug while implementing a custom node intended to function like a raw HTML node. The removeWhitespaces(html) call inside elementFromString prevents access to whitespace.

Implementation Approach

There are a couple ways to solve this.

  1. Fix this correctly.
  2. Provide an escape hatch for the user to fix this themselves.

Fix this correctly

The "best" way to solve this would be to invert the whitespace stripping process:

  • Parse the document with ProseMirror
  • Traverse the document tree, removing empty text nodes if whitespace: pre isn't set on any parent of that node.

(Currently whitespace is stripped before the document is parsed, causing issues).

Escape Hatch

The alternative approach is to allow an "escape hatch" for the useEditor hook earlier in the process. The full call chain there looks like:

  • useEditor (calls EditorInstanceManager)
  • packages/react/EditorInstanceManager.createEditor()
  • Editor()
  • Editor.createDoc
  • createDocument
  • createNodeFromContent
  • elementFromString

This entire call chain is private, which means that the only way to circumvent this behavior is to reimplement + extend from:

  • useEditor, EditorInstanceManager and Editor.

This is a lot of code duplication to do this. Any option to override this in createNodeFromContent would make this much easier, such as:

  • CreateNodeFromContentOptions.removeWhitespaceNodes (passed to elementFromString to strip whitespace or not)
  • CreateNodeFromContentOptions.elementFromString (optional function override)

Testing Done

[WIP] Will update

Verification Steps

[WIP] Will update

Additional Notes

N/A

Checklist

  • I have created a changeset for this PR if necessary.
  • My changes do not break the library.
  • I have added tests where applicable.
  • I have followed the project guidelines.
  • I have fixed any lint issues.

Related Issues

#4792

Let me know which approach is preferred (if any) and I will add it.

@changeset-bot
Copy link

changeset-bot bot commented Sep 16, 2025

⚠️ No Changeset found

Latest commit: 3d5204f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@netlify
Copy link

netlify bot commented Sep 16, 2025

Deploy Preview for tiptap-embed ready!

Name Link
🔨 Latest commit 3d5204f
🔍 Latest deploy log https://app.netlify.com/projects/tiptap-embed/deploys/68c8b36b750ef50008772021
😎 Deploy Preview https://deploy-preview-6962--tiptap-embed.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

cy.get('.tiptap').then(([{ editor }]) => {
editor.commands.insertContent('<pre><div>foo</div>\n<code>foo\nbar</code></pre>')
cy.get('.tiptap').should('contain.html', '<pre><div>foo</div>\n<code>foo\nbar</code></pre>')
})
Copy link
Author

@reteps reteps Sep 16, 2025

Choose a reason for hiding this comment

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

This is a specific issue for our project, in which we have nodes like:

<my-custom-node {whitespace: `pre`}>
  <subnode>Item 1</subnode>
  <subnode>Item 2</subnode>
</my-custom-node>

The whitespace is getting collapsed, so we end up with a document like:

<my-custom-node><subnode>Item 1</subnode><subnode>Item 2</subnode>
</my-custom-node>

and a tree of

my-custom-node

  • subnode
  • subnode

We actually want a tree like:

my-custom-node

  • subnode-whitespace
  • subnode
  • subnode-whitespace
  • subnode

@reteps reteps changed the title Add failing reproduction (wip): Allow for fully whitespace-sensitive nodes with whitespace: pre Sep 16, 2025
@bdbch
Copy link
Member

bdbch commented Oct 11, 2025

I'm unsure what to do with your PR but I can look into the bug you're describing. Should we rather re-open #4792 instead of going forward with issue-related discussions on a PR?

@reteps
Copy link
Author

reteps commented Oct 11, 2025

That would be good. I opened this as a PR because I am willing to open a PR fixing this, if you suggest which of the two strategies you would prefer @bdbch !

@reteps
Copy link
Author

reteps commented Oct 17, 2025

bump @bdbch

@reteps
Copy link
Author

reteps commented Oct 21, 2025

bump @bdbch . Let me know if this is something I can contribute to.

@reteps
Copy link
Author

reteps commented Oct 23, 2025

cc @arnaugomez

@reteps reteps changed the title (wip): Allow for fully whitespace-sensitive nodes with whitespace: pre [GUIDANCE/COMMENT WANTED!!!] fix: Allow for fully whitespace-sensitive nodes with whitespace: pre Oct 23, 2025
@bdbch bdbch changed the title [GUIDANCE/COMMENT WANTED!!!] fix: Allow for fully whitespace-sensitive nodes with whitespace: pre fix: Allow for fully whitespace-sensitive nodes with whitespace: pre Oct 23, 2025
@bdbch
Copy link
Member

bdbch commented Oct 23, 2025

Sorry, I'm currently sick and can't work actively on Tiptap or react as fast as usually.

I reopened the issue. Lets discuss the problem there.

In general I'm having trouble with understanding your requirements. I guess you're using the default code block extension when you try to parse <pre></pre> with whitespaces inside?

@bdbch
Copy link
Member

bdbch commented Oct 23, 2025

I'm also closing this PR because it's not really making sense (description is saying it's fixing something while it's just adding a test and is more a bug-report).

I'd invite you to maybe explain your use case a little bit more in #4792.

@bdbch bdbch closed this Oct 23, 2025
@reteps
Copy link
Author

reteps commented Oct 23, 2025

Thank you, I did that!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants