# EditTextToolApi

The Edit Text tool, drivable from code. This is the one that replaces DOM puppeteering outright.

Every member needs the tool to be active (`await viewer.activateTool('editText')` first) and the `edit-text` feature; `beginEdit`, and `setText` with any text but `''`, also need `extract`. A page is analyzed on demand, so editing does not depend on what the user happens to have scrolled into view. Text set this way travels the same path as typing, so font substitution, reflow, and undo all behave identically.

A tool handle throws `SDKError` `INVALID_STATE`, with instructions, when its tool is not running, rather than failing silently: "The editText tool is not active. Call viewer.activateTool('editText') and await it first."

`commit()` and `cancel()` both **deactivate the tool**, exactly as pressing Save or Escape in the toolbar does, because committing rewrites and reloads the page. Re-activate before further edits, and treat every block id from before a commit as stale — ids are only stable within one detection pass.

- Kind: namespace
- Access: `viewer.tools.editText`

## Usage

```ts
await viewer.activateTool('editText');

const editText = viewer.tools.editText;
const blocks = await editText.listBlocks(0);

const total = blocks.find((b) => b.text.startsWith('Total:'));
if (total) {
  await editText.setText(total.id, 'Total: $1,299.00');
  await editText.commit();
}
```

## Reading

### `listBlocks`

```ts
listBlocks(pageIndex: number): Promise<EditableTextBlock[]>
```

The editable text blocks on a page, as `EditableTextBlock[]`. Each block's `text` is `''` under a license without `extract`.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `pageIndex` | `number` | Zero-based page index. |

Returns `Promise<EditableTextBlock[]>`: Each `{ id, pageIndex, text, bounds, fontFamily, fontSize, fontWeight, isItalic, fillColor, opacity }`; `id` is stable within one detection pass, `text` includes an uncommitted edit, `bounds` is a `Rect` in page space.

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.
- `INVALID_ARGUMENT` for a page index the document has not.
- `PAGE_ERROR` when the page could not be loaded.

```ts
const blocks = await viewer.tools.editText.listBlocks(0);
```

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/listblocks

### `editingBlockId`

```ts
get editingBlockId(): string | null
```

The block currently open for editing, or `null`.

- Kind: getter
- Since: 1.0.0

Returns `string | null`

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/editingblockid

### `selectedBlockId`

```ts
get selectedBlockId(): string | null
```

The selected block, or `null`.

- Kind: getter
- Since: 1.0.0

Returns `string | null`

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/selectedblockid

### `hasPendingEdits`

```ts
get hasPendingEdits(): boolean
```

Whether edits are pending — not yet in the document, so not yet in [viewer.hasUnsavedChanges](https://kernstra.com/docs/web-sdk/api/pdfviewer/hasunsavedchanges). Every way of leaving the tool writes them, and so does an export from [createExporter()](https://kernstra.com/docs/web-sdk/api/pdfviewer/createexporter), so this is for a host's own `beforeunload` warning beside `hasUnsavedChanges`; `false` while the tool is not active.

- Kind: getter
- Since: 1.0.0

Returns `boolean`

```ts
window.addEventListener('beforeunload', (e) => {
  if (viewer.hasUnsavedChanges || viewer.tools.editText.hasPendingEdits) e.preventDefault();
});
```

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/haspendingedits

## Editing

### `beginEdit`

```ts
beginEdit(blockId: string): Promise<void>
```

Opens a block for editing — what a double-click does. Needs `edit-text` and `extract`: the editor shows the block's words in the page.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `blockId` | `string` | A block id from `listBlocks()` of the current detection pass. |

Returns `Promise<void>`

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.
- `FEATURE_NOT_LICENSED` without `extract`.
- `INVALID_ARGUMENT` for a text block id that names no block.
- `PAGE_ERROR` when the block's page could not be loaded.

```ts
const [first] = blocks;
if (first) await viewer.tools.editText.beginEdit(first.id);
```

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/beginedit

### `setText`

```ts
setText(blockId: string, text: string): Promise<void>
```

Replaces a block's text, opening it first if needed. An empty string removes the block, as the toolbar's delete does. Without `extract` only that is allowed; retyping rejects with `FEATURE_NOT_LICENSED`, as it opens the block. A block read as right-aligned — an amount in a column, a heading over values set flush under it — keeps its right edge and grows to the left, exactly as when typed.

- Kind: method
- Since: 1.0.0

| Parameter | Type | Description |
| --- | --- | --- |
| `blockId` | `string` | A block id from `listBlocks()` of the current detection pass. |
| `text` | `string` | The new text; `''` removes the block. |

Returns `Promise<void>`

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.
- `INVALID_ARGUMENT`, the text left as it was, when it holds a character no available font can draw; or for a block id that names no block.
- `FEATURE_NOT_LICENSED` without `extract` for any text but `''`.
- `INVALID_STATE` when other blocks keep being opened while it waits for fonts (a text block that kept losing its editing surface to another).
- `PAGE_ERROR` when the block's page could not be loaded.

```ts
await viewer.tools.editText.setText(total.id, 'Total: $1,299.00');
await viewer.tools.editText.setText(footnote.id, ''); // removes the block
```

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/settext

### `commit`

```ts
commit(): Promise<void>
```

Writes every pending edit into the document and reports [textChanged](https://kernstra.com/docs/web-sdk/api/events#ev-textchanged). Deactivates the tool, as pressing Save in the toolbar does; re-activate before further edits, and re-read `listBlocks()` — every block id from before a commit is stale.

- Kind: method
- Since: 1.0.0

Returns `Promise<void>`

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.

```ts
await viewer.tools.editText.commit();
```

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/commit

### `cancel`

```ts
cancel(): Promise<void>
```

Discards every pending edit — the one way to: leaving the tool by any other means writes them. Deactivates the tool, as pressing Escape in the toolbar does.

- Kind: method
- Since: 1.0.0

Returns `Promise<void>`: Resolves once discarded.

Throws:

- `INVALID_STATE` while the tool is not active — without `edit-text` it cannot be activated.

```ts
await viewer.tools.editText.cancel();
```

Page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext/cancel

Web page: https://kernstra.com/docs/web-sdk/api/viewer-tools-edittext
