0
# Selection Management
1
2
Text selection and cursor positioning APIs for programmatic text selection control.
3
4
## Capabilities
5
6
### Get Current Range
7
8
Get the current text selection range in the editor.
9
10
```javascript { .api }
11
/**
12
* Get current selection range
13
* @returns Range object representing current selection, or null if no selection
14
*/
15
getRange(): Range | null;
16
```
17
18
**Usage Examples:**
19
20
```javascript
21
// Get current selection
22
const range = editor.selection.getRange();
23
if (range) {
24
console.log('Selection start:', range.startOffset);
25
console.log('Selection end:', range.endOffset);
26
console.log('Selected text:', range.toString());
27
} else {
28
console.log('No selection');
29
}
30
31
// Check if text is selected
32
function hasSelection() {
33
const range = editor.selection.getRange();
34
return range && !range.collapsed;
35
}
36
37
// Get selection info
38
function getSelectionInfo() {
39
const range = editor.selection.getRange();
40
if (!range) return null;
41
42
return {
43
text: range.toString(),
44
collapsed: range.collapsed,
45
startOffset: range.startOffset,
46
endOffset: range.endOffset
47
};
48
}
49
```
50
51
### Save Current Range
52
53
Save the current selection range for later restoration.
54
55
```javascript { .api }
56
/**
57
* Save current selection range
58
* @param range - Optional specific range to save, defaults to current selection
59
*/
60
saveRange(range?: Range): void;
61
```
62
63
**Usage Examples:**
64
65
```javascript
66
// Save current selection
67
editor.selection.saveRange();
68
69
// Save specific range
70
const range = editor.selection.getRange();
71
if (range) {
72
editor.selection.saveRange(range);
73
}
74
75
// Save selection before modal/dialog
76
function openModal() {
77
editor.selection.saveRange(); // Save current position
78
showModal(); // User interaction may lose focus
79
}
80
81
// Save selection in event handler
82
editor.customConfig.onblur = function() {
83
editor.selection.saveRange(); // Preserve selection when editor loses focus
84
};
85
```
86
87
### Restore Saved Selection
88
89
Restore a previously saved selection range.
90
91
```javascript { .api }
92
/**
93
* Restore previously saved selection
94
* Must be called after saveRange()
95
*/
96
restoreSelection(): void;
97
```
98
99
**Usage Examples:**
100
101
```javascript
102
// Save and restore selection pattern
103
editor.selection.saveRange();
104
// ... some operation that may change selection
105
editor.selection.restoreSelection();
106
107
// Restore after modal close
108
function closeModal() {
109
hideModal();
110
editor.selection.restoreSelection(); // Restore saved position
111
}
112
113
// Maintain selection during operations
114
function insertAtSelection(html) {
115
editor.selection.saveRange();
116
editor.cmd.do('insertHTML', html);
117
// Selection automatically moves to after inserted content
118
}
119
```
120
121
### Create Range by Element
122
123
Create a selection range based on a DOM element.
124
125
```javascript { .api }
126
/**
127
* Create selection range by DOM element
128
* @param elem - Target DOM element
129
* @param toStart - Whether to position at start of element
130
* @param isCollapseToEnd - Whether to collapse selection to end
131
*/
132
createRangeByElem(elem: Element, toStart: boolean, isCollapseToEnd: boolean): void;
133
```
134
135
**Usage Examples:**
136
137
```javascript
138
// Select entire paragraph
139
const paragraph = editor.$textElem.find('p').get(0);
140
if (paragraph) {
141
editor.selection.createRangeByElem(paragraph, true, false);
142
}
143
144
// Position cursor at start of element
145
const heading = editor.$textElem.find('h1').get(0);
146
if (heading) {
147
editor.selection.createRangeByElem(heading, true, true);
148
}
149
150
// Position cursor at end of element
151
const lastParagraph = editor.$textElem.find('p').last().get(0);
152
if (lastParagraph) {
153
editor.selection.createRangeByElem(lastParagraph, false, true);
154
}
155
```
156
157
### Get Selection Container
158
159
Get the DOM element that contains the current selection.
160
161
```javascript { .api }
162
/**
163
* Get container element of current selection
164
* @param range - Optional specific range, defaults to current selection
165
* @returns DOM element containing the selection
166
*/
167
getSelectionContainerElem(range?: Range): Element;
168
```
169
170
**Usage Examples:**
171
172
```javascript
173
// Get container of current selection
174
const container = editor.selection.getSelectionContainerElem();
175
console.log('Selection is in:', container.tagName);
176
177
// Get container of specific range
178
const range = editor.selection.getRange();
179
if (range) {
180
const container = editor.selection.getSelectionContainerElem(range);
181
console.log('Container:', container);
182
}
183
184
// Check if selection is in specific element type
185
function isSelectionInElement(tagName) {
186
const container = editor.selection.getSelectionContainerElem();
187
return container && container.tagName.toLowerCase() === tagName.toLowerCase();
188
}
189
190
// Usage
191
if (isSelectionInElement('h1')) {
192
console.log('Selection is in a heading');
193
}
194
```
195
196
### Get Selection Start Element
197
198
Get the DOM element at the start of the current selection.
199
200
```javascript { .api }
201
/**
202
* Get DOM element at selection start
203
* @param range - Optional specific range, defaults to current selection
204
* @returns DOM element at start of selection
205
*/
206
getSelectionStartElem(range?: Range): Element;
207
```
208
209
### Get Selection End Element
210
211
Get the DOM element at the end of the current selection.
212
213
```javascript { .api }
214
/**
215
* Get DOM element at selection end
216
* @param range - Optional specific range, defaults to current selection
217
* @returns DOM element at end of selection
218
*/
219
getSelectionEndElem(range?: Range): Element;
220
```
221
222
### Collapse Range
223
224
Collapse the current selection range to a single point.
225
226
```javascript { .api }
227
/**
228
* Collapse current selection to start or end
229
* @param toStart - Whether to collapse to start (true) or end (false)
230
*/
231
collapseRange(toStart?: boolean): void;
232
```
233
234
### Get Selection Text
235
236
Get the plain text content of the current selection.
237
238
```javascript { .api }
239
/**
240
* Get plain text of current selection
241
* @returns Selected text as string, empty string if no selection
242
*/
243
getSelectionText(): string;
244
```
245
246
### Check If Selection Is Empty
247
248
Check whether the current selection is empty (collapsed).
249
250
```javascript { .api }
251
/**
252
* Check if current selection is empty/collapsed
253
* @returns True if selection is empty, false otherwise
254
*/
255
isSelectionEmpty(): boolean;
256
```
257
258
### Create Empty Range
259
260
Create an empty selection range with a zero-width space marker.
261
262
```javascript { .api }
263
/**
264
* Create empty range with invisible marker
265
* Used for maintaining cursor position in empty elements
266
*/
267
createEmptyRange(): void;
268
```
269
270
## Complete Selection API Interface
271
272
```javascript { .api }
273
interface SelectionAPI {
274
/** Get current selection range */
275
getRange(): Range | null;
276
277
/** Save current selection range */
278
saveRange(range?: Range): void;
279
280
/** Restore previously saved selection */
281
restoreSelection(): void;
282
283
/** Create selection range by DOM element */
284
createRangeByElem(elem: Element, toStart: boolean, isCollapseToEnd: boolean): void;
285
286
/** Get container element of selection */
287
getSelectionContainerElem(range?: Range): Element;
288
289
/** Get DOM element at selection start */
290
getSelectionStartElem(range?: Range): Element;
291
292
/** Get DOM element at selection end */
293
getSelectionEndElem(range?: Range): Element;
294
295
/** Collapse selection to start or end */
296
collapseRange(toStart?: boolean): void;
297
298
/** Get plain text of selection */
299
getSelectionText(): string;
300
301
/** Check if selection is empty */
302
isSelectionEmpty(): boolean;
303
304
/** Create empty range with marker */
305
createEmptyRange(): void;
306
}
307
```
308
309
## Advanced Selection Patterns
310
311
### Selection State Management
312
313
```javascript
314
class SelectionManager {
315
constructor(editor) {
316
this.editor = editor;
317
this.savedRanges = [];
318
}
319
320
pushSelection() {
321
const range = this.editor.selection.getRange();
322
if (range) {
323
this.savedRanges.push(range.cloneRange());
324
}
325
}
326
327
popSelection() {
328
const range = this.savedRanges.pop();
329
if (range) {
330
this.editor.selection.saveRange(range);
331
this.editor.selection.restoreSelection();
332
}
333
}
334
335
hasSelection() {
336
const range = this.editor.selection.getRange();
337
return range && !range.collapsed;
338
}
339
}
340
341
// Usage
342
const selectionManager = new SelectionManager(editor);
343
selectionManager.pushSelection();
344
// ... operations
345
selectionManager.popSelection();
346
```
347
348
### Smart Content Insertion
349
350
```javascript
351
// Insert content at selection with smart positioning
352
function smartInsert(html, restoreSelection = true) {
353
// Save current selection
354
editor.selection.saveRange();
355
356
// Insert content
357
editor.cmd.do('insertHTML', html);
358
359
// Optionally restore selection
360
if (restoreSelection) {
361
// Move selection to after inserted content
362
setTimeout(() => {
363
const range = editor.selection.getRange();
364
if (range) {
365
range.collapse(false); // Collapse to end
366
editor.selection.saveRange(range);
367
editor.selection.restoreSelection();
368
}
369
}, 0);
370
}
371
}
372
373
// Usage
374
smartInsert('<strong>Bold text</strong>');
375
smartInsert('<img src="image.jpg" alt="Image">', false);
376
```
377
378
### Selection-based Formatting
379
380
```javascript
381
// Apply formatting only to selected text
382
function formatSelection(command, value) {
383
const range = editor.selection.getRange();
384
385
if (!range || range.collapsed) {
386
console.log('No text selected');
387
return false;
388
}
389
390
// Save selection
391
editor.selection.saveRange();
392
393
// Apply formatting
394
editor.cmd.do(command, value);
395
396
// Restore selection to see the result
397
editor.selection.restoreSelection();
398
399
return true;
400
}
401
402
// Usage
403
formatSelection('bold');
404
formatSelection('foreColor', '#ff0000');
405
```
406
407
### Context-aware Operations
408
409
```javascript
410
// Perform operations based on selection context
411
function contextAwareOperation() {
412
const container = editor.selection.getSelectionContainerElem();
413
const tagName = container.tagName.toLowerCase();
414
415
switch (tagName) {
416
case 'h1':
417
case 'h2':
418
case 'h3':
419
console.log('Selection is in a heading');
420
// Heading-specific operations
421
break;
422
423
case 'p':
424
console.log('Selection is in a paragraph');
425
// Paragraph-specific operations
426
break;
427
428
case 'li':
429
console.log('Selection is in a list item');
430
// List-specific operations
431
break;
432
433
default:
434
console.log('Selection is in:', tagName);
435
}
436
}
437
```
438
439
### Selection Utilities
440
441
```javascript
442
// Utility functions for common selection tasks
443
const SelectionUtils = {
444
// Check if entire element is selected
445
isElementSelected(element) {
446
const range = editor.selection.getRange();
447
if (!range) return false;
448
449
const selection = window.getSelection();
450
return selection.containsNode(element, false);
451
},
452
453
// Select entire word at cursor
454
selectWordAtCursor() {
455
const range = editor.selection.getRange();
456
if (!range) return;
457
458
range.expand('word');
459
editor.selection.saveRange(range);
460
editor.selection.restoreSelection();
461
},
462
463
// Get selected text with formatting preserved
464
getSelectedHTML() {
465
const range = editor.selection.getRange();
466
if (!range) return '';
467
468
const container = document.createElement('div');
469
container.appendChild(range.cloneContents());
470
return container.innerHTML;
471
},
472
473
// Move cursor to end of editor
474
moveToEnd() {
475
const textElem = editor.$textElem.get(0);
476
if (textElem) {
477
editor.selection.createRangeByElem(textElem, false, true);
478
}
479
}
480
};
481
482
// Usage
483
if (SelectionUtils.isElementSelected(someElement)) {
484
console.log('Element is fully selected');
485
}
486
487
SelectionUtils.selectWordAtCursor();
488
const selectedHTML = SelectionUtils.getSelectedHTML();
489
SelectionUtils.moveToEnd();
490
```