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