Schema Definition
Schema definition for the Mention node type:
{
mention: {
inline: true,
attrs: {
id: { default: '' },
label: { default: '' }
},
}
}Model Representation
Example model representation:
{
type: 'mention',
attrs: {
id: 'user123',
label: '@username'
}
}HTML Serialization
Converting model to HTML:
function serializeMention(node) {
return '<span data-type="mention" data-id="' + escapeHtml(node.attrs.id) +
'">' + escapeHtml(node.attrs.label) + '</span>';
}HTML Deserialization
Parsing HTML to model:
function parseMention(domNode) {
return {
type: 'mention',
attrs: {
id: domNode.getAttribute('data-id') || '',
label: domNode.textContent || ''
}
};
}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 mention
const mention = document.createElement('span');
mention.setAttribute('data-type', 'mention');
mention.setAttribute('data-id', node.attrs.id);
mention.textContent = node.attrs.label;
mention.className = 'mention';
mention.contentEditable = 'false'; // Mentions 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: Mention autocomplete
// Solution: Implement mention autocomplete
function handleMentionInput(e) {
const query = e.target.value;
if (query.startsWith('@')) {
showMentionSuggestions(query.slice(1));
}
}
// Issue: Mention deletion
// Solution: Handle mention deletion as a unit
function handleMentionDeletion(mention) {
// Delete entire mention, not just part of it
mention.remove();
}Implementation
Complete implementation example:
class MentionNode {
constructor(attrs) {
this.type = 'mention';
this.attrs = {
id: attrs?.id || '',
label: attrs?.label || ''
};
}
toDOM() {
const mention = document.createElement('span');
mention.setAttribute('data-type', 'mention');
mention.setAttribute('data-id', this.attrs.id);
mention.textContent = this.attrs.label;
mention.className = 'mention';
return mention;
}
static fromDOM(domNode) {
return new MentionNode({
id: domNode.getAttribute('data-id') || '',
label: domNode.textContent || ''
});
}
}