Remove contenteditable completely?


As mentioned in the docs, using contenteditable for rendering/cursor tracking reduces complexity by avoiding the need to implement layout. However, this means ProseMirror is not aware of where things are rendered on the screen.

For most use cases, this is not a problem. However, this makes implementing certain features that rely on knowing where things are rendered more difficult. From what I’ve seen, commercial close-sourced word processors such as Google Docs and MS Word Online handle rendering/cursor tracking instead of delegating to contenteditable.

Some example use cases:

  • Break up document to fixed-size pages - can’t do this without knowing the height of each line being rendered
  • Multiple cursor placement in collaborative editing - the browser can only render one cursor, to render multiple cursors we need to be able to project document position to screen coordinates, expensive to do without having rendered layout information cached
  • More sophisticated marks such as inline highlighting and commenting - as far as I know, marks in ProseMirror are rendered by wrapping inline text with spans and decorating the wrapper spans, if you want to render more complex structures, such as a popover comment box centered/above the highlighted text, you’d have to render the highlight as a span, and then determine the wrapper span bounding box position after the mark is rendered and append the popover comment box, which I think is a workaround to the system

I have been exploring the possibility of handling layout/rendering instead of delegating to contenteditable. It seems this involves breaking up the document into boxes that cannot be broken up further and laying them out as lines with the document’s size constraints, before finally rendering them. I don’t think this can fit with the current APIs of ProseMirror, since the concept of box and layout are missing and model toDOM simplify returns DOM specifications with no layout information.

Is there any recommendation for bridging the gap here? I’d love to use ProseMirror for its beautiful model and state implementation, but I’d also like to have more control over the view layer.

I really appreciate all the work put into ProseMirror, it’s a complicated but useful problem to solve and it’s a very generous act to open source it!


You can do this, but it’d be a different project with different issues. It’s definitely not something that ProseMirror will ever do.


I was hoping there might be a way to implement a custom view layer that deals with layout. But if not, I’ll take a stab at implementing this as a different project.