Getting Started
Overview
Installation
Theme
Forms
Basic Inputs
Custom Inputs
Select
Components
Components
78
Micro Charts
Navigation
Libraries
Content Editor
Data View
Form Builder
Headless Editor
Image Designer
Kanban Board
PDF Builder
PDF Signer
PDF Viewer
Video Player
GitHub repositoryGitHub starsGitHub forksNgStarter UI npm versionNgStarter UI npm downloads per month

Selection and History

Selection and history are part of the editor state and available as signals. Selection is expressed in model coordinates, so it survives re-rendering and can be set from code.

Loading example…

Selection

A selection has an anchor, where it started, and a focus, where it ends. Both are block id and offset pairs; the focus can come first for backward selections. A collapsed selection, with equal points, is the caret.

const [first] = editor.document().blocks;
const last = editor.document().blocks.at(-1)!;

// select everything
editor.setSelection({
  anchor: { blockId: first.id, offset: 0 },
  focus: { blockId: last.id, offset: getNgsHeadlessEditorBlockText(last).length }
});
surface.focus();

// caret after the third character of the first block
editor.setSelection({
  anchor: { blockId: first.id, offset: 3 },
  focus: { blockId: first.id, offset: 3 }
});
  • The surface updates the selection from the DOM on selectionchange, focus, and before input.
  • setSelection() clamps offsets to the block text and stores the selection in the model. Call the surface focus() to apply it to the DOM.
  • Moving the selection drops stored marks and starts a new undo step.
  • Buttons that change the document through editor methods should prevent mousedown so the DOM selection is not lost; ngsHeadlessEditorCommand does this for you.

Editing at the selection

MethodDescription
insertText(text, origin?)Replaces the selection with text; line breaks create paragraphs.
deleteBackward(), deleteForward()Delete the selection, one character, or merge blocks at a boundary.
deleteRange(selection, origin, group?)Deletes an explicit range.
splitBlock()Splits the block at the caret.
clear()Replaces the content with an empty paragraph and clears history.

History

Every change records a snapshot of the previous document and selection. Snapshots share unchanged blocks with the live document, so history is cheap even for long documents.

  • Typing single characters is grouped into one undo step; a space, another kind of change, a caret move, or a pause of one second starts a new step.
  • Deleting character by character is grouped the same way.
  • Everything else, such as formatting, paste, block changes, and API edits, is its own step.
  • The history keeps the last 200 steps (NGS_HEADLESS_EDITOR_HISTORY_LIMIT); the grouping delay is NGS_HEADLESS_EDITOR_HISTORY_GROUP_DELAY.
  • Mod-z undoes, Mod-Shift-z and Mod-y redo. Any new change clears the redo stack.
editor.canUndo();            // signal
editor.undo();
editor.redo();

// Load content without clearing the undo stack, so the load can be undone.
editor.setDocument(serverDocument, false);

// Replace content and clear history.
editor.clear();

Revision and origin

revision increases with every document change. origin tells where the last change came from:

OriginSource
externalsetDocument(): content loaded by the application.
keyboardTyping, deleting, and Enter in the surface.
pastePlain-text paste.
compositionIME composition, drag and drop, and other DOM read-backs.
commandFormatting and block operations.
historyUndo and redo.
apiYour own calls that pass 'api', and clear().

Use it to avoid writing loaded documents straight back to where they came from.