0
# Formatting System
1
2
Comprehensive formatting system supporting inline formats (bold, italic, links), block formats (headers, lists, blockquotes), embed formats (images, videos), and custom attributors for style-based formatting. Quill's formatting system is built on Parchment blots that map directly to DOM elements.
3
4
## Capabilities
5
6
### Inline Formats
7
8
Text-level formatting that can be applied to character ranges within a line.
9
10
```typescript { .api }
11
// Bold formatting
12
class Bold extends Inline {
13
static blotName: 'bold';
14
static tagName: ['STRONG', 'B'];
15
}
16
17
// Italic formatting
18
class Italic extends Inline {
19
static blotName: 'italic';
20
static tagName: ['EM', 'I'];
21
}
22
23
// Underline formatting
24
class Underline extends Inline {
25
static blotName: 'underline';
26
static tagName: 'U';
27
}
28
29
// Strikethrough formatting
30
class Strike extends Inline {
31
static blotName: 'strike';
32
static tagName: ['S', 'STRIKE'];
33
}
34
35
// Inline code formatting
36
class Code extends Inline {
37
static blotName: 'code';
38
static tagName: 'CODE';
39
}
40
41
// Superscript/subscript formatting
42
class Script extends Inline {
43
static blotName: 'script';
44
static tagName: ['SUB', 'SUP'];
45
static create(value: 'sub' | 'super'): HTMLElement;
46
static formats(domNode: HTMLElement): string;
47
}
48
```
49
50
**Usage Examples:**
51
52
```typescript
53
// Apply inline formatting
54
quill.formatText(0, 5, 'bold', true);
55
quill.formatText(6, 4, 'italic', true);
56
quill.formatText(11, 3, 'underline', true);
57
quill.formatText(15, 6, 'strike', true);
58
quill.formatText(22, 4, 'code', true);
59
quill.formatText(27, 4, 'script', 'super');
60
61
// Multiple formats at once
62
quill.formatText(0, 10, {
63
bold: true,
64
italic: true,
65
color: '#ff0000'
66
});
67
68
// Remove formatting
69
quill.formatText(0, 10, {
70
bold: false,
71
italic: null // null also removes formatting
72
});
73
```
74
75
### Link Format
76
77
Hyperlink formatting with URL validation and sanitization.
78
79
```typescript { .api }
80
class Link extends Inline {
81
static blotName: 'link';
82
static tagName: 'A';
83
static SANITIZED_URL: 'about:blank';
84
static PROTOCOL_WHITELIST: ['http', 'https', 'mailto', 'tel', 'sms'];
85
86
/**
87
* Create link element with href attribute
88
* @param value - URL for the link
89
* @returns HTMLAnchorElement with href set
90
*/
91
static create(value: string): HTMLAnchorElement;
92
93
/**
94
* Get href value from link element
95
* @param domNode - Link element
96
* @returns URL from href attribute
97
*/
98
static formats(domNode: HTMLAnchorElement): string;
99
100
/**
101
* Sanitize URL to prevent XSS attacks
102
* @param url - URL to sanitize
103
* @returns Sanitized URL or fallback URL
104
*/
105
static sanitize(url: string): string;
106
107
/**
108
* Format this link blot
109
* @param name - Format name ('link')
110
* @param value - URL value or false to remove link
111
*/
112
format(name: string, value: string | boolean): void;
113
}
114
115
/**
116
* Standalone URL sanitization function
117
* @param url - URL to sanitize
118
* @param protocols - Allowed protocols (default: Link.PROTOCOL_WHITELIST)
119
* @returns Sanitized URL
120
*/
121
function sanitize(url: string, protocols?: string[]): string;
122
```
123
124
**Usage Examples:**
125
126
```typescript
127
// Create links
128
quill.formatText(0, 5, 'link', 'https://example.com');
129
quill.formatText(10, 8, 'link', 'mailto:user@example.com');
130
quill.formatText(20, 12, 'link', 'tel:+1234567890');
131
132
// Get current link value
133
const formats = quill.getFormat(5, 0);
134
if (formats.link) {
135
console.log('Link URL:', formats.link);
136
}
137
138
// Remove link
139
quill.formatText(0, 5, 'link', false);
140
141
// Insert link with text
142
quill.insertText(0, 'Click here', { link: 'https://example.com' });
143
```
144
145
### Block Formats
146
147
Line-level formatting that affects entire lines or paragraphs.
148
149
```typescript { .api }
150
// Header formatting (H1-H6)
151
class Header extends Block {
152
static blotName: 'header';
153
static tagName: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'];
154
155
/**
156
* Get header level from DOM element
157
* @param domNode - Header element
158
* @returns Header level (1-6)
159
*/
160
static formats(domNode: HTMLElement): number;
161
162
/**
163
* Create header element for specified level
164
* @param value - Header level (1-6)
165
* @returns Header element
166
*/
167
static create(value: number): HTMLElement;
168
}
169
170
// Blockquote formatting
171
class Blockquote extends Block {
172
static blotName: 'blockquote';
173
static tagName: 'blockquote';
174
}
175
176
// Code block formatting
177
class CodeBlock extends Block {
178
static blotName: 'code-block';
179
static tagName: 'DIV';
180
static className: 'ql-code-block';
181
static TAB: string;
182
183
/**
184
* Handle tab key in code blocks
185
* @param range - Current selection range
186
* @param context - Keyboard context
187
*/
188
static handleTab(range: Range, context: any): boolean;
189
}
190
```
191
192
**Usage Examples:**
193
194
```typescript
195
// Apply block formatting
196
quill.formatLine(0, 1, 'header', 1); // H1
197
quill.formatLine(20, 1, 'header', 2); // H2
198
quill.formatLine(40, 1, 'blockquote', true);
199
quill.formatLine(60, 1, 'code-block', true);
200
201
// Multiple lines
202
quill.formatLine(0, 50, 'header', 3); // Format multiple lines as H3
203
204
// Remove block formatting
205
quill.formatLine(0, 1, 'header', false);
206
quill.formatLine(20, 1, 'blockquote', false);
207
```
208
209
### List Formats
210
211
Ordered and unordered list formatting with nested list support.
212
213
```typescript { .api }
214
// List item formatting
215
class ListItem extends Block {
216
static blotName: 'list';
217
static tagName: 'LI';
218
219
/**
220
* Create list item element
221
* @param value - List type ('ordered' | 'bullet')
222
* @returns List item element
223
*/
224
static create(value: 'ordered' | 'bullet'): HTMLLIElement;
225
226
/**
227
* Get list type from DOM element
228
* @param domNode - List item element
229
* @returns List type string
230
*/
231
static formats(domNode: HTMLLIElement): string;
232
233
/**
234
* Register list container with Parchment
235
*/
236
static register(): void;
237
238
/**
239
* Format this list item
240
* @param name - Format name
241
* @param value - Format value
242
*/
243
format(name: string, value: any): void;
244
}
245
246
// List container formatting
247
class ListContainer extends Container {
248
static blotName: 'list-container';
249
static tagName: 'OL';
250
251
/**
252
* Create list container element
253
* @param value - List type
254
* @returns List container element
255
*/
256
static create(value: string): HTMLOListElement | HTMLUListElement;
257
}
258
```
259
260
**Usage Examples:**
261
262
```typescript
263
// Create bullet list
264
quill.formatLine(0, 1, 'list', 'bullet');
265
quill.formatLine(20, 1, 'list', 'bullet');
266
quill.formatLine(40, 1, 'list', 'bullet');
267
268
// Create ordered list
269
quill.formatLine(0, 1, 'list', 'ordered');
270
quill.formatLine(20, 1, 'list', 'ordered');
271
quill.formatLine(40, 1, 'list', 'ordered');
272
273
// Remove list formatting
274
quill.formatLine(0, 1, 'list', false);
275
276
// Insert list items
277
quill.insertText(0, 'First item\n', { list: 'bullet' });
278
quill.insertText(11, 'Second item\n', { list: 'bullet' });
279
```
280
281
### Embed Formats
282
283
Self-contained elements like images, videos, and formulas.
284
285
```typescript { .api }
286
// Image embed
287
class Image extends EmbedBlot {
288
static blotName: 'image';
289
static tagName: 'IMG';
290
291
/**
292
* Create image element
293
* @param value - Image URL or configuration object
294
* @returns Image element
295
*/
296
static create(value: string | { src: string; alt?: string; [key: string]: any }): HTMLImageElement;
297
298
/**
299
* Get image attributes
300
* @param domNode - Image element
301
* @returns Object with image attributes
302
*/
303
static formats(domNode: HTMLImageElement): Record<string, string>;
304
305
/**
306
* Check if URL is valid image
307
* @param url - URL to check
308
* @returns True if URL appears to be an image
309
*/
310
static match(url: string): boolean;
311
312
/**
313
* Sanitize image URL
314
* @param url - URL to sanitize
315
* @returns Sanitized URL
316
*/
317
static sanitize(url: string): string;
318
319
/**
320
* Get image source URL
321
* @param domNode - Image element
322
* @returns Image source URL
323
*/
324
static value(domNode: HTMLImageElement): string;
325
326
/**
327
* Format image attributes
328
* @param name - Attribute name
329
* @param value - Attribute value
330
*/
331
format(name: string, value: any): void;
332
}
333
334
// Video embed
335
class Video extends BlockEmbed {
336
static blotName: 'video';
337
static tagName: 'IFRAME';
338
static ATTRIBUTES: string[];
339
340
/**
341
* Create video iframe element
342
* @param value - Video URL
343
* @returns Iframe element
344
*/
345
static create(value: string): HTMLIFrameElement;
346
347
/**
348
* Get video URL from iframe
349
* @param domNode - Iframe element
350
* @returns Video URL
351
*/
352
static formats(domNode: HTMLIFrameElement): string;
353
354
/**
355
* Sanitize video URL
356
* @param url - URL to sanitize
357
* @returns Sanitized URL
358
*/
359
static sanitize(url: string): string;
360
361
/**
362
* Get video URL value
363
* @param domNode - Iframe element
364
* @returns Video URL
365
*/
366
static value(domNode: HTMLIFrameElement): string;
367
}
368
369
// Formula embed (for mathematical expressions)
370
class Formula extends EmbedBlot {
371
static blotName: 'formula';
372
static tagName: 'SPAN';
373
static className: 'ql-formula';
374
375
/**
376
* Create formula element
377
* @param value - LaTeX formula string
378
* @returns Span element with formula
379
*/
380
static create(value: string): HTMLSpanElement;
381
382
/**
383
* Get formula value
384
* @param domNode - Formula element
385
* @returns LaTeX formula string
386
*/
387
static value(domNode: HTMLSpanElement): string;
388
389
/**
390
* Render formula (requires KaTeX or similar)
391
* @param value - LaTeX formula
392
* @returns Rendered formula HTML
393
*/
394
html(): string;
395
}
396
```
397
398
**Usage Examples:**
399
400
```typescript
401
// Insert image
402
quill.insertEmbed(0, 'image', 'https://example.com/image.jpg');
403
404
// Insert image with attributes
405
quill.insertEmbed(0, 'image', {
406
src: 'https://example.com/image.jpg',
407
alt: 'Example image',
408
width: '300'
409
});
410
411
// Insert video
412
quill.insertEmbed(10, 'video', 'https://youtube.com/watch?v=abc123');
413
414
// Insert formula
415
quill.insertEmbed(20, 'formula', 'E = mc^2');
416
417
// Get embed values
418
const delta = quill.getContents();
419
delta.ops.forEach(op => {
420
if (op.insert && typeof op.insert === 'object') {
421
if (op.insert.image) {
422
console.log('Image URL:', op.insert.image);
423
} else if (op.insert.video) {
424
console.log('Video URL:', op.insert.video);
425
} else if (op.insert.formula) {
426
console.log('Formula:', op.insert.formula);
427
}
428
}
429
});
430
```
431
432
### Attributor-Based Formats
433
434
Style-based formatting using CSS classes or inline styles.
435
436
```typescript { .api }
437
// Color attributor (style-based)
438
class ColorStyle extends StyleAttributor {
439
static attrName: 'color';
440
static keyName: 'color';
441
static styleName: 'color';
442
}
443
444
// Color attributor (class-based)
445
class ColorClass extends ClassAttributor {
446
static attrName: 'color';
447
static keyName: 'color';
448
static className: 'ql-color';
449
}
450
451
// Font attributor
452
class FontClass extends ClassAttributor {
453
static attrName: 'font';
454
static keyName: 'font';
455
static className: 'ql-font';
456
}
457
458
class FontStyle extends StyleAttributor {
459
static attrName: 'font';
460
static keyName: 'font';
461
static styleName: 'font-family';
462
}
463
464
// Size attributor
465
class SizeClass extends ClassAttributor {
466
static attrName: 'size';
467
static keyName: 'size';
468
static className: 'ql-size';
469
}
470
471
class SizeStyle extends StyleAttributor {
472
static attrName: 'size';
473
static keyName: 'size';
474
static styleName: 'font-size';
475
}
476
477
// Background attributor
478
class BackgroundClass extends ClassAttributor {
479
static attrName: 'background';
480
static keyName: 'background';
481
static className: 'ql-bg';
482
}
483
484
class BackgroundStyle extends StyleAttributor {
485
static attrName: 'background';
486
static keyName: 'background';
487
static styleName: 'background-color';
488
}
489
490
// Alignment attributor
491
class AlignClass extends ClassAttributor {
492
static attrName: 'align';
493
static keyName: 'align';
494
static className: 'ql-align';
495
}
496
497
class AlignStyle extends StyleAttributor {
498
static attrName: 'align';
499
static keyName: 'align';
500
static styleName: 'text-align';
501
}
502
503
// Direction attributor
504
class DirectionAttribute extends AttributeAttributor {
505
static attrName: 'direction';
506
static keyName: 'direction';
507
static htmlAttribute: 'dir';
508
}
509
510
class DirectionClass extends ClassAttributor {
511
static attrName: 'direction';
512
static keyName: 'direction';
513
static className: 'ql-direction';
514
}
515
516
class DirectionStyle extends StyleAttributor {
517
static attrName: 'direction';
518
static keyName: 'direction';
519
static styleName: 'direction';
520
}
521
522
// Indent attributor
523
class Indent extends ClassAttributor {
524
static attrName: 'indent';
525
static keyName: 'indent';
526
static className: 'ql-indent';
527
528
/**
529
* Add value to current indent level
530
* @param node - DOM node
531
* @param value - Indent level to add
532
*/
533
add(node: HTMLElement, value: number): void;
534
535
/**
536
* Compute new indent level
537
* @param value - Current indent level
538
* @param delta - Change in indent level
539
* @returns New indent level
540
*/
541
canAdd(value: number, delta: number): boolean;
542
543
/**
544
* Remove indent level
545
* @param node - DOM node
546
*/
547
remove(node: HTMLElement): void;
548
549
/**
550
* Get current indent value
551
* @param node - DOM node
552
* @returns Current indent level
553
*/
554
value(node: HTMLElement): number;
555
}
556
```
557
558
**Usage Examples:**
559
560
```typescript
561
// Apply color formatting
562
quill.formatText(0, 10, 'color', '#ff0000');
563
quill.formatText(15, 5, 'background', '#ffff00');
564
565
// Apply font formatting
566
quill.formatText(0, 10, 'font', 'serif');
567
quill.formatText(15, 5, 'size', 'large');
568
569
// Apply alignment
570
quill.formatLine(0, 1, 'align', 'center');
571
quill.formatLine(20, 1, 'align', 'right');
572
573
// Apply direction
574
quill.formatLine(0, 1, 'direction', 'rtl');
575
576
// Apply indentation
577
quill.formatLine(0, 1, 'indent', 1); // Indent once
578
quill.formatLine(20, 1, 'indent', 2); // Indent twice
579
580
// Remove attributor formatting
581
quill.formatText(0, 10, 'color', false);
582
quill.formatLine(0, 1, 'align', false);
583
```
584
585
### Custom Format Registration
586
587
Register custom formats and blots with Quill.
588
589
```typescript { .api }
590
// Register custom formats
591
Quill.register('formats/highlight', HighlightBlot);
592
Quill.register('formats/mention', MentionBlot);
593
594
// Register multiple formats
595
Quill.register({
596
'formats/highlight': HighlightBlot,
597
'formats/mention': MentionBlot,
598
'attributors/style/custom': CustomStyleAttributor
599
});
600
601
// Register with overwrite option
602
Quill.register('formats/bold', CustomBoldBlot, true);
603
```
604
605
**Usage Examples:**
606
607
```typescript
608
// Define custom highlight format
609
class Highlight extends Inline {
610
static blotName = 'highlight';
611
static tagName = 'MARK';
612
static className = 'ql-highlight';
613
614
static create(value) {
615
const node = super.create();
616
node.setAttribute('data-color', value);
617
node.style.backgroundColor = value;
618
return node;
619
}
620
621
static formats(node) {
622
return node.getAttribute('data-color');
623
}
624
}
625
626
// Register and use
627
Quill.register('formats/highlight', Highlight);
628
629
const quill = new Quill('#editor', {
630
formats: ['bold', 'italic', 'highlight']
631
});
632
633
// Use custom format
634
quill.formatText(0, 10, 'highlight', 'yellow');
635
```
636
637
## Table Formats
638
639
Table formatting system for creating and managing tabular data with cells, rows, and full table structures.
640
641
### Table Structure
642
643
Tables in Quill follow a hierarchical structure: TableContainer > TableBody > TableRow > TableCell.
644
645
### TableCell
646
647
Individual table cell format for containing content within table rows.
648
649
```typescript { .api }
650
class TableCell extends Block {
651
static blotName: 'table';
652
static tagName: 'TD';
653
static create(value?: string): HTMLTableCellElement;
654
static formats(domNode: HTMLElement): string | undefined;
655
656
cellOffset(): number;
657
format(name: string, value: string): void;
658
row(): TableRow;
659
rowOffset(): number;
660
table(): TableContainer | null;
661
}
662
```
663
664
### TableRow
665
666
Table row format for containing table cells in a horizontal layout.
667
668
```typescript { .api }
669
class TableRow extends Container {
670
static blotName: 'table-row';
671
static tagName: 'TR';
672
673
checkMerge(): boolean;
674
optimize(context: { [key: string]: any }): void;
675
rowOffset(): number;
676
table(): TableContainer | null;
677
}
678
```
679
680
### TableBody
681
682
Table body format for containing table rows within a table structure.
683
684
```typescript { .api }
685
class TableBody extends Container {
686
static blotName: 'table-body';
687
static tagName: 'TBODY';
688
}
689
```
690
691
### TableContainer
692
693
Main table container format providing table manipulation methods and structure management.
694
695
```typescript { .api }
696
class TableContainer extends Container {
697
static blotName: 'table-container';
698
static tagName: 'TABLE';
699
700
balanceCells(): void;
701
cells(column: number): (TableCell | null)[];
702
deleteColumn(index: number): void;
703
insertColumn(index: number): void;
704
insertRow(index: number): void;
705
rows(): TableRow[];
706
}
707
```
708
709
**Usage Examples:**
710
711
```typescript
712
import { TableCell, TableRow, TableBody, TableContainer } from 'quill';
713
714
// Tables are typically created through the module system
715
// rather than direct format application
716
const quill = new Quill('#editor', {
717
modules: {
718
table: true
719
}
720
});
721
722
// Use table module methods for table manipulation
723
const tableModule = quill.getModule('table');
724
tableModule.insertTable(3, 3); // 3x3 table
725
```