@docx-editor.dev/core/contracts/editor
@docx-editor.dev/core/contracts/editor — the Editor contract adapters are written against.
Commands go through can before exec; queries answer against the live, laid-out document. Type-only declarations let adapters name the surface without importing the engine.
Functions (6)
compareDocumentsErrorKeyfunctionSource ↗
The @docx-editor.dev/i18n key of the message for a refused compare: compareDocuments.reasons.<reason> when the refusal names a reason, else compareDocuments.errors.<code>.
declare function compareDocumentsErrorKey(refusal: {
readonly code: CompareDocumentsErrorCode;
readonly reason?: CompareDocumentsRefusalReason;
}): `compareDocuments.errors.${CompareDocumentsErrorCode}` | `compareDocuments.reasons.${CompareDocumentsRefusalReason}`;```ts
const outcome = await session.apply({ revised });
if (!outcome.ok) showError(t(compareDocumentsErrorKey(outcome)));
```resolveReviewPanefunctionSource ↗
Merge options over base. Throws a TypeError for an unknown field or value, so a misspelled setting fails loudly instead of being ignored. Returns base itself when nothing changes, so the snapshot keeps its reference.
declare function resolveReviewPane(options: ReviewPaneOptions | undefined, base?: ResolvedReviewPane): ResolvedReviewPane;resolveRevisionMarkupfunctionSource ↗
Validate and merge preferences without modifying the input.
declare function resolveRevisionMarkup(input?: RevisionMarkupOptions, previous?: ResolvedRevisionMarkup): ResolvedRevisionMarkup;reviewPaneListsItemfunctionSource ↗
Whether the review pane lists a card for item under revisionsIn.
With 'balloons', a balloon at the text shows every tracked change and every comment that replies to a tracked change, so the pane lists neither. Give the item as an unfiltered getReviewItems() read returns it: a query that excludes revision kinds removes parentRevisionId from replies to the changes it drops.
The engine applies this rule to every review item when it decides whether the pane opens by itself or closes after a settings change. A review pane must apply the same rule before its own filters, such as a hidden kind or a host filter. Those filters can hide every card, and then the pane that the engine opens is empty.
declare function reviewPaneListsItem(revisionsIn: RevisionDisplay, item: ReviewPaneItemFields): boolean;revisionMarkupColorfunctionSource ↗
CSS token for a validated named color.
declare function revisionMarkupColor(color: RevisionMarkupColor, authorColor: string, auto?: string): string;revisionMarkupStylefunctionSource ↗
Select the visual style without changing revision identity.
declare function revisionMarkupStyle(settings: ResolvedRevisionMarkup, kind: 'insert' | 'delete' | 'moveFrom' | 'moveTo' | 'format'): RevisionMarkupTextStyle<RevisionDeletionMark>;Classes (1)
EditorFontErrorclassSource ↗
Typed adapter error reported both through onFontError and accessible alert UI.
declare class EditorFontError extends Error| Member | Type | Summary |
|---|---|---|
| (constructor) | | Constructs a new instance of the `EditorFontError` class |
| code | EditorFontErrorCode | |
| diagnostic? | string | |
| name | string | |
| request? | FontFaceRequest |
Interfaces (151)
AnchorHighlightAnimationinterfaceSource ↗
Opacity fade settings. Reduced motion limits fades to 125 milliseconds.
interface AnchorHighlightAnimation| Member | Type | Summary |
|---|---|---|
| durationMs? | number | Fade duration in milliseconds. Default: 180. Must be finite and between 0 and 10000. |
| easing? | string | CSS timing function for both fades. Defaults to --doc-motion-ease-out. This option does not accept CSS variables. |
| exitDurationMs? | number | Automatic and explicit exit fade duration. Defaults to durationMs. Range: 0 through 10000. |
AnchorHighlightOptionsinterfaceSource ↗
Presentation for temporary paragraph highlights. Each call starts from these defaults. Document refresh RefreshHighlightOptions extends this type, so one style object serves both.
interface AnchorHighlightOptions| Member | Type | Summary |
|---|---|---|
| animation? | boolean | AnchorHighlightAnimation | Default: true, a 180-millisecond fade. False disables motion. Repeated calls for the same paragraph do not restart the fade. |
| borderColor? | string | CSS border color. Defaults to color. Use an alpha color for a translucent border; opacity controls only the fill. |
| borderRadius? | number | Corner radius in CSS pixels at 100% zoom. Default: 6. Must be finite and nonnegative. |
| borderStyle? | 'solid' | 'dashed' | 'dotted' | Border pattern. Default: solid. |
| borderWidth? | number | Border width in CSS pixels at 100% zoom. Default: 0. Finite and nonnegative. |
| className? | string | Optional CSS classes for shadows or patterns. The editor controls highlight placement and size. |
| color? | string | CSS color, including var(). Default: a light blue theme token, var(--doc-anchor-highlight-color) for anchors and var(--doc-refresh-highlight-color) for refresh. |
| opacity? | number | Fill opacity, from 0 to 1. Default: 0.14. Does not change document text opacity. |
| padding? | number | Extra space on each edge, in CSS pixels at 100% zoom. Default: 4. Must be finite and nonnegative. |
| timeoutMs? | number | null | Milliseconds before dismissal starts. Default: 3000. Set `null` to keep highlights until you dismiss them. Maximum: 2147483647. |
AuthoredNoteNumberinginterfaceSource ↗
Authored note-numbering fields as Word's properties dialog writes them.
interface AuthoredNoteNumbering| Member | Type | Summary |
|---|---|---|
| numFmt? | string | |
| numRestart? | string | |
| numStart? | number | |
| pos? | string |
BookmarkSummaryinterfaceSource ↗
One bookmark, as the bookmarks query lists it.
interface BookmarkSummary| Member | Type | Summary |
|---|---|---|
| atSelection | boolean | Whether the start of the selection is inside the bookmark, edges included. |
| duplicates | number | How many other places carry the same name. Usually 0. Collaborators who add one name while offline can leave copies; the list, Go To and links use this bookmark, the first in document order. Adding the name again at this bookmark keeps it and removes the copies. |
| empty | boolean | Whether the bookmark marks a point rather than a range of text. |
| name | string | The name as the document writes it. Names compare without case. |
| order | number | Position in document order: the main text first, then headers, footers and notes. Sort by this value to list bookmarks by location. |
| place | BookmarkPlace | The same story, telling a header from a footer and a footnote from an endnote. |
| story | BookmarkStory | The story the bookmark starts in. |
ClearAnchorHighlightOptionsinterfaceSource ↗
Explicit highlight dismissal.
interface ClearAnchorHighlightOptions| Member | Type | Summary |
|---|---|---|
| animation? | boolean | AnchorHighlightAnimation | Defaults to the last highlight call's exit animation. False removes highlights immediately. |
CollaborationParticipantsDiagnosticinterfaceSource ↗
The number of people in the collaboration room changed.
interface CollaborationParticipantsDiagnostic extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| count | number | People present, this editor included. A person with two tabs counts twice. |
| kind | 'collab.participants' |
CollaborationStatusDiagnosticinterfaceSource ↗
A collaboration session changed status: it joined, disconnected, failed, or healed.
interface CollaborationStatusDiagnostic extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| code? | CollaborationDiagnosticCode | Why the session holds `status`, when something is wrong. |
| connectMs? | number | Milliseconds from the editor attaching the session to its first `ready`. Present only on that change, and only when the editor saw the wait: a session that was already ready when the editor attached, as `useHocuspocusCollaboration` makes it, reports none. |
| kind | 'collab.status' | |
| previous | CollaborationStatus | 'none' | The status before this change; `'none'` for the first status the editor saw. |
| recovering | boolean | True when the session will heal on its own; wait instead of rejoining. |
| status | CollaborationStatus |
CommentRecordinterfaceSource ↗
One comment as authored in word/comments.xml.
interface CommentRecord| Member | Type | Summary |
|---|---|---|
| author | string | |
| blocks | readonly OoxmlElement[] | Body paragraphs, as tree nodes, so the surface renders measured text rather than a string. |
| date? | string | |
| id | string | |
| initials? | string | |
| paraId? | string | `w14:paraId` of the last body paragraph — the key thread state is stored under. |
| parentCommentId? | string | `@w16cid:parentId` — the `w:id` of the comment this replies to, when the file names it. |
CompareDocumentsChromeHandlersinterfaceSource ↗
Host rendering for the Compare documents dialog.
interface CompareDocumentsChromeHandlers| Member | Type | Summary |
|---|---|---|
| onRequest? | (session: CompareDocumentsDialogSession) => void |
CompareDocumentsDialogSessioninterfaceSource ↗
One open Compare documents dialog. The editor owns it: the session aborts when the dialog closes, is replaced, or the document, mount, or editor goes away.
interface CompareDocumentsDialogSession| Member | Type | Summary |
|---|---|---|
| apply | | Compare the open document with the revised DOCX and record the differences in it as tracked changes, as one undoable step. Closes the session when the document changes. With no differences (`changed` false) or a refusal, the session stays open with a message to show. |
| canApply | | Whether a compare can run now. |
| cancel | | Close the dialog. A running background compare stops, and nothing changes. |
| cancelable | boolean | Whether `cancel()` can stop a running compare: true when compares run in the background. A compare that falls back to the main thread, because the worker never started, cannot stop. |
| defaultAuthor | string | The author name the dialog offers first: the editor's author, or an empty string. |
| originalHasTrackedChanges | boolean | Whether the open document has tracked changes when the dialog opens. The compare treats them as accepted, so a dialog says so before the user compares. |
| signal | AbortSignal | Aborts on close, replacement, load, detach, or destroy. |
CompareDocumentsProgressinterfaceSource ↗
How far a background compare is.
interface CompareDocumentsProgress| Member | Type | Summary |
|---|---|---|
| fraction | number | The share of the work done, from 0 to 1. It never decreases. |
| phase | CompareDocumentsPhase | The step that runs now. |
CompareDocumentsRequestinterfaceSource ↗
What one compare request carries: the revised DOCX and its options.
interface CompareDocumentsRequest| Member | Type | Summary |
|---|---|---|
| authorName? | string | Author recorded on every revision. When absent or blank, the editor's author. Without an editor author, the revised document's last author, then its creator, then `Comparison`. |
| detectFormatChanges? | boolean | Record formatting differences as formatting revisions. Default `true`. |
| removeDateAndTime? | boolean | Write the revisions without dates. Default `false`. |
| revised | Uint8Array | The revised document's DOCX bytes. The open document is the original. |
ContentControlinterfaceSource ↗
Structured document tag (w:sdt).
interface ContentControl| Member | Type | Summary |
|---|---|---|
| alias? | string | |
| content | readonly Block[] | |
| controlType | ContentControlType | |
| id | string | |
| kind | 'contentControl' | |
| locked? | boolean | |
| tag? | string |
ContentControlFilterinterfaceSource ↗
Narrows a content-control query. Fields combine with AND; an empty filter matches every control.
interface ContentControlFilter| Member | Type | Summary |
|---|---|---|
| alias? | string | |
| controlType? | ContentControlType | |
| tag? | string |
ContentControlSummaryinterfaceSource ↗
A content control reduced to what a listing needs: its identity, kind, and lock state.
interface ContentControlSummary| Member | Type | Summary |
|---|---|---|
| alias? | string | |
| controlType | ContentControlType | |
| id | string | |
| locked? | boolean | |
| tag? | string |
CustomNodeDiagnosticEventinterfaceSource ↗
A custom node's stored payload could not be read. The node and its data are not named.
interface CustomNodeDiagnosticEvent extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| code | CustomNodeDiagnosticCode | |
| kind | 'custom-node' |
DiagnosticBaseinterfaceSource ↗
Fields every diagnostic carries.
interface DiagnosticBase| Member | Type | Summary |
|---|---|---|
| editorSessionId | string | Random for each editor instance and never stored, so one open failure can be linked to the edits after it. It identifies no person and no document. |
| schemaVersion | number | [DIAGNOSTIC_SCHEMA_VERSION](DIAGNOSTIC_SCHEMA_VERSION) when the event was made. |
| time | number | Milliseconds since the epoch. |
DiagnosticExplanationinterfaceSource ↗
What a diagnostic code means and what to do about it.
Both strings are constants written for developers. They never contain document content, so an exporter can send them with the event.
interface DiagnosticExplanation| Member | Type | Summary |
|---|---|---|
| docs | string | The documentation anchor for this code, such as `…/guides/diagnostics#edit-read-only`. |
| hint | string | One or two sentences: the cause, then the action. |
DiagnosticFailureDetailinterfaceSource ↗
Anonymous detail of a failure, for the engineer who fixes it. Every field is optional and comes from a closed list: never a part name, an element name, a message, or document text.
interface DiagnosticFailureDetail| Member | Type | Summary |
|---|---|---|
| cause? | string | The engine's own reason, such as `undeclared-prefix` under `open.xml-malformed`, or `exception` for an error the engine did not expect. Causes can change between engine versions: match on `code`, and include the `cause` when you report a problem. See `diagnosticCauses()` for every value. |
| errorName? | DiagnosticErrorName | The class of the exception when `cause` is `exception`. Its message is never reported. |
| stage? | FailureStage | Where the exception was caught, when `cause` is `exception`. |
DocAnchorinterfaceSource ↗
The LLM- and JSON-facing address for a piece of a document.
paraId is the 8-hex w14:paraId, matched case-insensitively. search is a phrase that must match EXACTLY ONCE inside that paragraph; ambiguous or missing matches fail with 'ambiguous' / 'notFound' rather than falling back to first-match.
Offset-based addressing was tried and abandoned: an agent cannot compute a character offset it has not seen, and offsets do not survive concurrent edits. Do not reintroduce { blockId, offset }.
interface DocAnchor| Member | Type | Summary |
|---|---|---|
| occurrence? | number | Opt-in disambiguation. Omit to require uniqueness. |
| paraId | string | |
| search? | string |
DocAnchorRangeinterfaceSource ↗
A position in one story: a paragraph and a UTF-16 offset inside it.
The same offset space the ops and the caret use, so an anchor read here can be handed straight back to a selection without re-deriving anything.
interface DocAnchorRange| Member | Type | Summary |
|---|---|---|
| endOffset | number | |
| endParagraphId | string | May sit in a later paragraph: the range markers are independent elements. |
| part | string | Canonical part name of the story the range lives in, e.g. `/word/document.xml`. |
| startOffset | number | |
| startParagraphId | string |
DocCommentinterfaceSource ↗
One comment or reply, as comments.xml records it.
A reply is a comment with a parentId; OOXML gives replies no separate element, so the thread is reconstructed from that link rather than from nesting.
interface DocComment| Member | Type | Summary |
|---|---|---|
| anchor? | DocAnchorRange | Where the comment is anchored, absent when the file gave it no usable range. |
| author | string | |
| date? | string | OPTIONAL, because `CT_Comment` makes `@w:date` optional and files omit it. A comment with no date is a comment, not a defect, and fabricating one is a content change. |
| id | string | |
| orphaned? | boolean | True when the file gave this comment no usable range — a reference with no markers, or a start with no end. Reported rather than dropped: a reviewer's remark vanishing silently is worse than one that says it lost its text. |
| parentId? | string | |
| resolved? | boolean | |
| text | string |
DocEditsinterfaceSource ↗
The document-executable edit vocabulary.
An interface rather than a closed union so extensions can widen it by declaration merging. A sealed union cannot be extended by a plugin, and the runtime dispatch is already registry-backed.
interface DocEdits| Member | Type | Summary |
|---|---|---|
| acceptAllRevisions | Record<never, never> | |
| acceptRevision | {
id: number;
part?: 'body' | 'footnote' | 'endnote';
noteId?: number;
} | |
| addComment | {
target: DocTarget;
text: string;
author: string;
} | |
| addRepeatingSectionItem | {
target: DocTarget;
index?: number;
} | |
| adjustIndent | {
target: DocTarget;
direction: 'increase' | 'decrease';
} | Word's Increase/Decrease Indent. |
| applyFormatting | {
target: DocTarget;
marks: RunFormatting;
} | |
| applyVariables | {
values: Record<string, string>;
} | |
| deleteText | {
target: DocTarget;
} | |
| insertBreak | {
target: DocTarget;
kind: 'page' | 'column' | 'line' | 'section' | 'sectionContinuous';
} | `'section'` is Word's Next Page break; `'sectionContinuous'` keeps the new section on the sheet the previous one ended, which is how a mid-page column or margin change is authored. `'column'` belongs to the multi-column lane and is refused for now. |
| insertContentControl | {
target: DocTarget;
subtype: InsertableContentControlType;
tag?: string;
title?: string;
} | Author a NEW control over the addressed span. |
| insertHyperlink | {
target: DocTarget;
href: string;
text?: string;
} | |
| insertImage | {
target: DocTarget;
data: Uint8Array;
extent?: Extent;
} | |
| insertTable | {
target: DocTarget;
rows: number;
cols: number;
} | |
| insertText | {
target: DocTarget;
text: string;
} | |
| mergeParagraphs | {
target: DocTarget;
} | |
| proposeDeletion | {
target: DocTarget;
author: string;
} | |
| proposeInsertion | {
target: DocTarget;
text: string;
author: string;
} | |
| proposeReplacement | {
target: DocTarget;
replaceWith: string;
author: string;
} | Authored family. `author` is required: tracked-ness is verb identity, not a boolean flag, so there is no global trackChanges toggle to forget. |
| rejectAllRevisions | Record<never, never> | |
| rejectRevision | {
id: number;
part?: 'body' | 'footnote' | 'endnote';
noteId?: number;
} | |
| removeContentControl | {
target: DocTarget;
} | |
| removeHyperlink | {
target: DocTarget;
} | |
| removeRepeatingSectionItem | {
target: DocTarget;
index: number;
} | |
| replaceText | {
target: DocTarget;
text: string;
} | |
| replyComment | {
commentId: string;
text: string;
author: string;
} | |
| resolveComment | {
commentId: string;
} | |
| setContentControlValue | {
target: DocTarget;
value: string;
} | |
| setParagraphStyle | {
target: DocTarget;
styleId: string;
} | |
| setVariable | {
name: string;
value: string;
} | |
| splitParagraph | {
target: DocTarget;
} | |
| toggleList | {
target: DocTarget;
kind: 'bullet' | 'ordered';
} | Word's Bullets and Numbering. |
DocLocationinterfaceSource ↗
Structural addressing for content the paraId map cannot reach.
interface DocLocation| Member | Type | Summary |
|---|---|---|
| container | ContainerRef | |
| offset? | number | |
| path | number[] | Block indices, descending into tables and content controls. |
DocQueriesinterfaceSource ↗
The document-readable query vocabulary, keyed identically to [DocQueryResults](DocQueryResults).
An interface rather than a closed union for the same reason [DocEdits](DocEdits) is: an extension widens it by declaration merging, and the runtime dispatch is registry-backed.
interface DocQueries| Member | Type | Summary |
|---|---|---|
| comments | {
resolved?: boolean;
} | |
| contentControls | {
filter?: ContentControlFilter;
} | |
| findText | {
text: string;
container?: ContainerRef;
} | |
| paragraphs | {
container?: ContainerRef;
} | |
| revisions | {
part?: 'body' | 'footnote' | 'endnote';
} | |
| styles | Record<never, never> | |
| variables | Record<never, never> |
DocQueryResultsinterfaceSource ↗
What each query returns. Keyed identically to DocQueries.
interface DocQueryResults| Member | Type | Summary |
|---|---|---|
| comments | readonly DocComment[] | |
| contentControls | readonly ContentControlSummary[] | |
| findText | readonly DocRange[] | |
| paragraphs | readonly ParagraphSummary[] | |
| revisions | readonly Revision[] | |
| styles | StyleDefinitions | |
| variables | Readonly<Record<string, string>> |
DocRangeinterfaceSource ↗
A span between two positions. The endpoints may be addressed either way, independently.
interface DocRange| Member | Type | Summary |
|---|---|---|
| from | DocAnchor | DocLocation | |
| to | DocAnchor | DocLocation |
DocumentBodyinterfaceSource ↗
The main story: its blocks in reading order, plus the sections derived from them.
interface DocumentBody| Member | Type | Summary |
|---|---|---|
| content | readonly Block[] | |
| sections | readonly Section[] | Derived, not stored: recomputed on read from section-break markers and section inheritance. Never treat it as a spreadable field. |
DocumentChangeinterfaceSource ↗
The payload of the change event / onChange. It carries revision + identity deltas, NOT serialized bytes: serializing a whole DOCX on every keystroke would be prohibitive for large documents. Call save() to get bytes on demand.
interface DocumentChange| Member | Type | Summary |
|---|---|---|
| created? | readonly string[] | Block ids created/deleted/edited by this change, when the engine reports them. |
| deleted? | readonly string[] | |
| dirty? | readonly string[] | |
| revision | number | Package revision after this change — `getDocumentHandle()`'s number, monotonic. |
| source? | 'load' | 'refresh' | 'recovery' | Replacement events must not start another external processing request. Absent for edits. |
DocumentHandleinterfaceSource ↗
An opaque handle to a loaded document — its stable identity and current revision. The canonical authored state is the engine's PackageModel, NOT a simplified tree; advanced automation (DocxEditor.run(handle, …)) addresses a document through this handle rather than a serialized structure. Kept deliberately minimal and open so it can carry more identity later without a breaking change.
interface DocumentHandle| Member | Type | Summary |
|---|---|---|
| revision | number | Package revision: rises for every edit, wherever it landed. Safe to compare. |
DocumentOpenFailureinterfaceSource ↗
A document the editor refused to open. It carries a stable code only, never the file's content or name, so a host can show it, log it, or send it with a support request.
Each refusal is a new object, so a host can compare it by reference to tell a second refusal of the same file from the first.
interface DocumentOpenFailure| Member | Type | Summary |
|---|---|---|
| code | DocumentOpenDiagnosticCode | The stable open code, the same one the `document.open` diagnostic reports. |
| reason | DocumentOpenFailureReason | The group of [DocumentOpenFailure.code](DocumentOpenFailure.code) that picks the message. |
DocumentProtectionStateinterfaceSource ↗
The document's protection, as the file states it.
interface DocumentProtectionState| Member | Type | Summary |
|---|---|---|
| edit | DocumentProtectionEdit | The restriction named by `@w:edit`; `none` when absent or unrecognised. |
| enforced | boolean | True when `@w:enforcement` puts that restriction in force. Always false for `none`. |
| password | boolean | True when lifting the protection would ask for a password in Word. |
DocumentShapeinterfaceSource ↗
The bucketed shape of an opened document.
interface DocumentShape| Member | Type | Summary |
|---|---|---|
| embeddedFonts | CountBucket | |
| paragraphs | CountBucket | |
| parts | CountBucket | XML parts in the package. |
| reviewItems | CountBucket | Tracked changes and comments, as the review queue lists them. |
DocxDocumentinterfaceSource ↗
A parsed .docx.
NOT JSON-round-trippable: it holds Maps and Dates, plus an internal side-table of verbatim XML used for lossless round-tripping. Use toJSON / fromJSON before sending it over JSON-RPC or handing it to a model.
interface DocxDocument| Member | Type | Summary |
|---|---|---|
| body | DocumentBody | |
| comments | readonly DocComment[] | |
| revisions | readonly Revision[] | |
| styles | StyleDefinitions | |
| theme? | Theme |
DocxDocumentJSONinterfaceSource ↗
The JSON-safe projection of a document.
interface DocxDocumentJSON| Member | Type | Summary |
|---|---|---|
| (member-0) | |
DrawingLocksinterfaceSource ↗
What a drawing refuses: selection, movement, resizing, aspect change.
Read and honoured rather than advisory — chrome that offered a handle the store will refuse would promise an edit that cannot happen.
interface DrawingLocks| Member | Type | Summary |
|---|---|---|
| changeAspect | boolean | |
| move | boolean | |
| resize | boolean | |
| select | boolean |
DrawingPositionInputinterfaceSource ↗
An anchored drawing's position: offsets, and the frames they are relative to.
The relative-to bases matter as much as the offsets. Writing an offset without preserving its base re-anchors the drawing against a different reference and moves it somewhere nobody asked.
interface DrawingPositionInput| Member | Type | Summary |
|---|---|---|
| horizontalEmu? | number | |
| mode? | 'frame' | 'simple' | `'simple'` when `@simplePos="1"`: `horizontalEmu` / `verticalEmu` are authoritative `wp:simplePos` x/y. `'frame'` (default) uses positionH/V relative frames. |
| relativeToH? | DrawingHorizontalReferenceFrame | |
| relativeToV? | DrawingVerticalReferenceFrame | |
| verticalEmu? | number |
EditorinterfaceSource ↗
The engine's whole public surface: load and save, execute and query, observe and subscribe.
Commands go through can before exec — the same check chrome uses to decide whether a control is enabled, so a button and the engine never disagree about what is possible.
snapshot() is version-cached: the same reference until state actually moves, with reference-stable sub-objects, which is what makes it safe as a useSyncExternalStore source.
interface Editor extends EditorAnchorNavigation, EditorHighlights, EditorReviewHits```ts
const editor = createDocxEditor({ container });
editor.load(bytes);
if (editor.can({ type: 'toggleBold' }).ok) editor.exec({ type: 'toggleBold' });
const bytesOut = await editor.save();
```| Member | Type | Summary |
|---|---|---|
| acceptReviewItem | | Accept or reject the revision behind a card. |
| addComment | | Comment on the current selection. |
| addComment | | [addComment](addComment) with an author for this call, overriding the configured author. |
| beginHistoryGroup | | Create an explicit gesture handle; creates no undo entry. |
| can | | Dry run: reports whether `exec` would apply. Never reports `changed`. |
| canExecuteImageCommand | | Dry run for byte commands that require [Editor.executeImageCommand](Editor.executeImageCommand). Generic [Editor.can](Editor.can) on `insertImage` / `replaceImage` refuses with an async-path reason; this method answers whether async execution can proceed right now. |
| deleteReviewItem | | Discard the item behind a card: the destructive half of the review verbs. |
| destroy | | |
| exec | | |
| executeImageCommand | | Insert or replace picture bytes as one package undo unit. |
| findMatches | | Find across body, headers, footers, footnotes, endnotes, and selectable text boxes. |
| findMatches | | Find many terms in one pass, such as a glossary: one result list per term, in order. |
| focus | | |
| getActivatedReviewItemKey | | The key of the ACTIVATED review item: the one [setActiveReviewItem](setActiveReviewItem), Next Change, or Previous Change made active, while the caret stays in it. |
| getActiveScope | | The scope editing is in, as [setActiveScope](setActiveScope) last set it or a press moved it. |
| getAvailableFonts | | Selectable standard and provider-supported families plus the configured catalog (the default face, the Word-name families the substitution map stands in for, and host-registered source families) merged with [getDocumentFonts](getDocumentFonts). Never empty — a brand-new document offers the same standard choices. This does not report installed or loaded fonts. |
| getComments | | Comment threads anchored in the document. |
| getCurrentPage | | One-based page at the caret (default), or at the centre of the mounted scroll viewport. Viewport mode falls back to the caret when no measurable viewport is attached. |
| getCustomNodeDefinitions | | Custom-node definitions registered through `createDocxEditor({ modules })`, in registration order. |
| getDocumentFonts | | Font families the document actually uses, for the font picker. |
| getDocumentHandle | | |
| getDocumentStyles | | Paragraph/character styles defined by the document, for the style picker. |
| getDocumentThemeColors | | The document theme's ten picker colours (`a:clrScheme`) in Word's column order (Background 1, Text 1, Background 2, Text 2, Accent 1-6), each a six-digit hex without '#'. Empty when the document has no complete scheme — the picker then falls back to a default palette. |
| getEditingMode | | How edits are written: directly, as suggestions, or not at all. |
| getHeaderFooterState | | Header/footer editing state: which region is being edited, if any. |
| getNotePreviewText | | Plain-text note preview for hover chrome. |
| getNotePropertiesState | | Resolved and authored note properties for the caret section — properties dialog read-model. |
| getOutline | | Heading outline for the navigation panel, in document order. |
| getPageGeometry | | Page boxes in stack coordinates, each with the text area the engine laid out. `contentBox` is the page inset by the section margin. Rulers use it for margin zones. The engine's margin is uniform, so do not present this as per-side fidelity. Empty before the first layout, which is the honest answer rather than a guessed page. |
| getPageSetup | | Section page setup — size, orientation and margins — for the page-setup dialog. |
| getRenderScale | | Layout points to CSS pixels, zoom included. |
| getReviewItems | | Every pending decision in the document, with where its card belongs. |
| getReviewRevision | | A counter that changes exactly when [getReviewItems](getReviewItems) would return something new. |
| getSelectedImage | | The image at the selection, for the image toolbar and transform controls. |
| getSelectedTable | | The table containing the selection, for the table toolbar. `null` outside a table. |
| getSelectionFormatting | | Formatting at the current selection, for toolbar value display (font, size, colour, alignment, list state). `null` when nothing is selected or nothing is derivable. |
| getSelectionPlacement | | Where a comment on the current selection would sit, in the same space as [ReviewItemPlacement.anchorY](ReviewItemPlacement.anchorY), or null when nothing is selected. |
| getTableCellSelection | | Live rectangular cell selection, if any. `null` when the caret is not in a cell rectangle. |
| getTotalPages | | |
| getTrackedChanges | | Tracked changes in the document — body AND header/footer stories. |
| getWatermark | | The watermark the document shows, read from the first section's headers; null when it shows none. For a picture watermark's bytes, use `query({ type: 'watermark' })`. |
| getZoom | | |
| getZoomMode | | Whether the scale is a number the engine holds, or one it recomputes from the viewport. |
| isActive | | Whether a formatting command is currently APPLIED at the selection — distinct from `can`, which answers whether it may run. |
| isReviewPaneOpen | | Whether the review pane is showing its cards. |
| load | | Load a new document (DOCX bytes, `'blank'`, or a handle), replacing the current one. |
| on | | |
| query | | |
| rejectReviewItem | | The rejecting half of [acceptReviewItem](acceptReviewItem), with the same rules and options. |
| relayout | | Replaces the module-scope cache-invalidation calls adapters make today. |
| releaseSelection | | Release only the pin installed by the matching [retainSelection](retainSelection) call. |
| replyToReviewItem | | Reply to a review item. |
| replyToReviewItem | | [replyToReviewItem](replyToReviewItem) with an author for this call, overriding the configured author. |
| reportCustomNodeDiagnostic | | Report a custom-node diagnostic to the modules registered on THIS editor. |
| retainSelection | | Pin the selection while chrome has focus. Returns null while detached. |
| save | | Serialize the current document, finalizing pending text form values first. Invalid input rejects with `EditorError.code === 'invalidArgs'` and remains editable. Validation does not open a dialog. Other write refusals also reject the save. |
| scrollToBlock | | `options` takes the [ScrollToAnchorOptions](ScrollToAnchorOptions) fields. `block` defaults to `'start'` here (`scrollToAnchor` defaults to `'centerIfNeeded'`), `behavior` to `'instant'`, and `offsetPx` to 24. An invalid option also returns false, and nothing scrolls. |
| scrollToPage | | Scroll a page or a block into view. Returns false when the target does not exist or the host has no scroll container. During a large open, a target not laid out yet answers true and scrolls once it is; input cancels that, and a page past the end never scrolls. |
| selectMatch | | Move the selection to a found match — what a find dialog's next/previous do. |
| setActiveReviewItem | | Card to document: a COLLAPSED caret at the range start, and a scroll to it. `null` clears it. |
| setActiveScope | | Move editing into `scope`: the body, a header or footer, a note, or a text box (`frame`). |
| setCommentResolved | | Resolve or reopen the comment thread behind a review card. |
| setEditingMode | | |
| setReviewActivationExclusions | | Revision kinds the caret must never activate, or null for none. |
| setTableInteractionLabel | | Update table furniture aria labels without remounting the editor. |
| setTrackedChangesFilter | | Set the view-time tracked-change filter, or clear it with `null`. |
| setZoom | | Set the display scale. Values outside a sane range are rejected rather than clamped silently, so a caller learns its input was refused. |
| setZoomMode | | Choose between holding a scale and tracking the viewport. |
| snapshot | |
EditorAnchorNavigationinterfaceSource ↗
Navigation and temporary highlights for external paragraph references.
interface EditorAnchorNavigation| Member | Type | Summary |
|---|---|---|
| clearAnchorHighlight | | Dismiss the anchor highlight with a fade, or immediately with `animation: false`. Validates options even when nothing is highlighted. |
| highlightAnchor | | Highlight the paragraph that a [DocAnchor](DocAnchor) resolves to, without scrolling. Matching follows `scrollToAnchor`; `search` must resolve, and the whole paragraph is marked. A new call replaces the previous anchor highlight. Repeating a call resets its timeout. |
| scrollToAnchor | | Reveal a paragraph by its `w14:paraId` without changing selection, focus, or editing scope. With `search`, reveal the start of the matched text. Matching follows [DocAnchor](DocAnchor). By default, an offscreen target is centered and an already visible target does not move the viewport. |
EditorBookmarkCommandsinterfaceSource ↗
The bookmark commands an editor accepts.
interface EditorBookmarkCommands| Member | Type | Summary |
|---|---|---|
| deleteBookmark | {
name: string;
} | Remove the bookmark with this name, compared without case, and any copies of it in other places. The text stays. |
| goToBookmark | {
name: string;
} | Select the bookmark's text, or put the caret at a point bookmark, and scroll to it. |
| insertBookmark | {
name: string;
} | Bookmark the selection under `name`, or the caret position when the selection is collapsed. A bookmark that already has the name, compared without case, moves here, also from another story, in one undo step. Two collaborators who add one name offline both keep their bookmark; every replica reads the first in document order until the next write of the name, which replaces or removes both. Refused with `invalidArgs` for a name that does not start with a letter, holds a character other than a letter, a digit or an underscore, or has more than 40 characters. |
| keepFirstBookmark | {
name: string;
} | Keep the bookmark this name means, the first in document order, and remove its copies, in one undo step. The selection does not move. Collaborators who add one name while offline can leave copies; `BookmarkSummary.duplicates` counts them. Refused with `notFound` when no bookmark has the name, and with `unsupported` when it has no copies. |
| openBookmarkDialog | Record<never, never> | Open the Bookmark dialog the host registered, the same request the Insert menu and Ctrl/Cmd+Shift+F5 send. Allowed in a read-only document, where Go To still works. Refused with `unsupported` while no host shows a bookmark dialog, for example when the `bookmark` popup is `false`. |
| openGoTo | {
readonly fromShortcut?: boolean;
} | Open the host's Go To UI, the Go to tab of `DocxEditor.Navigation`, the request its shortcut (Ctrl+G, Cmd+Option+G on macOS) sends. Allowed in a read-only document. Refused with `unsupported` while no host shows one. To jump without UI, run `goToBookmark`. |
| toggleBookmarks | Record<never, never> | Show or hide bracket marks at bookmarks. A view command: the document does not change. |
EditorCommandsinterfaceSource ↗
Every command the editor accepts, keyed by name with its payload as the value.
Extends the document-level [DocEdits](DocEdits) vocabulary with the things only a LIVE editor has: selection, view state, chrome modes, header/footer and note editing. An interface rather than a closed union so an extension can widen it by declaration merging.
interface EditorCommands extends EditorCommandShape<DocEdits>, EditorHeaderFooterCommands, EditorNoteCommands, EditorFormatPainterCommands, EditorBookmarkCommands| Member | Type | Summary |
|---|---|---|
| clearFormatting | Record<never, never> | Word's Clear All Formatting (Home Font the eraser). |
| commitTableColumnDividerResize | {
target: TableColumnDividerResizeTarget;
leftWidthTwips: number;
rightWidthTwips: number;
} | Commit an internal column-divider resize from an explicit pointer target. Widths are twips for the adjacent pair; their sum must match the pre-drag total. |
| commitTableRightEdgeResize | {
target: TableRightEdgeResizeTarget;
columnWidthTwips: number;
tableWidthTwips: number;
} | Commit an outer-right table-edge resize from an explicit pointer target. Updates the last grid column and overall table width together. |
| compareDocuments | CompareDocumentsRequest | Compare the open document (the original) with a revised DOCX and record the differences in it as tracked changes, as one undoable step. For hosts with their own file picker. The result's `compareDocuments` field carries the revision count, or the refusal as a code to translate (`compareDocuments.errors.<code>`). |
| copy | Record<never, never> | Put the selected text on the clipboard. Reports `changed: false` — the document is untouched. |
| cut | Record<never, never> | Put the selected text on the clipboard and delete it. Refused at a collapsed selection, and — unlike `copy` — in a read-only document. |
| deleteColumn | {
target?: TableColumnOccurrenceTarget;
} | |
| deleteImage | {
drawingNodeId?: string;
expectedPackageRevision?: number;
} | Delete the selected picture drawing as one package undo unit. |
| deleteRow | {
target?: TableRowOccurrenceTarget;
} | |
| deleteTable | Record<never, never> | |
| editTextFormField | Record<never, never> | Open options for the selected or context-clicked legacy text form. |
| insertColumn | {
where: 'left' | 'right';
target?: TableColumnOccurrenceTarget;
} | |
| insertImage | {
data: Uint8Array;
mime: SupportedImageMime;
widthPoints: number;
heightPoints: number;
expectedPackageRevision?: number;
title?: string;
description?: string;
hyperlink?: string;
} | |
| insertRow | {
where: 'above' | 'below';
target?: TableRowOccurrenceTarget;
} | |
| insertTextBox | Record<never, never> | Insert a rectangular body textbox and enter its text. |
| insertToc | Record<never, never> | Insert a generated, hyperlink-enabled TOC for heading levels 1–3 at the selection. |
| mergeCells | Record<never, never> | |
| navigateReviewChange | {
direction: 'next' | 'previous';
} | Navigate tracked changes, including hidden formatting balloons, and wrap at the end. |
| openCompareDocumentsDialog | Record<never, never> | Open the Compare documents dialog supplied by the review module. |
| openRevisionMarkupDialog | Record<never, never> | Open the local review settings dialog supplied by the review module. |
| paste | {
text: string;
html?: string;
} | Insert the clipboard payload at the selection, replacing it. |
| pasteWithoutFormatting | {
text: string;
} | Insert `text` as if typed, whatever richer flavours the clipboard held. |
| redo | Record<never, never> | |
| refreshToc | {
tocId?: string;
mode?: 'entire' | 'pageNumbers';
} | |
| removeTabMark | {
positionTwips: number;
} | Remove the tab stop at this position (twips) from the current paragraph. |
| removeToc | {
tocId?: string;
} | Remove a table of contents: its field, or the table of contents control around it with its heading. Text before and after the field stays. Without `tocId`, removes the table of contents last right-clicked, the one at the selection, or the only one. One undo step. Refuses with `notFound` when there is none, and while suggesting. |
| replaceAllMatches | {
query: string;
text: string;
matchCase?: boolean;
wholeWord?: boolean;
} | Replace EVERY match of `query` in one undoable step. Separate from looping `replaceMatch` because each replacement shifts the offsets of the ones after it — legacy applied its edits back-to-front for exactly this reason, and that ordering belongs with whoever owns the offsets. |
| replaceImage | {
data: Uint8Array;
mime?: SupportedImageMime;
drawingNodeId?: string;
expectedPackageRevision?: number;
} | Replace the selected picture's bytes as one package undo unit. |
| replaceMatch | {
match: TextMatch;
text: string;
} | Replace one found match with `text`, addressed by the [TextMatch](TextMatch) `findMatches` returns. An empty `text` deletes it. The selection and scroll position stay put. In suggesting mode it is a tracked replacement under the editor's author, refused where `proposeReplacement` would be. The match must be in the open story, not a text box. |
| resolveAllReviewChanges | ResolveReviewChangesOptions | Resolve eligible changes shown by the active filters, or an explicit scope, in one undo step. |
| selectAll | Record<never, never> | Select the whole body. Word's Ctrl+A, as a command rather than only a keystroke. |
| selectTableRegion | {
region: 'table' | 'row' | 'column';
} | Select a table region — the whole table, the current row, or the current column. Legacy's table toolbar offers all three. |
| setAlignment | {
align: 'left' | 'center' | 'right' | 'justify';
} | Physical alignment on every paragraph the selection touches. A right-to-left paragraph reaches its right margin with `w:jc="left"`, so the written value follows each paragraph's direction. |
| setCellFill | {
color: ColorValue | null;
} | Selected-cell fill. `null` clears direct fill so the table-style cascade applies again. |
| setEditingMode | {
mode: DocumentEditingMode;
} | Switch how edits are written. A view command: it changes no document state. |
| setImagePosition | {
drawingNodeId?: string;
expectedPackageRevision?: number;
horizontalEmu?: number;
verticalEmu?: number;
relativeToH?: string;
relativeToV?: string;
} | Anchor position of the selected floating image, from the position dialog. |
| setImageProperties | {
drawingNodeId?: string;
expectedPackageRevision?: number;
selectionParagraphId?: string;
selectionOffset?: number;
widthEmu?: number;
heightEmu?: number;
alt?: string;
title?: string;
description?: string;
hyperlink?: string | null;
crop?: ImageCropPercent;
resetToNaturalSize?: boolean;
wrap?: ImageWrapTarget;
horizontalEmu?: number;
verticalEmu?: number;
relativeToH?: string;
relativeToV?: string;
borderWidthEmu?: number;
borderColor?: ColorValue;
} | Size, alt text, crop, position, and border of the selected image, from the properties dialog. |
| setImageWrapType | {
drawingNodeId?: string;
expectedPackageRevision?: number;
target: 'inline' | 'square' | 'squareLeft' | 'squareRight' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';
initialPositionEmu?: {
horizontalEmu: number;
verticalEmu: number;
};
} | How the selected image sits relative to text. `inline` flows in the line; the rest are `wp:anchor` variants, with `squareLeft`/`squareRight` distinguishing which side text wraps on. Legacy's vocabulary, unchanged. |
| setIndent | {
left?: number | null;
right?: number | null;
firstLine?: number | null;
} | Exact paragraph indent, in twips, on every paragraph the selection touches. |
| setLineSpacing | {
rule: 'multiple' | 'exact' | 'atLeast';
value: number;
} | Word's Line Spacing, on every paragraph the selection touches. |
| setMarkAttr | {
mark: string;
attr: string;
value: unknown;
} | |
| setPageSetup | {
pageWidth?: number;
pageHeight?: number;
marginTop?: number;
marginRight?: number;
marginBottom?: number;
marginLeft?: number;
orientation?: 'portrait' | 'landscape';
scope?: 'document' | 'section';
} | Section-level page setup: the fields Word's Page Setup dialog and the rulers' margin drags change. Twips throughout, matching OOXML. Every field is optional — a margin drag sends one, the dialog sends several — and an omitted field is left as it is rather than reset. `scope` is Word's "Apply to": `'document'` (the default) writes every section; `'section'` writes only the section the selection is in. An orientation change without explicit dimensions swaps each written section's own dimensions, preserving distinct paper sizes. |
| setParagraphDirection | {
direction: 'ltr' | 'rtl';
} | Word's Left-to-Right and Right-to-Left Text Direction: the base direction (`w:bidi`) of every paragraph the selection touches, table cells included. `rtl` writes `w:bidi`. `ltr` removes a direct `w:bidi`, and writes `w:bidi w:val="0"` only where a style would otherwise make the paragraph right-to-left. Run text, run direction (`w:rtl`) and `w:jc` are untouched: alignment and indents are leading and trailing sides, so a start-aligned paragraph moves to the other margin with its direction. A paragraph already in the requested direction is left as it is. |
| setParagraphFormat | ParagraphFormatCommand | The Paragraph dialog as one command: alignment, indents, spacing, line spacing and the five paragraph flags, applied to every paragraph the selection touches. |
| setParagraphSpacing | {
beforePt?: number | null;
afterPt?: number | null;
} | Space above and below a paragraph, in points, on every paragraph the selection touches. Omitting a field leaves it as authored; `null` clears it, which is how Word's "Remove space before/after paragraph" differs from setting it to zero. |
| setReviewChangesAuthor | SetReviewChangesAuthorOptions | Attribute eligible changes to another author, keeping them pending, in one undo step. |
| setReviewDisplayMode | {
mode: ReviewDisplayMode;
} | Change the review projection without accepting or rejecting document revisions. |
| setSelection | {
anchor: DocAnchor;
} | {
range: EditorSelection;
} | Move the selection. Three accepted forms, and `can()` names all three when it refuses: a collapsed paraId anchor, a range of two paraId anchors, or a semantic anchor/head pair. |
| setTableBorders | {
scope: 'none';
target: TableBorderEdgeTarget;
} | {
scope: TableBorderEdgeTarget;
spec: TableBorderSpec;
} | Selected-cell borders. Concrete edge scopes require a complete spec; `{ scope: 'none', target }` clears only that active edge target and MUST NOT carry `spec`. |
| setTableCellVerticalAlignment | {
alignment: TableCellVerticalAlignment;
} | Vertically align content inside the selected table cells. |
| setTableProperties | {
width?: number | null;
widthType?: string | null;
justification?: 'left' | 'center' | 'right' | null;
} | Table-level properties from the table properties dialog: preferred width and its unit (`dxa`, `pct`, `auto`), and horizontal justification. `null` clears a property; omitting it leaves the current value alone. |
| setWatermark | {
watermark: Watermark | null;
} | Replace the document watermark in every header the document shows; null removes it. One undo step. Refuses with `invalidArgs` for an invalid option and `locked` in a protected document; a refusal writes nothing. See [Watermark](Watermark) for the options and defaults. |
| splitCell | {
rows: number;
cols: number;
} | |
| toggleDocumentProtection | Record<never, never> | Word's Protect Document: enforce filling-in-forms protection, or lift the enforced one. |
| toggleHeaderRow | Record<never, never> | |
| toggleList | {
kind: 'bullet' | 'ordered';
} | |
| toggleMark | {
mark: string;
} | |
| toggleParagraphMarks | Record<never, never> | Word's Show/Hide paragraph marks; presentation only. |
| toggleReviewPane | Record<never, never> | Show or hide the review pane. |
| transformImage | {
drawingNodeId?: string;
expectedPackageRevision?: number;
action: 'rotateCW' | 'rotateCCW' | 'flipH' | 'flipV';
} | Rotate or flip the selected image. Legacy composed these into a CSS transform. |
| undo | Record<never, never> |
EditorErrorinterfaceSource ↗
An error the engine raised, carrying a machine-readable code alongside the message.
code is optional because an Error from deeper down (a parser, a codec) is surfaced as-is rather than wrapped in a fabricated code. The editor's own codes: invalidTarget (attach cannot mount there), unsupported (a source it refuses to open), and hostCallback (a host callback such as a bookmark mark's decorate threw; the editor kept its default behavior).
interface EditorError extends Error| Member | Type | Summary |
|---|---|---|
| code? | string |
EditorEventsinterfaceSource ↗
What editor.on(...) can be subscribed to, and what each handler receives.
These are PUSH notifications and are not interchangeable with reading snapshot(): a snapshot read cannot observe an event that was never emitted, which is why adapter behaviour is asserted against these rather than against the snapshot.
interface EditorEvents| Member | Type | Summary |
|---|---|---|
| change | (change: DocumentChange) => void | A document mutation committed, with the ids it touched. |
| diagnostic | (event: EditorDiagnostic) => void | An anonymous diagnostic: a document opened or failed to open, an edit or a tracked change was refused, a font failed. Carries stable codes and bucketed numbers, never document content, so a handler may send it to an error tracker as it is. |
| error | (error: EditorError) => void | |
| historyDiagnostic | (diagnostic: HistoryDiagnostic) => void | |
| hostChange | (event: EditorHostChange) => void | The editor's pages are now in another document: it was attached for the first time, moved into another element or window, detached (`document` is `null`), or found its element moved to another window by the host. Custom chrome that listens on the editor's document or measures its window re-binds here. |
| reviewChangesResolved | (event: ReviewChangesResolvedEvent) => void | An accept-all or reject-all decision committed: from the toolbar, the menu, or `exec({ type: 'resolveAllReviewChanges' })`. `skipped` names the changes it left pending, so a host can say why they stay. A remote decision in a collaboration session never fires it: it is a local event. |
| reviewItemReveal | (event: ReviewItemRevealEvent) => void | An explicit request landed on a review item, and its card or balloon should open. |
| revisionMarkupChange | (settings: ResolvedRevisionMarkup) => void | Local viewer preferences changed through the API or review dialog. |
| selectionChange | (snapshot: EditorSnapshot) => void | Observable editor state moved without a document change: the selection or its derived formatting, the armed typing format, the open header or footer, the collaboration session's status, or the page count when pages finish laying out in the background. |
EditorExecOptionsinterfaceSource ↗
Options for a command's editing view and explicit gesture.
interface EditorExecOptions extends HistoryGroupOptions| Member | Type | Summary |
|---|---|---|
| historyGroup? | HistoryGroup | An open handle from this editor. Supported for synchronous formatting commands, tracked proposals (`proposeInsertion`, `proposeDeletion`, `proposeReplacement`), `resolveAllReviewChanges`, and `setReviewChangesAuthor`. Other commands refuse a handle with `code: 'unsupported'`. Intervening writes and undo/redo can split a gesture; inspect `ExecResult.history`. Read-only commands do not close a gesture. Ungrouped collaboration uses timed capture. See the core history grouping guide for gesture bindings and boundary rules. |
| scope? | EditorScope | Omitted, the command addresses the current selection. |
EditorFormatPainterCommandsinterfaceSource ↗
Word's Format Painter, as the two halves a keyboard user drives separately.
The pair is deliberately NOT one command with a direction flag: copyFormatting reads and pasteFormatting writes, so they answer can differently — copying is allowed on a document open for viewing, and applying is not.
interface EditorFormatPainterCommands| Member | Type | Summary |
|---|---|---|
| copyFormatting | Record<never, never> | Capture the formatting at the selection (Word's Ctrl+Shift+C). |
| pasteFormatting | Record<never, never> | Apply the captured formatting to the current selection (Word's Ctrl+Shift+V). |
EditorHeaderFooterCommandsinterfaceSource ↗
Header/footer lifecycle and page-field commands on [EditorCommands](EditorCommands).
Kept as a mixin so editor.ts can extend it without inlining the furniture vocabulary.
interface EditorHeaderFooterCommands| Member | Type | Summary |
|---|---|---|
| editHeaderFooter | {
position: 'header' | 'footer';
variant?: FurnitureVariant;
firstPage?: boolean;
evenPage?: boolean;
sectionIndex?: number;
} | Open a header or footer for editing, materialising an empty one if the section has none — which is what a double-click on the header band means in Word. |
| exitHeaderFooter | Record<never, never> | Leave header/footer editing and return to the body. |
| insertPageField | {
field: 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES' | 'PAGE_X_OF_Y';
} | Insert an allowlisted page-number field at the caret. Only valid while a header or footer scope is open. `PAGE_X_OF_Y` writes PAGE + " of " + NUMPAGES as one undo unit. |
| linkHeaderFooterToPrevious | HeaderFooterSlotArgs | Turn on "Same as Previous" for a section's furniture slot (drop its declared ref). Refused on the first section. Omitted fields default to the active story when scoped. |
| removeHeaderFooter | HeaderFooterSlotArgs | Delete a declared header/footer reference (and GC the part when orphaned). When the editor is already in furniture scope, omitted fields default to the active story. |
| setHeaderFooterOptions | {
sectionIndex?: number;
titlePage?: boolean;
evenAndOddHeaders?: boolean;
headerDistanceTwips?: number;
footerDistanceTwips?: number;
} | Section/document furniture options: `titlePg` and header/footer distances on a section; `evenAndOddHeaders` document-wide in settings. |
| unlinkHeaderFooterFromPrevious | HeaderFooterSlotArgs | Turn off "Same as Previous": clone the inherited part into a declared reference. When the active scope was the inherited rId, the editor rebinds to the clone. |
EditorHighlightsinterfaceSource ↗
Paint-only text highlights: search results, glossary terms, review findings.
Highlights are view state. They never change the document, selection, focus, or undo history, they are never saved, and they are not shared with collaborators.
interface EditorHighlights| Member | Type | Summary |
|---|---|---|
| clearHighlights | | Remove one highlight set, or every set when `name` is omitted. |
| getHighlightsAt | | The marks under a client point, topmost first. Use it from `pointermove` or `click` handlers on the editor to show definitions or details for a marked term. Only marks on painted pages are reported. |
| setHighlights | | Mark text ranges as one named set, replacing the set's previous ranges and options. |
EditorHostChangeinterfaceSource ↗
The payload of the hostChange event.
interface EditorHostChange| Member | Type | Summary |
|---|---|---|
| document | EditorHostDocument | null | The document the pages are mounted in now, or `null` while the editor is detached. |
EditorNoteCommandsinterfaceSource ↗
Footnote/endnote lifecycle and properties commands on [EditorCommands](EditorCommands).
interface EditorNoteCommands| Member | Type | Summary |
|---|---|---|
| convertAllNotes | {
fromKind: NoteKind;
} | Convert every note of one kind to the other in document order (one undo step). |
| convertNote | {
fromKind: NoteKind;
noteId: number;
} | Convert one note to the other kind. |
| deleteNote | {
noteKind: NoteKind;
noteId: number;
} | Delete a note and its body reference together. |
| insertNote | {
noteKind: NoteKind;
} | Insert a footnote or endnote reference at the caret (body only). |
| setNoteProperties | {
scope?: 'document' | 'section';
sectionIndex?: number;
footnote?: {
numFmt?: string;
numRestart?: string;
position?: string;
numStart?: number;
};
endnote?: {
numFmt?: string;
numRestart?: string;
position?: string;
numStart?: number;
};
} | Footnote and endnote properties: numbering format, start value, restart rule and position. |
EditorQueriesinterfaceSource ↗
Every query the editor answers, keyed by name with its arguments as the value.
Extends [DocQueries](DocQueries) with the reads that only mean something against a live, laid-out document: the selection, its formatting, the table or hyperlink under the caret.
interface EditorQueries extends DocQueries| Member | Type | Summary |
|---|---|---|
| bookmarks | Record<never, never> | Every bookmark in the document, hidden ones included, in document order. |
| contentControlAt | {
filter?: ContentControlFilter;
} | |
| hyperlinkAt | {
pos?: number;
fallbackHref?: string;
} | |
| isInsideToc | {
pos: number;
} | |
| selectedText | Record<never, never> | |
| selection | Record<never, never> | |
| selectionFormatting | Record<never, never> | |
| splitCellConfig | Record<never, never> | |
| tableContext | Record<never, never> | |
| trackedChanges | Record<never, never> | |
| watermark | Record<never, never> |
EditorQueryResultsinterfaceSource ↗
What each editor query returns. Keyed identically to EditorQueries.
interface EditorQueryResults extends DocQueryResults| Member | Type | Summary |
|---|---|---|
| bookmarks | readonly BookmarkSummary[] | |
| contentControlAt | ContentControlSummary | null | |
| hyperlinkAt | HyperlinkInfo | null | |
| isInsideToc | boolean | |
| selectedText | string | |
| selection | DocRange | null | |
| selectionFormatting | RunFormatting | null | |
| splitCellConfig | {
maxRows: number;
maxCols: number;
} | null | |
| tableContext | TableContext | null | |
| trackedChanges | readonly Revision[] | |
| watermark | Watermark | null |
EditorReviewHitsinterfaceSource ↗
Hit testing for hosts that draw their own review chrome.
interface EditorReviewHits| Member | Type | Summary |
|---|---|---|
| getReviewItemRects | | The bands one review item paints, one per line part, in client coordinates. |
| getReviewItemsAt | | The review items whose text is under a client point, innermost first. |
EditorSnapshotinterfaceSource ↗
A read model of the current editor state, safe to hand to framework rendering. Named EditorSnapshot rather than EditorState so it never collides with an editing engine's own state type.
interface EditorSnapshot| Member | Type | Summary |
|---|---|---|
| canRedo? | boolean | |
| canUndo? | boolean | Whether undo/redo have anything to apply, derived from the session's history. Optional and additive: an implementation that has not derived them omits them, and a consumer treats absent as `false` — the honest empty answer. |
| collaborationStatus | CollaborationStatus | 'inactive' | Lifecycle of the attached collaboration replica, or `'inactive'` when no collaboration module is registered. |
| documentProtection? | DocumentProtectionState | null | The document's `w:documentProtection`, as the file states it; null with no document. |
| editable | boolean | Whether the loaded document is being edited: a patchable document opened in edit mode. A read-only document (tables/SDTs/unpreservable) or `mode: 'view'` reports false. |
| editingMode? | DocumentEditingMode | How edits are written right now. |
| fontSubstitutions? | readonly string[] | Document font families that are NOT AVAILABLE: declared by the document, but with no byte source admitted, no redirect to an admitted face, nothing embedded, and nothing the platform could resolve. Chrome shows a compatibility notice from this the way Word does. |
| formatPainter? | FormatPainterSurfaceState | Format painter arming, and the level of what it holds. Here for the same reason `lastRejection` is: it moves no revision and no caret, so a mode the snapshot does not carry is a mode no toolbar can reflect. Optional and additive. |
| formatting | RunFormatting | null | |
| hasReviewContent? | boolean | Whether the document carries review content — tracked changes or comment anchors — independent of any registered review module. |
| image | ImageContext | null | |
| isLoading | boolean | Whether the editor is still waiting for a document: no bytes handed over yet, and no parse failure. Bytes count from the moment they are supplied, not from the moment pages paint, so this stays false across a detach and remount. Safe to gate a mount point on — it never depends on one existing. |
| isOpening? | boolean | Whether a supplied document is still on its way to painted pages. A large document mounts behind one painted frame so a loading screen can show instead of a frozen page, with the previous document (if any) still on screen. Show an overlay while it holds, but gate only chrome on it, never the mount point, which must stay mounted for the open to complete ([EditorSnapshot.isLoading](EditorSnapshot.isLoading) is the gate-safe flag). It turns false when the first pages paint; they take input while the rest lay out. Optional and additive: absent means the implementation has not derived it, read as `false`. |
| lastRejection? | string | null | Why the last edit was refused, or null. |
| openFailure? | DocumentOpenFailure | null | Why the last supplied document did not open, or `null` while it opens or after it opened. Unlike [EditorSnapshot.parseError](EditorSnapshot.parseError), it holds a stable code and never quotes the file, so a host can show it to a person. `DocxEditor.OpenFailure` renders it. Optional and additive: absent means the implementation has not derived it, read as `null`. |
| page | {
readonly current: number;
readonly total: number;
} | |
| pageSetup? | PageSetup | null | The section's page setup, reference-stable across ticks that did not change it. Optional and additive like `canUndo`: absent means the implementation has not derived it, `null` means no document is loaded. |
| parseError | string | null | |
| reviewDisplayMode? | ReviewDisplayMode | The displayed revision projection. The document and its revision history stay unchanged. |
| reviewPane | ResolvedReviewPane | The review pane settings in force: every field of `ReviewPaneOptions`, such as when the pane opens by itself and what it does when its card column does not fit. Change them with `setReviewPaneOptions`. Never saved. Always set: an editor without a review module reports `DEFAULT_REVIEW_PANE`. |
| reviewPaneOpen? | boolean | Whether the review pane is showing its cards. |
| revisionMarkup | ResolvedRevisionMarkup | Resolved local viewer preferences. Never saved into the document. |
| scope | EditorScope | |
| selection | DocRange | null | |
| selectionCollapsed | boolean | Whether the selection is a CARET rather than a range. `true` when nothing is loaded. |
| showBookmarks? | boolean | Whether bracket marks are shown at bookmarks. |
| showParagraphMarks? | boolean | Whether Show/Hide paragraph marks is enabled. |
| table | TableContext | null | |
| tocContext | {
readonly id: string;
} | null | The table of contents the last right-click landed on, or null. |
| zoom | number | |
| zoomMode? | ZoomMode | Where [EditorSnapshot.zoom](EditorSnapshot.zoom) came from. |
EditRejectedDiagnosticinterfaceSource ↗
An edit, a command or a tracked change was refused.
interface EditRejectedDiagnostic extends DiagnosticBase, DiagnosticFailureDetail| Member | Type | Summary |
|---|---|---|
| code | EditDiagnosticCode | |
| command? | EditorCommand['type'] | The command type for `origin: 'command'`, such as `'insertTable'`. |
| kind | 'edit.rejected' | |
| origin | EditRejectionOrigin | `'command'` for `exec(...)`, `'input'` for typing, clipboard, drag and pointer edits, and `'automation'` for a batch from the editing API. |
| tracked | boolean | True when the editor was suggesting (tracking changes) at the time. |
ExtentinterfaceSource ↗
A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch.
interface Extent| Member | Type | Summary |
|---|---|---|
| heightEmu | number | |
| widthEmu | number |
FontConfigurationinterfaceSource ↗
Public font source configuration sampled when an adapter mounts. It must be immutable for that editor lifetime; remount the adapter to replace bytes or substitutions atomically.
interface FontConfiguration| Member | Type | Summary |
|---|---|---|
| defaultFont | {
readonly family: string;
readonly sizeHalfPoints: number;
} | |
| epoch | number | |
| language? | string | |
| maxFontBytes | number | |
| sources | readonly FontSource[] | |
| substitutions? | readonly FontSourceSubstitution[] | |
| supportedFamilies? | readonly string[] | Selectable provider families, independent of loaded bytes. Listing them performs no fetch. |
FontDefinitioninterfaceSource ↗
A font the document names, and whether its bytes travel inside the package.
interface FontDefinition| Member | Type | Summary |
|---|---|---|
| embedded | boolean | |
| family | string |
FontFaceRequestinterfaceSource ↗
A concrete font face requested by authored document content.
interface FontFaceRequest| Member | Type | Summary |
|---|---|---|
| family | string | |
| style | 'normal' | 'italic' | |
| weight | number |
FontFailedDiagnosticinterfaceSource ↗
A font failed to load. The editor kept working with a substitute.
interface FontFailedDiagnostic extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| code | FontDiagnosticCode | |
| kind | 'font.failed' |
FontSourceinterfaceSource ↗
Immutable, byte-backed font face supplied to layout and browser paint.
interface FontSource| Member | Type | Summary |
|---|---|---|
| availability? | 'available' | 'forbidden' | |
| bytes | Uint8Array | |
| faceIndex | number | |
| hash | string | |
| id | string | |
| request | FontFaceRequest |
FontSourceSubstitutioninterfaceSource ↗
An explicit authored-font substitution. No implicit platform fallback is performed.
interface FontSourceSubstitution| Member | Type | Summary |
|---|---|---|
| from | FontFaceRequest | |
| lineMetrics? | {
readonly heightEm: number;
readonly baselineEm: number;
} | Word line-box metrics for the requested face, expressed as em ratios. |
| to | FontFaceRequest |
FormatPainterSurfaceStateinterfaceSource ↗
Painter state, as the editor publishes it.
Chrome state rather than document state, so it moves through the same report every other observable surface state uses — a toolbar's pressed state has one source. It lives in the CONTRACTS lane rather than beside the surface implementation because EditorSnapshot names it, and the contracts lane may not reach into the editor lane.
interface FormatPainterSurfaceState| Member | Type | Summary |
|---|---|---|
| level | FormatPainterLevel | |
| mode | FormatPainterMode |
HeaderFooterSetinterfaceSource ↗
A section's three header (or footer) variants, each a relationship id.
All optional: a variant a section does not declare inherits the previous section's, and one absent everywhere means the document simply has none.
interface HeaderFooterSet| Member | Type | Summary |
|---|---|---|
| default? | string | |
| even? | string | |
| first? | string |
HeaderFooterSlotArgsinterfaceSource ↗
Optional slot targeting shared by remove / link / unlink furniture commands.
interface HeaderFooterSlotArgs| Member | Type | Summary |
|---|---|---|
| evenPage? | boolean | |
| firstPage? | boolean | |
| position? | 'header' | 'footer' | |
| sectionIndex? | number | |
| variant? | FurnitureVariant | Prefer over `firstPage` / `evenPage` when selecting a furniture variant. |
HeaderFooterStateinterfaceSource ↗
Header/footer editing state: which region is being edited, if any.
interface HeaderFooterState| Member | Type | Summary |
|---|---|---|
| editing | 'header' | 'footer' | null | |
| evenAndOddHeaders? | boolean | Document `w:evenAndOddHeaders` — even-page furniture is distinct when true. |
| footerDistanceTwips? | number | Section footer distance from sheet edge, twips (`w:pgMar w:footer`). |
| headerDistanceTwips? | number | Section header distance from sheet edge, twips (`w:pgMar w:header`). |
| inherited? | boolean | Whether the resolved part is inherited from a preceding section ("Same as Previous") rather than declared on this section. |
| partName? | string | Package part name of the open story. |
| rId? | string | Relationship id of the open story (`EditorScope.rId`). |
| sectionIndex | number | |
| titlePage? | boolean | Section `w:titlePg` — first-page furniture is distinct when true. |
| variant? | FurnitureVariant | Furniture variant in effect on the page used to enter the scope. |
HighlightHitinterfaceSource ↗
One painted mark under a point. R is your range type: pass ranges with extra fields, such as a glossary definition, and read them back from range.
interface HighlightHit<R extends HighlightRange = HighlightRange>| Member | Type | Summary |
|---|---|---|
| active | boolean | Whether this range is the set's active range. |
| index | number | Index of the range in the array passed to `setHighlights()`. |
| length | number | Current length of the highlighted text. |
| name | string | Set name passed to `setHighlights()`. |
| range | R | The range object exactly as it was passed, including your own fields. Its offsets are the ones you passed; `start` and `length` are where the text is now. |
| rect | HighlightRect | The marked line box under the point, in client coordinates. Anchor popovers to it. |
| start | number | Current start of the highlighted text in its paragraph, after edits moved it. |
HighlightOptionsinterfaceSource ↗
Presentation for one named highlight set. Every field is optional.
interface HighlightOptions| Member | Type | Summary |
|---|---|---|
| activeColor? | string | Fill for the active range. Default: `var(--doc-text-highlight-active-color)`, orange. |
| activeIndex? | number | Index of the active range, or `-1` for none. An index past the last range also means none. The active range takes `activeColor` and the `docx-text-highlight--active` class. Default: `-1`. |
| className? | string | Space-separated CSS classes added to every mark of this set. |
| color? | string | Fill for every range: a CSS color or `var()` expression. Default: `var(--doc-text-highlight-color)`, a translucent yellow. |
| priority? | number | Stacking order between sets, as an integer from -1000 to 1000. A higher value paints on top. Sets with equal priority stack in the order they were first set. Default: `0`. The built-in Find pane uses the set name `search` with priority `10`. |
HighlightRangeinterfaceSource ↗
One text range to mark. A TextMatch from findMatches() is a valid range, so search results pass straight through.
interface HighlightRange| Member | Type | Summary |
|---|---|---|
| blockId | string | Paragraph that holds the range: `TextMatch.blockId`. IDs belong to the open document. |
| expectedText? | string | Model text the range must cover to paint. Set it for ranges computed outside the editor, such as on a server, so a range that no longer matches the document never paints. When it is omitted, a range must keep covering the text it covered when it was first set. |
| length | number | Range length in the same units. A zero length marks nothing. |
| scope? | ViewScope | Story that holds the paragraph. Informational; `blockId` already names the paragraph. |
| start | number | UTF-16 offset in the paragraph's model text, as `TextMatch.start` counts it. |
HighlightRectinterfaceSource ↗
A client-space rectangle, compatible with DOMRect readers such as positioning libraries.
interface HighlightRect| Member | Type | Summary |
|---|---|---|
| bottom | number | |
| height | number | |
| left | number | |
| right | number | |
| top | number | |
| width | number | |
| x | number | |
| y | number |
HighlightResultinterfaceSource ↗
What setHighlights() resolved against the open document.
interface HighlightResult| Member | Type | Summary |
|---|---|---|
| applied | number | Ranges that resolve to their text in the open document and can paint. |
| unavailable | number | Ranges that do not resolve or cannot paint: an unknown paragraph, offsets past the paragraph end, a zero length, text that differs from `expectedText`, or a story without a layout position. |
HistoryDiagnosticinterfaceSource ↗
Optional diagnostic notification; subscribing does not change history behavior.
interface HistoryDiagnostic| Member | Type | Summary |
|---|---|---|
| kind | 'split' | 'possible-ungrouped-gesture' | 'possible-fragmented-gesture' | |
| reason | string |
HistoryDiagnosticEventinterfaceSource ↗
The undo history did not group edits as the gesture intended. Informational.
interface HistoryDiagnosticEvent extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| code | HistoryDiagnosticCode | |
| kind | 'history' |
HistoryGroupinterfaceSource ↗
interface HistoryGroup| Member | Type | Summary |
|---|---|---|
| [historyGroupBrand] | true | |
| end | | End this gesture without reverting any edits. Safe to call more than once. |
| lastOutcome | HistoryGroupOutcome | null | The outcome of the latest write that named this handle, or `null` before the first one. |
| state | 'open' | 'closed' | Closed after `end()`, document replacement, detach, or destruction. |
HistoryGroupOptionsinterfaceSource ↗
Options for a review write that can join an explicit history group.
Every write that names one open handle becomes part of one undo step, across commands, review methods, and browser automation runs. A closed handle, or a handle from another editor, refuses the write with code: 'unsupported' and changes nothing.
interface HistoryGroupOptions```ts
const decision = editor.beginHistoryGroup();
// Reply first: the card's key no longer exists after the change is accepted.
const reply = editor.replyToReviewItem(key, 'Accepted with one change.', {
historyGroup: decision,
});
const accepted = editor.acceptReviewItem(key, { historyGroup: decision });
decision.end();
if (!reply.ok || !accepted.ok) throw new Error('the review card was refused');
editor.exec({ type: 'undo' }); // reverts both writes
```| Member | Type | Summary |
|---|---|---|
| historyGroup? | HistoryGroup | An open handle from [Editor.beginHistoryGroup](Editor.beginHistoryGroup) on this editor. |
HistoryGroupOutcomeinterfaceSource ↗
The history authority's result for this frame.
interface HistoryGroupOutcome| Member | Type | Summary |
|---|---|---|
| kind | 'started' | 'extended' | 'split' | 'none' | |
| reason? | 'history-boundary' | 'undo-redo' | 'no-history'
/** @deprecated No longer reported: writes that span document parts now extend the group. */
| 'package-unit' | 'composition' |
HyperlinkInfointerfaceSource ↗
The hyperlink under a position: where it points, how far it reaches, and what Word shows on hover.
href has already been through sanitizeHref — it comes from a file, so a javascript: or data: target is dropped at the parse boundary rather than here.
interface HyperlinkInfo| Member | Type | Summary |
|---|---|---|
| href | string | |
| range | DocRange | |
| tooltip? | string | `w:tooltip` on the `w:hyperlink` — the text Word shows on hover, and what the hyperlink dialog seeds its tooltip field with when editing an existing link. |
ImageCropPercentinterfaceSource ↗
Crop edge in UI percent (0–100).
interface ImageCropPercent| Member | Type | Summary |
|---|---|---|
| bottom | number | |
| left | number | |
| right | number | |
| top | number |
IndentFormattinginterfaceSource ↗
Indent at the selection, in twips.
Unlike every other field here, this does NOT go absent when the selection's paragraphs disagree. A ruler has to draw its handles somewhere, and Word draws them at the FIRST selected paragraph's values — Select All is the commonest indent gesture, and hiding the handles for it would be worse than showing one paragraph's truth. The values are therefore always the first touched paragraph's, and [mixed](mixed) records per field whether the rest agree.
firstLine is ONE SIGNED offset: negative is a hanging indent. OOXML spells it as two mutually exclusive attributes and this collapses them hanging-wins (§17.3.1.12), which is the model Word itself keeps.
Absent inside a table. The value would be correct there, but it is measured from the cell's content edge while a ruler is drawn against the page's margin, and the ruler does not know the cell.
interface IndentFormatting| Member | Type | Summary |
|---|---|---|
| firstLine | number | First-line offset from [left](left), signed. Negative is a hanging indent. |
| left | number | Leading indent (`w:left`), signed: the left one, or the right one in a right-to-left paragraph. Negative pulls text into the margin, as Word allows. |
| mixed | {
readonly left: boolean;
readonly right: boolean;
readonly firstLine: boolean;
} | Per field, whether the selection's paragraphs disagree about it. |
| right | number | Trailing indent (`w:right`), signed: the right one, or the left one right to left. |
| rtl? | true | The first selected paragraph reads right to left, so `left` and the first line sit on the right margin. Absent for a left-to-right paragraph. |
NotePropertiesSideinterfaceSource ↗
One note kind's resolved + authored properties for the caret section.
interface NotePropertiesSide| Member | Type | Summary |
|---|---|---|
| documentAuthored? | AuthoredNoteNumbering | The document settings (settings.xml) values. Only the endnote `pos` affects `resolved`; the other fields are kept for files that carry them. |
| resolved | ResolvedNoteNumbering | |
| sectionAuthored? | AuthoredNoteNumbering | The caret section's own values, which set numbering and the footnote position. |
NotePropertiesStateinterfaceSource ↗
Resolved and authored note properties for the caret section — properties dialog read-model.
interface NotePropertiesState| Member | Type | Summary |
|---|---|---|
| endnote | NotePropertiesSide | |
| footnote | NotePropertiesSide | |
| sectionIndex | number |
NumberingRefinterfaceSource ↗
A paragraph's list membership: which numbering.xml definition, and at which level.
interface NumberingRef| Member | Type | Summary |
|---|---|---|
| level | number | Zero-based. OOXML numbering has nine levels, 0 through 8. |
| numId | string |
PageMarginsinterfaceSource ↗
Page margins in twips.
interface PageMargins| Member | Type | Summary |
|---|---|---|
| bottomTwips | number | |
| leftTwips | number | |
| rightTwips | number | |
| topTwips | number |
PageSetupinterfaceSource ↗
Section page setup — size, orientation and margins, in twips — as getPageSetup() and snapshot().pageSetup report it and the setPageSetup command writes it. In a multi-section document this is the setup of the section the SELECTION is in, which is what a ruler or a dialog reflects — Word's behaviour.
interface PageSetup| Member | Type | Summary |
|---|---|---|
| gutterTwips? | number | Binding gutter (`w:gutter`), folded into the left margin by layout. |
| marginsTwips | {
readonly top: number;
readonly right: number;
readonly bottom: number;
readonly left: number;
} | |
| orientation | 'portrait' | 'landscape' | |
| pageHeightTwips | number | |
| pageWidthTwips | number |
ParagraphinterfaceSource ↗
One paragraph: its runs, the style it names, and its list membership.
interface Paragraph| Member | Type | Summary |
|---|---|---|
| kind | 'paragraph' | |
| numbering? | NumberingRef | |
| paraId? | string | `w14:paraId`. The stable handle `DocAnchor` addresses. |
| runs | readonly Run[] | |
| styleId? | string |
ParagraphDisagreementsinterfaceSource ↗
Which paragraph-level reads the selection disagrees about.
interface ParagraphDisagreements| Member | Type | Summary |
|---|---|---|
| alignment | boolean | |
| direction | boolean | The selection mixes left-to-right and right-to-left paragraphs. |
| lineSpacing | boolean | |
| spaceAfterPt | boolean | |
| spaceBeforePt | boolean | |
| tabStops | boolean |
ParagraphFlagsinterfaceSource ↗
The five paragraph flags a Paragraph dialog shows as checkboxes.
contextualSpacing is Word's "Don't add space between paragraphs of the same style"; the rest are its Pagination block. null means the selection disagrees.
interface ParagraphFlags| Member | Type | Summary |
|---|---|---|
| contextualSpacing | boolean | null | |
| keepLines | boolean | null | |
| keepNext | boolean | null | |
| pageBreakBefore | boolean | null | |
| widowControl | boolean | null |
ParagraphFormatCommandinterfaceSource ↗
Every field of the Paragraph dialog, as setParagraphFormat takes it.
An omitted field is left as authored. null REMOVES a setting so the style supplies it again — not the same as a zero, which blocks the cascade.
interface ParagraphFormatCommand| Member | Type | Summary |
|---|---|---|
| alignment? | 'left' | 'center' | 'right' | 'justify' | |
| contextualSpacing? | boolean | |
| direction? | 'ltr' | 'rtl' | Paragraph base direction (`w:bidi`), Word's Direction setting. `ltr` writes an explicit off value where a style would otherwise make the paragraph right-to-left. |
| indentFirstLineTwips? | number | null | ONE signed first-line offset: negative is a hanging indent. |
| indentLeftTwips? | number | null | |
| indentRightTwips? | number | null | |
| keepLines? | boolean | |
| keepNext? | boolean | |
| lineSpacing? | {
rule: 'multiple' | 'exact' | 'atLeast';
value: number;
} | null | |
| pageBreakBefore? | boolean | |
| spaceAfterPt? | number | null | |
| spaceBeforePt? | number | null | |
| tabStops? | readonly ParagraphTabStop[] | Replace the paragraph's custom tab stops. An empty list CLEARS them, which is what "Clear All" does; omit the field to leave them as authored. |
| widowControl? | boolean |
ParagraphSummaryinterfaceSource ↗
A paragraph reduced to what a listing needs: its stable handle, its text, and its style.
paraId is what a follow-up edit addresses, so a summary without one names a paragraph the file gave no w14:paraId and that a DocAnchor cannot reach.
interface ParagraphSummary| Member | Type | Summary |
|---|---|---|
| paraId? | string | |
| styleId? | string | |
| text | string |
ParagraphTabStopinterfaceSource ↗
One custom tab stop, as a command states it.
interface ParagraphTabStop| Member | Type | Summary |
|---|---|---|
| alignment | 'left' | 'center' | 'right' | 'decimal' | 'bar' | |
| leader? | 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot' | |
| positionTwips | number |
PerformanceDiagnosticinterfaceSource ↗
How the editor performed while it was used: one summary per window, never one event per key press. Sent after a minute of use, when the page is hidden, and when the editor is destroyed, if anything was measured since the last summary.
interface PerformanceDiagnostic extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| code? | PerformanceDiagnosticCode | Present when the summary needs attention: `performance.slow-interaction` when at least 20 presses were timed and more than one in 20 took over 200 ms. |
| interaction? | TimingSummary | Key presses and pointer presses on the pages, from the browser event to the next frame on screen: the delay a person feels. Presses queued behind slow work count with their full delay. Presses of modifier keys alone, and presses while the page is hidden, are not timed. |
| kind | 'performance' | |
| layout? | TimingSummary | Engine layout passes that the person causes, by an edit or a view change such as zoom. Each pass includes its main-thread work in the background, and the work of a pass that a newer edit replaced. Layouts that loading causes are not here: the opening layout, which `document.open` reports as `durationMs`, and layouts after fonts or images arrive. |
| pagesBucket? | CountBucket | Pages in the document at the last paint. |
| paint? | TimingSummary | Engine paints of the pages. |
| windowMs | number | Milliseconds from the window's first timing to the summary, one minute or less. Idle time inside the window counts, so this is not active editing time. Use the `count` of `interaction` to measure activity. |
PointinterfaceSource ↗
A position in points.
interface Point| Member | Type | Summary |
|---|---|---|
| x | number | |
| y | number |
RectinterfaceSource ↗
An axis-aligned rectangle in points, the unit layout works in throughout.
interface Rect| Member | Type | Summary |
|---|---|---|
| height | number | |
| width | number | |
| x | number | |
| y | number |
ResolvedNoteNumberinginterfaceSource ↗
Resolved note-numbering fields for one section. Numbering and the footnote position come from the section's own properties and the defaults; the endnote position comes from the document settings.
interface ResolvedNoteNumbering| Member | Type | Summary |
|---|---|---|
| numFmt | string | |
| numRestart | string | |
| numStart | number | |
| pos | string |
ResolvedReviewPaneinterfaceSource ↗
The review pane settings in force, with every field resolved.
interface ResolvedReviewPane| Member | Type | Summary |
|---|---|---|
| commentMarkers | CommentMarkerStyle | How a collapsed comment marker looks. |
| opening | ReviewPaneOpening | When the pane opens by itself. |
| overflow | ReviewPaneOverflow | What the open pane does when its card column does not fit beside the page. |
| revisionsIn | RevisionDisplay | Where tracked changes open. |
ResolvedRevisionMarkupinterfaceSource ↗
Fully resolved, immutable viewer preferences.
interface ResolvedRevisionMarkup| Member | Type | Summary |
|---|---|---|
| cells | {
readonly inserted: RevisionMarkupNamedColor | 'byAuthor' | 'none';
readonly deleted: RevisionMarkupNamedColor | 'byAuthor' | 'none';
readonly merged: RevisionMarkupNamedColor | 'byAuthor' | 'none';
readonly split: RevisionMarkupNamedColor | 'byAuthor' | 'none';
} | |
| changedLines | RevisionMarkupStyle<RevisionChangedLinesMark> | |
| deletions | RevisionMarkupTextStyle<RevisionDeletionMark> | |
| formatting | RevisionMarkupTextStyle | |
| insertions | RevisionMarkupTextStyle | |
| movedFrom | RevisionMarkupTextStyle<RevisionDeletionMark> | |
| movedTo | RevisionMarkupTextStyle | |
| trackFormatting | boolean | |
| trackMoves | boolean |
ResolveReviewChangesOptionsinterfaceSource ↗
Selection and unsupported-change policy for a bulk review decision.
interface ResolveReviewChangesOptions| Member | Type | Summary |
|---|---|---|
| action | 'accept' | 'reject' | |
| keys? | readonly string[] | Exact keys from getReviewItems(); overrides scope. Duplicate keys resolve once. |
| scope? | 'visible' | 'document' | Defaults to revisions included by author visibility and the tracked-changes predicate. |
| unsupported? | 'skip' | 'fail' | Defaults to skip. Strict refuses the entire selection if any target cannot resolve. |
ReviewActivationOptionsinterfaceSource ↗
How activating a review item places it in the viewport, and whether it announces the reveal.
interface ReviewActivationOptions| Member | Type | Summary |
|---|---|---|
| announce? | boolean | Whether a successful activation fires the `reviewItemReveal` event. Default `false`. |
| reveal? | ScrollPlacement | false | Where the item lands, or `false` to open it without scrolling at all. |
ReviewChangesAttributioninterfaceSource ↗
Who and when a change of tracked-change author records. Shared by both selections.
interface ReviewChangesAttribution| Member | Type | Summary |
|---|---|---|
| author? | string | The author to record. Defaults to the editor's `author`, so a reviewer adopts changes as their own. A command with neither refuses, because `w:author` is required. |
| date? | string | An ISO 8601 `xsd:dateTime` to record. Omit it to keep each change's own date. |
| unsupported? | 'skip' | 'fail' | Defaults to skip. Strict refuses the entire selection if any target cannot change. |
ReviewChangesResolvedEventinterfaceSource ↗
The payload of the reviewChangesResolved event.
interface ReviewChangesResolvedEvent| Member | Type | Summary |
|---|---|---|
| action | 'accept' | 'reject' | Whether the decision accepted or rejected the changes. |
| resolvedCount | number | How many listed changes it resolved. The `exec` result lists them in `revisions.resolved`. |
| skipped | readonly {
readonly key: string;
readonly pairKey?: string;
readonly reason: 'unsupported-revision' | 'incomplete-group' | 'retained-structure' | 'unknown-revision';
readonly detail?: RevisionBatchSkipDetail;
}[] | The listed changes it left pending, with why: `'retained-structure'` for a row that stays to keep a nested table, `'incomplete-group'` for a change that would also resolve one the selection leaves out, `'unsupported-revision'` for a structure the engine cannot resolve, and `'unknown-revision'` for a key that no longer names a change. `reviewCodeOfSkip(skip)` gives each entry's review code, with its `detail`. |
ReviewCommentIteminterfaceSource ↗
One comment as a review card. A reply carries parentId; OOXML gives replies no separate element, so threads are reconstructed from that link.
interface ReviewCommentItem| Member | Type | Summary |
|---|---|---|
| comment | CommentRecord | |
| id | string | |
| kind | 'comment' | |
| orphaned | boolean | True when the file gave this comment no usable range. |
| parentId? | string | The comment this replies to, absent for a top-level comment. |
| parentRevisionId? | string | The REVISION this comment answers, when it covers exactly that change's characters. |
| range | ReviewRange | null | |
| replyIds | readonly string[] | Replies to this comment, in document order. Empty for a reply or a childless comment. |
| resolved | boolean |
ReviewCommentPlacementinterfaceSource ↗
A comment thread's card.
interface ReviewCommentPlacement extends ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| item | ReviewCommentItem | |
| kind | 'comment' | |
| parentId? | string | The comment this replies to, absent at the top of a thread. |
| parentRevisionId? | string | The REVISION this comment answers, absent unless it does. |
| resolved | boolean | Whether `w15:commentsEx` marks the thread done. |
ReviewCustomIteminterfaceSource ↗
A card contributed by a recognized custom node (defineCustomNode with a reviewCard hook), anchored at the node's range.
Informational, never resolvable: there is nothing to accept or reject, so the engine refuses those verbs on it. title and detail are HOST-authored (the definition's hook produced them), but attrs and text originate in a file an attacker controls — a surface renders every one of these as text, never markup.
interface ReviewCustomItem| Member | Type | Summary |
|---|---|---|
| attrs | Readonly<Record<string, string>> | Attrs decoded from the tag, after the definition's recognition hook. Untrusted input. |
| carded | boolean | Whether this node asked for a sidebar card. |
| data? | unknown | The payload the node's control binds to, after the definition validated it. |
| detail? | string | Card body, from the definition's `reviewCard` hook. |
| icon? | string | Glyph for this node in the collapsed rail, as an SVG path in a `0 -960 960 960` viewBox. |
| id | string | The SDT node's stable id in the canonical tree. |
| kind | 'custom' | |
| name | string | The definition's `name`. |
| range | ReviewRange | null | |
| tag | string | The raw `w:tag` the node was recognized from. Untrusted input. |
| text | string | The SDT's literal content text. Untrusted input. |
| title | string | Card title, from the definition's `reviewCard` hook. Empty when `carded` is false. |
ReviewCustomPlacementinterfaceSource ↗
A custom node's card (defineCustomNode with a reviewCard hook).
interface ReviewCustomPlacement extends ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| item | ReviewCustomItem | |
| kind | 'custom' |
ReviewItemHitinterfaceSource ↗
One review item under a client point.
interface ReviewItemHit| Member | Type | Summary |
|---|---|---|
| placement | ReviewItemPlacement | The item, as `getReviewItems()` with the same query returns it. |
| rect | HighlightRect | The item's painted band on the line under the point, in client coordinates. It covers the part of the item's range on that line, not the whole range. Anchor popovers to it. |
ReviewItemPlacementBaseinterfaceSource ↗
What every review card carries, whatever kind of decision it represents.
Presentation-ready by design: author, initials, date and text are derived by the ENGINE, because deriving them means walking runs and reading w15:commentsEx. An adapter doing that walk would put document derivation in the host and would have to be written once per framework.
interface ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| activatable | boolean | Whether [Editor.setActiveReviewItem](Editor.setActiveReviewItem) would take this key. |
| anchorY | number | null | Document-space Y of the anchor, or null when the item has no resolvable range. |
| author | string | |
| date? | string | `@w:date`, absent when the file omits it — Word does when date stamping is off. |
| id | string | The engine's own id for the comment, the revision, or the custom node. |
| initials | string | Initials for an avatar: `@w:initials` when the file carries one, else from the name. |
| isActive | boolean | |
| key | string | Stable and unique per decision within this editor instance. |
| pageIndex | number | null | |
| readOnly | boolean | True when the engine cannot resolve this kind structurally, so accept and reject must not be offered. A card offering a button the engine will refuse is worse than one that explains why it cannot. |
| replyIds | readonly string[] | Replies to this item, in document order. |
| text | string | The comment's body, the words the revision covers, or the custom card's detail. |
ReviewItemQueryinterfaceSource ↗
Narrows what getReviewItems returns.
Filtering revision kinds is how a host hides structural cards it has no UI for, placement: false skips the layout pass entirely when only metadata is wanted, and pairReplacements: false lists a typed-over selection as its two halves.
interface ReviewItemQuery| Member | Type | Summary |
|---|---|---|
| excludeRevisionKinds? | readonly ReviewRevisionKind[] | Revision kinds to leave out of the returned items, for example structural kinds that the host has no card for. Default: none. Comments and custom items are never removed. This filters only the returned data; to stop the caret from activating the same kinds, call `setReviewActivationExclusions`. |
| pairReplacements? | boolean | Whether to list a deletion and the insertion that touches it as one `'replace'` item. Typing over a selection writes the deletion first; a document compare writes the insertion first. Both pair. Default true. Set it to false to list the deletion and the insertion as separate items, for example to accept or reject each half on its own. |
| placement? | boolean | When false, skip layout geometry; metadata is unchanged and anchors are null. Default true. |
ReviewItemRevealEventinterfaceSource ↗
The payload of the reviewItemReveal event.
interface ReviewItemRevealEvent| Member | Type | Summary |
|---|---|---|
| key | string | The key of the review item to open, as `getReviewItems({ pairReplacements: false })` lists it, so for a replacement this is the key of its deletion or its insertion. Next Change and Previous Change stop once on a replacement and report its deletion's key, with the pair's key in [ReviewItemRevealEvent.pairKey](ReviewItemRevealEvent.pairKey). `setActiveReviewItem` reports the key it was given, so a call with a pair's key reports that key here and in [ReviewItemRevealEvent.pairKey](ReviewItemRevealEvent.pairKey). |
| pairKey? | string | The key that `getReviewItems()` gives the replacement this item belongs to, since it pairs replacements by default. Present only when the item is a paired replacement or one half of one. A host that reads the default list opens `pairKey ?? key`. |
| source | ReviewItemRevealSource | What asked for the item. `'navigate'` is Next Change or Previous Change, from the menu, the toolbar, a shortcut, or `exec({ type: 'navigateReviewChange' })`. `'host'` is a call to `setActiveReviewItem` (and so `useReview().setActive`) with `announce: true`. |
ReviewPaneItemFieldsinterfaceSource ↗
The fields of a review item that decide whether the review pane lists it. A ReviewItem and a review item placement both have them.
interface ReviewPaneItemFields| Member | Type | Summary |
|---|---|---|
| kind | 'revision' | 'comment' | 'custom' | The item kind, as `ReviewItem.kind` gives it. |
| parentRevisionId? | string | For a comment, the tracked change it replies to. |
ReviewPaneOptionsinterfaceSource ↗
Review pane settings to change. Every field is optional, and an omitted field keeps its current value.
interface ReviewPaneOptions| Member | Type | Summary |
|---|---|---|
| commentMarkers? | CommentMarkerStyle | Default `'icon'`. |
| opening? | ReviewPaneOpening | Default `'auto'`. |
| overflow? | ReviewPaneOverflow | Default `'float'`. |
| revisionsIn? | RevisionDisplay | Default `'pane'`. |
ReviewPositioninterfaceSource ↗
A position in the model offset space of one story.
interface ReviewPosition| Member | Type | Summary |
|---|---|---|
| offset | number | |
| paragraphId | string |
ReviewRangeinterfaceSource ↗
Where an item is anchored: a range in one story.
interface ReviewRange| Member | Type | Summary |
|---|---|---|
| end | ReviewPosition | |
| partName | string | |
| start | ReviewPosition |
ReviewRevisionIteminterfaceSource ↗
One tracked change as a review card.
Keyed per DECISION rather than per site: a revision spanning three ranges is one card, because accepting it accepts all three.
interface ReviewRevisionItem| Member | Type | Summary |
|---|---|---|
| address | RevisionAddress | The payload `acceptRevision` / `rejectRevision` take. |
| addresses | readonly RevisionAddress[] | EVERY address this decision covers, `address` first. |
| author | string | |
| date? | string | |
| formattingChanges? | readonly {
readonly property: 'bold' | 'italic' | 'underline' | 'strike' | 'fontFamily' | 'fontSize' | 'color' | 'highlight' | 'alignment' | 'leftIndent' | 'rightIndent' | 'firstLineIndent' | 'hangingIndent' | 'spaceBefore' | 'spaceAfter' | 'direction';
readonly value: string | null;
}[] | Changed direct formatting values, ready for localized review summaries. |
| formattingKind? | string | OOXML property-change element, used to resolve independently numbered formatting kinds. |
| formattingLanguages? | readonly string[] | Newly applied proofing language codes in a tracked formatting change. |
| id | string | Stable across renders and unique per decision within this editor instance. |
| kind | 'revision' | |
| markDirection? | 'insert' | 'delete' | 'moveFrom' | 'moveTo' | WHICH decision a `paragraphMark` records, absent for every other kind. |
| nesting | number | How deeply this change is NESTED inside other changes, 0 for an unenclosed one. |
| pairedWith? | string | The other half of a move, or the other side of a delete/insert replacement. |
| ranges | readonly ReviewRange[] | Every site this decision touches, in document order. |
| readOnly | boolean | True when the engine cannot resolve this kind, so accept and reject must not be offered. |
| replacedRangeCount? | number | How many leading `ranges` are the STRUCK half of a replacement. |
| replacedText | string | The words a replacement removes. Empty for every other kind. |
| replyIds | readonly string[] | Comments answering this change, in document order. |
| revisionKind | ReviewRevisionKind | |
| structuralChanges? | readonly ('rowInsert' | 'rowDelete' | 'cellInsert' | 'cellDelete' | 'cellMerge' | 'numberingInsert')[] | Distinct structural operations covered by this decision, in document order. |
| text | string | Text the revision covers, for the card summary. Empty for changes with no characters. |
ReviewRevisionPlacementinterfaceSource ↗
A tracked change's card.
interface ReviewRevisionPlacement extends ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| item | ReviewRevisionItem | |
| kind | 'revision' | |
| replacedText? | string | The words a replacement decision removes when [revisionKind](revisionKind) is `'replace'`. The built-in reader lists separate deletion and insertion cards when the query sets [ReviewItemQuery.pairReplacements](ReviewItemQuery.pairReplacements) to false. |
| revisionKind | ReviewRevisionKind | Which decision this is. |
ReviewSkippedDiagnosticinterfaceSource ↗
An accept, reject or re-author request skipped one or more tracked changes. One event for each code and kind of change in the request.
interface ReviewSkippedDiagnostic extends DiagnosticBase| Member | Type | Summary |
|---|---|---|
| cause? | string | The structure behind the skip. For `review.revision-unsupported`, the engine condition that refused the change, such as `unaddressed` (no `w:id` or author). For `review.incomplete-group`, the change the decision would also decide, such as `paired-change` (the other half of a move or merge) or `removed-content`. For `review.retained-structure`, `nested-table`. See `diagnosticCauses()`. |
| changeKind? | ReviewChangeKind | The kind of the skipped changes, absent when the change no longer exists. |
| code | ReviewDiagnosticCode | |
| count | number | How many items were skipped for this code and kind in the one request. |
| formattingKind? | FormattingChangeKind | For `changeKind: 'format'`, which property change it is. |
| kind | 'review.skipped' | |
| operation? | ReviewOperation | What the request asked: accept, reject, or attribute to another author. |
| part? | DocumentPartKind | The role of the part the changes are in, such as `'footnotes'`. Never its name. |
RevisioninterfaceSource ↗
One tracked change.
Addressing needs BOTH id and part: @w:id is unique only within a part, so an id alone names two revisions in any package that has a header or a comments part.
interface Revision| Member | Type | Summary |
|---|---|---|
| author | string | |
| date? | string | OPTIONAL. `CT_TrackChange` requires `@w:id` and `@w:author` and makes `@w:date` optional, and producers that omit it are ordinary. Requiring it here forced either a fabricated date — a content change — or dropping the revision from the list. |
| id | number | Numeric, and unique only WITHIN a part. Pair with `part` to address one. |
| part | string | REQUIRED, and a canonical PART NAME rather than a three-value enum. |
| type | RevisionType |
RevisionAddressinterfaceSource ↗
How a tracked change is addressed: @w:id, @w:author and @w:date together, within a part.
All of them, always. @w:id is unique only within a part, so an id alone names two revisions in any package with a header or a comments part — and it is not author-scoped either, so (part, id) would merge two authors' distinct revisions. One logical revision is also deliberately many elements sharing an id, as a tracked row insertion is, which no uniqueness rule could express.
interface RevisionAddress| Member | Type | Summary |
|---|---|---|
| author | string | |
| date? | string | Absent when the file wrote no `@w:date`; part of the identity either way. |
| id | string |
RevisionAuthorEntryinterfaceSource ↗
One reattributed change. key and author describe the change after the update, because review keys include the author.
interface RevisionAuthorEntry extends RevisionBatchEntry| Member | Type | Summary |
|---|---|---|
| previousAuthor | string | The author the change had before the update. |
| previousKey | string | The key the caller selected the change by. It differs from `key` when the attribution changed, because review keys include the author and date. |
RevisionAuthorResultinterfaceSource ↗
Outcome of one attribution change. Counts refer to review decisions, not XML markers.
interface RevisionAuthorResult| Member | Type | Summary |
|---|---|---|
| skipped | readonly {
readonly key: string;
readonly reason: RevisionAuthorSkipReason;
readonly revision?: RevisionBatchEntry;
}[] | Requested changes that kept their attribution. |
| updated | readonly RevisionAuthorEntry[] | Changes that now carry the requested attribution, in selection order. |
RevisionBatchEntryinterfaceSource ↗
A canonical review decision. Keys are valid only in the open document.
interface RevisionBatchEntry| Member | Type | Summary |
|---|---|---|
| author | string | |
| formattingKind? | string | For a formatting change, its OOXML property-change element, as the review item has it. |
| key | string | |
| partName | string | |
| revisionKind | ReviewRevisionItem['revisionKind'] |
RevisionBatchResultinterfaceSource ↗
Outcome of one selected-set decision. Counts refer to review decisions, not XML markers.
interface RevisionBatchResult| Member | Type | Summary |
|---|---|---|
| remaining | number | All pending decisions in the addressed scope, including excluded and unsupported changes. |
| resolved | readonly RevisionBatchEntry[] | |
| skipped | readonly {
readonly key: string;
readonly reason: RevisionBatchSkipReason;
readonly revision?: RevisionBatchEntry;
readonly detail?: RevisionBatchSkipDetail;
}[] |
RevisionMarkupChromeHandlersinterfaceSource ↗
Host rendering for the Track changes options dialog.
interface RevisionMarkupChromeHandlers| Member | Type | Summary |
|---|---|---|
| onRequest? | (session: RevisionMarkupDialogSession) => void |
RevisionMarkupDialogSessioninterfaceSource ↗
A local settings draft owned by the editor.
interface RevisionMarkupDialogSession| Member | Type | Summary |
|---|---|---|
| apply | | Commit the draft and close. Returns false after cancellation. |
| canApply | | |
| cancel | | Close without committing the draft. |
| get | | Read the immutable draft. |
| reset | | Restore default preferences in the draft only. |
| set | | Merge validated options into the draft without committing preferences. |
| signal | AbortSignal | Aborts on close, replacement, load, detach, destroy, or renderer disposal. |
| subscribe | | Observe draft changes, including effective external preference changes. |
RevisionMarkupStyleinterfaceSource ↗
interface RevisionMarkupStyle<Mark extends string = RevisionMarkupMark>| Member | Type | Summary |
|---|---|---|
| color | RevisionMarkupColor | |
| mark | Mark |
RevisionMarkupTextStyleinterfaceSource ↗
Viewer-only text styling. Document highlighting remains unchanged.
interface RevisionMarkupTextStyle<Mark extends string = RevisionMarkupMark> extends RevisionMarkupStyle<Mark>| Member | Type | Summary |
|---|---|---|
| background | RevisionMarkupNamedColor | 'byAuthor' | 'none' | Background color behind revision text. Defaults to `none`. |
RuninterfaceSource ↗
A stretch of text sharing one set of character properties.
interface Run| Member | Type | Summary |
|---|---|---|
| formatting? | RunFormatting | |
| revisionId? | number | Set when the run carries a tracked change. Unique only within its part. |
| text | string |
RunFormattinginterfaceSource ↗
Character formatting, and — at selection level — the paragraph properties a toolbar reads alongside it.
One type serves both roles so a toolbar reads alignment, style and script state from the same object as bold and italic. On a [Run](Run) the selection-level fields stay absent: a run has no alignment or paragraph style of its own.
interface RunFormatting| Member | Type | Summary |
|---|---|---|
| alignment? | 'left' | 'center' | 'right' | 'both' | Paragraph alignment at the selection, as a PHYSICAL edge. `both` is OOXML's spelling of justify. A right-to-left paragraph with no `w:jc` reads `right`. |
| bold? | boolean | |
| color? | ColorValue | |
| direction? | 'ltr' | 'rtl' | Paragraph base direction at the selection (`w:bidi` through the style cascade). Absent when the selection's paragraphs disagree; `disagrees.direction` then says so. |
| disagrees? | ParagraphDisagreements | Which paragraph-level fields above are absent because the selection DISAGREES, as opposed to because nothing states them. |
| fontFamily? | string | |
| fontSizePt? | number | |
| highlight? | string | |
| indent? | IndentFormatting | The EFFECTIVE paragraph indent at the selection — cascade and numbering merge included, so a numbered item that authors no `w:ind` reports the indent its list definition gives it. Absent when nothing is loaded, or when the selection is inside a table (see [IndentFormatting](IndentFormatting)). |
| italic? | boolean | |
| lineSpacing? | {
readonly rule: 'multiple' | 'exact' | 'atLeast';
readonly value: number;
} | Line spacing at the selection, in the unit its rule implies — LINES for `multiple`, points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a control can show what it reads and send back what it shows. The effective value: a paragraph whose cascade states none reads as single spacing (`multiple`, 1). Absent when the selection's paragraphs disagree. |
| paragraphFlags? | ParagraphFlags | The paragraph flags the Paragraph dialog shows as checkboxes. |
| spaceAfterPt? | number | |
| spaceBeforePt? | number | Space above and below the paragraph at the selection, in points. |
| strike? | boolean | |
| styleId? | string | Paragraph style id (`w:pStyle`) at the selection. |
| subscript? | boolean | |
| superscript? | boolean | |
| tabStops? | readonly ParagraphTabStop[] | The paragraph's custom tab stops at the selection, cascade included. Absent when the selection disagrees or the paragraphs have none. |
| underline? | boolean |
ScrollToAnchorOptionsinterfaceSource ↗
Scroll settings for [EditorAnchorNavigation.scrollToAnchor](EditorAnchorNavigation.scrollToAnchor). Every field is optional. The fields match document refresh NavigateToChangeOptions.
interface ScrollToAnchorOptions| Member | Type | Summary |
|---|---|---|
| behavior? | 'instant' | 'smooth' | Default: instant. Reduced motion uses instant even when smooth is requested. |
| block? | ScrollPlacement | Target placement. The default depends on the method: `scrollToAnchor` uses `'centerIfNeeded'`, which keeps the viewport still for a visible target, and `scrollToBlock` uses `'start'`. |
| offsetPx? | number | Edge padding for start/nearest placement, in CSS pixels. Default: 24. Finite and nonnegative. |
SectioninterfaceSource ↗
One section: the page it lays out on, and the header/footer stories it declares.
interface Section| Member | Type | Summary |
|---|---|---|
| footers | HeaderFooterSet | |
| headers | HeaderFooterSet | |
| properties | SectionProperties |
SectionPropertiesinterfaceSource ↗
w:sectPr: the page a section lays out on. Twips throughout, as the file stores them.
interface SectionProperties| Member | Type | Summary |
|---|---|---|
| columns? | {
count: number;
gapTwips: number;
} | |
| margins | PageMargins | |
| pageSize | {
widthTwips: number;
heightTwips: number;
} | |
| titlePage? | boolean | `w:titlePg` — whether the section's first page takes the `first` header/footer variant. |
SelectedImageStateinterfaceSource ↗
Canonical selected-image read model shared by [EditorSnapshot.image](EditorSnapshot.image) and [Editor.getSelectedImage](Editor.getSelectedImage).
interface SelectedImageState| Member | Type | Summary |
|---|---|---|
| canChangeWrap | boolean | Whether `setImageWrapType` applies: pictures only, never text boxes. |
| canCrop | boolean | Whether `setImageProperties` can crop: pictures only, never text boxes. |
| canMove | boolean | Whether `setImagePosition` can move the drawing. False for an inline drawing, which flows with its line, for a locked or hidden drawing, a rotated legacy VML text box, and in viewing mode. |
| canResize | boolean | Whether `setImageProperties` can change the size. False for a hidden drawing, a drawing whose size is locked, a rotated legacy VML text box or one sized as a percentage of a frame, and in viewing mode. An inline text box resizes. |
| crop | ImageCropPercent | Crop inset per edge in UI percent (0–100); OOXML stores permille (×1000). |
| description | string | |
| heightEmu | number | |
| hyperlink | string | null | |
| id | string | |
| intrinsic | Readonly<{
readonly pixelWidth: number;
readonly pixelHeight: number;
readonly dpiX: number;
readonly dpiY: number;
}> | null | |
| kind | DrawingKind | |
| locks | DrawingLocks | |
| name | string | |
| position | DrawingPositionInput | null | |
| resourceStatus | ImageResourceState['kind'] | |
| rotationDegrees | number | |
| title | string | |
| widthEmu | number | |
| wrap | ImageWrapTarget |
SemanticIdentityinterfaceSource ↗
Model-derived stable identity within a scope. Positions resolve through this index, not accumulated display-item lengths or editing-engine coordinates.
interface SemanticIdentity| Member | Type | Summary |
|---|---|---|
| blockId | string | |
| storyId | string |
SemanticPositioninterfaceSource ↗
A caret position in the model.
interface SemanticPosition| Member | Type | Summary |
|---|---|---|
| offset | number | |
| paragraphId | string |
SemanticSelectioninterfaceSource ↗
A selection as two semantic positions — never as DOM nodes.
anchor is where the selection started and head is where it currently ends, so head before anchor is an ordinary backwards selection rather than an error. Collapsed when the two are equal, which is what a caret is.
interface SemanticSelection| Member | Type | Summary |
|---|---|---|
| anchor | SemanticPosition | |
| head | SemanticPosition |
SessionActivityinterfaceSource ↗
What an editor did over a window of use or over its whole session. Counts and milliseconds only: no key, position, command argument or text.
interface SessionActivity| Member | Type | Summary |
|---|---|---|
| activeMs | number | Milliseconds of use: the time between key presses, pointer presses and edits that are at most 30 seconds apart. A longer pause counts as idle. |
| automationEdits | number | Editing API batches that changed the document. |
| commandEdits | number | Editor commands, from `exec(...)` or the toolbar, that changed the document. |
| durationMs | number | For `active`, milliseconds from the window's first activity to the summary. For `end`, milliseconds from the editor's creation to its end, idle time included. |
| inputEdits | number | Edits from typing, the clipboard, drag and drop, keyboard undo, and other input that changed the document. Each committed change counts once: typing commits about one change per character, and characters typed faster than the editor paints commit together. |
StyleDefinitioninterfaceSource ↗
One style: the ID content references, the name a reader sees, and its inheritance link.
interface StyleDefinition| Member | Type | Summary |
|---|---|---|
| basedOn? | string | `w:basedOn` — the style this one inherits from. Absent at the root of a chain. |
| id | string | |
| name | string |
StyleDefinitionsinterfaceSource ↗
styles.xml, split by the three style families that address separately.
Keyed by style ID rather than by the name a reader sees, because the ID is what a paragraph or run actually references.
interface StyleDefinitions| Member | Type | Summary |
|---|---|---|
| character | ReadonlyMap<string, StyleDefinition> | |
| paragraph | ReadonlyMap<string, StyleDefinition> | |
| table | ReadonlyMap<string, StyleDefinition> |
TableinterfaceSource ↗
A table: its rows, and the table style they resolve through.
interface Table| Member | Type | Summary |
|---|---|---|
| kind | 'table' | |
| rows | readonly TableRow[] | |
| styleId? | string |
TableBorderSpecinterfaceSource ↗
Complete border spec for [EditorCommands.setTableBorders](EditorCommands.setTableBorders). Size is in eighths of a point.
interface TableBorderSpec| Member | Type | Summary |
|---|---|---|
| color | ColorValue | |
| size | number | |
| style | TableBorderStyle |
TableCellinterfaceSource ↗
One cell. Its content is ordinary blocks, so a cell may hold paragraphs, nested tables and content controls alike.
interface TableCell| Member | Type | Summary |
|---|---|---|
| colSpan? | number | `w:gridSpan`. Absent means 1. |
| content | readonly Block[] | |
| rowSpan? | number | Vertical merge span. Absent means 1. |
TableColumnDividerResizeTargetinterfaceSource ↗
Adjacent grid columns addressed by an internal divider resize gesture.
sourceRevision is the PACKAGE revision of the layout the target was read from — the number getDocumentHandle() reports, never one story's own. Commit MUST refuse when it no longer equals the current one, even if an older layout remains published for geometry.
interface TableColumnDividerResizeTarget| Member | Type | Summary |
|---|---|---|
| isHeaderRepeat | boolean | |
| leftGridColumnId | string | |
| rightGridColumnId | string | |
| sourceRevision | number | |
| tableId | string |
TableColumnOccurrenceTargetinterfaceSource ↗
Explicit column occurrence. sourceRevision per [TableColumnDividerResizeTarget](TableColumnDividerResizeTarget).
interface TableColumnOccurrenceTarget| Member | Type | Summary |
|---|---|---|
| gridColumnId | string | |
| isHeaderRepeat | boolean | |
| sourceRevision | number | |
| tableId | string |
TableContextinterfaceSource ↗
Where the caret sits inside a table: its shape and current cell.
interface TableContext| Member | Type | Summary |
|---|---|---|
| columnIndex | number | Zero-based, within the row. |
| columns | number | |
| rowIndex | number | Zero-based, within the table. |
| rows | number |
TableRightEdgeResizeTargetinterfaceSource ↗
Last grid column and table width addressed by an outer-right-edge resize gesture.
sourceRevision follows the same rule as [TableColumnDividerResizeTarget](TableColumnDividerResizeTarget): the package revision of the layout the target was read from, and commit refuses once it no longer equals the current one.
interface TableRightEdgeResizeTarget| Member | Type | Summary |
|---|---|---|
| gridColumnId | string | |
| isHeaderRepeat | boolean | |
| sourceRevision | number | |
| tableId | string |
TableRowinterfaceSource ↗
One table row. Cell count may vary between rows: colSpan and vertical merges reshape it.
interface TableRow| Member | Type | Summary |
|---|---|---|
| cells | readonly TableCell[] |
TableRowOccurrenceTargetinterfaceSource ↗
Explicit row occurrence. sourceRevision per [TableColumnDividerResizeTarget](TableColumnDividerResizeTarget).
interface TableRowOccurrenceTarget| Member | Type | Summary |
|---|---|---|
| isHeaderRepeat | boolean | |
| rowId | string | |
| sourceRevision | number | |
| tableId | string |
TextMatchinterfaceSource ↗
One occurrence of a search query in the document.
Carries TWO addresses on purpose. blockId + start is the engine's own: stable across edits and independent of ordering. paragraphIndex + runIndex + runOffset is the positional one a find/replace UI needs to show and navigate results, and it is derived from the same walk rather than left to the caller to reconstruct — a caller guessing at run boundaries would send the selection to the wrong place.
A match can span runs when formatting changes mid-word; the run address is where it STARTS. scope identifies a non-body story so navigation opens the correct surface. A frame scope selects its anchoring drawing and never places a caret inside its story. A match inside a field result reports the field atom's model range. Its length is one, while text carries the visible match and can be longer. Select with start and length. Never derive the selected length from text.length.
interface TextMatch| Member | Type | Summary |
|---|---|---|
| blockId | string | |
| contextAfter? | string | |
| contextBefore? | string | Paragraph text immediately before and after the match, bounded at the derivation boundary. A results list shows the match in its sentence — "…as described in this **Exhi**bit A" — and nothing else in the contract can reach paragraph text, so a caller would otherwise have to re-read the document to render one row. |
| length | number | |
| paragraphIndex | number | Paragraph ordinal within this match's story. Table and nested-table paragraphs count. Non-paragraph blocks add no ordinal. |
| runIndex | number | Index of the run the match starts in, and the offset within that run. |
| runOffset | number | |
| scope? | ViewScope | Story containing the match. Absence means the body. |
| start | number | Character offset within the paragraph's concatenated run text. |
| text | string | The matched text as it appears in the document. |
ThemeinterfaceSource ↗
theme1.xml — what a [ColorValue](ColorValue) of kind theme resolves against.
interface Theme| Member | Type | Summary |
|---|---|---|
| colorScheme | ThemeColorScheme | |
| fontScheme? | Record<string, string> |
TimingSummaryinterfaceSource ↗
Timings of one kind over a performance window. Every value is in milliseconds, rounded to whole milliseconds.
interface TimingSummary| Member | Type | Summary |
|---|---|---|
| bands | readonly number[] | Timings per band, always exact. Eight counts: up to 16, 33, 50, 100, 200, 500, and 1000 ms, then over 1000 ms. A metrics backend builds a histogram from these. |
| count | number | Timings measured in the window. |
| maxMs | number | The slowest timing, always exact. |
| p50Ms | number | Median. Exact up to 2048 timings; above that, from a uniform sample of 2048. |
| p95Ms | number | 95th percentile, from the same sample as the median. |
ValidatedImageBytesHandleinterfaceSource ↗
Opaque handle — bytes are reachable only through [mintValidatedImageBytes](mintValidatedImageBytes).
interface ValidatedImageBytesHandle| Member | Type | Summary |
|---|---|---|
| contentId | string | |
| generation | number | |
| registryId | number | |
| resourceKey | string |
WatermarkinterfaceSource ↗
A document watermark: text or a picture drawn behind the text of every page.
Set text for a text watermark or imageData for a picture watermark, never both. Omitted options take the defaults in each field's description. The watermark goes into every header the document shows; a section with no header gets one.
Text options apply only with text; scale and washout apply only with imageData. setWatermark refuses a mixed or out-of-range value with invalidArgs and a reason naming the field, and writes nothing.
interface Watermark```ts
// A red, horizontal text watermark at 72pt.
editor.exec({
type: 'setWatermark',
watermark: { text: 'CONFIDENTIAL', color: 'C00000', fontSizePt: 72, layout: 'horizontal' },
});
// A washed-out picture watermark at its natural size.
editor.exec({ type: 'setWatermark', watermark: { imageData: pngBytes, scale: 1 } });
```| Member | Type | Summary |
|---|---|---|
| bold? | boolean | Text: bold. Defaults to false. |
| color? | string | Text: the colour as `RRGGBB`. Defaults to `C0C0C0` (silver). |
| fontFamily? | string | Text: the font family. Defaults to `Calibri`. |
| fontSizePt? | number | null | Text: the size in points, from 1 to 1000. Omitted or null is Auto, which fills the page. |
| imageData? | Uint8Array | The PNG, JPEG, GIF, BMP or WebP bytes of a picture watermark. |
| italic? | boolean | Text: italic. Defaults to false. |
| layout? | WatermarkLayout | Text: the orientation. Defaults to `diagonal`. |
| scale? | number | null | Picture: a factor of the picture's natural size. Omitted or null is Auto, which fits the page. |
| text? | string | The text of a text watermark, up to 256 characters on one line. |
| transparency? | number | Text: transparency from 0 (opaque) to 1. Defaults to 0.5. |
| washout? | boolean | Picture: lighten the picture so text over it stays readable. Defaults to true. |
WatermarkStateinterfaceSource ↗
The watermark a document shows, as Editor.getWatermark() reads it.
The text fields are present for a text watermark, washout for a picture watermark.
interface WatermarkState| Member | Type | Summary |
|---|---|---|
| bold? | boolean | |
| color? | string | `RRGGBB`. |
| fontFamily? | string | |
| fontSizePt? | number | null | Null for Auto size. |
| italic? | boolean | |
| kind | 'text' | 'image' | |
| layout? | WatermarkLayout | |
| text? | string | |
| transparency? | number | |
| washout? | boolean |
Type aliases (109)
BlocktypeSource ↗
Anything that can sit at block level in a story. Discriminate on kind.
type Block = Paragraph | Table | ContentControl;BookmarkPlacetypeSource ↗
Where a bookmark is, finer than [BookmarkStory](BookmarkStory): the main text, a header, a footer, a footnote or an endnote.
type BookmarkPlace = 'body' | 'header' | 'footer' | 'footnote' | 'endnote';BookmarkStorytypeSource ↗
Which kind of story a bookmark is in: the main text, a header or footer, or a note.
type BookmarkStory = 'body' | 'headerFooter' | 'note';ByteSizeBuckettypeSource ↗
A coarse size, in powers of two, so a size cannot single out one document. '0-64KiB' covers everything under 64 KiB; '512MiB+' everything above.
type ByteSizeBucket = '0-64KiB' | '64-128KiB' | '128-256KiB' | '256-512KiB' | '512KiB-1MiB' | '1-2MiB' | '2-4MiB' | '4-8MiB' | '8-16MiB' | '16-32MiB' | '32-64MiB' | '64-128MiB' | '128-256MiB' | '256-512MiB' | '512MiB+';CanResulttypeSource ↗
Whether a command would be accepted, and why not when it would not.
The reason is the ENGINE's own words, which is what lets disabled chrome explain itself instead of guessing — see toolbarCommandState.
type CanResult = {
ok: true;
} | {
ok: false;
code: ExecErrorCode;
reason: string;
};CollaborationDiagnosticCodetypeSource ↗
Why a collaboration session failed or refused work: collab. and the session's own public [CollaborationFailureCode](CollaborationFailureCode), such as collab.authentication-failed.
type CollaborationDiagnosticCode = `collab.${CollaborationFailureCode}`;CollaborationFailureCodetypeSource ↗
Why a replica refused work, left ready, or failed a schema check.
Free-form extras (a transport phrase, a blob key, a store refusal) travel in [CollaborationFailure.detail](CollaborationFailure.detail), not here. Branch on the code; log the detail.
Codes are grouped by cause, and each group comment names the host action. In error, only a remote update that is not applied yet, or one refused local edit, heals on its own. The failure codes table in the collaboration reference lists every code. transport-disconnected and authentication-failed need opposite answers: wait for the first; refresh the credential and rejoin for the second. room-generation-changed means the server compacted the room while this replica was away: save a copy if it holds unsent changes, then rejoin.
type CollaborationFailureCode =
/** Edit refused by the session gate. The status does not change. Wait for `ready`. */
'collaboration-session-destroyed' | 'collaboration-session-not-attached' | 'collaboration-session-not-ready' | 'collaboration-text-limit' | 'experimental-collaboration-body-text-only'
/** Factory input rejected before joining. Fix the value the host passed. */
| 'invalid-document-id' | 'invalid-identity' | 'invalid-identity-color' | 'invalid-session-id'
/** Join or seed did not complete. Connect the provider, check the room id, and retry. */
| 'already-initialized' | 'document-id-mismatch' | 'initialization-aborted' | 'initialization-timeout' | 'not-initialized'
/** The seed document cannot seed a room. Fix the file. */
| 'baseline-too-large' | 'blob-read' | 'invalid-baseline' | 'missing-local-blob' | 'no-main-document-part'
/** This client and the room have different formats. Terminal. Save local work. */
| 'collaboration-format-mismatch' | 'protocol-version-mismatch' | 'schema-version-mismatch'
/** The room is unusable. Terminal. Create a new room from saved bytes. */
| 'blob-digest-mismatch' | 'concurrent-seed' | 'port-already-attached'
/** A remote update is not applied yet. Heals when a later update arrives. Wait. */
| 'duplicate-paragraph-id' | 'invalid-relationships' | 'materialize-dropped-content' | 'missing-blob' | 'missing-root' | 'remote-apply-failed' | 'unknown-paragraph-id'
/** Over a resource limit. A local edit realigns; shared state over a limit is terminal. */
| 'blob-store-full' | 'blob-too-large' | 'invalid-blob-descriptor' | 'invalid-bound' | 'invalid-logical-id' | 'invalid-string' | 'prototype-key' | 'text-too-long' | 'too-many-attributes' | 'too-many-children' | 'too-many-nodes' | 'too-many-parts' | 'too-many-relationships' | 'tree-too-deep' | 'unknown-logical-id' | 'unsafe-part-name'
/** Transport state. Only `transport-disconnected` recovers on its own. */
| 'authentication-failed' | 'room-generation-changed' | 'transport' | 'transport-disconnected'
/** Reserved for a room server that refuses a saved room. Passed through, never emitted. */
| 'invalid-saved-room' | 'saved-room-unavailable'
/** @deprecated Emitted by nothing. Kept for compatibility; do not branch on these. */
| 'baseline-digest-mismatch' | 'experimental-collaboration-existing-paragraphs-only' | 'experimental-collaboration-text-only' | 'experimental-collaboration-untracked-text-only' | 'immutable-baseline-changed' | 'immutable-metadata-changed' | 'invalid-shared-metadata' | 'local-mirror-failed' | 'paragraph-set-mismatch' | 'shared-schema-invalid' | 'unsupported-root-key';CollaborationStatustypeSource ↗
Lifecycle state of one collaboration replica.
One axis, because the only question a host has to answer is whether to tell the reader to wait or to reload:
- initializing — joining. Edits are refused. Recovers on its own. - ready — replicating. Accepts edits. - disconnected — the transport dropped. The replica is intact and recovers on its own, so wait rather than reload. Edits continue by default, and the buffered updates merge on reconnect. A session created with offlineEditing: false refuses them until reconnect. - error — this replica does not agree with the room. Edits are refused. [CollaborationStatusSnapshot.reason](CollaborationStatusSnapshot.reason) says why. A remote update the replica could not apply yet heals when a later update completes shared state ([CollaborationStatusSnapshot.recovering](CollaborationStatusSnapshot.recovering)). A format or version mismatch needs an upgrade of this client or the room; every other cause needs a rejoin. - destroyed — torn down. Terminal.
type CollaborationStatus = 'initializing' | 'ready' | 'disconnected' | 'error' | 'destroyed';ColorValuetypeSource ↗
A colour as the FILE expresses it, not as a resolved RGB string.
A theme colour stays a theme reference — slot plus tint or shade — so that changing the theme repaints the document the way Word does. Flattening to hex at read time would freeze the resolved value and break that link. auto is Word's "let the renderer decide", usually black on white.
type ColorValue = {
readonly kind: 'hex';
readonly value: string;
} | {
readonly kind: 'theme';
readonly slot: string;
readonly tint?: number;
readonly shade?: number;
} | {
readonly kind: 'auto';
};CommentMarkerStyletypeSource ↗
How a collapsed comment marker looks.
- 'initials': a badge with the thread author's initials in the author's color, a reply count, and a check mark when the thread is resolved. - 'icon': the comment icon.
type CommentMarkerStyle = 'initials' | 'icon';CompareDocumentsEngineErrorCodetypeSource ↗
Why the compare engine refused a compare, as a stable code: the codes that the engine, compareDocuments, and a background engine return. compareDocuments.errors.<code> in @docx-editor.dev/i18n translates every code.
type CompareDocumentsEngineErrorCode =
/**
* An option has a value of the wrong type, such as a `detectFormatChanges` that is not a
* boolean, or the revised document is not a `Uint8Array`.
*/
'invalidOptions'
/** The original document is not a readable DOCX package. */
| 'invalidOriginal'
/** The revised document is not a readable DOCX package. */
| 'invalidRevised'
/** The documents exceed the compare's size limits. */
| 'tooLarge'
/**
* The original document enforces protection that the compare would break: read-only,
* comments, forms, or tracked-changes protection. A compare also writes differences that
* have no tracked form, such as style definitions and content control properties, so
* tracked-changes protection refuses too.
*/
| 'protected'
/** The differences include content that no tracked change can record. */
| 'unsupportedContent';CompareDocumentsErrorCodetypeSource ↗
Why a compare was refused, as a stable code. compareDocuments.errors.<code> in @docx-editor.dev/i18n translates every code. The engine and compareDocuments return [CompareDocumentsEngineErrorCode](CompareDocumentsEngineErrorCode) values. The editor command and dialog can also return the editor-only codes.
type CompareDocumentsErrorCode = CompareDocumentsEngineErrorCode
/** Editor only: no review module, no open document, or no mount. */
| 'unavailable'
/** Editor only: a collaboration session is attached. */
| 'collaboration'
/** Editor only: the document is open for viewing only. */
| 'viewing'
/** Editor only: the dialog closed, or the compare was canceled, before it finished. */
| 'closed'
/** Editor only: the revised file is a `Uint8Array` with no bytes. */
| 'empty'
/**
* Editor only: another compare of the same dialog runs, or a preview or an external document
* refresh blocks writes to the document. Try again when it ends.
*/
| 'busy'
/**
* Editor only: the open document changed while a background compare ran, so its result
* no longer applies. The editor never retries by itself.
*/
| 'documentChanged'
/** Editor only: any other failure. */
| 'failed';CompareDocumentsOutcometypeSource ↗
The outcome of one compare.
type CompareDocumentsOutcome = {
readonly ok: true;
readonly revisionCount: number;
readonly changed: boolean;
} | {
readonly ok: false;
readonly code: CompareDocumentsErrorCode;
readonly reason?: CompareDocumentsRefusalReason;
readonly message: string;
};CompareDocumentsPhasetypeSource ↗
A step of a compare that runs in the background. The steps run in this order:
1. reading: read both documents. 2. comparing: find their differences. 3. checking: check that accepting and rejecting all changes give back each document. 4. applying: apply the result to the open document.
type CompareDocumentsPhase = 'reading' | 'comparing' | 'checking' | 'applying';CompareDocumentsRefusalReasontypeSource ↗
What an unsupportedContent refusal is about, as a stable code. compareDocuments.reasons.<reason> in @docx-editor.dev/i18n translates every reason.
type CompareDocumentsRefusalReason =
/** The documents differ inside a content control that is locked or bound to data. */
'lockedContent'
/** A document holds tracked changes that cannot be accepted, so its final state is unknown. */
| 'unresolvedRevisions'
/** The documents differ in content with no tracked-change form, such as an embedded file. */
| 'untrackedContent'
/** The revised document adds section or table settings that a reject cannot restore. */
| 'unrecordedSettings'
/** A header or footer of an earlier section cannot be paired with one of the original. */
| 'headerFooter'
/** The result needs a part type that the original document does not declare. */
| 'packageStructure'
/**
* The result fails the check: accepting all changes does not give the revised text, rejecting
* them does not give the original text, or a tracked change cannot be accepted or rejected.
*/
| 'unverified';ContainerReftypeSource ↗
Which STORY a location belongs to.
The body is one container; every header, footer and note is another. A path alone is ambiguous without it, because block index 0 exists in every story a document has.
type ContainerRef = {
part: 'body';
} | {
part: 'header' | 'footer';
rId: string;
} | {
part: 'footnote' | 'endnote';
noteId: number;
};ContentControlTypetypeSource ↗
Which kind of control a w:sdt is, and therefore what a value written into it must be.
type ContentControlType = 'richText' | 'plainText' | 'checkbox' | 'dropdown' | 'comboBox' | 'date' | 'picture' | 'buildingBlockGallery' | 'repeatingSection';CountBuckettypeSource ↗
A coarse count: '0', '1', '2-9', '10-99', '100-999', '1000+'.
type CountBucket = '0' | '1' | '2-9' | '10-99' | '100-999' | '1000+';CustomNodeDiagnosticCodetypeSource ↗
Why a custom node's stored payload could not be read. The node name is never reported.
type CustomNodeDiagnosticCode = 'custom-node.payload-invalid' | 'custom-node.payload-missing';DiagnosticCodetypeSource ↗
Every public diagnostic code. Codes are stable: a new one is additive, none is renamed.
type DiagnosticCode = DocumentOpenDiagnosticCode | DocumentSaveDiagnosticCode | EditDiagnosticCode | ReviewDiagnosticCode | FontDiagnosticCode | HistoryDiagnosticCode | CustomNodeDiagnosticCode | PerformanceDiagnosticCode | CollaborationDiagnosticCode;DiagnosticErrorNametypeSource ↗
The class of an unexpected exception, for a failure the engine did not name. The message is never reported, because it can quote document content.
type DiagnosticErrorName = 'Error' | 'TypeError' | 'RangeError' | 'ReferenceError' | 'SyntaxError' | 'other';DocTargettypeSource ↗
Anything an operation can be pointed at: a paragraph-relative [DocAnchor](DocAnchor), a structural [DocLocation](DocLocation), or a [DocRange](DocRange) spanning two of them.
type DocTarget = DocAnchor | DocLocation | DocRange;DocumentEditingModetypeSource ↗
How a keystroke reaches the document.
'suggesting' changes what an edit MEANS rather than whether it is allowed: typing writes w:ins and deleting writes w:del over the words it would have removed, so every change arrives as a proposal somebody else accepts or rejects.
type DocumentEditingMode = 'editing' | 'suggesting' | 'viewing';DocumentOpenDiagnostictypeSource ↗
A document opened, or failed to open.
type DocumentOpenDiagnostic = DiagnosticBase & {
readonly kind: 'document.open';
} & ({
readonly outcome: 'opened';
readonly sizeBucket: ByteSizeBucket;
readonly pagesBucket?: CountBucket;
readonly shape?: DocumentShape;
readonly durationMs: number;
} | (DiagnosticFailureDetail & {
readonly outcome: 'rejected';
readonly code: DocumentOpenDiagnosticCode;
readonly sizeBucket?: ByteSizeBucket;
readonly part?: DocumentPartKind;
}));DocumentOpenDiagnosticCodetypeSource ↗
Why a document could not be opened.
type DocumentOpenDiagnosticCode = 'open.unsupported-source' | 'open.zip-corrupt' | 'open.zip-invalid-entry-name' | 'open.zip-entry-limit' | 'open.zip-size-limit' | 'open.zip-ratio-limit' | 'open.xml-malformed' | 'open.xml-dtd-forbidden' | 'open.xml-part-size-limit' | 'open.xml-depth-limit' | 'open.xml-element-limit' | 'open.invalid-limits' | 'open.content-types-invalid' | 'open.missing-main-document' | 'open.relationships-invalid' | 'open.relationship-limit' | 'open.part-limit' | 'open.failed';DocumentOpenFailureReasontypeSource ↗
What a person can do about a document that did not open. It groups the open codes so a host can pick a message without listing every code:
- damaged: the archive or its XML is broken. Saving the file again in a desktop editor can repair it. - not-docx: the bytes are not a .docx document, or hold no main document. - too-large: the file crosses a size, count or depth limit. - blocked: the file uses XML features that the editor refuses for security. - unknown: any other failure.
type DocumentOpenFailureReason = 'damaged' | 'not-docx' | 'too-large' | 'blocked' | 'unknown';DocumentPartKindtypeSource ↗
Which kind of package part a failure is in, by its role, never by its name: a part's real name is file data. A name outside the standard layout reports 'other'.
type DocumentPartKind = 'package' | 'content-types' | 'relationships' | 'main-document' | 'glossary' | 'styles' | 'numbering' | 'settings' | 'web-settings' | 'font-table' | 'theme' | 'header' | 'footer' | 'footnotes' | 'endnotes' | 'comments' | 'people' | 'custom-xml' | 'document-properties' | 'media' | 'embedding' | 'other';DocumentProtectionEdittypeSource ↗
ST_DocProtect: the restriction a document asks for. none also stands for "no element".
type DocumentProtectionEdit = 'none' | 'readOnly' | 'comments' | 'trackedChanges' | 'forms';DocumentSaveDiagnostictypeSource ↗
A save() call returned the document, or failed. Reported for each call, by the editor that saved. A save the host does afterwards, such as an upload, is the host's to measure.
type DocumentSaveDiagnostic = DiagnosticBase & {
readonly kind: 'document.save';
} & ({
readonly outcome: 'saved';
readonly sizeBucket: ByteSizeBucket;
readonly durationMs: number;
} | (DiagnosticFailureDetail & {
readonly outcome: 'rejected';
readonly code: DocumentSaveDiagnosticCode;
readonly durationMs: number;
}));DocumentSaveDiagnosticCodetypeSource ↗
Why save() did not return the document: no document was loaded, the document changed while a pending edit finished, or the save threw.
type DocumentSaveDiagnosticCode = 'save.no-document' | 'save.document-changed' | 'save.failed';DocumentSourcetypeSource ↗
What createDocxEditor/load accept as a document: raw DOCX bytes, an existing in-memory DocumentHandle (shared/handed off), or 'blank'. The engine is byte-native (PackageModel is canonical); there is intentionally no structured-tree input, which would be lossy against the canonical package.
'blank' is Word's blank template, the same bytes blankDocumentBytes() returns from @docx-editor.dev/core/editor. OMITTING the document is not a way to ask for an empty one: with no document there is no editing surface, so every command refuses with "no document is loaded" behind a loading screen waiting for bytes that are not coming.
The two spellings serve different gestures. 'blank' is a CONSTANT, so an adapter that remounts on document identity holds one document — right for MOUNTING. blankDocumentBytes() allocates, so it starts a fresh document every call — right for File › New. Call the function into load() or host state, never inline in a prop, where a new array per render rebuilds the editor per render.
type DocumentSource = ArrayBuffer | Uint8Array | DocumentHandle | 'blank';DrawingHorizontalReferenceFrametypeSource ↗
type DrawingHorizontalReferenceFrame = 'character' | 'column' | 'insideMargin' | 'leftMargin' | 'margin' | 'outsideMargin' | 'page' | 'rightMargin';DrawingKindtypeSource ↗
Whether a drawing sits in the text flow or is positioned against a frame.
The distinction that decides everything downstream: an inline drawing occupies a character position, while an anchored one has offsets relative to a page, margin or column.
type DrawingKind = 'inline' | 'anchored';DrawingVerticalReferenceFrametypeSource ↗
type DrawingVerticalReferenceFrame = 'bottomMargin' | 'insideMargin' | 'line' | 'margin' | 'outsideMargin' | 'page' | 'paragraph' | 'topMargin';EditDiagnosticCodetypeSource ↗
Why an edit, a command or a tracked change was refused.
type EditDiagnosticCode = 'edit.read-only' | 'edit.protected-content' | 'edit.suggesting-needs-author' | 'edit.review-module-required' | 'edit.tracked-drawing-delete-unsupported' | 'edit.tracked-structure-unsupported' | 'edit.tracked-operation-unsupported' | 'edit.tracking-mode-unsupported' | 'edit.tracking-author-required' | 'edit.comment-author-required' | 'edit.tracking-unsupported-host' | 'edit.revision-unsupported' | 'edit.tracking-required' | 'edit.tracked-image-replace-unsupported' | 'edit.tracked-deleted-text-only' | 'edit.tracked-foreign-revision-unsupported' | 'edit.tracked-own-pending-change' | 'edit.picture-selected' | 'edit.cross-structure-join' | 'edit.indivisible-content' | 'edit.field-structure' | 'edit.field-unsupported' | 'edit.field-result-unsupported' | 'edit.ooxml-unsupported' | 'edit.style-not-defined' | 'edit.no-styles-defined' | 'edit.section-mark' | 'edit.table-structure-unsupported' | 'edit.table-merge-not-rectangle' | 'edit.table-split-unsupported' | 'edit.table-insert-refused' | 'edit.table-of-contents-refused' | 'edit.unsupported-content' | 'edit.operation-unsupported' | 'edit.unsupported-story' | 'edit.unmapped-change' | 'edit.stale-target' | 'edit.invalid-argument' | 'edit.resource-limit' | 'edit.refresh-in-progress' | 'edit.preview-active' | 'edit.preview-unsupported' | 'edit.preview-composing' | 'edit.preview-diverged' | 'edit.read-after-commit' | 'edit.collaboration-not-ready' | 'edit.collaboration-text-limit' | 'edit.internal-invariant' | 'edit.refused';EditorCommandtypeSource ↗
One command, as a discriminated union derived from [EditorCommands](EditorCommands).
This is what can and exec take. Widening EditorCommands widens it automatically.
type EditorCommand = {
[K in keyof EditorCommands]: {
type: K;
} & EditorCommands[K];
}[keyof EditorCommands];EditorCommandShapetypeSource ↗
In the editor a command targets the current selection unless told otherwise, and authoring is ambient — the author comes from DocxEditorConfig/the session, the way the Office JS API sources it from context — so the document layer's required target and author both become optional here.
type EditorCommandShape<T> = {
[K in keyof T]: Omit<T[K], 'target' | 'author'> & (T[K] extends {
target: infer G;
} ? {
target?: G;
} : unknown) & (T[K] extends {
author: infer A;
} ? {
author?: A;
} : unknown);
};EditorDiagnostictypeSource ↗
One anonymous diagnostic. Switch on kind to narrow code.
type EditorDiagnostic = DocumentOpenDiagnostic | EditRejectedDiagnostic | ReviewSkippedDiagnostic | FontFailedDiagnostic | HistoryDiagnosticEvent | CustomNodeDiagnosticEvent | CollaborationStatusDiagnostic | CollaborationParticipantsDiagnostic | PerformanceDiagnostic | DocumentSaveDiagnostic | SessionDiagnostic;```ts
editor.on('diagnostic', (event) => {
if (event.kind === 'edit.rejected') {
console.warn(event.code, explainDiagnostic(event.code).hint);
}
});
```EditorDiagnosticKindtypeSource ↗
The kind of every [EditorDiagnostic](EditorDiagnostic).
type EditorDiagnosticKind = EditorDiagnostic['kind'];EditorFontErrorCodetypeSource ↗
Why a font was not admitted.
Distinguished rather than collapsed because the responses differ: overLimit and malformed are the caller's own bytes, while forbidden and hashMismatch mean the source was not what it claimed and the load should not be retried. wasmUnavailable alone is a HOST fault — the shaper's WASM never loaded, diagnostic carries the remedy — surface it as a setup error.
type EditorFontErrorCode = 'initializationFailed' | 'wasmUnavailable' | 'missing' | 'forbidden' | 'overLimit' | 'malformed' | 'hashMismatch' | 'metadataMismatch' | 'fontFaceLoadFailed' | 'unsupportedFaceIndex' | 'missingFont' | 'hashInvalid' | 'fontMismatch' | 'unsupportedFace' | 'loadFailed';EditorHostDocumenttypeSource ↗
The DOM Document, wherever DOM types are loaded (every browser host).
Read from globalThis rather than named, so this contract also compiles in the engine's DOM-free lanes and on servers, where it falls back to object.
type EditorHostDocument = typeof globalThis extends {
readonly document: infer D;
} ? D : object;EditorPositiontypeSource ↗
A selection endpoint, in either vocabulary the engine resolves.
[DocAnchor](DocAnchor) addresses a paragraph by its w14:paraId, which is what an LLM or an automation script can name in a payload. [SemanticPosition](SemanticPosition) addresses it by the paragraph id the painted surface and the ops already use, with a UTF-16 offset inside it.
Neither subsumes the other. A paraId survives being written to a file and read back, so it is the one an out-of-process caller can hold; but it is OPTIONAL in the document, and ParagraphSummary.paraId says so — a paragraph the file gave no w14:paraId cannot be reached by a DocAnchor at all. The paragraph id reaches every paragraph.
type EditorPosition = DocAnchor | SemanticPosition;EditorQuerytypeSource ↗
One query, as a discriminated union derived from [EditorQueries](EditorQueries).
This is what query takes; [EditorQueryResults](EditorQueryResults) says what each answers.
type EditorQuery = {
[K in keyof EditorQueries]: {
type: K;
} & EditorQueries[K];
}[keyof EditorQueries];EditorScopetypeSource ↗
The editor is N+1 editing views: one body plus one per header/footer relationship, plus footnotes, text boxes, and other addressable regions. Commands must name their target.
This set is open-ended. Treat it as non-exhaustive as more regions become addressable.
type EditorScope = {
kind: 'body';
} | {
kind: 'headerFooter';
rId: string;
}
/**
* A footnote/endnote region.
*
* `id` encodes kind and signed note id as `footnote:<id>` or `endnote:<id>`. Use
* `formatNoteScopeId` or `parseNoteScopeId` from the store package.
*/
| {
kind: 'note';
id: string;
} | {
kind: 'frame';
id: string;
drawingNodeId: string;
hostParagraphId: string;
owner?: {
kind: 'headerFooter';
rId: string;
} | {
kind: 'note';
id: string;
};
}
/** Read-only aggregate across every view. Valid for queries, not for writes. */
| {
kind: 'all';
};EditorSelectiontypeSource ↗
A selection, in one endpoint vocabulary or the other.
The two do NOT mix: a range is a pair of paraId anchors, or a semantic anchor/head pair, and can() refuses anything else with the engine's own reason. Spelled as two arms rather than { from: EditorPosition; to: EditorPosition } for exactly that reason — the looser shape would type a mixed pair the engine rejects at runtime.
type EditorSelection = SemanticSelection | {
from: DocAnchor;
to: DocAnchor;
};EditRejectionOrigintypeSource ↗
Where a refused edit came from.
type EditRejectionOrigin = 'command' | 'input' | 'automation';ExecErrorCodetypeSource ↗
Why a write was refused, as a value to branch on.
Deliberately finer-grained than a boolean: "no-op", "target not found" and "content control is locked" are different outcomes, and a caller retrying the first should not retry the third.
type ExecErrorCode = 'notFound' | 'ambiguous' | 'locked' | 'bound' | 'typeMismatch' | 'kindMismatch' | 'outOfBounds' | 'unsupported' | 'invalidArgs';ExecResulttypeSource ↗
Every write returns this rather than boolean.
A bare boolean cannot distinguish "no-op" from "target not found" from "content control is locked", and the editor layer already throws eight distinct ContentControl error classes that a boolean would flatten.
type ExecResult = {
ok: true;
changed: boolean;
revisions?: RevisionBatchResult;
revisionAuthors?: RevisionAuthorResult;
history?: HistoryGroupOutcome;
compareDocuments?: CompareDocumentsOutcome;
} | {
ok: false;
code: ExecErrorCode;
reason: string;
target?: DocTarget;
revisions?: RevisionBatchResult;
compareDocuments?: CompareDocumentsOutcome;
revisionAuthors?: RevisionAuthorResult;
};FailureStagetypeSource ↗
Where an exception the engine did not expect was caught: the mount of an open, a later layout slice of an open, a command, a single review action, or an editing API batch.
type FailureStage = 'open-mount' | 'open-layout' | 'command' | 'review-item' | 'automation' | 'save';FontDiagnosticCodetypeSource ↗
Why a font did not load. The family name is never reported.
type FontDiagnosticCode = 'font.shaper-unavailable' | 'font.load-failed' | 'font.missing' | 'font.integrity-mismatch' | 'font.malformed' | 'font.size-limit' | 'font.unsupported-face';FormatPainterLeveltypeSource ↗
What a capture carries.
'run' is character formatting alone — the level a range INSIDE one paragraph copies. 'paragraph' adds the paragraph style and its direct paragraph properties, which is what a selection covering a paragraph mark copies. 'none' means nothing has been captured.
type FormatPainterLevel = 'none' | 'run' | 'paragraph';FormatPainterModetypeSource ↗
How long the painter stays armed.
Word's two gestures, named: a single press arms it for ONE application, a double press locks it on until the user presses Esc. 'off' is the resting state.
type FormatPainterMode = 'off' | 'once' | 'locked';FormattingChangeKindtypeSource ↗
Which property change a formatting change is, by its OOXML element. A name outside this list reports 'other'.
type FormattingChangeKind = 'rPrChange' | 'pPrChange' | 'sectPrChange' | 'tblPrChange' | 'tblPrExChange' | 'tblGridChange' | 'trPrChange' | 'tcPrChange' | 'numberingChange' | 'other';FurnitureVarianttypeSource ↗
Furniture variant selected by section title-page / even-and-odd flags.
type FurnitureVariant = 'default' | 'first' | 'even';HistoryDiagnosticCodetypeSource ↗
Why the undo history did not group edits as one step. Informational: nothing was refused.
type HistoryDiagnosticCode = 'history.split' | 'history.possible-ungrouped-gesture' | 'history.possible-fragmented-gesture';ImageContexttypeSource ↗
The selected image and what may be done to it — the imageContext query's answer.
An alias of SelectedImageState, kept as its own name because it is the query's result type and chrome is written against it.
type ImageContext = SelectedImageState;ImageResourceStatetypeSource ↗
What is known about one embedded image: validated, refused, or still decoding.
Content type is a CLAIM. Signature sniffing, structural header validation and the decode port are authoritative, and bytes that fail them never enter public state.
type ImageResourceState = {
readonly kind: 'ready';
readonly partName: string;
readonly contentId: string;
readonly resourceKey: string;
readonly validatedHandle: ValidatedImageBytesHandle;
readonly mime: RenderableImageMime;
readonly pixelWidth: number;
readonly pixelHeight: number;
readonly dpiX: number;
readonly dpiY: number;
} | {
readonly kind: 'unrenderable';
readonly partName: string | null;
readonly mime: RenderableImageMime | PreservedImageMime | 'unknown';
readonly reason: 'unsupported-format' | 'non-picture-graphic' | 'signature-mismatch' | 'decode-failed' | 'resource-limit';
} | {
readonly kind: 'external';
readonly relationshipId: string;
readonly sinkSafe: boolean;
} | {
readonly kind: 'missing';
readonly relationshipId: string;
} | {
readonly kind: 'pending';
readonly resourceKey: string;
};ImageWrapTargettypeSource ↗
Nine Word wrap menu targets (inline plus eight floating modes).
type ImageWrapTarget = 'inline' | 'square' | 'squareLeft' | 'squareRight' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';InsertableContentControlTypetypeSource ↗
The control kinds an insertion can author.
A NARROWING of [ContentControlType](ContentControlType), not a separate vocabulary: a kind read off an existing control can be handed straight back to insertContentControl. Three kinds are absent because an insertion would have to invent what they carry — a checkbox needs its two declared glyph states, a picture needs an image part, a building block gallery needs a glossary to list, and a repeating section is a container whose items have their own verbs. Reading still answers the wider type; a document may hold kinds this cannot create.
dropDownList is the same kind as dropdown, spelt as OOXML spells it. Both are accepted, so a type read off a control can be handed back without translating it — and the OOXML spelling is the one the automation protocol takes, so a caller who uses both surfaces can write that one everywhere.
type InsertableContentControlType = Extract<ContentControlType, 'richText' | 'plainText' | 'dropdown' | 'comboBox' | 'date'> | 'dropDownList';InteractionAffinitytypeSource ↗
Bidi/grapheme affinity for a text caret or hit target.
type InteractionAffinity = 'upstream' | 'downstream';InteractionOutcometypeSource ↗
The result of one interaction attempt.
A rejection carries the ENGINE's own reason, which is what lets a caller surface why an interaction was refused instead of guessing.
type InteractionOutcome<T> = {
readonly ok: true;
readonly value: T;
} | {
readonly ok: false;
readonly code: InteractionOutcomeCode;
readonly reason: string;
};InteractionOutcomeCodetypeSource ↗
Typed rejection for pending, read-only, invalid, or unsupported interaction.
type InteractionOutcomeCode = 'pendingLayout' | 'pendingSelection' | 'readOnly' | 'invalidTarget' | 'unsupported';NoteKindtypeSource ↗
Footnote vs endnote — the public Editor vocabulary.
type NoteKind = 'footnote' | 'endnote';PerformanceDiagnosticCodetypeSource ↗
Why a performance summary needs attention. Informational: nothing was refused.
type PerformanceDiagnosticCode = 'performance.slow-interaction';PreservedImageMimetypeSource ↗
Media kept in the package byte-for-byte that the painter cannot hand to an <img>. A decode port may rasterize it; without one it paints as a labelled placeholder.
type PreservedImageMime = 'image/tiff' | 'image/x-emf' | 'image/x-wmf';RenderableImageMimetypeSource ↗
Every mime the painter can hand to an <img>.
type RenderableImageMime = SupportedImageMime | VectorImageMime;ReviewChangeKindtypeSource ↗
The kind of a tracked change, as the review queue lists it.
type ReviewChangeKind = 'insert' | 'delete' | 'replace' | 'moveFrom' | 'moveTo' | 'format' | 'paragraphMark' | 'structural';ReviewDiagnosticCodetypeSource ↗
Why accepting, rejecting or re-authoring a tracked change skipped an item.
type ReviewDiagnosticCode = 'review.revision-unsupported' | 'review.incomplete-group' | 'review.retained-structure' | 'review.locked-content' | 'review.bound-content' | 'review.stale-revision';ReviewDisplayModetypeSource ↗
The views the review chrome offers, in Word's terms: the three layout projections plus Simple Markup, which reads as the proposed result with a red change bar beside every line a change touched — the document as accepting everything would leave it, and where.
type ReviewDisplayMode = RevisionDisplayMode | 'simple-markup';ReviewItemtypeSource ↗
One pending decision in the review queue: a tracked change, a comment thread, or a pro custom-node card. Discriminate on kind.
The store's own derivation (collectReviewItems) only ever produces the first two; the kind: 'custom' card is contributed by the pro review module, which recognizes the node.
type ReviewItem = ReviewRevisionItem | ReviewCommentItem | ReviewCustomItem;ReviewItemPlacementtypeSource ↗
A DISCRIMINATED union on [ReviewItemPlacementBase.kind](ReviewItemPlacementBase.kind): narrowing the kind narrows item and the kind-specific fields with it, so a consumer never writes the placement.kind === 'custom' && placement.item.kind === 'custom' double check.
type ReviewItemPlacement = ReviewCommentPlacement | ReviewRevisionPlacement | ReviewCustomPlacement;ReviewItemRevealSourcetypeSource ↗
What asked to reveal a review item. See [ReviewItemRevealEvent.source](ReviewItemRevealEvent.source).
type ReviewItemRevealSource = 'navigate' | 'host';ReviewOperationtypeSource ↗
What a tracked-change request was asked to do.
type ReviewOperation = 'accept' | 'reject' | 'reassign';ReviewPaneOpeningtypeSource ↗
When the review pane opens by itself.
- 'auto': the pane opens when a document with review items loads, and when a tracked change is made while it is closed, in both cases when the pane has items to list. With revisionsIn: 'balloons' the pane lists no tracked change and no reply to one, so tracked changes and their replies alone do not open it. - 'manual': the pane stays closed until the host or the user opens it. Use it when the host shows review items its own way, such as in balloons or margin markers.
type ReviewPaneOpening = 'auto' | 'manual';ReviewPaneOverflowtypeSource ↗
What the open review pane does when its full card column does not fit beside the page at the page's zoom.
- 'float': the pane shrinks to a strip of markers, and the open card floats over the page. - 'shrinkPage': under a fit zoom mode, the page may shrink down to the mode's minZoom (or 10%) so that the full column fits. The pane changes to the marker strip only when the column does not fit at that floor either. A fixed zoom behaves as 'float'. - 'scroll': the page keeps the size it has beside the closed pane's marker strip, and the full column stands beside it. The document and the column scroll together: the viewport scrolls sideways to reach the cards.
The setting applies to the review pane only. The navigation pane stays docked at its side in every mode: it never scrolls with the document, and it takes its room beside the page exactly as it does with no review pane.
type ReviewPaneOverflow = 'float' | 'shrinkPage' | 'scroll';ReviewRevisionKindtypeSource ↗
What kind of decision a revision card represents.
Wider than the four content wrappers, because a reviewer has to be shown every pending decision, including the ones that decorate no characters. A card the surface cannot show is a change the reviewer never learns about — and acceptAllRevisions refuses if ANY revision in the document is one the engine cannot resolve, so an invisible one makes Accept All fail for a reason nothing on screen explains.
type ReviewRevisionKind = 'insert' | 'delete'
/**
* A combined deletion and insertion decision. The built-in reader lists them separately,
* unless a review query asks to pair replacements or a custom review provider combines them.
*/
| 'replace' | 'moveFrom' | 'moveTo'
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
| 'format'
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
| 'paragraphMark'
/** A row, cell, section or grid revision. Supported row revisions are resolvable. */
| 'structural';RevisionAuthorSkipReasontypeSource ↗
Why a requested change keeps its attribution.
type RevisionAuthorSkipReason = 'unknown-revision' | 'unsupported-revision';RevisionBatchSkipDetailtypeSource ↗
The structure behind a skip.
For unsupported-revision: a refused site, a formatting change whose earlier properties were not recorded so it cannot be rejected, a read-only review item, a change with no sites, a change a content control lock keeps (locked-content), or a change in a data-bound content control (bound-content). The last two have their own codes, review.locked-content and review.bound-content; reviewCodeOfSkip reads them.
For incomplete-group, the change the decision would also decide: the other half of a move or merge (paired-change), a change inside content the decision removes (removed-content) or inside properties a reject replaces (replaced-properties), a change the decision would empty (emptied-change), a change that encloses the selected one (enclosing-change), or another site of a group the planner keeps together (grouped-change).
For retained-structure: a row kept for the table nested in it (nested-table).
type RevisionBatchSkipDetail = RevisionSiteRefusal | 'unrecorded-properties' | 'read-only' | 'no-sites' | 'paired-change' | 'removed-content' | 'replaced-properties' | 'emptied-change' | 'enclosing-change' | 'grouped-change' | 'nested-table' | 'locked-content' | 'bound-content';RevisionBatchSkipReasontypeSource ↗
Why a requested decision remains pending.
type RevisionBatchSkipReason = 'unsupported-revision' | 'incomplete-group' | 'retained-structure' | 'unknown-revision';RevisionChangedLinesMarktypeSource ↗
type RevisionChangedLinesMark = 'none' | 'leftBorder' | 'rightBorder' | 'outsideBorder';RevisionDeletionMarktypeSource ↗
type RevisionDeletionMark = RevisionMarkupMark | 'hidden' | 'caret' | 'pound';RevisionDisplaytypeSource ↗
Where tracked changes open.
- 'pane': the review pane lists tracked changes as cards beside the comments. - 'balloons': the pane lists comments only, except comments that reply to a tracked change: the change's balloon shows those. A tracked change opens in a balloon at its text when the reader clicks it, or when Next Change, Previous Change, or setActiveReviewItem(key, { announce: true }) reaches it. A replacement is one balloon. In both settings, Next Change and Previous Change stop on a replacement once.
type RevisionDisplay = 'pane' | 'balloons';RevisionDisplayModetypeSource ↗
Which revisions layout resolves before producing pages.
- all-markup shows both halves of every change. - proposed shows what the document becomes if every change is accepted. - original shows what it was before any of them.
The last two are specified as equal to accept-all and reject-all OUTPUT, which is what makes them testable, without either applying an op.
type RevisionDisplayMode = 'all-markup' | 'proposed' | 'original';RevisionMarkupColortypeSource ↗
type RevisionMarkupColor = RevisionMarkupNamedColor | 'byAuthor' | 'auto';RevisionMarkupMarktypeSource ↗
type RevisionMarkupMark = 'none' | 'colorOnly' | 'bold' | 'italic' | 'underline' | 'doubleUnderline' | 'strikethrough' | 'doubleStrikethrough';RevisionMarkupNamedColortypeSource ↗
type RevisionMarkupNamedColor = (typeof REVISION_MARKUP_COLORS)[number];RevisionMarkupOptionstypeSource ↗
Partial viewer preferences. Omitted values keep the previous value.
type RevisionMarkupOptions = {
readonly [K in keyof ResolvedRevisionMarkup]?: ResolvedRevisionMarkup[K] extends boolean ? boolean : Partial<ResolvedRevisionMarkup[K]>;
};RevisionSiteRefusaltypeSource ↗
Why a revision site cannot be resolved: no w:id or author, a content marker where content cannot be, a wrapper whose content is itself marked, a structural revision outside tables and numbering, or a move whose ranges do not pair up.
type RevisionSiteRefusal = 'unaddressed' | 'misplaced-marker' | 'nested-marker' | 'unsupported-structure' | 'unsupported-move';RevisionTypetypeSource ↗
What kind of decision a revision represents.
Wider than insert/delete/format, and it has to be. w:moveFrom/w:moveTo are not a deletion and an insertion — resolving one half alone duplicates or loses the content; w:pPr/w:rPr/w:ins|w:del decorates no characters at all and merges paragraphs when resolved; a row or cell revision is structural. A reviewer shown only three kinds is a reviewer who never learns about the rest.
type RevisionType = 'insert' | 'delete'
/** A deletion and an insertion that are one edit: text typed over a selection. */
| 'replace' | 'moveFrom' | 'moveTo'
/** `w:rPrChange` / `w:pPrChange` — the words are unchanged, their formatting is not. */
| 'format'
/** `w:pPr/w:rPr/w:ins|w:del` — a paragraph split or merge. */
| 'paragraphMark'
/** A row, cell, section or grid revision. */
| 'structural';ScrollPlacementtypeSource ↗
Where a scroll places its target in the viewport.
- 'start': near the top, like a jump to a heading. - 'center': centred. - 'centerIfNeeded': still while the target is on screen, centred when it has to move. - 'nearest': the minimum scroll, which leaves the target at the edge it came in from.
Each method that takes a placement states its own default.
type ScrollPlacement = 'start' | 'center' | 'centerIfNeeded' | 'nearest';SelectionPintypeSource ↗
Ownership token for one retained selection highlight.
type SelectionPin = symbol;SemanticTargettypeSource ↗
A PM-free semantic caret, range endpoint, or atomic selection target.
type SemanticTarget = {
readonly kind: 'text';
readonly scope: ViewScope;
readonly identity: SemanticIdentity;
readonly graphemeOffset: number;
readonly affinity: InteractionAffinity;
} | {
readonly kind: 'atomic';
readonly scope: ViewScope;
readonly objectId: string;
};SessionDiagnostictypeSource ↗
The lifecycle and activity of one editor instance, without any content.
- start: the editor was created. - active: a summary of one window of use. Sent after a minute of activity, when the page is hidden, and before end, if anything happened since the last summary. An idle editor sends none, so active is not a heartbeat. - end: the editor was destroyed, or the page closed. Carries totals for the whole session.
Edits count changes this editor committed. Refused edits are in edit.rejected, and edits that collaborators made are not counted. Sum active summaries or read end totals, not both: the totals include every summary.
type SessionDiagnostic = DiagnosticBase & {
readonly kind: 'session';
} & ({
readonly phase: 'start';
} | (SessionActivity & {
readonly phase: 'active' | 'end';
}));SetReviewChangesAuthorOptionstypeSource ↗
Selection and attribution for a change of tracked-change author. The changes stay pending.
Select exact keys from getReviewItems(), or a scope narrowed by authors. The two selections exclude each other.
type SetReviewChangesAuthorOptions = ReviewChangesAttribution & ({
keys: readonly string[];
scope?: never;
authors?: never;
} | {
keys?: never;
scope?: 'visible' | 'document';
authors?: readonly string[];
});SupportedImageMimetypeSource ↗
Raster media the decode port measures and any authoring path may write.
BMP and WebP are here for the same reason the other three are: an <img> decodes them natively, so they need a signature and a structural header and nothing else. BMP is what older documents carry; WebP is what current Word writes.
type SupportedImageMime = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp' | 'image/webp';TableBorderEdgeTargettypeSource ↗
Concrete scopes that apply a complete border spec.
type TableBorderEdgeTarget = Exclude<TableBorderTarget, 'none'>;TableBorderStyletypeSource ↗
Allowlisted OOXML table border line styles.
Kept identical to store/table-border-style.ts; table-border-style-parity.test-d.ts fails if the contract and store vocabularies drift.
type TableBorderStyle = 'single' | 'dashed' | 'dotted' | 'double' | 'triple' | 'thick';TableBorderTargettypeSource ↗
Which cell edges a table border command targets.
type TableBorderTarget = 'all' | 'outside' | 'inside' | 'none' | 'top' | 'bottom' | 'left' | 'right';TableCellVerticalAlignmenttypeSource ↗
Vertical placement of content inside selected table cells.
type TableCellVerticalAlignment = 'top' | 'center' | 'bottom';TableInteractionLabelKeytypeSource ↗
Keys for the table furniture's accessible names, resolved by tableInteractionLabel.
type TableInteractionLabelKey = 'table.insertRowBelow' | 'table.insertColumnRight' | 'table.selectTable';ThemeColorSchemetypeSource ↗
Theme colour slots (accent1, dk1, lt2, …) to hex.
type ThemeColorScheme = Readonly<Record<string, string>>;TrackedChangeFilterModetypeSource ↗
How revisions excluded by a tracked-changes predicate project into the view.
type TrackedChangeFilterMode = 'accept' | 'reject';TrackedChangePredicatetypeSource ↗
Decides whether one tracked change renders as markup.
Return true to keep the revision visible as tracked markup. Return false to render it with the selected [TrackedChangeFilterMode](TrackedChangeFilterMode) without changing the document. The callback receives the complete revision item, including its author, date, kind, text, ranges, nesting, and resolution metadata.
type TrackedChangePredicate = (revision: ReviewRevisionItem) => boolean;UnsubscribetypeSource ↗
What every subscription returns. Calling it twice is safe.
type Unsubscribe = () => void;VectorImageMimetypeSource ↗
Vector media painted straight from validated bytes. An <img> renders SVG in the browser's secure static mode — no script, no external subresource loads — so there is no decode step and no raster buffer sized by a file-supplied number.
type VectorImageMime = 'image/svg+xml';ViewScopetypeSource ↗
A concrete editing view.
type ViewScope = Exclude<EditorScope, {
kind: 'all';
}>;WatermarkLayouttypeSource ↗
How a text watermark crosses the page.
type WatermarkLayout = 'diagonal' | 'horizontal';ZoomFitTargettypeSource ↗
What a fit mode fits the page to.
One member today. It is a union rather than a boolean because Word's other two — the whole sheet including its height, and the text column inside the margins — are the same computation with a different numerator, and a later change adds one without breaking the shape a host already stores.
type ZoomFitTarget = 'pageWidth';ZoomModetypeSource ↗
Where the display scale comes from.
fixed is a number the engine holds until someone changes it. fit is a number the engine recomputes whenever the room beside the page changes — a resized window, an opened comments rail, a docked navigation pane — bounded by minZoom/maxZoom.
The bounds are what make one mode serve both cases. The default, 'auto', is this fit bounded at both ends: it leaves a page that fits at 100%, shrinks one that does not, and stops at 50% — past which it would be trading a scrollbar nobody minds for a page nobody can read.
type ZoomMode = {
readonly type: 'fixed';
} | {
readonly type: 'fit';
readonly fit: ZoomFitTarget;
readonly minZoom?: number;
readonly maxZoom?: number;
};Variables (5)
COMPARE_DOCUMENTS_ACCEPTconstSource ↗
The accept value for a file input that picks the revised document: DOCX files only.
COMPARE_DOCUMENTS_ACCEPT = ".docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document"DEFAULT_REVIEW_PANEconstSource ↗
The settings an editor starts with when nothing sets them.
DEFAULT_REVIEW_PANE: ResolvedReviewPaneDEFAULT_REVISION_MARKUPconstSource ↗
Initial viewer preferences.
DEFAULT_REVISION_MARKUP: ResolvedRevisionMarkupDIAGNOSTIC_SCHEMA_VERSIONconstSource ↗
Version of the [EditorDiagnostic](EditorDiagnostic) shape. Raised only when a field changes meaning.
DIAGNOSTIC_SCHEMA_VERSION = 1REVISION_MARKUP_COLORSconstSource ↗
Named revision colors. Identifiers are stable and never contain CSS.
REVISION_MARKUP_COLORS: readonly ['black', 'blue', 'turquoise', 'green', 'pink', 'red', 'yellow', 'white', 'darkBlue', 'teal', 'darkGreen', 'violet', 'darkRed', 'darkYellow', 'gray50', 'gray25', 'lightBlue', 'lightYellow', 'lightOrange', 'lightPurple', 'lightGreen', 'gray']