Strikethrough Node Type

Category: Formatting • Detailed implementation guide with view integration notes

Schema Definition

Schema definition for the Strikethrough mark type:

{
  strikethrough: {
  }
}

Model Representation

Example model representation:

{
  type: 'text',
  text: 'Deleted text',
  marks: [{ type: 'strikethrough' }]
}

HTML Serialization

Converting model to HTML:

function serializeStrikethroughMark(text, mark) {
  return '<s>' + text + '</s>';
}

HTML Deserialization

Parsing HTML to model:

function extractStrikethroughMark(element) {
  if (element.tagName === 'S' || 
      element.tagName === 'STRIKE' || 
      element.tagName === 'DEL') {
    return { type: 'strikethrough' };
  }
  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 strikethrough
function toggleStrikethrough() {
  const selection = window.getSelection();
  if (!selection.rangeCount) return;
  
  const range = selection.getRangeAt(0);
  const hasStrikethrough = hasMarkInSelection(range, 'strikethrough');
  
  if (hasStrikethrough) {
    removeMark('strikethrough');
  } else {
    addMark({ type: 'strikethrough' });
  }
}

Common Issues

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

Common issues and solutions:

// Issue: <s> vs <del> vs <strike>
// Solution: Normalize to <s>
function normalizeStrikethrough(element) {
  element.querySelectorAll('strike, del').forEach(el => {
    const s = document.createElement('s');
    s.innerHTML = el.innerHTML;
    el.parentNode.replaceChild(s, el);
  });
}

// Issue: Strikethrough semantic meaning
// Solution: <del> has semantic meaning (deleted content)
// Consider using <del> for version control scenarios

Implementation

Complete implementation example:

class StrikethroughMark {
  constructor() {
    this.type = 'strikethrough';
  }
  
  toDOM() {
    return ['s', 0];
  }
  
  static fromDOM(element) {
    if (['S', 'STRIKE', 'DEL'].includes(element.tagName)) {
      return new StrikethroughMark();
    }
    return null;
  }
}