NodeViews with nested, first class rich text fields

We’re currently overhauling our embed system in Prosemirror. It handles things like embedded images, youtube videos, pullquotes, etc. At the moment, it’s hopelessly intertwined with a particular view in our Angular-based CMS – we hope to come up with a solution that makes our embed system renderer-agnostic.

Previously, we modelled all of our embed fields as node attributes within an atomic NodeView. This works OK for non-RTE elements, but as soon as we introduce RTEs, the questions arise:

  • How do we model this in a way that works natively with collaborative editing? (With attributes, my assumption is that this will always be last-write-wins for a given node)
  • How do we model this in a way that would enable the parent editor to share marks, for example to present a single interface in a style-guide checker?

One solution might be to model rich text fields in the schema as children of the embed’s NodeView via contentDOM. We’ve spiked this and it seems to work fine, but this seems to limit us to a single RTE field per NodeView, or put up with the limitation that multiple RTE fields must coexist next to eachother as DOM nodes as they do in the schema – not ideal from a styling or layout perspective.

Another solution might be to model RTE attributes in the schema, but render them in the NodeView. This would require us to nest Prosemirror instances and keep them in sync with the parent. This seems … fiddly! But possible? Just as a first pass, we’d need to translate transactions from child to parent each time, adjusting positions accordingly, as in the embedded CodeMirror example. I don’t know how easy it’d be to pass marks and decorations across that boundary, too.

As I begin a spike to test this approach (and I suspect this is probably necessary to meet the requirements mentioned above!), I’m wondering – has anyone else tried something along these lines? Was it difficult to create or maintain? Or perhaps there’s a different solution to this problem I’m missing?

That about covers it, yes. See also the footnote example, which uses little ProseMirror editors to allow the user to edit footnotes.

Thanks Marijn! We’re giving this a try now, and synchronising state seems to work well.