Setting up a NodeView that needs context

When a NodeView is initialized, it does no know yet where it is in a document: getPos() returns undefined. My NodeView relies on knowing the context in the parent node. This information is available in update() calls.

The usecase is this: I’d like to decorate blocks with ‘+’ and ‘x’ buttons for adding and removing blocks from the tree. The ‘+’ button will have a dropdown to select the type of node that is allowed at that position. Blocks will also have a combobox to change their type.

To render the ‘+’, ‘x’ and type comboboxes, context information is needed. Node.canReplaceWith is what I use to determine the contents of the combox and to determine if the ‘+’ and ‘x’ should be enabled or disabled.

This works fine in update(), but the NodeView constructor could be more efficient if setPos() would already return the node position when constructing. Alternatively, is there an efficient function for finding the position of a node?

1 Like

You can’t reliably make it depend on that – the parent can get modified and your node view won’t get an update call unless it itself was changed. As such, node views should be treated as depending only on the node and its content, and no other external values.

What you’re doing could be done with decorations, I guess. But it sounds like you only actually need the context information when the button is clicked, which would be a much cheaper and easier thing to arrange.

Would it be possible to make a NodeView impementation that calls into ProseMirror for the rendering the individual child nodes? That way, a node can render the + and x buttons and the combobox interspersed between its children. The parent has all the required context.

From experimenting with decorations, I had the impression that they provide inline-content only.

You can either allow the library to completely manage the rendering of a node view’s child nodes (by providing a contentDOM property), or you have to completely manage them yourselves. I think providing more variants here would get too complex.