Thank you for CM & its excellent documentation!
I’m attempting to use mark decorations to annotate a document. I’d like my annotation decorations to apply to arbitrary code ranges, be highlighted (accomplished with CSS) and, when clicked, to render the corresponding annotation outside the CM editor. I’ve set up my annotations as a mark decoration through a StateField for ser/de (see below). Unfortunately, possibly as expected, my onclick
function reference is not directly attached to the rendered DOM element. Instead it’s stringified, so the handler does not work as I would hope.
Is this expected behavior? If so, is there a better way to achieve what I’m after? I did not feel the other decoration types matched this use case as well as mark.
const addAnnotation = StateEffect.define();
const annotationField = StateField.define({
create() {
return Decoration.none;
},
update(annotations, tr) {
annotations = annotations.map(tr.changes);
tr.effects.forEach((e) => {
if (e.is(addAnnotation)) {
const annotationMark = Decoration.mark({
attributes: {
class: 'cm-underline',
// trouble here
onclick: function() { alert(e.value.annotationId) },
},
annotationId: e.value.annotationId,
});
annotations = annotations.update({
add: [annotationMark.range(e.value.from, e.value.to)],
});
}
});
return annotations;
},
provide: (f) => EditorView.decorations.from(f),
toJSON: (value, state) => {
const annotations = [];
value.between(1, state.doc.length, (from, to, v2) => {
annotations.push({
annotationId: v2.spec.annotationId,
from,
to,
});
});
return annotations;
},
fromJSON: (json, state) => {
...
},
});