Schema Definition
Schema definition for the Blockquote node type:
{
blockquote: {
content: 'block+',
group: 'block'
}
}Model Representation
Example model representation:
{
type: 'blockquote',
children: [
{
type: 'paragraph',
children: [{ type: 'text', text: 'Quoted text' }]
}
]
}HTML Serialization
Converting model to HTML:
function serializeBlockquote(node) {
return '<blockquote>' + serializeChildren(node.children) + '</blockquote>';
}HTML Deserialization
Parsing HTML to model:
function parseBlockquote(domNode) {
return {
type: 'blockquote',
children: parseChildren(domNode.childNodes)
};
}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
const blockquote = document.createElement('blockquote');
blockquote.contentEditable = 'true';
node.children.forEach(child => {
blockquote.appendChild(renderNode(child));
});
// Creating blockquote
function createBlockquote() {
return {
type: 'blockquote',
children: [{
type: 'paragraph',
children: []
}]
};
}Common Issues
Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.
Common issues and solutions:
// Issue: Empty blockquote
// Solution: Ensure at least one block
if (node.children.length === 0) {
node.children.push({
type: 'paragraph',
children: []
});
}
// Issue: Nested blockquotes
// Solution: Handle or prevent nesting
function validateBlockquote(blockquote) {
// Check for nested blockquotes
const nested = blockquote.querySelector('blockquote');
if (nested) {
// Unwrap or handle
}
}Implementation
Complete implementation example:
class BlockquoteNode {
constructor(children) {
this.type = 'blockquote';
this.children = children || [];
}
toDOM() {
const blockquote = document.createElement('blockquote');
this.children.forEach(child => {
blockquote.appendChild(child.toDOM());
});
return blockquote;
}
static fromDOM(domNode) {
const children = Array.from(domNode.childNodes)
.map(node => parseNode(node))
.filter(Boolean);
return new BlockquoteNode(children);
}
}