or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

commands.mdconfiguration.mdcontent-operations.mdeditor-management.mdimage-upload.mdindex.mdmenus.mdselection.md

selection.mddocs/

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

```