Schema Definition
Schema definition for the Horizontal Rule node type:
{
horizontalRule: {
group: 'block',
}
}Model Representation
Example model representation:
{
type: 'horizontalRule'
}HTML Serialization
Converting model to HTML:
function serializeHorizontalRule(node) {
return '<hr>';
}HTML Deserialization
Parsing HTML to model:
function parseHorizontalRule(domNode) {
return {
type: 'horizontalRule'
};
}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 hr = document.createElement('hr');
// Horizontal rules are self-closing block elements
// Inserting horizontal rule
function insertHorizontalRule() {
const hr = {
type: 'horizontalRule'
};
insertNode(hr);
}Common Issues
Common Pitfalls: These are issues frequently encountered when implementing this node type. Review carefully before implementation.
Common issues and solutions:
// Issue: Horizontal rule styling
// Solution: Apply consistent styles
function styleHorizontalRule(hr) {
hr.style.border = 'none';
hr.style.borderTop = '1px solid #ccc';
hr.style.margin = '1em 0';
}
// Issue: Selection around <hr>
// Solution: Handle cursor positioning
function getPositionAroundHr(hr) {
// Position cursor after <hr>
const range = document.createRange();
range.setStartAfter(hr);
range.collapse(true);
return range;
}
// Issue: <hr> in nested contexts
// Solution: Ensure <hr> is always a direct child of block
function validateHorizontalRule(hr) {
const parent = hr.parentNode;
if (!isBlockNode(parent)) {
// Move to block parent
moveToBlockParent(hr);
}
}Implementation
Complete implementation example:
class HorizontalRuleNode {
constructor() {
this.type = 'horizontalRule';
}
toDOM() {
const hr = document.createElement('hr');
return hr;
}
static fromDOM(domNode) {
return new HorizontalRuleNode();
}
}