Skip to content

refactor: serialize clipboard to json instead of html #1790

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nperez0111
Copy link
Contributor

@nperez0111 nperez0111 commented Jun 25, 2025

Instead of trying to serialize everything into blocknote/html, we can instead serialize into blocknote/json whatever slice of data we want to be on the clipboard or drag & drop.

This should resolve a number of issues related to drag & drop, and simplifies things significantly.

HTML cannot encode the same sort of information that json can, for example, that a slice has different depths is not representable by html & has to be inferred, whereas just representing it as a slice, just works.

Does not resolve:

  • PDF Block cannot be moved to any desired location. #1205
  • Dragging text around copies the text instead of moving it #1610 need to handle a drag like that as a sort of cut & paste
  • Likely the same code block cannot be moved (example page) #1653
    • this likely needs to be re-worked:
      // Drop event occurred within an editor.
      if (parentEditorElement) {
      // When ProseMirror handles a drop event on the editor while
      // `view.dragging` is set, it deletes the selected content. However, if
      // a block from a different editor is being dropped, this causes some
      // issues that the code below fixes:
      if (!this.isDragOrigin && this.pmView.dom === parentEditorElement) {
      // Because the editor selection is unrelated to the dragged content, we
      // don't want PM to delete its content. Therefore, we collapse the
      // selection.
      this.pmView.dispatch(
      this.pmView.state.tr.setSelection(
      TextSelection.create(
      this.pmView.state.tr.doc,
      this.pmView.state.tr.selection.to,
      ),
      ),
      );
      } else if (this.isDragOrigin && this.pmView.dom !== parentEditorElement) {
      // Because the editor from which the block originates doesn't get a drop
      // event on it, PM doesn't delete its selected content. Therefore, we
      // need to do so manually.
      //
      // Note: Deleting the selected content from the editor from which the
      // block originates, may change its height. This can cause the position of
      // the editor in which the block is being dropping to shift, before it
      // can handle the drop event. That in turn can cause the drop to happen
      // somewhere other than the user intended. To get around this, we delay
      // deleting the selected content until all editors have had the chance to
      // handle the event.
      setTimeout(
      () => this.pmView.dispatch(this.pmView.state.tr.deleteSelection()),
      0,
      );
      }
  • Needs more info: Custom blocks change type when dragging. #1452
  • Did not check, but unlikely to resolve: Dragging doesn't work on mobile #1693
  • Did not check, but unlikely to resolve: Dragging custom block show Error: block type does not match #1694
  • Don't know what is happening here: Can't copy paste multiple times #1788

What is left?

  • We should add some tests around this to make sure that copy & paste results in the correct document (rather than just testing clipboard serialization)
  • There is some work to do when it comes to drag & drop behavior (i.e. when to cut & paste)

Copy link

vercel bot commented Jun 25, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
blocknote ✅ Ready (Inspect) Visit Preview Jun 26, 2025 8:40am
blocknote-website ✅ Ready (Inspect) Visit Preview Jun 26, 2025 8:40am

Copy link

pkg-pr-new bot commented Jun 25, 2025

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/ariakit@1790

@blocknote/code-block

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/code-block@1790

@blocknote/core

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@1790

@blocknote/mantine

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/mantine@1790

@blocknote/react

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@1790

@blocknote/server-util

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/server-util@1790

@blocknote/shadcn

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/shadcn@1790

@blocknote/xl-ai

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-ai@1790

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-docx-exporter@1790

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-email-exporter@1790

@blocknote/xl-multi-column

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-multi-column@1790

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-odt-exporter@1790

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/xl-pdf-exporter@1790

commit: 0eb3bce

@nperez0111 nperez0111 changed the title fix: resolve a number of clipboard & serialization issues refactor: serialize clipboard to json instead of html Jun 26, 2025
@YousefED
Copy link
Collaborator

@nperez0111 following up from our discussion yesterday. What I missed is that the existing serializer is also used for blocksToFullHTML; which is used (for scenarios like server-side rendering) to get the HTML structure of a document that's the same (as much as possible) as what's rendered in the editor.

I think the workarounds you pointed to are mostly in place for that, not for the clipboard handling.

Also, in the preview environment I can also not move the PDF block (#1205).

The idea (json on clipboard) makes sense of course, but as far as I can see now it doesn't resolve the open issues. This makes me think it becomes more of an architectural decision which we should explore when we get to streamlining the exporters / rendering - wdyt?

@nperez0111
Copy link
Contributor Author

Yep, that's fine. I renamed the PR to reflect 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.

Dragging custom block show Error: block type does not match Dragging doesn't work on mobile
2 participants