How to resolve parent ViewDesc in a custom NodeView generator?

I was wondering if there is an easy way to get the parent ViewDesc object from within a custom NodeView generator function? At the time the function is called, descObj doesn’t exist, so the getPos function that is provided in the argument list returns undefined. This means that the only way I’ve found to get the parent is to recursively search for the new node on the view.state.doc, then search view.docView for the corresponding desc object, which seems needlessly cumbersome. If parent was passed into the call to custom(), that would make my use case extremely easy, but I’m open to other suggestions for how to best resolve the parent desc object?

What do you want to use the parent for? ViewDesc objects aren’t documented or exposed to client code, at this point.

It’s part of my continuing quest to integrate some angular-enabled widgets cleanly into an editor. If I’m selectively rendering custom, “angularized” views on certain node types, it’s ideal to be able to find the parent DOM element they are being rendered into (which allows a built-in angular function to retrieve a context object). To me, the easiest way to do this seemed like having access to the parent ViewDesc, since a numeric position isn’t available to us at the time that custom() gets called.

Open to suggestions for alternative approaches to get that parent DOM element?

Would it be workable to wrap your Angular leaf elements into an additional wrapper node and just use that as your parent? Even if you were able to get the position of the parent node when the node view is being created, there’s no guarantee that that parent is part of the DOM yet, so that still wouldn’t work (and I don’t really want to make that a requirement, since it’d complicate the DOM management code).

This could be close to a solution. I’ll make this a bit more concrete with a slightly simplified actual example:

I have a custom “list type” that defines multiple choice questions in a document - I’d like to structure these just like a regular ul/ol or radio form element - basically a root node that defines the question group, then a series of possible responses that the user can select between. I want to be able to tie into my Angular code base to handle click events, perform validations/other actions when the user responds to things. In this case, we’ll have a DOM structure that looks like this:

question root

  • response 1 DOM node
  • response 2 DOM node
  • ...

The way Angular works, a hierarchy of “scope” objects get created which mirror the DOM hierarchy and enable the inheriting/communication of context between the nested response elements and the question root wrapper controller. The approach I’ve been playing with is to try to manually find the appropriate parent scope and then set up the binding I want when the custom node view renders a new DOM element - the idea here was to set the contentDOM attribute to a child of the question root so that Prosemirror can take over rendering all the children again. However, if there’s an easy way for question root, as a block node, to render all its children by hand with the appropriate scope reference, that would be ideal. Basically I’m envisioning not setting the contentDOM attribute, and then manually calling almost the same rendering steps that Prosemirror would on children, but with the added step of calling $compile with the wrapper node’s scope. Does that make sense? Can you point me in the right direction for how I would go about manually rendering all of a block node’s children?

Thanks for you help!

Yes, that’s supported, simply have your nodeview export a dom but no contentDOM, and in your update method, make sure you redraw the children when they change (which probably requires keeping track of your current child nodes).

But note that users won’t be able to directly interact (edit, select, etc) the child nodes through ProseMirror’s interface logic. If the content of these has to be editable, that might be problematic.

Hrm, that’s a major limitation for my particular use case. Is there a way to basically replicate Prosemirror’s built-in updateChildren functionality, but add a step? (in this case the step that I need to add is a context-aware custom node view function)

(Apologies for the late response – this dropped off the first page of my email.)

Could you say a bit more about that that custom function is doing? If it’s just influencing something about the outer node based on the content, you can already do this with a regular update method.