Schema Definition
Schema definition for the Annotation node type:
{
annotation: {
inline: true,
attrs: {
id: { default: '' },
type: { default: 'comment' }
},
}
}Model Representation
Example model representation:
{
type: 'annotation',
attrs: {
id: 'annotation123',
type: 'comment'
}
}HTML Serialization
Converting model to HTML:
function serializeAnnotation(node) {
return '<span data-type="annotation" data-id="' + escapeHtml(node.attrs.id) +
'" data-annotation-type="' + node.attrs.type + '"></span>';
}HTML Deserialization
Parsing HTML to model:
function parseAnnotation(domNode) {
return {
type: 'annotation',
attrs: {
id: domNode.getAttribute('data-id') || '',
type: domNode.getAttribute('data-annotation-type') || 'comment'
}
};
}View Integration
View Integration Notes: Pay special attention to contenteditable behavior, selection handling, and event management when implementing this node type in your view layer.
View integration code:
// Rendering annotation
const annotation = document.createElement('span');
annotation.setAttribute('data-type', 'annotation');
annotation.setAttribute('data-id', node.attrs.id);
annotation.setAttribute('data-annotation-type', node.attrs.type);
annotation.className = 'annotation';
annotation.contentEditable = 'false'; // Annotations are typically not directly editableCommon Issues
Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.
Common issues and solutions:
// Issue: Annotation display
// Solution: Show annotation on hover or click
function showAnnotation(annotation) {
const id = annotation.getAttribute('data-id');
// Fetch and display annotation content
displayAnnotationPopup(id);
}
// Issue: Annotation synchronization
// Solution: Sync annotations across collaborative editing
function syncAnnotation(annotation, changes) {
// Update annotation based on document changes
}Implementation
Complete implementation example:
class AnnotationNode {
constructor(attrs) {
this.type = 'annotation';
this.attrs = {
id: attrs?.id || '',
type: attrs?.type || 'comment'
};
}
toDOM() {
const annotation = document.createElement('span');
annotation.setAttribute('data-type', 'annotation');
annotation.setAttribute('data-id', this.attrs.id);
annotation.setAttribute('data-annotation-type', this.attrs.type);
annotation.className = 'annotation';
return annotation;
}
static fromDOM(domNode) {
return new AnnotationNode({
id: domNode.getAttribute('data-id') || '',
type: domNode.getAttribute('data-annotation-type') || 'comment'
});
}
}