Italic Node Type

Category: Formatting • Detailed implementation guide with view integration notes

Schema Definition

Schema definition for the Italic mark type:

{
  italic: {
    // Marks don't have content, they wrap text nodes
  }
}

Model Representation

Example model representation:

{
  type: 'text',
  text: 'Italic text',
  marks: [{ type: 'italic' }]
}

HTML Serialization

Converting model to HTML:

function serializeItalicMark(text, mark) {
  return '<em>' + text + '</em>';
}

HTML Deserialization

Parsing HTML to model:

function extractItalicMark(element) {
  if (element.tagName === 'EM' || element.tagName === 'I') {
    return { type: 'italic' };
  }
  return null;
}

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:

// Toggling italic
function toggleItalic() {
  const selection = window.getSelection();
  if (!selection.rangeCount) return;
  
  const range = selection.getRangeAt(0);
  const hasItalic = hasMarkInSelection(range, 'italic');
  
  if (hasItalic) {
    removeMark('italic');
  } else {
    addMark({ type: 'italic' });
  }
}

Common Issues

Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.

Common issues and solutions:

// Issue: <i> vs <em> normalization
// Solution: Always convert <i> to <em>
function normalizeItalic(element) {
  element.querySelectorAll('i').forEach(i => {
    const em = document.createElement('em');
    em.innerHTML = i.innerHTML;
    i.parentNode.replaceChild(em, i);
  });
}

// Issue: Bold and italic together
// Solution: Handle nested marks correctly
// <strong><em>text</em></strong> or <em><strong>text</strong></em>
function applyBoldAndItalic(text) {
  // Order matters for semantic HTML
  return '<strong><em>' + text + '</em></strong>';
}

Implementation

Complete implementation example:

class ItalicMark {
  constructor() {
    this.type = 'italic';
  }
  
  toDOM() {
    return ['em', 0];
  }
  
  static fromDOM(element) {
    if (element.tagName === 'EM' || element.tagName === 'I') {
      return new ItalicMark();
    }
    return null;
  }
}