Finding positions in a reliable way (with nesting included)

Hey! First off - thanks for maintaining Prosemirror and helping us out over here Marijn! I’m Dominik, one of the maintainers over at Tiptap. I’m currently trying to improve the list behaviour of our listItem extension so it works similar to other editors (some users where pretty confused on how list items are joined/lifted on backspace or delete.

I already fixed some of the backspace / delete behaviors and edgecases I ran into - but I really struggle with finding positions inside nested elements. I feel confident while I’m not working in nested elements, but as soon as nesting comes in I feel super lost.

Lets say I have a $bulletListPos which is a ResolvedPos of a bulletList node - and this list contains nested lists too and I want to add / move / cut content into the last listItem node found in the bulletList - what would be the best way to find this position?

Since the last item can be deeply nested, I can’t just find it by using $bulletListPos.end() - 1 because this will point into the nested bulletList, right?

Should I go via descendents here? Or is there any easier way I didn’t grasp yet? I’m still quite new to Prosemirror and I tried to get a grasp on everything via the Docs and looking at existing code but finding positions is still a big issue for me.

Thanks already for your support :pray: take your time.

descendents works, yes, or recursively enter last child nodes, keeping track of your position, until you find the node you’re looking for.

1 Like

Thanks for letting me know! I was able to find the last item via descendants but may switch to last item approach.

But in general it’s safe to find the previous node Position via the current nodes start position - 2 or are there caveats where this could break? It always feels weird to hardcode this offset of 2 and I wonder if there is a more reliable way to not accidentally point I to the doc node :grinning:

If you are skipping a closing and an opening token, that has an offset of 2 yeah. But if one of the nodes is an atom that doesn’t have open/close tokens, then this doesn’t work. (Also, a node position is usually understood to be the position before the node, and in this sentence you seem to be using it to mean the position at the start of the node’s content.)

1 Like

I try to iterate over via descendants() but somehow it does not return last child. What can be possible reason for that?

Thanks in advance

please help