Custom conversion of nodes with children to/from DOM

I’m trying to convert a node and it’s children in a particular way to the DOM. This is the schema:

mynode: {
    content: "child_a child_b child_c",
    parseDOM: [???],
    toDOM() {???}
},
child_a: {
    content: "text*",
    parseDOM: [{tag: "span.child_a"}],
    toDOM() { return ["span", {class: "child_a"}, 0] }
},
child_b: {
    content: "text*",
    parseDOM: [{tag: "span.child_b"}],
    toDOM() { return ["span", {class: "child_b"}, 0] }
},
child_c: {
    content: "text*",
    parseDOM: [{tag: "span.child_c"}],
    toDOM() { return ["span", {class: "child_c"}, 0] }
},

This is an example of a a mynode node:

{type: "mynode",
 content: [
    {type: "child_a", content: [{type: "text", text: "one"}]},
    {type: "child_b", content: [{type: "text", text: "two"}]},
    {type: "child_c", content: [{type: "text", text: "three"}]}
  ]
}

I want to convert this to HTML of this form:

<div class="mynode">
    <div class="group">
        <span class="child_a">one</span>
        <span class="child_b">two</span>
    </div>
    <span class="child_c">three</span>
</div>

The issue is creating the group div. I haven’t been able to figure out how this can be achieved. I have tried writing a toDOM function for mynode that returns a dom.Node instance (using document.createElement() etc.), but I don’t know how to retrieve the DOM nodes for the children. I was thinking I could create them by calling DOMSerializer.serializeNode(), but of course the schema required to instantiate a DOMSerializer is not yet available at this point.

I guess I could perform the toDOM conversion of the child nodes also inside mynode.toDOM(), And even if that works, is it possible to write a parseDOM that can parse the result?

I have also briefly looked at custom NodeViews. This would seem to run into the same issue, as contentDOM will contain the children, one after another, without an option to wrap the first two with an extra div.

This is simply not supported, at least not in the editor itself—all the children of a given node must appear in the same parent DOM node. That’s a hard-coded requirement. You could create an additional wrapper node. Or, if this is only important outside of the editor, write a custom serializer that replaces DOMSerializer.

1 Like