Content Formatting
The Formatter is Editor42's engine for applying, removing, and querying rich-text formats. It replaces the browser's inconsistent document.execCommand with a reliable, extensible API that works identically across all browsers.
Every editor instance exposes the Formatter via editor.formatter. Use it to register custom formats, apply them to selections or nodes, check whether a format is active, and react to format changes in real time.
editor42.init({
selector: '#my-editor',
setup: (editor) => {
editor.on('init', () => {
// Register a custom format
editor.formatter.register('highlight', {
inline: 'span',
styles: { 'background-color': '#ff0' }
});
// Apply it to the current selection
editor.formatter.apply('highlight');
});
}
});
Registering Custom Formats
Use register to add new formats and unregister to remove them. Formats can target inline elements, block elements, or match existing elements via CSS selectors.
// Register a single format
editor.formatter.register('customCode', {
inline: 'code',
styles: { 'font-family': 'monospace', 'background-color': '#f4f4f4' }
});
// Register multiple formats at once
editor.formatter.register({
note: { block: 'p', classes: 'note' },
warning: { block: 'div', classes: 'warning', wrapper: true }
});
// Check if a format exists
if (editor.formatter.has('customCode')) {
console.log('customCode format is registered');
}
// Retrieve a registered format
const fmt = editor.formatter.get('customCode');
// Remove a format from the registry
editor.formatter.unregister('customCode');
Applying and Removing Formats
Once registered, formats can be applied to the current selection, toggled on and off, or explicitly removed.
// Apply bold to the current selection
editor.formatter.apply('bold');
// Apply a format with variables (e.g. a color)
editor.formatter.apply('forecolor', { value: '#e03e2d' });
// Apply a format to a specific node
editor.formatter.apply('bold', {}, someNode);
// Remove a format from the current selection
editor.formatter.remove('bold');
// Remove with the "similar" flag — removes formats
// that are similar but not an exact variable match
editor.formatter.remove('forecolor', { value: '#e03e2d' }, null, true);
// Toggle a format on or off depending on current state
editor.formatter.toggle('bold');
editor.formatter.toggle('italic');
Querying Formats
The Formatter provides several methods for checking whether formats are active on the current selection or on specific nodes.
// Check if bold is active on the current selection
const isBold = editor.formatter.match('bold');
// Check if a specific color is active
const isRed = editor.formatter.match('forecolor', { value: '#e03e2d' });
// Find all active formats from a list
const active = editor.formatter.matchAll(['bold', 'italic', 'underline']);
// e.g. ['bold', 'italic']
// Find the closest matching format from a set
const closest = editor.formatter.closest(['h1', 'h2', 'h3', 'p']);
// e.g. 'h2'
// Check a specific node
const fmt = editor.formatter.matchNode(someNode, 'bold');
if (fmt) {
console.log('Node matches bold format');
}
// Check if a format can be applied to the current selection
if (editor.formatter.canApply('bold')) {
console.log('Bold can be applied here');
}
Observing Format Changes
Use formatChanged to run a callback whenever the current selection enters or leaves a formatted region. The names parameter accepts a comma-separated list of format names.
// React when bold or italic state changes
const watcher = editor.formatter.formatChanged('bold,italic', (active, args) => {
console.log(`Format "${args.format}" is now ${active ? 'on' : 'off'}`);
});
// Stop observing
watcher.unbind();
API Reference
| Method | Signature | Returns | Description |
|---|---|---|---|
get | get(name?: string) | Array | Object | Returns the format by name, or all registered formats if no name is specified. |
has | has(name: string) | boolean | Returns whether a format is registered for the given name. |
register | register(name: string | object, format?: object | array) | — | Registers a format by name. Pass an object as the first argument to register multiple formats at once. |
unregister | unregister(name: string) | — | Unregisters a format by name. |
apply | apply(name: string, vars?: FormatVars, node?: Node | RangeLikeObject | null) | — | Applies the named format to the current selection or specified node. |
remove | remove(name: string, vars?: FormatVars, node?: Node | Range, similar?: boolean) | — | Removes the named format from the current selection or specified node. |
toggle | toggle(name: string, vars?: FormatVars, node?: Node) | — | Toggles the named format on or off. |
match | match(name: string, vars?: FormatVars, node?: Node, similar?: boolean) | boolean | Returns whether the current selection or specified node matches the named format. |
closest | closest(names: string[]) | string | null | Returns the closest matching format name from the given array, or null. |
matchAll | matchAll(names: string[], vars?: FormatVars) | string[] | Returns the subset of format names that match the current selection. |
matchNode | matchNode(node: Node | null, name: string, vars?: FormatVars, similar?: boolean) | Format | undefined | Returns the format object if the node matches the named format, or undefined. |
canApply | canApply(name: string) | boolean | Returns whether the named format can be applied to the current selection. |
formatChanged | formatChanged(names: string, callback: FormatChangeCallback, similar?: boolean, vars?: FormatVars) | { unbind: () => void } | Calls the callback when the selection enters or leaves the specified formats. Returns an object with an unbind method. |
getCssText | getCssText(format: string | ApplyFormat) | string | Returns a preview CSS text string for the format. Useful for rendering format previews in UI elements. |
Format Specification
A format is a plain object describing how an element should be created, matched, or removed. There are three primary format types — inline, block, and selector — determined by which top-level property you set.
| Property | Type | Description |
|---|---|---|
inline | string | Inline element to produce (e.g. 'span', 'b', 'i', 'code'). |
block | string | Block element to produce (e.g. 'h1', 'p', 'div', 'blockquote'). |
selector | string | CSS selector to match existing elements instead of creating new ones. |
styles | object | CSS styles to apply as key/value pairs (e.g. { 'color': '#f00' }). |
attributes | object | HTML attributes to set as key/value pairs (e.g. { 'title': 'Note' }). |
classes | string | string[] | CSS class names to add to the element. |
wrapper | boolean | Whether the format wraps content in a new container element. |
remove | string | Controls removal behavior: 'none', 'empty', or 'all'. |
exact | boolean | Require an exact match of styles/classes/attributes for removal. |
Examples
// Inline format — wraps selection in a styled <span>
editor.formatter.register('highlight', {
inline: 'span',
styles: { 'background-color': '#ff0' }
});
// Block format — converts paragraph to <h2>
editor.formatter.register('heading2', {
block: 'h2'
});
// Selector format — applies a class to an existing <p>
editor.formatter.register('intro', {
selector: 'p',
classes: 'intro'
});
// Format with attributes and exact matching
editor.formatter.register('langSpan', {
inline: 'span',
attributes: { 'lang': '%value' },
exact: true
});
editor.formatter.apply('langSpan', { value: 'fr' });