The 2D layer · interface

TextModel

A caret, a selection, and the operations that move them.

Explained in Sprites and tilemaps.

interface TextModel
import type { TextModel } from '@driftengine/ui2d';

In depth

Pure, and it is pure on purpose. Every editing defect anybody has met lives here rather than in the platform: a caret inside a character, a right-to-left selection that deletes the wrong end, a backspace that removes half an emoji. Pure, each of those is a test that runs in under a millisecond. Wired to a host, none of them is.

Offsets are into the string and are always on a code-point boundary. JavaScript strings are UTF-16, so an astral character is two units and a caret between them is a caret inside a character — which renders as a replacement glyph and deletes as a lone surrogate. Every move and every delete steps over the pair.

anchor is where a selection started and caret is where it is now, so anchor > caret is an ordinary right-to-left selection rather than an error. selectionRange is the only thing that orders them and everything else goes through it.

Properties

NameTypeDescription
textstring
caretnumberWhere the caret is, as a UTF-16 offset on a code-point boundary.
anchornumberWhere the current selection began. Equal to caret when nothing is selected.
composeFromnumberThe range an in-progress composition occupies, or -1 when none is in progress.
More

Written only by applyComposition in textHost.ts. It lives on the model rather than in the host because the range is a property of the text, and a host that crashed mid-composition would otherwise leave the field permanently convinced it was still composing.

composeTonumber