toDOM can return a DOM Node, how to "renderInlineFlat" it?


i’m trying to use a custom NodeType toDOM to be able to render a pm node:

  <div name="content">my content</div>

like this

<div is="custom">
  <div something-ignored-by-pm>...</div>
  <div pm-container>
    <div name="content" pm-container>my content</div>

By listening to selectionChange events, i forbid selection to go in the ignored places. However, when returning a DOM Node in a DOMOutputSpec, that DOM Node is not “drawn” by pm, and in particular, the inner div is not flattened like:

<div name="content">
  <span pm-offset="0" pm-size="10">my content</span>

which is a problem, since it becomes flattened the first time the user selects it, which offsets the position by 1 (because of the span wrapping).

I know this is all unsupported, but it would be fantastic if there was a way to ask pm to “flatten” arbitrary DOM Nodes (or parts of them) that are returned by toDOM. The the flattening function doing it is not accessible in version 0.10.1. I could somewhat achieve a correct rendering by exporting it and calling

var dopts = pm.draw.drawOptions(pm.ranges.activeRangeTracker())

but it was a bit too much of a hack.

Are you making the ignored node contenteditable=false? That should prevent the browser from moving the selection into it.

I don’t really understand what you mean by flattening, and why you would want to do it to a node that’s not editable inline content.

Oh yes, i failed to set contenteditable=false on the nodes to ignore. So it’s possible to render a node A to a DOM Node with some childNodes ignored by pm. I could reformulate what i’m trying to do as: Is it possible to render a pm node A to a dom node domA containing domB containing domC, but without domB being rendered from a pm node B, as if A > C was rendered into dom as domA > domB > domC ? (When i try to do that i need to feedle with pm-offset attribute).

Do I understand correctly that you want to render intermediate DOM structure between the outer node and its children? Yes, that’s definitely possible, just return something like ["div", ["div", 0]], but make sure your DOM parsing logic also notifies the parser (using the content property in its returned spec) that it has to continue parsing in a child node.

Yes, i want to do that. I ended up with a different approach using schema and a node type that is just there to wrap nodes (it was more flexible) and a node type that is just there to be non-editable and with custom html. You can read the code at

However now i’m seeing something weird that i don’t really understand: all nodes with contenteditable="false" attribute are wrapped in a div when drawn:

It’s problematic - if i just comment out that line everything works as expected.

(I also tried to work around that by making HoldType to be isBlock == false but that breaks selection and offsets so it wasn’t a good idea).

Re-reading previous discussions, the feature i’m missing is actually simply the “locked node”. Thank you for your patience and your help.