Widget decoration duplication issue

In my code, I added a decoration plugin to insert widget decorations (not inline ones) to put some html into the DOM (such as a page break for pagination mimicry). But what happens is that on each click or character entry all the decorations are getting duplicated within the plugin as I am using newDecorationSet.add(tr.doc, decorations) when the apply is run. The decoration set thus doubles each time, inserting the same html in the same spot over and over.

The problem does get solved if I always start with an empty decoration set in the apply function, but that means throwing out all the old decorations and building the entire list of decorations each time.

How can I just copy the current decorations then update the position of the existing decorations when possible, only adding new ones in the apply function when a new one is needed?

Related, it seems my decorations plugin does not get fired untl I click on the editor, when the view is first created it does not get fired. What might I be doing wrong there?

Take the old value that’s passed to your state field’s apply function, and call .map(tr.mapping)on it to move it from the old document space to the new. Then optionally call add to add new decorations as needed.

The state field’s init function will be called when the editor state is created.

Further on point 1: For the widget decorations, can I do the standard map copy then change the positions in the decoration set returned and then return those, assuming I don’t want new decorations, but instead to move the current ones around?

And on point 2: The examples I have seen just return an empty decoration set in the init, it is the apply that does the heavy lifting. It gets called when I click or type, but not initially on the page and editor load. I want the document to load up and then do an immediate calculation of the needed widget decorations. That is my confusion here.

Mapping a decoration will keep the decorations in the same conceptual position relative to the content around them, but move their positions if there are changes before them.

Right, because those examples don’t need decorations on document load. If you do, it seems pretty obvious what you need to do here.

With the Init function, what to do is easy for you, obviously. Am I meant to create a transaction that fires off the apply function to get the deocations created? What might be obvious to you isn’t actually obvious to me as a newcomer to PM.

The init function returns the state field’s initial value. All you have to do is build up your decorations and return them (assuming the state field’s value holds only that set).

Sounds great, however right now all my logic is in the apply function, which uses the transaction passed in to do mapping and to get the document value to cycle through the nodes. Should I be removing the logic there and putting it in a function that has an optional transaction value and then only do mapping if one is passed in? Perhaps I could just pass in the editor document for the initial render with null for the transaction to have the function build an initial set of decorations.