Blockquote Node Type

Category: Structural • Detailed implementation guide with view integration notes

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);
  }
}