On copy, extra line is added between paragraphs, list items and more

Hello, I did a search across the forum and haven’t found anyone discussing this issue. So the issue is that when we just copy the content of the editor which contains 'p’s or ‘li’, there is always an extra line between each p/li… element that was copied.

Even if I alter a schema and make ‘div’ of 'span’s to be instead of

s the result doesn’t change. I believe this is due to some internal logic in prosemirror that takes care of copy action.

Could you suggest what would be the proper way of altering copy behavior and “tell” to prosemirror "hey do not add extra line if you happen to process ‘p’ or li. And also a little following bug, as you can see on the screenshot, ctrl/shift+enter adds a line break to the editor, but after being copied the text is glued into the same line

I discovered a couple of methods and clipboardTextSerializer sounds interesting and what I do in it right is building clipboard text myself

slice.content.forEach((node: Node) => {
    if (node.type.name === "paragraph") {
      // Add a newline after each paragraph
      result += node.textContent + "\n"; // Preserve content and add a newline.
    } else if (node.isText) {
      // Add text nodes without additional handling (this should be rare)
      result += node.text;
    }
  });

  // Remove any additional unnecessary newlines from the end of the text
  return result.trim();

But it all feels wrong, because I should to add a lot of checks and a recursion eventually to build all the text in a right way.

So could you suggest a better way of doing it? I checked tiptap and jira/confluence and they have these issues kind of resolved (they use prose mirror under the hood)

These aren’t bugs, but intentional behavior. You can define your own clipboard text serializer if you want to customize the way a document is converted to text.

But is the fact that “br” line breaks are copied without going to a next line? To me having p to have a line break does make sense, but I thought li shouldn’t have that, but it had eventually (because it contained p inside) I believe this is the only way to use clipboardTextSerializer to do a thing the way we want it to be done? Could you share maybe any document you were following when you were implementing copy behavior. I might be needed to discuss it with my team

Thanks a lot for the response!

The default behavior uses textBetween, as the docs state. You can add leafText fields to your node specs to customize the way a given leaf node is converted to text. By default, since the library itself doesn’t know anything about a given node type, they do not emit any text.

1 Like