It seems that only the highest precedence transaction extender is applied to a transaction. This is at least true of the transaction that reaches the update() method of a view plugin. The documentation and the code suggest that the idea is that effects and annotations should instead be combined. For example:
import {EditorView} from "@codemirror/view"
import {EditorState, Annotation} from "@codemirror/state"
const annotation1 = Annotation.define()
const annotation2 = Annotation.define()
const listener = EditorView.updateListener.of(update => {
const hasAnnotation1 = update.transactions.some(tr => tr.annotation(annotation1))
const hasAnnotation2 = update.transactions.some(tr => tr.annotation(annotation2))
console.log(`Transaction has annotation 1 is ${hasAnnotation1}, has annotation 2 is ${hasAnnotation2}`)
})
const annotator1 = EditorState.transactionExtender.of(tr => {
console.log("annotator1")
return {
annotations: annotation1.of(true)
}
})
const annotator2 = EditorState.transactionExtender.of(tr => {
console.log("annotator2")
return {
annotations: annotation2.of(true)
}
})
const view = new EditorView({
doc: "",
extensions: [annotator1, annotator2, listener],
parent: document.body
})
view.dispatch({})
The console output is
annotator2
annotator1
Transaction has annotation 1 is true, has annotation 2 is false
I’d expect the transaction observed by the update listener to have both annotations but it only has annotation1, the highest precedence one.
This issue is also mentioned briefly near the end of this post: