I appear to have run into the infamous footnote problem. I am trying to add footnotes (annotations) to the document. I’ve taken a nodeView approach to solving this.
My Schema (abbreviated)
nodes: {
doc: { content: 'block+' },
paragraph: {
group: 'block',
content: 'inline<_>*',
parseDOM: [{tag: 'p'}],
toDOM: function toDOM () { return ['p', 0]; }
},
annotation: {
group: 'inline',
inline: true,
attrs: {
...
},
parseDOM: [{
tag: 'annotation',
getAttrs: function (node) {
var attrs = {};
_.each(node.attributes, function (attr) {
if (attr.name.indexOf('annotation') !== -1) {
attrs[attr.name] = attr.value;
}
});
return attrs;
},
getContent: function (node) {
return node.innerText;
}
}],
toDOM: function (node) {
return ['span', {class: 'annotation'}];
}
}
}
My NodeView
nodeViews: {
annotation: function (node, view, getPos) {
var $dom = $('<span>').addClass('annotation').attr(node.attrs);
$('<span>').addClass('annotation-target').text(node.textContent).appendTo($dom);
$('<div>').addClass('annotation-wrapper').html('<div class="annotation-body"><div class="annotation-title">Annotation</div><p class="annotation-comment"></p></div>').appendTo($dom);
return {
dom: $dom[0]
};
}
}
With some CSS the annotation-wrapper is floated into a gutter and the annotation-target stays within the document editor. That all looks fine but editing is a little weird. The problem that I am looking at now though has to do with parseDom on the annotation. The dom it parses is one annotation tag with no children. Just some attributes and text content. The content of the annotation tag is never retrieved. I think this might be because the annotation node is considered to be a leaf node and when parsing its contents is never set:
ParseContext.prototype.addElementByRule
if (nodeType.isLeaf) { this.insertNode(nodeType.create(rule.attrs, null, this.marks)) }
When the addElementByRule function is called it considers the node to be a leaf and sets the contents to null. It never tries to retrieve the content even though I have getContent defined on the annotation node spec. Which seems to be the case for inline nodes (or nodes without content). Because of this I am not able to parse the annotation target’s text content to put into the doc.
Is there a way for me to parse and set the content? Is this a good method for adding annotations to ProseMirror?
Even if I solve this problem of parsing the dom I am concerned that I will run into other issues like editing the annotation target text and selecting and moving the cursor around it.