Will setNodeMarkUp remove decoration at same pos?

I’m using setNodeMarkup to update the Node being decorated and use DecorationSet.map to update the decorations.

After updating the Node attributes, the decoration of Node is deleted.

Is that the expected behavior? How to update attrs only?

setNodeMarkup will replace the opening token for the node with a new one, which causes decoration set mapping to discard any node decorations on that node. There’s currently no way to update only attributes, but you could write a custom Step subclass that does this and (like mark-related steps) doesn’t show any replacements in its step map.

1 Like

OK! Thank you!

Would you consider changing this? It’s not clear to me if there is any benefit there is to replacing the node and killing the decoration mapping? Meanwhlie, here is the ugly code that I had to use not to have my decoration mapping clobbered by use of setNodeMarkup

const newDecorations = [];
decorationSet.local.forEach(deco => {
  const mapped = deco.map(tr.mapping, 0, 0);
  if (mapped && mapped.type.valid(tr.doc, mapped)) {
    newDecorations.push(mapped);
  } else {
    newDecorations.push(deco);
  }
});
const newDecorationSet = DecorationSet.create(tr.doc, newDecorations);

We’ve had to write different flavors of this code a few different times. In another case we used the onRemove method to capture decorations and re-add them to the DecorationSet, but that only works when the decoration has a spec that can be used to identify and repopulate it.

If setNodeMarkup didn’t treat the node as a removal when the node type is non-changing, that would seem to make a lot more sense for the mapping of existing decorations that pertain to that node?

3 Likes