Replace a node using tr.replaceWith - how to find node position?

I use transformPasted event to return a new Slice with some custom nodes in it. Such custom nodes load remote data to set attributes, so first i create them and return them in the slice returned in the event subscriber, then load remote data, then i think the right way to update them is:

pm.tr.replaceWith(pos, pos+1, schema.types.mynode.createAndFill(...)).apply()

But i don’t find how to get a node position. Is there some way i overlooked in the 0.9 reference ?

1 Like

Found a way to workaround this by setting an id on the node and getting the position using

var node = document.getElementById(id); var pos = pm.posFromDOM(node); var begin = pos.pos; var $pos = pm.doc.resolve(begin); var end = begin + $pos.nodeAfter.nodeSize; pm.tr.replace(begin, end, ...);

but it feels ugly. I don’t understand yet how to use a marked range but i suppose it’s the way to go.

I think you could use a MarkedRange in the following way:

// Create the node without the attributes
pm.tr.insertInline(pos, schema.types.mynode.createAndFill(...)).apply();
// Create a marked range for the node's position
const markedRange = pm.markRange(pos, pos + 1);

// Load data from remote...

// Update your node with the retrieved attributes
pm.tr.setNodeType(markedRange.from, null, attributes).apply();
// Clean up
pm.removeRange(markedRange)

Hope this helps!

Yes, this helps. Unfortunately i think i can’t make it to play well with transformPasted event subscriber: it returns a slice that is not yet inserted in the document and unless there’s a way to mark a range in that slice (which doesn’t make any sense to me) i’m still stuck with my “bad” solution.

What if you give your placeholder node some kind of id attribute, and let the asynchronous action that is supposed to complete it search for that id?

Yes, that’s what i did. You can see it in action there: http://kiwi.eda.sarl/~eda/sample/index.html (paste a url into the editor).

You’re right, I hadn’t thought of this! Alternatively, I think the newly introduced domPaste event could help in that case if you wanted to go with a MarkedRange. Of course if your current approach with the id works well, there’s not really a need to change it.

Can you share the source code of this demo? I have the same problem now, and I want to replace the text of the link with remote data after pasting. thank you

the link is 404, can you share a valid demo? Thanks a lot!