0
# Editor Core
1
2
Core editor functionality for creating and managing rich text editor instances. The main Quill class provides all essential editing operations including content manipulation, selection management, formatting, and event handling.
3
4
## Capabilities
5
6
### Quill Constructor
7
8
Creates a new Quill editor instance attached to a DOM container with optional configuration.
9
10
```typescript { .api }
11
/**
12
* Creates a new Quill editor instance
13
* @param container - DOM element or CSS selector for the editor container
14
* @param options - Configuration options for the editor
15
*/
16
constructor(container: HTMLElement | string, options?: QuillOptions): Quill;
17
18
interface QuillOptions {
19
/** Theme to use ('snow', 'bubble', or custom theme name) */
20
theme?: string;
21
/** Debug level for logging */
22
debug?: DebugLevel | boolean;
23
/** Custom registry for formats and modules */
24
registry?: Parchment.Registry;
25
/** Whether editing should be disabled */
26
readOnly?: boolean;
27
/** Placeholder text when editor is empty */
28
placeholder?: string;
29
/** Scrolling container for editor bounds */
30
bounds?: HTMLElement | string | null;
31
/** Module configuration */
32
modules?: Record<string, unknown>;
33
/** Allowed formats (null means all formats allowed) */
34
formats?: string[] | null;
35
}
36
37
type DebugLevel = 'error' | 'warn' | 'log' | 'info';
38
```
39
40
**Usage Examples:**
41
42
```typescript
43
import Quill from 'quill';
44
45
// Basic editor
46
const quill = new Quill('#editor');
47
48
// Editor with configuration
49
const quill = new Quill('#editor', {
50
theme: 'snow',
51
readOnly: false,
52
placeholder: 'Start typing...',
53
modules: {
54
toolbar: [
55
['bold', 'italic'],
56
['link', 'image']
57
],
58
history: {
59
delay: 1000,
60
maxStack: 100
61
}
62
},
63
formats: ['bold', 'italic', 'link', 'image']
64
});
65
```
66
67
### Content Operations
68
69
Methods for getting, setting, and updating the editor's content using Delta format or plain text.
70
71
```typescript { .api }
72
/**
73
* Get editor contents as Delta
74
* @param index - Starting index (default: 0)
75
* @param length - Length to retrieve (default: all remaining)
76
* @returns Delta representing the content
77
*/
78
getContents(index?: number, length?: number): Delta;
79
80
/**
81
* Set editor contents, replacing all existing content
82
* @param delta - Delta or array of operations to set
83
* @param source - Source of the change
84
* @returns Delta representing the change applied
85
*/
86
setContents(delta: Delta | Op[], source?: EmitterSource): Delta;
87
88
/**
89
* Apply delta changes to current contents
90
* @param delta - Delta operations to apply
91
* @param source - Source of the change
92
* @returns Delta representing the change applied
93
*/
94
updateContents(delta: Delta | Op[], source?: EmitterSource): Delta;
95
96
/**
97
* Get plain text content
98
* @param index - Starting index (default: 0)
99
* @param length - Length to retrieve (default: all remaining)
100
* @returns Plain text string
101
*/
102
getText(index?: number, length?: number): string;
103
104
/**
105
* Set editor content to plain text, removing all formatting
106
* @param text - Plain text to set
107
* @param source - Source of the change
108
* @returns Delta representing the change applied
109
*/
110
setText(text: string, source?: EmitterSource): Delta;
111
112
/**
113
* Get semantic HTML representation of content
114
* @param index - Starting index (default: 0)
115
* @param length - Length to retrieve (default: all remaining)
116
* @returns HTML string with semantic markup
117
*/
118
getSemanticHTML(index?: number, length?: number): string;
119
120
type EmitterSource = 'api' | 'user' | 'silent';
121
```
122
123
**Usage Examples:**
124
125
```typescript
126
// Get current content
127
const content = quill.getContents();
128
console.log('Current content:', content);
129
130
// Set new content
131
const newContent = new Delta()
132
.insert('Hello ')
133
.insert('World', { bold: true })
134
.insert('\n');
135
quill.setContents(newContent);
136
137
// Apply changes
138
const changes = new Delta()
139
.retain(6) // Skip first 6 characters
140
.insert('Beautiful ', { italic: true });
141
quill.updateContents(changes);
142
143
// Get plain text
144
const text = quill.getText();
145
console.log('Plain text:', text);
146
147
// Get HTML
148
const html = quill.getSemanticHTML();
149
console.log('HTML:', html);
150
```
151
152
### Selection Operations
153
154
Methods for managing text selection and cursor position within the editor.
155
156
```typescript { .api }
157
/**
158
* Get current selection range
159
* @param focus - Whether to focus editor before getting selection
160
* @returns Current selection range or null if no selection
161
*/
162
getSelection(focus?: boolean): Range | null;
163
164
/**
165
* Set selection range
166
* @param range - Range to select (null to remove selection)
167
* @param source - Source of the change
168
*/
169
setSelection(range: Range | null, source?: EmitterSource): void;
170
171
/**
172
* Set selection by index and length
173
* @param index - Starting position
174
* @param length - Length of selection (default: 0 for cursor)
175
* @param source - Source of the change
176
*/
177
setSelection(index: number, length?: number, source?: EmitterSource): void;
178
179
/**
180
* Get bounding box for a range or position
181
* @param index - Position or range to get bounds for
182
* @param length - Length if index is a number
183
* @returns Bounds object with position and dimensions
184
*/
185
getBounds(index: number | Range, length?: number): Bounds | null;
186
187
interface Range {
188
/** Starting position of selection */
189
index: number;
190
/** Length of selection (0 for cursor) */
191
length: number;
192
}
193
194
interface Bounds {
195
bottom: number;
196
height: number;
197
left: number;
198
right: number;
199
top: number;
200
width: number;
201
}
202
```
203
204
**Usage Examples:**
205
206
```typescript
207
// Get current selection
208
const selection = quill.getSelection();
209
if (selection) {
210
console.log(`Selected text from ${selection.index} to ${selection.index + selection.length}`);
211
}
212
213
// Set cursor position
214
quill.setSelection(10);
215
216
// Select text range
217
quill.setSelection(5, 10); // Select 10 characters starting at position 5
218
219
// Get bounds for tooltip positioning
220
const bounds = quill.getBounds(selection);
221
if (bounds) {
222
positionTooltip(bounds.left, bounds.top);
223
}
224
```
225
226
### Formatting Operations
227
228
Methods for applying, removing, and querying text formatting at specific ranges.
229
230
```typescript { .api }
231
/**
232
* Apply formatting to current selection
233
* @param name - Format name
234
* @param value - Format value
235
* @param source - Source of the change
236
* @returns Delta representing the change applied
237
*/
238
format(name: string, value: unknown, source?: EmitterSource): Delta;
239
240
/**
241
* Format text in specified range
242
* @param index - Starting position
243
* @param length - Length to format
244
* @param formats - Object with format names and values
245
* @param source - Source of the change
246
* @returns Delta representing the change applied
247
*/
248
formatText(index: number, length: number, formats: Record<string, unknown>, source?: EmitterSource): Delta;
249
250
/**
251
* Format text in specified range with single format
252
* @param index - Starting position
253
* @param length - Length to format
254
* @param name - Format name
255
* @param value - Format value
256
* @param source - Source of the change
257
* @returns Delta representing the change applied
258
*/
259
formatText(index: number, length: number, name: string, value: unknown, source?: EmitterSource): Delta;
260
261
/**
262
* Format lines in specified range
263
* @param index - Starting position
264
* @param length - Length to format
265
* @param formats - Object with format names and values
266
* @param source - Source of the change
267
* @returns Delta representing the change applied
268
*/
269
formatLine(index: number, length: number, formats: Record<string, unknown>, source?: EmitterSource): Delta;
270
271
/**
272
* Remove all formatting from specified range
273
* @param index - Starting position
274
* @param length - Length to clear formatting
275
* @param source - Source of the change
276
* @returns Delta representing the change applied
277
*/
278
removeFormat(index: number, length: number, source?: EmitterSource): Delta;
279
280
/**
281
* Get formatting at specified range
282
* @param index - Starting position (defaults to current selection)
283
* @param length - Length to check (default: 0)
284
* @returns Object with active formats and their values
285
*/
286
getFormat(index?: number, length?: number): { [format: string]: unknown };
287
```
288
289
**Usage Examples:**
290
291
```typescript
292
// Format current selection
293
quill.format('bold', true);
294
quill.format('color', '#ff0000');
295
296
// Format specific range
297
quill.formatText(0, 5, { bold: true, italic: true });
298
quill.formatText(10, 3, 'underline', true);
299
300
// Format lines (for block formats)
301
quill.formatLine(0, 10, { header: 1 });
302
quill.formatLine(20, 15, { list: 'ordered' });
303
304
// Remove formatting
305
quill.removeFormat(0, 10);
306
307
// Check current formatting
308
const formats = quill.getFormat();
309
console.log('Active formats:', formats);
310
```
311
312
### Text Operations
313
314
Methods for inserting, deleting, and manipulating text content within the editor.
315
316
```typescript { .api }
317
/**
318
* Insert text at specified position
319
* @param index - Position to insert at
320
* @param text - Text to insert
321
* @param source - Source of the change
322
* @returns Delta representing the change applied
323
*/
324
insertText(index: number, text: string, source?: EmitterSource): Delta;
325
326
/**
327
* Insert formatted text at specified position
328
* @param index - Position to insert at
329
* @param text - Text to insert
330
* @param formats - Formatting to apply to inserted text
331
* @param source - Source of the change
332
* @returns Delta representing the change applied
333
*/
334
insertText(index: number, text: string, formats: Record<string, unknown>, source?: EmitterSource): Delta;
335
336
/**
337
* Insert formatted text with single format
338
* @param index - Position to insert at
339
* @param text - Text to insert
340
* @param name - Format name
341
* @param value - Format value
342
* @param source - Source of the change
343
* @returns Delta representing the change applied
344
*/
345
insertText(index: number, text: string, name: string, value: unknown, source?: EmitterSource): Delta;
346
347
/**
348
* Insert embed (image, video, etc.) at specified position
349
* @param index - Position to insert at
350
* @param embed - Embed type name
351
* @param value - Embed value/configuration
352
* @param source - Source of the change
353
* @returns Delta representing the change applied
354
*/
355
insertEmbed(index: number, embed: string, value: unknown, source?: EmitterSource): Delta;
356
357
/**
358
* Delete text in specified range
359
* @param index - Starting position
360
* @param length - Length to delete
361
* @param source - Source of the change
362
* @returns Delta representing the change applied
363
*/
364
deleteText(index: number, length: number, source?: EmitterSource): Delta;
365
```
366
367
**Usage Examples:**
368
369
```typescript
370
// Insert plain text
371
quill.insertText(0, 'Hello World!');
372
373
// Insert formatted text
374
quill.insertText(0, 'Bold Text', { bold: true });
375
quill.insertText(10, 'Red Text', 'color', '#ff0000');
376
377
// Insert embed
378
quill.insertEmbed(5, 'image', 'https://example.com/image.jpg');
379
quill.insertEmbed(10, 'video', 'https://youtube.com/watch?v=abc123');
380
381
// Delete text
382
quill.deleteText(0, 5); // Delete first 5 characters
383
```
384
385
### Editor State Management
386
387
Methods for controlling editor focus, enabled state, and basic editor properties.
388
389
```typescript { .api }
390
/**
391
* Focus the editor
392
* @param options - Focus options
393
*/
394
focus(options?: { preventScroll?: boolean }): void;
395
396
/**
397
* Remove focus from editor
398
*/
399
blur(): void;
400
401
/**
402
* Enable or disable editing
403
* @param enabled - Whether editing should be enabled (default: true)
404
*/
405
enable(enabled?: boolean): void;
406
407
/**
408
* Disable editing (shorthand for enable(false))
409
*/
410
disable(): void;
411
412
/**
413
* Check if editing is enabled
414
* @returns True if editing is enabled
415
*/
416
isEnabled(): boolean;
417
418
/**
419
* Check if editor has focus
420
* @returns True if editor is focused
421
*/
422
hasFocus(): boolean;
423
424
/**
425
* Get total length of editor content
426
* @returns Length including final newline
427
*/
428
getLength(): number;
429
430
/**
431
* Get module instance
432
* @param name - Module name
433
* @returns Module instance or undefined
434
*/
435
getModule(name: string): Module | undefined;
436
437
/**
438
* Scroll current selection into view
439
*/
440
scrollSelectionIntoView(): void;
441
442
/**
443
* Update editor state
444
* @param source - Source of the update
445
* @returns Delta of any changes made during update
446
*/
447
update(source?: EmitterSource): Delta | undefined;
448
```
449
450
**Usage Examples:**
451
452
```typescript
453
// Focus management
454
quill.focus();
455
quill.focus({ preventScroll: true });
456
quill.blur();
457
458
// Enable/disable editing
459
quill.disable(); // Make read-only
460
quill.enable(); // Re-enable editing
461
462
// State checking
463
if (quill.isEnabled()) {
464
console.log('Editor is enabled');
465
}
466
467
if (quill.hasFocus()) {
468
console.log('Editor has focus');
469
}
470
471
// Utility methods
472
const length = quill.getLength();
473
console.log(`Content length: ${length}`);
474
475
const toolbar = quill.getModule('toolbar');
476
if (toolbar) {
477
toolbar.addHandler('custom', customHandler);
478
}
479
480
// Ensure selection is visible
481
quill.scrollSelectionIntoView();
482
```
483
484
### Event Handling
485
486
Methods for listening to and handling editor events including text changes, selection changes, and custom events.
487
488
```typescript { .api }
489
/**
490
* Add event listener
491
* @param event - Event name
492
* @param handler - Event handler function
493
* @returns Emitter instance for chaining
494
*/
495
on(event: string, handler: (...args: any[]) => void): Emitter;
496
497
/**
498
* Add text-change event listener
499
* @param event - 'text-change' event name
500
* @param handler - Handler receiving delta, old delta, and source
501
* @returns Emitter instance
502
*/
503
on(event: 'text-change', handler: (delta: Delta, oldDelta: Delta, source: EmitterSource) => void): Emitter;
504
505
/**
506
* Add selection-change event listener
507
* @param event - 'selection-change' event name
508
* @param handler - Handler receiving current and old ranges and source
509
* @returns Emitter instance
510
*/
511
on(event: 'selection-change', handler: (range: Range, oldRange: Range, source: EmitterSource) => void): Emitter;
512
513
/**
514
* Add editor-change event listener (fired for both text and selection changes)
515
* @param event - 'editor-change' event name
516
* @param handler - Handler receiving event type and event-specific arguments
517
* @returns Emitter instance
518
*/
519
on(event: 'editor-change', handler: (eventType: string, ...args: any[]) => void): Emitter;
520
521
/**
522
* Remove event listener
523
* @param event - Event name
524
* @param handler - Handler to remove (if omitted, removes all handlers)
525
* @returns Emitter instance
526
*/
527
off(event: string, handler?: (...args: any[]) => void): Emitter;
528
529
/**
530
* Add one-time event listener
531
* @param event - Event name
532
* @param handler - Event handler function
533
* @returns Emitter instance
534
*/
535
once(event: string, handler: (...args: any[]) => void): Emitter;
536
```
537
538
**Usage Examples:**
539
540
```typescript
541
// Listen for text changes
542
quill.on('text-change', (delta, oldDelta, source) => {
543
if (source === 'user') {
544
console.log('User changed text:', delta);
545
saveContent(quill.getContents());
546
}
547
});
548
549
// Listen for selection changes
550
quill.on('selection-change', (range, oldRange, source) => {
551
if (range) {
552
console.log(`Selection: ${range.index}-${range.index + range.length}`);
553
updateToolbar(range);
554
} else {
555
console.log('Editor lost focus');
556
}
557
});
558
559
// Listen for any editor changes
560
quill.on('editor-change', (eventType, ...args) => {
561
if (eventType === 'text-change') {
562
const [delta, oldDelta, source] = args;
563
handleTextChange(delta, source);
564
} else if (eventType === 'selection-change') {
565
const [range, oldRange, source] = args;
566
handleSelectionChange(range, source);
567
}
568
});
569
570
// One-time listener
571
quill.once('text-change', () => {
572
console.log('First change detected');
573
});
574
575
// Remove listeners
576
const handler = (delta) => console.log('Changed:', delta);
577
quill.on('text-change', handler);
578
quill.off('text-change', handler); // Remove specific handler
579
quill.off('text-change'); // Remove all text-change handlers
580
```