Decoration spec

Hey, I have created some plugins with decorations, and in each case I need to be able to identify the individual decorations, among other things when the decoration gets deleted by the editor. In my particular place, I don’t place two decorations of the same plugin in the exact same place at the exact same time, so this happens to work right now:

let deco = Decoration.inline(from, to, {}, {id: `${Date.now()}-${from}`})
decos = decos.add(doc, [deco])
...
decos = decos.map(tr.mapping, tr.doc, {onRemove: decoSpec => {
    let index = decos.find().findIndex(deco => deco.spec.id === decoSpec.id)
    .... (do something with index)
} 

But adding a “unique” id like that feels a bit hacky. Surely this isn’t how it is supposed to be used? Is there another way?

Another things: node decorations seem to auto-destroy when using a setNodeType transaction to change the attributes of the tracked node. Is there some other way to set attributes now? Or should I not use decorations at all if the point is simply to track nodes?

I’ve been using http://prosemirror.net/docs/ref/#view.DecorationSet.find to retrieve the existing decoration for my start/end. Luckily my plugins either deal with a single decoration or several but never overlapping.

@wes-r In the example, I also use the find function. But when one decoration is deleted, how do you know which one it is? You only get the “decoration spec”, which I couldn’t find a description of, but it just seems to be any object with any contents one can pass as the 4th argument when creating an inline decoration. It just feels like I am missing something.

The spec you give to a decoration can be an arbitrary object, with any extra properties you want. It is also preserved (by value) as the decoration is mapped, so you could either add an id-type property, or compare the spec property by value.

1 Like

Ok, got it. How about the decorations themselves? Are they preserved? During my test it seemed to work to first add a decoration to a decoration set and later get it back using decos.find() and it would still be the same object. But is this something one can rely on, or should one always just keep the decorationspec for this purpose?

No, they are replaced with new objects when you map them.

1 Like