Ok, after a brief trip to the implementation described in this thread I’ve changed to a much simpler implementation
For counting and renumbering footnotes
let findTheFoot = (state) => {
let footnotes = []
let counter = 0;
let transaction = null
state.doc.descendants((node, pos) => {
if(node.type.name != 'footnote') return true
counter = counter + 1
if (node.attrs.number != counter) {
if(transaction == null) transaction = state.tr
transaction.setNodeMarkup(pos, null, { number: counter })
}
})
return transaction
}
export function createFootNotesPlugin() {
return new Plugin({
key: 'footnotes',
appendTransaction: (transactions, oldState, newState) => {
return findTheFoot(newState)
}
})
}
The view:
class FootnoteNodeView {
constructor(node, view, getPos) {
this.dom = window.document.createElement('footnote')
let head = this.dom.appendChild(window.document.createElement('footnotehead'))
head.innerText = `Footnote ${node.attrs.number}`
head.contentEditable = false
this.contentDOM = this.dom.appendChild(window.document.createElement('content'))
head.addEventListener("click", e => {
if (this.dom.classList.contains('expanded')) {
this.dom.classList.remove('expanded')
}
else {
this.dom.classList.add('expanded')
}
})
}
ignoreMutation(rec) {
return rec.target.tagName == 'FOOTNOTE' && rec.type == 'attributes' && rec.attributeName == 'class'
}
}
export default FootnoteNodeView
I think I’ll need to tweak the header for accessibility purposes, but so far this works a treat.