How to modify the default behavior of inserting necessary nodes to conform to the schema

Say I have a box node with

content: 'config very-complex-node-contains-children-and-descendants'

and the config node

content: 'setting+'

When you paste a very-complex-node-contains-children-and-descendants node (maybe from other tools) into prosemirror editor, the editor will generate a config node with one setting node and make it a valid box node. This is the default behavior, and it works for most cases.

In my case, however, I have to generate more than one setting node according to the config of the box node.

I know it could be done by transformPasted. But I wonder if there is a more efficient way handling it.

I tried to use getContent in the parse rule of box node to create setting nodes by myself (which returns a fragment contains [config node with multiple setting nodes, very-complex-node-contains-children-and-descendants node]). This almost works. But the very-complex-node-contains-children-and-descendants node (get parsed by DOMParser.fromSchema(schema).parseSlice(dom.children[1]), I am not sure if this is the problem) got lost because findWrapping returns null, resulting in just the config node and an empty very-complex-node-contains-children-and-descendants node in the editor.

I also tried the getContent in the parse rule of config node. But it does not get called at all in this case.

Now I am also thinking if it is possible to tell the default handler a function with the parent node(in my case it is a box node) how to generate the necessary content.

No, that’s not possible. Also, parse rules for the content node won’t be activated when creating a wrapper for an orphan child node. Handling this in a transformPasted function is probably your best bet.

@marijn Thank you for the instruction.

But is it possible to use getContent in the parse rule of box node to get it done? As I said it almost worked. I debugged the function. It seems no problem with the generated fragment. It contains a config node and a very-complex-node-contains-children-and-descendants node, both with right contents. But the very-complex-node-contains-children-and-descendants node get lost because findWrapping returns null.

BTW, I create the very-complex-node-contains-children-and-descendants node by DOMParser.fromSchema(schema).parseSlice(dom.children[1]).content.content[0], am I doing right?

It sounds like your parse rule is producing a very-complex-... node, but you’re using getContent to generate another such node (plus a config node) as its content. Since that node can’t be wrapped in itself, that will fail.

It may be possible to create a parse rule for box (either in its node spec or passed directly to DOMParser with a node property that does this. But then if you try to parse such a DOM node into a box, you’ll get a similar problem where it tries to put a box in a box node which isn’t possible. You could work around that by defining an additional, higher-precedence parse rule that creates a plain very-complex-... node, and restrict its context to only apply when already inside a box node.

Yes, that is what I did.

// for box node
parseDOM: [..., {tag: 'box', getContent: function(dom, schema){
    const slice = DOMParser.fromSchema(schema).parseSlice(dom)
    ... // generate config node
    return Fragment.from([config, slice.content.content[0]])
}]

// for very-complex-node-contains-children-and-descendants node
parseDOM: [..., {tag: 'box', context: 'box/', priority: 1000}]

But the very-complex-node-contains-children-and-descendants node is still lost.

BTW, the generated slice has some openStart and openEnd bigger than 3, but it is not the problem, right?