@docx-editor.dev/core

v2.36.0 · 15 published subpaths with full TypeScript signatures and JSDoc.

Subpaths

@docx-editor.dev/core/automation

`@docx-editor.dev/core/automation` — the host protocol document automation runs against.

@docx-editor.dev/core/binding

`@docx-editor.dev/core/binding` — the canonical tree ↔ ProseMirror binding.

@docx-editor.dev/core/collaboration

`@docx-editor.dev/core/collaboration` — provider-neutral collaboration contracts.

@docx-editor.dev/core/collaboration/replication

`@docx-editor.dev/core/collaboration/replication` — the seam a replication implementation binds to, not the surface a host consumes.

@docx-editor.dev/core/contracts/editor

`@docx-editor.dev/core/contracts/editor` — the `Editor` contract adapters are written against.

@docx-editor.dev/core/contracts/document

`@docx-editor.dev/core/contracts/document` — the document-level edit and query vocabulary.

@docx-editor.dev/core/contracts/interaction

`@docx-editor.dev/core/contracts/interaction` — semantic addressing and interaction outcomes.

@docx-editor.dev/core/contracts/modules

`@docx-editor.dev/core/contracts/modules` — the `EditorModule` seam.

@docx-editor.dev/core/contracts/types

`@docx-editor.dev/core/contracts/types` — the shared type vocabulary. Zero runtime.

@docx-editor.dev/core/layout

`@docx-editor.dev/core/layout` — DOM-free pagination, shaping, and hit testing.

@docx-editor.dev/core/output

`@docx-editor.dev/core/output` — painting a layout into DOM.

@docx-editor.dev/core/export

`@docx-editor.dev/core/export` — DOM-free semantic export sessions and shared resources.

@docx-editor.dev/core/store

`@docx-editor.dev/core/store` — the canonical OOXML tree and the only write path into it.

@docx-editor.dev/core/editor

`@docx-editor.dev/core/editor` — the editor facade and its chrome vocabulary.

Package root

One preservation model and one pipeline: bytes are read into a canonical typed-and-generic OOXML tree, mutated only through the store's ops, laid out DOM-free, and painted onto pages that ARE the editable surface. Content the engine does not model is carried losslessly rather than dropped, so an unfamiliar document never locks editing.

Functions (37)

bindHistoryGroupfunctionSource ↗

Bind native gesture events. Framework change handlers apply values; this binding ends groups. Native color change means value commitment, not portable popup closure. Controls without a terminal change event end on the next activation, Escape, blur, or disposal. Range/repeat controls end on pointer release/cancel or keyup, including outside releases. Terminal events close after propagation so the final value can use the same handle.

declare function bindHistoryGroup(editor: Editor, element: HTMLElement, config: HistoryGroupBindingOptions): HistoryGroupBinding;

blankDocumentBytesfunctionSource ↗

A blank document, freshly zipped per call (the caller may hand the bytes to a loader that takes ownership). Calibri 11pt and Word's Normal paragraph spacing are authored in w:docDefaults, Word's built-in style gallery in styles.xml, and US Letter geometry in the section. Word opens the saved file.

A right-to-left interface usually wants { direction: 'rtl', bidiLanguage: 'ar-SA' } (or the reader's own language), so the first paragraph is ready for right-to-left typing.

declare function blankDocumentBytes(options?: BlankDocumentOptions): Uint8Array;

chromeMenuSlotsfunctionSource ↗

Every slot a menu places, in menu order, submenus flattened. What a parity test asserts against, and what a host enumerates to know which capabilities the menu bar reaches.

declare function chromeMenuSlots(): readonly ChromeSlotId[];

commandForSlotfunctionSource ↗

The public editor command behind one chrome slot, or null when the slot is not wired to a command yet (parity-only chrome, or save — which is not a command). The single source of command truth for both adapters.

declare function commandForSlot(slotId: ChromeSlotId): EditorCommand | null;

commandForSlotValuefunctionSource ↗

The engine command for a VALUE-TYPED slot carrying the picked value, or null for a slot that does not take a value.

Two families: the run-property pickers (font.family, font.size, text.color, text.highlight) resolve to setMarkAttr, and styles.style resolves to setParagraphStyle — a paragraph styleId, not a mark. Either way the value is validated by the engine's own gate (can refuses a malformed one with invalidArgs; a styleId the document does not define is refused at exec), so a host can pass user input through unmodified.

declare function commandForSlotValue(slotId: ChromeSlotId, value: unknown): EditorCommand | null;

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)));
```

composeFontConfigurationfunctionSource ↗

Merge a base and any number of fragments into one frozen FontConfiguration.

A bare fragment IS a valid base, so the single-origin case is one argument: composeFontConfiguration(await loadDefaultFonts()). Pass extra fragments to layer origins, and set epoch/maxFontBytes/defaultFont on the base only when you need something other than the documented defaults.

- Sources dedupe first-wins by (family, weight, style), in argument order — base before fragments, earlier fragments before later ones. - Substitutions dedupe first-wins by their from face, in the same order, and every substitution whose from face has a direct source anywhere in the composition is dropped: a real face always beats a stand-in. - The result is frozen (arrays included); the byte arrays themselves are the callers' and are not copied here — the resource snapshot takes its own defensive copy.

declare function composeFontConfiguration(base: FontConfigurationBase, ...fragments: readonly FontConfigurationFragment[]): FontConfiguration;

composeFontOriginsfunctionSource ↗

Resolve a list of [FontOrigin](FontOrigin)s against one document's needs and merge them, first-wins in list order.

Origins resolve IN ORDER, one after another, and each is told which faces the ones before it can already paint ([FontResolutionRequest.resolvedFaces](FontResolutionRequest.resolvedFaces)). Sequential rather than a Promise.all, and that is a real cost — one extra origin's latency on the critical path — bought deliberately: composition is first-wins, so a later origin's copy of a face an earlier one supplied can never be used, and fetching it anyway spends the bytes twice and tells a font host which families the document uses for a result that gets thrown away. Order origins cheapest-first.

A resolver that ignores resolvedFaces still composes correctly; it just spends more.

ONE ORIGIN CANNOT SINK THE REST. An origin that throws, answers null, or answers something malformed is reported and skipped whole, and the origins around it still compose — an app that listed a flaky network origin behind a bundled one keeps the bundled faces. Skipped WHOLE: an answer is read completely before any of it is committed, so a half-ingested origin can never reach composition.

The result carries NO epoch: it is a fragment for the engine to stamp with the load sequence. A fixed epoch from here would label every document's byte set as the same one. undefined means no origin contributed anything, which is a normal answer — the document stays on the fixed measurer.

declare function composeFontOrigins(origins: readonly FontOrigin[], request: FontResolutionRequest, options?: ComposeFontOriginsOptions): Promise<FontConfigurationFragment | undefined>;

createDocxEditorfunctionSource ↗

Build an editor: the full Editor contract over a paginated surface.

Construction is separate from mounting. Pass a container and the document mounts immediately; omit it and nothing touches the DOM until attach(el) — the provider-first shape. detach() parks the live document and a later attach(el) moves it in, with undo, selection and collaboration intact, even into another window (a pop-out or an iframe).

snapshot() is version-cached: the same reference until state actually moves, with reference-stable sub-objects, so it is safe as a useSyncExternalStore source.

declare function createDocxEditor(config: DocxEditorConfig): DocxEditorInstance;
```ts
const editor = createDocxEditor({ document: bytes, modules: [reviewModule()] });
editor.attach(element);
editor.on('change', () => setDirty(true));
```

createFontSourcefunctionSource ↗

Turn font bytes you ALREADY hold into a FontSource — a file input, IndexedDB, a bundler import. loadFonts covers URLs; this covers everything else, so no caller has to hand-assemble the record or reach for a hashing helper.

Returns a typed failure instead of throwing when the descriptor or the bytes are unusable, matching loadFonts: one bad face degrades itself, never its neighbours.

declare function createFontSource(bytes: Uint8Array, request: FontFaceRequest & {
    readonly faceIndex?: number;
}, options?: {
    readonly id?: string;
    readonly maxFontBytes?: number;
}): {
    readonly source: FontSource;
} | {
    readonly failure: FontLoadFailure;
};

customFontsfunctionSource ↗

Supply application fonts without manual resolver wiring.

Loads all listed faces when the editor resolves fonts, including families the document does not use yet. This makes company fonts available in the font picker for new documents. Faces supplied by earlier origins are skipped by family, weight, and style; family matching ignores case. URLs always come from sources, never from document text.

Uses [loadFonts](loadFonts) for validation, optional hash checks, and browser caching. The editor registers the returned bytes under private aliases. This function does not change the document's selected fonts or register page-wide family names.

Constructing the resolver does not fetch. Cancellation of the document load rejects with signal.reason, without warnings or onFailure calls. Other face failures are reported once per resolution, and successful faces remain available to the editor.

ts const fonts = useFonts( customFonts({ sources: companyFontFiles, onFailure: reportFontFailure }), packagedFonts(), googleFonts(), );

Use [loadFonts](loadFonts) directly to load every listed face eagerly.

declare function customFonts(options: CustomFontsOptions): CustomFontsResolver;

deferFontsfunctionSource ↗

Load an origin's faces after the document first paints, instead of before.

The editor opens the document with the faces the other origins supply, then lays it out again when these arrive. Use it for faces that are large or slow to fetch. Leave an origin unwrapped to install its faces with the document's other waiting fonts: a large document (over about 512 KB of uncompressed content) waits up to 2 seconds for them before its first paint.

ts const fonts = [packagedFonts(), deferFonts(myBrandFonts())];

A document export that receives this origin waits for its faces, so exported pages use them. The faces never change the configuration settings, such as defaultFont or maxFontBytes: those come from the origins that answer at once, so the document does not change its default font after it paints.

declare function deferFonts(origin: FontOrigin): MarkedFontResolver;

defineFontResolverfunctionSource ↗

Mark a function as an on-demand [FontResolver](FontResolver).

Wrap every resolver you put in a fonts list — useFonts(...), useDocxSource's fonts option, composeFontOrigins. The fonts PROP needs no marking, because a function there is always a resolver; a list also accepts the older zero-argument loader form ({ fonts: defaultFonts }), and this is what keeps the two apart.

Returns the same function object, mutated, so the mark survives being passed around and a marked resolver stays === to itself. It does NOT survive .bind() or being wrapped: both make a new function object. Re-mark the result.

ts const brandFonts = defineFontResolver(async ({ families }) => ({ sources: await loadMine(families), }));

Throws a TypeError on a frozen or sealed function, which cannot take the mark. That is deliberate: returning it unmarked would compile — the return TYPE says marked — and then lose every font at runtime.

declare function defineFontResolver<T extends FontResolver>(resolve: T): MarkedFontResolver<T>;

diagnosticCausesfunctionSource ↗

Every engine reason a diagnostic can carry as its cause. Causes are the engine's own reasons and can change between engine versions; match on the public code, and read the cause when you report or fix a failure.

declare function diagnosticCauses(): readonly string[];

diagnosticCodeOfRefusalfunctionSource ↗

The public code for a refused edit. A raw reason the tables do not know, such as a sentence written at one call site, falls back to the exec result code and then to edit.refused. The raw text never leaves this function.

declare function diagnosticCodeOfRefusal(reason: string, execCode?: ExecErrorCode): EditDiagnosticCode;
```ts
const reason = editor.snapshot().lastRejection;
if (reason) console.warn(explainDiagnostic(diagnosticCodeOfRefusal(reason)).hint);
```

diagnosticCodesfunctionSource ↗

Every public code, in declaration order. For coverage tests and catalogs.

declare function diagnosticCodes(): readonly DiagnosticCode[];

diagnosticCommandsfunctionSource ↗

Every built-in command type a diagnostic can name in its command field. A telemetry check uses it to refuse any other value.

declare function diagnosticCommands(): readonly EditorCommand['type'][];

explainDiagnosticfunctionSource ↗

What a diagnostic code means and what to do about it.

declare function explainDiagnostic(code: DiagnosticCode): DiagnosticExplanation;
```ts
editor.on('diagnostic', (event) => {
  if (event.kind === 'edit.rejected') console.warn(explainDiagnostic(event.code).hint);
});
```

initialChromePrintSettingsfunctionSource ↗

The settings a print form starts with: the editor's current display mode, with comments shown, as the PDF converter does by default. All Markup prints comments in a pane beside each page. The other modes print them as PDF annotations on the commented text.

declare function initialChromePrintSettings(snapshot: Pick<EditorSnapshot, 'reviewDisplayMode'> | null | undefined): ResolvedChromePrintSettings;

isChromePrintShortcutfunctionSource ↗

True for the print shortcut: Cmd+P on Apple platforms, Ctrl+P elsewhere. On macOS, Ctrl+P moves the caret to the previous line, so it is not a print shortcut there. The P key matches by code too when it types no Latin letter, as on Cyrillic or Hebrew layouts.

declare function isChromePrintShortcut(event: KeyboardEvent): boolean;

isFontResolverfunctionSource ↗

Whether a value is a function marked by [defineFontResolver](defineFontResolver).

False for an unmarked function, which callers read as a zero-argument loader. Calling a resolver that way reads request.defaultFamily off undefined and throws, so the callers that make this choice say so rather than swallowing it — and the type-level mark on [MarkedFontResolver](MarkedFontResolver) is there to stop it reaching runtime at all.

declare function isFontResolver(value: unknown): value is MarkedFontResolver;

loadFontsfunctionSource ↗

Fetch app-specified font URLs into verified, cache-backed FontSources.

Fetches ONLY the URLs listed — never a default host or engine-chosen CDN — and never rejects for a per-source failure: the result carries every admitted source and a typed entry for every drop. Cancellation instead rejects with signal.reason. Compose the result with composeFontConfiguration.

declare function loadFonts(request: LoadFontsRequest): Promise<LoadFontsResult>;

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;

reviewCodeOfRefusalfunctionSource ↗

The review code a tracked-change refusal leads with, such as retained-structure: ... for a row that stays to keep a nested table, or null when the refusal names no review reason. A card or an Accept All or Reject All that a content control lock or a data binding keeps gives review.locked-content or review.bound-content.

declare function reviewCodeOfRefusal(reason: string): ReviewDiagnosticCode | null;
```ts
const result = editor.exec({ type: 'resolveAllReviewChanges', action: 'reject' });
if (!result.ok) console.warn(reviewCodeOfRefusal(result.reason));
```

reviewCodeOfSkipfunctionSource ↗

The public code for a skipped tracked change, such as an entry of reviewChangesResolved's skipped list: the detail's own code when it has one (review.locked-content, review.bound-content), else the reason's.

declare function reviewCodeOfSkip(skip: {
    readonly reason: string;
    readonly detail?: string;
}): ReviewDiagnosticCode | null;
```ts
editor.on('reviewChangesResolved', ({ skipped }) => {
  for (const skip of skipped) console.warn(reviewCodeOfSkip(skip));
});
```

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>;

runChromeExportfunctionSource ↗

Saves the current document and converts those bytes through the configured handler. Missing handlers fail before saving. Conversion never changes the editor document. settings overrides the captured view for PDF conversion, such as print settings.

declare function runChromeExport(editor: Pick<Editor, 'save'> & Partial<Pick<DocxEditorInstance, 'snapshot' | 'getReviewAuthors'>>, format: ChromeExportFormat, handlers?: ChromeExportHandlers, settings?: ChromePrintSettings): Promise<ChromeExportResult>;

runChromePrintfunctionSource ↗

Saves the current document, converts it with the configured PDF handler, and prepares the result for printing. Uses the same handler and checks as File Export PDF, so a missing handler rejects with ChromeExportError before the document is saved. Saving commits pending form input and can refresh field results with an undo step. container receives the hidden print frame. For an editor inside a modal dialog, pass an element inside that dialog. settings carries the user's print settings, such as the display mode and whether comments print. Omitted settings keep the current view.

declare function runChromePrint(editor: Pick<Editor, 'save'> & Partial<Pick<DocxEditorInstance, 'snapshot' | 'getReviewAuthors'>>, handlers?: ChromeExportHandlers, container?: Document | Element, settings?: ChromePrintSettings): Promise<ChromePrintJob>;

runToolbarCommandfunctionSource ↗

Run a toolbar control: can first, then exec only if it said yes. Returns the engine's refusal untouched when it said no, so a caller cannot mistake a declined command for a no-op.

declare function runToolbarCommand(editor: Editor | null, id: ChromeSlotId): ExecResult;

runToolbarCommandfunctionSource ↗

declare function runToolbarCommand(editor: Editor | null, id: Exclude<ChromeSlotId, ToolbarValueSlot>, options: EditorExecOptions): ExecResult;

runToolbarCommandfunctionSource ↗

declare function runToolbarCommand<K extends keyof ToolbarValueMap>(editor: Editor | null, id: K, value: ToolbarValueMap[NoInfer<K>], options?: EditorExecOptions): ExecResult;

runToolbarCommandfunctionSource ↗

declare function runToolbarCommand(editor: Editor | null, id: TableChromeSlotId, value: unknown, options?: EditorExecOptions): ExecResult;

runToolbarCommandfunctionSource ↗

declare function runToolbarCommand(editor: Editor | null, id: ChromeSlotId, value: undefined, options: EditorExecOptions): ExecResult;

toolbarCommandStatefunctionSource ↗

Ask the engine whether one control should be enabled.

declare function toolbarCommandState(editor: Editor | null, id: ChromeSlotId): ToolbarCommandState;

Classes (3)

ChromeExportErrorclassSource ↗

An export has no configured converter.

declare class ChromeExportError extends Error
MemberTypeSummary
(constructor)Constructs a new instance of the `ChromeExportError` class
code
formatChromeExportFormat

ChromePrintErrorclassSource ↗

The browser could not print the converted PDF. The PDF at ChromePrintJob.url is still available, so the user can open it and print from the PDF viewer.

declare class ChromePrintError extends Error
MemberTypeSummary
(constructor)Constructs a new instance of the `ChromePrintError` class
codeChromePrintErrorCodeWhy the browser could not print.

EditorFontErrorclassSource ↗

Typed adapter error reported both through onFontError and accessible alert UI.

declare class EditorFontError extends Error
MemberTypeSummary
(constructor)Constructs a new instance of the `EditorFontError` class
codeEditorFontErrorCode
diagnostic?string
namestring
request?FontFaceRequest

Interfaces (218)

AnchorHighlightAnimationinterfaceSource ↗

Opacity fade settings. Reduced motion limits fades to 125 milliseconds.

interface AnchorHighlightAnimation
MemberTypeSummary
durationMs?numberFade duration in milliseconds. Default: 180. Must be finite and between 0 and 10000.
easing?stringCSS timing function for both fades. Defaults to --doc-motion-ease-out. This option does not accept CSS variables.
exitDurationMs?numberAutomatic 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
MemberTypeSummary
animation?boolean | AnchorHighlightAnimationDefault: true, a 180-millisecond fade. False disables motion. Repeated calls for the same paragraph do not restart the fade.
borderColor?stringCSS border color. Defaults to color. Use an alpha color for a translucent border; opacity controls only the fill.
borderRadius?numberCorner radius in CSS pixels at 100% zoom. Default: 6. Must be finite and nonnegative.
borderStyle?'solid' | 'dashed' | 'dotted'Border pattern. Default: solid.
borderWidth?numberBorder width in CSS pixels at 100% zoom. Default: 0. Finite and nonnegative.
className?stringOptional CSS classes for shadows or patterns. The editor controls highlight placement and size.
color?stringCSS 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?numberFill opacity, from 0 to 1. Default: 0.14. Does not change document text opacity.
padding?numberExtra space on each edge, in CSS pixels at 100% zoom. Default: 4. Must be finite and nonnegative.
timeoutMs?number | nullMilliseconds before dismissal starts. Default: 3000. Set `null` to keep highlights until you dismiss them. Maximum: 2147483647.

ApplyResultinterfaceSource ↗

What applying a batch of edits produced: the new document, and a per-edit verdict.

results is positionally aligned with the input, so an edit that failed is identified by its index rather than by anything the caller has to correlate.

interface ApplyResult
MemberTypeSummary
docDocxDocument
resultsExecResult[]One per edit, positionally aligned with the input.

AttachOptionsinterfaceSource ↗

How [DocxEditorInstance.attach](DocxEditorInstance.attach) moves an open document.

interface AttachOptions
```ts
// Bring the editor home from a pop-out and keep typing there.
editor.attach(mainSlot, { focus: true });
```
MemberTypeSummary
focus?booleanFocus the pages after the move, so the caret shows and typing continues. Default: focus returns only when the pages had it before the move or the `detach()`. A first mount from bytes does not take focus.

AuthoredNoteNumberinginterfaceSource ↗

Authored note-numbering fields as Word's properties dialog writes them.

interface AuthoredNoteNumbering
MemberTypeSummary
numFmt?string
numRestart?string
numStart?number
pos?string

BlankDocumentOptionsinterfaceSource ↗

How a blank document starts.

interface BlankDocumentOptions
MemberTypeSummary
bidiLanguage?stringThe language of right-to-left and complex-script text, as a BCP 47 tag such as `ar-SA` or `he-IL`, written as the run defaults' `w:lang/@w:bidi`. Layout follows it: European digits in an Arabic-script language draw in the Latin face. A value that is not a language tag is ignored.
direction?'ltr' | 'rtl'`'rtl'` starts the document right to left: its paragraphs (`w:bidi` in the paragraph defaults) and its section (`w:sectPr/w:bidi`) read right to left, as a new document does when a right-to-left editing language is the default. `'ltr'` is the default.

BookmarkChromeHandlersinterfaceSource ↗

Host chrome for bookmarks.

interface BookmarkChromeHandlers
MemberTypeSummary
onRequest?() => voidOpen the Bookmark dialog for the selection: the `openBookmarkDialog` command, which the Insert menu row and Ctrl/Cmd+Shift+F5 send.

BookmarkMarkInfointerfaceSource ↗

One painted bookmark mark, as BookmarkMarkOptions callbacks see it.

interface BookmarkMarkInfo
MemberTypeSummary
edge'start' | 'end' | 'point'Which mark this is: the start bracket, the end bracket, or a point bookmark's I-beam.
hiddenbooleanWhether the name starts with an underscore.
namestringThe bookmark's name as the document writes it.
storyBookmarkStoryThe story the bookmark is in.

BookmarkMarkOptionsinterfaceSource ↗

How Show bookmarks paints its marks. Register with setBookmarkMarks.

interface BookmarkMarkOptions
MemberTypeSummary
decorate?(element: HTMLElement, mark: BookmarkMarkInfo) => HTMLElement | voidAdjust each mark before it is placed: add a class, a `title` tooltip, or attributes. Return another element to replace the mark. The editor positions whatever comes back. Marks ignore the pointer; set `pointer-events: auto` on a mark that shows a tooltip.
include?'visible' | 'all' | ((bookmark: Omit<BookmarkMarkInfo, 'edge'>) => boolean)Which bookmarks get marks: `'visible'` (the default) skips hidden bookmarks, `'all'` includes them, and a function decides per bookmark.
print?booleanKeep the marks when the browser prints the page. Exports never include them.

BookmarkSummaryinterfaceSource ↗

One bookmark, as the bookmarks query lists it.

interface BookmarkSummary
MemberTypeSummary
atSelectionbooleanWhether the start of the selection is inside the bookmark, edges included.
duplicatesnumberHow 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.
emptybooleanWhether the bookmark marks a point rather than a range of text.
hiddenbooleanWhether the name starts with an underscore. Hidden bookmarks mark application targets.
namestringThe name as the document writes it. Names compare without case.
ordernumberPosition in document order: the main text first, then headers, footers and notes. Sort by this value to list bookmarks by location.
placeBookmarkPlaceThe same story, telling a header from a footer and a footnote from an endnote.
storyBookmarkStoryThe story the bookmark starts in.

ChromeExportHandlersinterfaceSource ↗

Conversion handlers for File Export. Install the corresponding converter package. Use exportMarkdown for Markdown. PDF requires exportPdf on a Node.js server. Browser hosts supply a PDF handler that calls that server after the user selects Export.

interface ChromeExportHandlers
MemberTypeSummary
markdown?(source: Uint8Array) => Promise<{ readonly markdown: string; }>Returns continuous document Markdown. Page output is not downloaded.
pdf?(source: Uint8Array, view?: ChromeExportView) => Promise<{ readonly bytes: Uint8Array; }>Returns PDF bytes from `@docx-editor.dev/docx-to-pdf` on Node.js.

ChromeExportResultinterfaceSource ↗

Download data from a completed conversion.

interface ChromeExportResult
MemberTypeSummary
bytesUint8Array
extension'md' | 'pdf'
mimeTypestring

ChromeExportViewinterfaceSource ↗

Viewer settings captured before PDF conversion.

interface ChromeExportView
MemberTypeSummary
comments?booleanWhether the PDF shows comments. Set from the print settings the user chose. Pass it to `exportPdf` as `comments`. Absent means the converter default, which shows comments.
displayModeReviewDisplayMode
revisionAuthorSlots?Readonly<Record<string, number>>Stable session slots, including gaps left by removed authors.
revisionMarkupResolvedRevisionMarkup

ChromeMenuinterfaceSource ↗

One menu of the menu bar.

interface ChromeMenu
MemberTypeSummary
entriesreadonly ChromeMenuEntry[]
idChromeMenuId
labelKeystring

ChromeMenuItemEntryinterfaceSource ↗

A row that runs one chrome slot.

interface ChromeMenuItemEntry
MemberTypeSummary
kind'item'
labelKey?stringPlain-label override for this row.
picker?'tableGrid'The row opens a size PICKER instead of firing on click — Word's insert-table grid. The slot still owns the label, the icon and the enabled state; only the dispatch differs, and the picked size is what the host sends.
shortcutKey?stringi18n key of the shortcut shown right-aligned on the row (`toolbar.saveShortcut`).
slotChromeSlotId

ChromeMenuSeparatorEntryinterfaceSource ↗

A horizontal rule between groups of rows.

interface ChromeMenuSeparatorEntry
MemberTypeSummary
kind'separator'

ChromeMenuSubmenuEntryinterfaceSource ↗

A row that opens a nested panel of rows (Insert › Break).

It carries its own label and icon rather than a slot, because a submenu PARENT has no command: clicking it opens the panel. Giving it a slot would mint a public id for a control that can never be enabled, and toolbarCommandState would have to invent an answer about it.

interface ChromeMenuSubmenuEntry
MemberTypeSummary
itemsreadonly ChromeMenuEntry[]
kind'submenu'
labelKeystring
pathsreadonly string[] | null

ChromePrintJobinterfaceSource ↗

A converted PDF, ready for the browser print dialog. Call dispose() when the job ends: it removes the print frame and revokes url.

interface ChromePrintJob
MemberTypeSummary
disposeRemoves the print frame and revokes `url`. Later `print()` calls reject.
printOpens the browser print dialog for the PDF from a hidden frame. Rejects with `ChromePrintError` when the browser has no PDF viewer, the frame cannot load the PDF, or the job has ended. A browser without a PDF viewer would download the PDF instead of loading it, so the frame is not created in that case.
urlstringAn object URL for the PDF. It stays valid until `dispose()`.

ChromePrintOptionsinterfaceSource ↗

Options for ChromePrintJob.print.

interface ChromePrintOptions
MemberTypeSummary
beforePrint?() => void | Promise<void>Runs after the PDF loads and before the print dialog opens. Close any modal dialog here: a modal dialog makes the rest of the page, including the print frame, inert.

ChromePrintSettingsinterfaceSource ↗

Settings the user picks before printing. Each omitted setting keeps the editor's current view: the review display mode, and comments shown.

interface ChromePrintSettings
MemberTypeSummary
comments?booleanWhether the PDF shows comments. All Markup prints them in a pane beside each page; the other modes print them as annotations on the commented text.
displayMode?ReviewDisplayModeWhich markup prints, as on the Review tab.

ClearAnchorHighlightOptionsinterfaceSource ↗

Explicit highlight dismissal.

interface ClearAnchorHighlightOptions
MemberTypeSummary
animation?boolean | AnchorHighlightAnimationDefaults to the last highlight call's exit animation. False removes highlights immediately.

CollaborationModuleContributioninterfaceSource ↗

What a collaboration module contributes: the replica the surface attaches.

interface CollaborationModuleContribution
MemberTypeSummary
sessionEditorCollaborationSessionA ready session. The host creates the Yjs room, then wraps it with `collaborationModule({ session })`.

CollaborationParticipantsDiagnosticinterfaceSource ↗

The number of people in the collaboration room changed.

interface CollaborationParticipantsDiagnostic extends DiagnosticBase
MemberTypeSummary
countnumberPeople 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
MemberTypeSummary
code?CollaborationDiagnosticCodeWhy the session holds `status`, when something is wrong.
connectMs?numberMilliseconds 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'
previousCollaborationStatus | 'none'The status before this change; `'none'` for the first status the editor saw.
recoveringbooleanTrue when the session will heal on its own; wait instead of rejoining.
statusCollaborationStatus

CommentDraftChromeHandlersinterfaceSource ↗

Host chrome for comment drafts: the review rail, or the host's own comment UI.

interface CommentDraftChromeHandlers
MemberTypeSummary
onRequest?() => voidOpen a comment draft on the selection: the `review.addComment` control's press. The handler takes no arguments. It reads the selection with `getSelectionPlacement`, and can pin it with `retainSelection` while the draft is open. The most recent registration receives each request.

CommentRecordinterfaceSource ↗

One comment as authored in word/comments.xml.

interface CommentRecord
MemberTypeSummary
authorstring
blocksreadonly OoxmlElement[]Body paragraphs, as tree nodes, so the surface renders measured text rather than a string.
date?string
idstring
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
MemberTypeSummary
onRequest?(session: CompareDocumentsDialogSession) => void

CompareDocumentsDialoginterfaceSource ↗

Compare documents dialog supplied by the review module.

interface CompareDocumentsDialog
MemberTypeSummary
destroy
open

CompareDocumentsDialogHostinterfaceSource ↗

What the Compare documents dialog may use: its session, mount, and strings.

interface CompareDocumentsDialogHost extends CompareDocumentsDialogSession
MemberTypeSummary
containerHTMLElement
translate?(key: string) => string | undefined

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
MemberTypeSummary
applyCompare 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.
canApplyWhether a compare can run now.
cancelClose the dialog. A running background compare stops, and nothing changes.
cancelablebooleanWhether `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.
defaultAuthorstringThe author name the dialog offers first: the editor's author, or an empty string.
originalHasTrackedChangesbooleanWhether 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.
signalAbortSignalAborts on close, replacement, load, detach, or destroy.

CompareDocumentsEngineOptionsinterfaceSource ↗

Options of one document compare.

interface CompareDocumentsEngineOptions
MemberTypeSummary
authorName?stringAuthor recorded on every revision. The engine picks a default when absent, empty, or only white space.
detectFormatChanges?booleanRecord formatting differences as formatting revisions. Default `true`.
removeDateAndTime?booleanOmit the revision timestamps. Default `false`.

CompareDocumentsProgressinterfaceSource ↗

How far a background compare is.

interface CompareDocumentsProgress
MemberTypeSummary
fractionnumberThe share of the work done, from 0 to 1. It never decreases.
phaseCompareDocumentsPhaseThe step that runs now.

CompareDocumentsRequestinterfaceSource ↗

What one compare request carries: the revised DOCX and its options.

interface CompareDocumentsRequest
MemberTypeSummary
authorName?stringAuthor 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?booleanRecord formatting differences as formatting revisions. Default `true`.
removeDateAndTime?booleanWrite the revisions without dates. Default `false`.
revisedUint8ArrayThe revised document's DOCX bytes. The open document is the original.

ComposeFontOriginsOptionsinterfaceSource ↗

Diagnostics hook for ordered font-origin composition.

interface ComposeFontOriginsOptions
MemberTypeSummary
onOriginFailure?(failure: FontOriginFailure) => voidFire-and-forget diagnostics; returned promises are observed but do not delay resolution.

ContentControlinterfaceSource ↗

Structured document tag (w:sdt).

interface ContentControl
MemberTypeSummary
alias?string
contentreadonly Block[]
controlTypeContentControlType
idstring
kind'contentControl'
locked?boolean
tag?string

ContentControlFilterinterfaceSource ↗

Narrows a content-control query. Fields combine with AND; an empty filter matches every control.

interface ContentControlFilter
MemberTypeSummary
alias?string
controlType?ContentControlType
tag?string

ContentControlSummaryinterfaceSource ↗

A content control reduced to what a listing needs: its identity, kind, and lock state.

interface ContentControlSummary
MemberTypeSummary
alias?string
controlTypeContentControlType
idstring
locked?boolean
tag?string

ContentControlWidgetChromeHandlersinterfaceSource ↗

Framework rendering for content-control value widgets.

interface ContentControlWidgetChromeHandlers
MemberTypeSummary
kinds?readonly ContentControlWidgetSession['kind'][]Session kinds this renderer takes. Defaults to `dropdown`, `comboBox`, `date` and `buildingBlockGallery` (the list-shaped sessions), so a renderer written for the pop-ups never receives a checkbox or picture press it does not expect. Include `'checkbox'` to take those presses too; the engine then leaves the toggle to `apply`, and a press nobody takes toggles the box as before. Include `'picture'` to own the image pick; a press nobody takes opens the engine's own file picker.
onRequest?(session: ContentControlWidgetSession) => void

ContentControlWidgetSessioninterfaceSource ↗

A core-owned content-control value edit.

kind names the widget that was pressed. A checkbox session carries the current state as 'true' / 'false' and expects the opposite (or the same) back through apply; the packaged pop-ups apply the toggle at once, so a host only sees it when it renders the widget itself. A buildingBlockGallery session is a list session: items are the glossary's blocks for the control's gallery, named by w:docPartPr/w:name, and apply takes a name. A picture session carries the control's drawing node id as value and takes new image bytes through replaceImage; apply refuses, since no text stands for an image.

interface ContentControlWidgetSession
MemberTypeSummary
anchorHTMLElement | null
apply
canApply
cancel
controlIdstring
itemsreadonly { readonly displayText: string; readonly value: string; }[]
kind'dropdown' | 'comboBox' | 'date' | 'checkbox' | 'picture' | 'buildingBlockGallery'
localestringThe editor's regional locale, for a date picker's month, weekday and first-day rules.
replaceImagePicture sessions only: replace the control's image with these bytes. The engine sniffs the format (PNG, JPEG, GIF, BMP or WebP) and keeps the drawing's size. Resolves false when the bytes are not a supported image, the control no longer takes a write, or the document is open for viewing or suggesting. Cancellation during decoding prevents the commit; only one replacement may be pending for a session.
signalAbortSignal
valuestring

ContentLockPolicyinterfaceSource ↗

An opt-in relaxation of ST_Lock for hosts that protect WHAT a control says, not how it looks.

ECMA-376 contentLocked forbids editing the control's contents and Word reads formatting as part of that, which is the default here. A host that puts protected text in a control (a template placeholder the user must not retype) but lets authors style it sets allowFormattingInLockedContent: a run-property write (bold, colour, font, size, highlight …), on runs or on a paragraph mark, then passes the CONTENT half of the lock. The exception never admits a property that hides text (w:vanish, w:specVanish, w:webHidden), which the run-property vocabulary refuses today anyway. Text edits, deletion of the content, paragraph properties, removal of a sdtLocked wrapper and w:dataBinding refusals are unchanged.

interface ContentLockPolicy
MemberTypeSummary
allowFormattingInLockedContent?booleanLet run formatting pass a content lock; text and removal stay refused. Default `false`.

ContentTypeIndexinterfaceSource ↗

The resolved lookup: Override by case-folded part name, Default by case-insensitive extension.

interface ContentTypeIndex
MemberTypeSummary
defaultsReadonlyMap<string, string>ext key - single MIME (identical duplicates collapsed).
overridesReadonlyMap<string, string>case-folded part name - MIME.

CustomFontsOptionsinterfaceSource ↗

Options for loading application fonts when the editor resolves its font configuration.

interface CustomFontsOptions extends Omit<LoadFontsRequest, 'signal'>
MemberTypeSummary
onFailure?(failure: FontLoadFailure) => voidReports each failed face. Defaults to a console warning. Cancellation does not call this handler.

CustomNodeDiagnosticEventinterfaceSource ↗

A custom node's stored payload could not be read. The node and its data are not named.

interface CustomNodeDiagnosticEvent extends DiagnosticBase
MemberTypeSummary
codeCustomNodeDiagnosticCode
kind'custom-node'

DiagnosticBaseinterfaceSource ↗

Fields every diagnostic carries.

interface DiagnosticBase
MemberTypeSummary
editorSessionIdstringRandom 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.
schemaVersionnumber[DIAGNOSTIC_SCHEMA_VERSION](DIAGNOSTIC_SCHEMA_VERSION) when the event was made.
timenumberMilliseconds 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
MemberTypeSummary
docsstringThe documentation anchor for this code, such as `…/guides/diagnostics#edit-read-only`.
hintstringOne 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
MemberTypeSummary
cause?stringThe 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?DiagnosticErrorNameThe class of the exception when `cause` is `exception`. Its message is never reported.
stage?FailureStageWhere 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
MemberTypeSummary
occurrence?numberOpt-in disambiguation. Omit to require uniqueness.
paraIdstring

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
MemberTypeSummary
endOffsetnumber
endParagraphIdstringMay sit in a later paragraph: the range markers are independent elements.
partstringCanonical part name of the story the range lives in, e.g. `/word/document.xml`.
startOffsetnumber
startParagraphIdstring

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
MemberTypeSummary
anchor?DocAnchorRangeWhere the comment is anchored, absent when the file gave it no usable range.
authorstring
date?stringOPTIONAL, 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.
idstring
orphaned?booleanTrue 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
textstring

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
MemberTypeSummary
acceptAllRevisionsRecord<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.
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.
rejectAllRevisionsRecord<never, never>
rejectRevision{ id: number; part?: 'body' | 'footnote' | 'endnote'; noteId?: number; }
removeContentControl{ 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
MemberTypeSummary
containerContainerRef
offset?number
pathnumber[]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
MemberTypeSummary
comments{ resolved?: boolean; }
contentControls{ filter?: ContentControlFilter; }
findText{ text: string; container?: ContainerRef; }
paragraphs{ container?: ContainerRef; }
revisions{ part?: 'body' | 'footnote' | 'endnote'; }
stylesRecord<never, never>
variablesRecord<never, never>

DocQueryResultsinterfaceSource ↗

What each query returns. Keyed identically to DocQueries.

interface DocQueryResults
MemberTypeSummary
commentsreadonly DocComment[]
contentControlsreadonly ContentControlSummary[]
findTextreadonly DocRange[]
paragraphsreadonly ParagraphSummary[]
revisionsreadonly Revision[]
stylesStyleDefinitions
variablesReadonly<Record<string, string>>

DocRangeinterfaceSource ↗

A span between two positions. The endpoints may be addressed either way, independently.

interface DocRange
MemberTypeSummary
fromDocAnchor | DocLocation
toDocAnchor | DocLocation

DocumentBodyinterfaceSource ↗

The main story: its blocks in reading order, plus the sections derived from them.

interface DocumentBody
MemberTypeSummary
contentreadonly Block[]
sectionsreadonly 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
MemberTypeSummary
created?readonly string[]Block ids created/deleted/edited by this change, when the engine reports them.
deleted?readonly string[]
dirty?readonly string[]
revisionnumberPackage 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
MemberTypeSummary
revisionnumberPackage 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
MemberTypeSummary
codeDocumentOpenDiagnosticCodeThe stable open code, the same one the `document.open` diagnostic reports.
reasonDocumentOpenFailureReasonThe group of [DocumentOpenFailure.code](DocumentOpenFailure.code) that picks the message.

DocumentProtectionStateinterfaceSource ↗

The document's protection, as the file states it.

interface DocumentProtectionState
MemberTypeSummary
editDocumentProtectionEditThe restriction named by `@w:edit`; `none` when absent or unrecognised.
enforcedbooleanTrue when `@w:enforcement` puts that restriction in force. Always false for `none`.
passwordbooleanTrue when lifting the protection would ask for a password in Word.

DocumentShapeinterfaceSource ↗

The bucketed shape of an opened document.

interface DocumentShape
MemberTypeSummary
embeddedFontsCountBucket
paragraphsCountBucket
partsCountBucketXML parts in the package.
reviewItemsCountBucketTracked 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
MemberTypeSummary
bodyDocumentBody
commentsreadonly DocComment[]
revisionsreadonly Revision[]
stylesStyleDefinitions
theme?Theme

DocxDocumentJSONinterfaceSource ↗

The JSON-safe projection of a document.

interface DocxDocumentJSON
MemberTypeSummary
(member-0)

DocxEditorConfiginterfaceSource ↗

Everything [createDocxEditor](createDocxEditor) accepts. Every field is optional.

container is the one that changes the shape of the whole lifecycle: omitting it produces an instance that does no DOM work until attach(el), which is what lets a provider own the editor before any component has rendered a mount point.

interface DocxEditorConfig
MemberTypeSummary
author?string
container?HTMLElementThe element the paginated surface mounts into. The surface owns this subtree.
contentLockPolicy?ContentLockPolicyOpt-in relaxation of content-control `w:lock`: with `allowFormattingInLockedContent`, `contentLocked` / `sdtContentLocked` controls refuse typing, pasting and deleting their text as always, but accept run formatting (toolbar, shortcuts, automation `setFont`) — for hosts that protect WHAT a control says and let authors style it. Default: Word's behaviour, where a content lock refuses every edit including formatting.
document?DocumentSourceA document to load at construction: DOCX bytes, or `'blank'` for Word's blank template. A `DocumentHandle` cannot be re-opened (the handle is identity, not content), so passing one emits a typed `error` event rather than silently loading nothing. Omitting this mounts NO document, which is not the same as an empty one.
fieldResults?FieldResultsModeHow the reader edits saved field results.
fonts?FontConfiguration | FontConfigurationFragment | FontResolverFont bytes for Word-accurate (HarfBuzz-shaped) line wrap and pagination. Omitted, layout falls back to a fixed-width estimate; fonts embedded in the document are wired in automatically either way. For Word's default faces (Calibri, Times New Roman, …) pass `await loadDefaultFonts()` from `@docx-editor.dev/fonts` — a bare fragment (`{ sources, substitutions }`) is accepted and composed with defaults, or merge several origins yourself with `composeFontConfiguration`. Sampled per load; failures degrade to the fixed measurer and report through `onFontError`.
fontShaping?FontShapingOptionsExplicit shaping execution limits. Omitted, the per-face byte ceiling remains 16 MiB.
imageDecodePort?ImageDecodePortOverride raster decode for insert/replace image commands; defaults to browser/headless.
locale?stringBCP-47 locale for regional date input and generated labels; defaults to en-US.
lockedControlNavigation?LockedControlNavigationHow the caret moves through an inline control with a content lock. `'atomic'` makes such a control one caret unit; `'characters'` (the default) walks through its characters, as Word does. Fixed for the instance.
mode?'edit' | 'view' | 'suggesting'The mode the editor opens in — one prop, matching the toolbar's three-state pill.
modules?readonly EditorModule[]Capability modules to register — the seam `@docx-editor.dev/pro` plugs in through. Omitted, the editor runs the free tier: lossless round-trip, final-state revision rendering, review chrome disabled with the engine's reason. See [EditorModule](EditorModule).
onFontError?(error: EditorFontError) => void
reviewDisplayMode?ReviewDisplayModeInitial review projection. Markup modes require a review module.
revisionMarkup?RevisionMarkupOptionsInitial local revision presentation and tracking preferences.
revisionStyles?RevisionStylesHow painted tracked changes are coloured. Presentation only — nothing is serialised.
tableInteractionLabel?(key: TableInteractionLabelKey) => stringLocalized labels for table insertion furniture on the painted surface.
translate?(key: string, params?: Record<string, string | number>) => stringDrawing and form-control UI labels; defaults to English when omitted.
unsupportedElementRules?readonly UnsupportedElementRule[]Ordered unsupported-content registrations; the first matching rule reserves a layout box.
zoom?numberThe scale to open at, as a fixed number.
zoomMode?ZoomMode | 'auto'Where the scale comes from. Defaults to `'auto'` — fit the page width, between 50% and 100% — unless [DocxEditorConfig.zoom](DocxEditorConfig.zoom) is supplied, which means fixed.

DocxEditorInstanceinterfaceSource ↗

The concrete facade type: the full Editor contract plus the instance-only surface.

surface, stateVersion, attach and detach live HERE rather than on Editor: they are what a store binding and a mounting host need, not what document commands need. Production adapters program against Editor for everything else.

interface DocxEditorInstance extends Editor
MemberTypeSummary
attachMount into `el`, which may belong to another document: a pop-out window opened with `window.open`, or a same-origin iframe.
collaborationSessionThe live collaboration replica, or null when this editor is not in a room.
detachTake the editor out of its element and keep it, with its undo history, selection and collaboration session, for a later `attach`. While detached the instance still saves, runs commands and receives remote edits; it paints when attached again. A `load` while detached replaces the kept document. `destroy()` releases everything. No-op when already detached or destroyed.
fontMeasurementWhich measurer the current document's layout runs on, and whether shaped resolution is still in flight — the honest "are wrap points Word-accurate yet?" readout a host shows instead of guessing. `fixed` with `resolving: false` is the steady state for a document with no usable font source (the documented zero-config fallback); `shaped` means HarfBuzz measurement over real font bytes. Changes bump `stateVersion()`.
getReviewAuthorsEvery author the review surface DRAWS, in Word's slot order, with the colour the review chrome draws them in. The discovery surface a legend or colour picker builds on — authors depend on the loaded file, so they cannot be known at configuration time.
isReviewAuthorVisibleWhether this author's revisions and comments are shown in the current review view.
mountGenerationnumberBumps on mount, detach, destroy, and document reload — guards async image intents.
presenceColorForThe presence colour the engine paints for one display name — the answer the remote caret label takes, so chrome built on this cannot disagree with the painted caret.
setAllReviewAuthorsVisibleShow or hide every reviewer in one layout pass.
setAuthorSet the author for runtime editor state.
setBookmarkChromeWire the host's bookmark dialog to Ctrl/Cmd+Shift+F5. Returns an unsubscribe that restores whatever was registered before, like [DocxEditorInstance.setHyperlinkChrome](DocxEditorInstance.setHyperlinkChrome).
setBookmarkMarksChoose which bookmarks Show bookmarks marks and customize each mark. Returns an unsubscribe that restores the previous options.
setCommentDraftChromeWire the host's comment draft UI to the `review.addComment` control. Returns an unsubscribe that restores whatever was registered before. While nothing is registered, the control is disabled, because nothing could open the draft. The review rail registers when it mounts.
setCompareDocumentsChromeRegister Compare documents chrome. Disposal cancels its active sessions. Manual renderers take priority over fallback renderers. Pass null to use the review module's own dialog until disposal restores the previous registration.
setContentControlWidgetChromeRegister typed content-control widget chrome.
setEquationChromeWire the host equation popover to painted equation clicks.
setFontsReplace host font resources without replacing the document or its edit history. Old resolution is cancelled. Existing host faces are removed before the new resolver runs; no answer keeps the bounded fallback. Document-embedded faces remain independent of host fonts. Failures report through `onFontError`.
setGoToChromeWire the host's Go To UI to the `openGoTo` command. Returns an unsubscribe that restores whatever was registered before. `DocxEditor.Navigation` registers its Go to tab.
setHyperlinkChromeWire the host's hyperlink chrome to the engine's gestures — a click on an external link, and Ctrl/Cmd+K. Returns an unsubscribe that restores whatever was registered before, so a popover component can register in an effect and clean up in its teardown.
setInvalidTextFormFieldChromeRegister invalid protected-field acknowledgement chrome.
setLocaleSet regional date input and generated labels without rebuilding the editor. Stored dates are preserved; an in-progress field edit retains its starting locale. Omitted, invalid, and unsupported locales use en-US. Translation catalogues fall back by language.
setModeSet the host editing mode without rebuilding the editor.
setOpeningIndicatorHostRender the host's own loading indicator on the first page while a large document lays out its remaining pages, or restore the packaged spinner with `null`. The engine keeps owning the element and its place on the page; the host owns its content.
setRemoteCaretLabelHostRender the host's own component as the remote-caret label, or restore the default collaborator-name label with `null`. The engine keeps owning label geometry, class, and presence colour; the host owns the content of each published element.
setReviewAuthorVisibleShow one author's markup, or render their revisions as accepted and hide their comments. This changes view state only. It does not apply tree operations or change saved bytes.
setReviewPaneOptionsChange the review pane settings: every field of `ReviewPaneOptions`, such as when the pane opens by itself and what it does when its card column does not fit. An omitted field keeps its value. Read the settings in force from `snapshot().reviewPane`. They stay in force across `load()` and are never saved into the document. This sets how the pane behaves; to open or close the pane itself, use `useReview().setPaneOpen` or the `toggleReviewPane` command.
setRevisionMarkupMerge local preferences and emit revisionMarkupChange after a change. Invalid settings throw TypeError without changing the previous settings.
setRevisionMarkupChromeRegister local revision settings chrome. Disposal cancels its active sessions. Manual renderers take priority over fallback renderers. Pass null to use native chrome until disposal restores the previous registration.
setRevisionStylesReplace how tracked changes are coloured, live. Paint-level: pages repaint without a layout pass, and the caret, selection and undo history stay where they are. Pass `'author'` to restore the default, or `'kind'` to opt out to the green/red rendering. Survives a document reload.
setTextFormFieldChromeRegister Field Options chrome. Disposal closes sessions owned by this registration.
setTranslateSet the drawing and form-control label resolver without rebuilding the editor. Open dialogs preserve their controls and input; later surface mounts use the same resolver.
setUnsupportedElementRulesReplace registrations while preserving document edits and undo history.
showAllReviewAuthorsRestore every reviewer to the shown state.
stateVersionMonotonic version of the observable editor state. Bumps whenever anything `snapshot()` reports could have moved — a committed change, a selection move, zoom, load success or failure, attach/detach, destroy. An external store (React's `useSyncExternalStore`) uses it as a cheap "did anything change" signal; `snapshot()` itself is cached per version and returns a stable reference between bumps.
surfacePaginatedSurface | nullThe underlying paginated surface for harnesses and tests that need capabilities the contract does not carry yet (select-all, node-id addressed selection).

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
MemberTypeSummary
changeAspectboolean
moveboolean
resizeboolean
selectboolean

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
MemberTypeSummary
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();
```
MemberTypeSummary
acceptReviewItemAccept or reject the revision behind a card.
addCommentComment on the current selection.
addComment[addComment](addComment) with an author for this call, overriding the configured author.
beginHistoryGroupCreate an explicit gesture handle; creates no undo entry.
canDry run: reports whether `exec` would apply. Never reports `changed`.
canExecuteImageCommandDry 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.
deleteReviewItemDiscard the item behind a card: the destructive half of the review verbs.
destroy
exec
executeImageCommandInsert or replace picture bytes as one package undo unit.
findMatchesFind across body, headers, footers, footnotes, endnotes, and selectable text boxes.
findMatchesFind many terms in one pass, such as a glossary: one result list per term, in order.
focus
getActivatedReviewItemKeyThe key of the ACTIVATED review item: the one [setActiveReviewItem](setActiveReviewItem), Next Change, or Previous Change made active, while the caret stays in it.
getActiveScopeThe scope editing is in, as [setActiveScope](setActiveScope) last set it or a press moved it.
getAvailableFontsSelectable 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.
getCommentsComment threads anchored in the document.
getCurrentPageOne-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.
getCustomNodeDefinitionsCustom-node definitions registered through `createDocxEditor({ modules })`, in registration order.
getDocumentFontsFont families the document actually uses, for the font picker.
getDocumentHandle
getDocumentStylesParagraph/character styles defined by the document, for the style picker.
getDocumentThemeColorsThe 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.
getEditingModeHow edits are written: directly, as suggestions, or not at all.
getHeaderFooterStateHeader/footer editing state: which region is being edited, if any.
getNotePreviewTextPlain-text note preview for hover chrome.
getNotePropertiesStateResolved and authored note properties for the caret section — properties dialog read-model.
getOutlineHeading outline for the navigation panel, in document order.
getPageGeometryPage 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.
getPageSetupSection page setup — size, orientation and margins — for the page-setup dialog.
getRenderScaleLayout points to CSS pixels, zoom included.
getReviewItemsEvery pending decision in the document, with where its card belongs.
getReviewRevisionA counter that changes exactly when [getReviewItems](getReviewItems) would return something new.
getSelectedImageThe image at the selection, for the image toolbar and transform controls.
getSelectedTableThe table containing the selection, for the table toolbar. `null` outside a table.
getSelectionFormattingFormatting at the current selection, for toolbar value display (font, size, colour, alignment, list state). `null` when nothing is selected or nothing is derivable.
getSelectionPlacementWhere a comment on the current selection would sit, in the same space as [ReviewItemPlacement.anchorY](ReviewItemPlacement.anchorY), or null when nothing is selected.
getTableCellSelectionLive rectangular cell selection, if any. `null` when the caret is not in a cell rectangle.
getTotalPages
getTrackedChangesTracked changes in the document — body AND header/footer stories.
getWatermarkThe 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
getZoomModeWhether the scale is a number the engine holds, or one it recomputes from the viewport.
isActiveWhether a formatting command is currently APPLIED at the selection — distinct from `can`, which answers whether it may run.
isReviewPaneOpenWhether the review pane is showing its cards.
loadLoad a new document (DOCX bytes, `'blank'`, or a handle), replacing the current one.
on
query
rejectReviewItemThe rejecting half of [acceptReviewItem](acceptReviewItem), with the same rules and options.
relayoutReplaces the module-scope cache-invalidation calls adapters make today.
releaseSelectionRelease only the pin installed by the matching [retainSelection](retainSelection) call.
replyToReviewItemReply to a review item.
replyToReviewItem[replyToReviewItem](replyToReviewItem) with an author for this call, overriding the configured author.
reportCustomNodeDiagnosticReport a custom-node diagnostic to the modules registered on THIS editor.
retainSelectionPin the selection while chrome has focus. Returns null while detached.
saveSerialize 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.
scrollToPageScroll 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.
selectMatchMove the selection to a found match — what a find dialog's next/previous do.
setActiveReviewItemCard to document: a COLLAPSED caret at the range start, and a scroll to it. `null` clears it.
setActiveScopeMove editing into `scope`: the body, a header or footer, a note, or a text box (`frame`).
setCommentResolvedResolve or reopen the comment thread behind a review card.
setEditingMode
setReviewActivationExclusionsRevision kinds the caret must never activate, or null for none.
setTableInteractionLabelUpdate table furniture aria labels without remounting the editor.
setTrackedChangesFilterSet the view-time tracked-change filter, or clear it with `null`.
setZoomSet the display scale. Values outside a sane range are rejected rather than clamped silently, so a caller learns its input was refused.
setZoomModeChoose between holding a scale and tracking the viewport.
snapshot

EditorAnchorNavigationinterfaceSource ↗

Navigation and temporary highlights for external paragraph references.

interface EditorAnchorNavigation
MemberTypeSummary
clearAnchorHighlightDismiss the anchor highlight with a fade, or immediately with `animation: false`. Validates options even when nothing is highlighted.
highlightAnchorHighlight 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.
scrollToAnchorReveal 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
MemberTypeSummary
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.
openBookmarkDialogRecord<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`.
toggleBookmarksRecord<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
MemberTypeSummary
clearFormattingRecord<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.
compareDocumentsCompareDocumentsRequestCompare 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>`).
copyRecord<never, never>Put the selected text on the clipboard. Reports `changed: false` — the document is untouched.
cutRecord<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; }
deleteTableRecord<never, never>
editTextFormFieldRecord<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; }
insertTextBoxRecord<never, never>Insert a rectangular body textbox and enter its text.
insertTocRecord<never, never>Insert a generated, hyperlink-enabled TOC for heading levels 1–3 at the selection.
mergeCellsRecord<never, never>
navigateReviewChange{ direction: 'next' | 'previous'; }Navigate tracked changes, including hidden formatting balloons, and wrap at the end.
openCompareDocumentsDialogRecord<never, never>Open the Compare documents dialog supplied by the review module.
openRevisionMarkupDialogRecord<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.
redoRecord<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.
resolveAllReviewChangesResolveReviewChangesOptionsResolve eligible changes shown by the active filters, or an explicit scope, in one undo step.
selectAllRecord<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.
setParagraphFormatParagraphFormatCommandThe 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.
setReviewChangesAuthorSetReviewChangesAuthorOptionsAttribute 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; }
toggleDocumentProtectionRecord<never, never>Word's Protect Document: enforce filling-in-forms protection, or lift the enforced one.
toggleHeaderRowRecord<never, never>
toggleList{ kind: 'bullet' | 'ordered'; }
toggleMark{ mark: string; }
toggleParagraphMarksRecord<never, never>Word's Show/Hide paragraph marks; presentation only.
toggleReviewPaneRecord<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.
undoRecord<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
MemberTypeSummary
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
MemberTypeSummary
change(change: DocumentChange) => voidA document mutation committed, with the ids it touched.
diagnostic(event: EditorDiagnostic) => voidAn 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) => voidThe 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) => voidAn 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) => voidAn explicit request landed on a review item, and its card or balloon should open.
revisionMarkupChange(settings: ResolvedRevisionMarkup) => voidLocal viewer preferences changed through the API or review dialog.
selectionChange(snapshot: EditorSnapshot) => voidObservable 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
MemberTypeSummary
historyGroup?HistoryGroupAn 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?EditorScopeOmitted, 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
MemberTypeSummary
copyFormattingRecord<never, never>Capture the formatting at the selection (Word's Ctrl+Shift+C).
pasteFormattingRecord<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
MemberTypeSummary
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.
exitHeaderFooterRecord<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.
linkHeaderFooterToPreviousHeaderFooterSlotArgsTurn 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.
removeHeaderFooterHeaderFooterSlotArgsDelete 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.
unlinkHeaderFooterFromPreviousHeaderFooterSlotArgsTurn 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
MemberTypeSummary
clearHighlightsRemove one highlight set, or every set when `name` is omitted.
getHighlightsAtThe 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.
setHighlightsMark text ranges as one named set, replacing the set's previous ranges and options.

EditorHostChangeinterfaceSource ↗

The payload of the hostChange event.

interface EditorHostChange
MemberTypeSummary
documentEditorHostDocument | nullThe document the pages are mounted in now, or `null` while the editor is detached.

EditorModuleinterfaceSource ↗

One registered capability module. Registration is construction-time (createDocxEditor({ modules })) and immutable for the instance's lifetime.

interface EditorModule
MemberTypeSummary
collaboration?CollaborationModuleContributionCollaboration replica. Absent, the editor stays single-user: local undo stays the authority, and `snapshot().collaborationStatus` is `'inactive'`.
customNodePayloadNamespaces?readonly string[]customXml payload namespaces this module OWNS, swept for orphans when a document opens.
customNodes?readonly unknown[]Custom inline node definitions. Reserved: the definition shape lands with the custom-nodes lane; the registry carries them opaquely until then.
idstringDiagnostic identity (`'review'`, `'custom-nodes'`); not a dispatch key.
onCustomNodeDiagnostic?(diagnostic: unknown) => voidTold when the recognition pass finds something wrong with a node in THIS editor's document.
onDiagnostic?(event: EditorDiagnostic) => voidTold about every anonymous diagnostic of this editor, from its first open on.
review?ReviewModuleContributionReview capability: queue derivation, commands gate, display modes.
wantsDiagnostic?(kind: EditorDiagnosticKind) => booleanWhether `onDiagnostic` wants events of `kind` now. Absent, it wants every kind. The editor asks before work that only a diagnostic needs, such as timing key presses for `performance`, and skips that work when no listener wants it. Read often: keep it cheap.

EditorNoteCommandsinterfaceSource ↗

Footnote/endnote lifecycle and properties commands on [EditorCommands](EditorCommands).

interface EditorNoteCommands
MemberTypeSummary
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
MemberTypeSummary
bookmarksRecord<never, never>Every bookmark in the document, hidden ones included, in document order.
contentControlAt{ filter?: ContentControlFilter; }
hyperlinkAt{ pos?: number; fallbackHref?: string; }
isInsideToc{ pos: number; }
selectedTextRecord<never, never>
selectionRecord<never, never>
selectionFormattingRecord<never, never>
splitCellConfigRecord<never, never>
tableContextRecord<never, never>
trackedChangesRecord<never, never>
watermarkRecord<never, never>

EditorQueryResultsinterfaceSource ↗

What each editor query returns. Keyed identically to EditorQueries.

interface EditorQueryResults extends DocQueryResults
MemberTypeSummary
bookmarksreadonly BookmarkSummary[]
contentControlAtContentControlSummary | null
hyperlinkAtHyperlinkInfo | null
isInsideTocboolean
selectedTextstring
selectionDocRange | null
selectionFormattingRunFormatting | null
splitCellConfig{ maxRows: number; maxCols: number; } | null
tableContextTableContext | null
trackedChangesreadonly Revision[]
watermarkWatermark | null

EditorReviewHitsinterfaceSource ↗

Hit testing for hosts that draw their own review chrome.

interface EditorReviewHits
MemberTypeSummary
getReviewItemRectsThe bands one review item paints, one per line part, in client coordinates.
getReviewItemsAtThe 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
MemberTypeSummary
canRedo?boolean
canUndo?booleanWhether 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.
collaborationStatusCollaborationStatus | 'inactive'Lifecycle of the attached collaboration replica, or `'inactive'` when no collaboration module is registered.
documentProtection?DocumentProtectionState | nullThe document's `w:documentProtection`, as the file states it; null with no document.
editablebooleanWhether 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?DocumentEditingModeHow 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?FormatPainterSurfaceStateFormat 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.
formattingRunFormatting | null
hasReviewContent?booleanWhether the document carries review content — tracked changes or comment anchors — independent of any registered review module.
hiddenReviewAuthors?readonly string[]Authors whose revisions currently render as accepted and whose comments stay hidden.
imageImageContext | null
isLoadingbooleanWhether 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?booleanWhether 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 | nullWhy the last edit was refused, or null.
openFailure?DocumentOpenFailure | nullWhy 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 | nullThe 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.
parseErrorstring | null
reviewDisplayMode?ReviewDisplayModeThe displayed revision projection. The document and its revision history stay unchanged.
reviewPaneResolvedReviewPaneThe 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?booleanWhether the review pane is showing its cards.
revisionMarkupResolvedRevisionMarkupResolved local viewer preferences. Never saved into the document.
scopeEditorScope
selectionDocRange | null
selectionCollapsedbooleanWhether the selection is a CARET rather than a range. `true` when nothing is loaded.
showBookmarks?booleanWhether bracket marks are shown at bookmarks.
showParagraphMarks?booleanWhether Show/Hide paragraph marks is enabled.
tableTableContext | null
tocContext{ readonly id: string; } | nullThe table of contents the last right-click landed on, or null.
zoomnumber
zoomMode?ZoomModeWhere [EditorSnapshot.zoom](EditorSnapshot.zoom) came from.

EditRejectedDiagnosticinterfaceSource ↗

An edit, a command or a tracked change was refused.

interface EditRejectedDiagnostic extends DiagnosticBase, DiagnosticFailureDetail
MemberTypeSummary
codeEditDiagnosticCode
command?EditorCommand['type']The command type for `origin: 'command'`, such as `'insertTable'`.
kind'edit.rejected'
originEditRejectionOrigin`'command'` for `exec(...)`, `'input'` for typing, clipboard, drag and pointer edits, and `'automation'` for a batch from the editing API.
trackedbooleanTrue when the editor was suggesting (tracking changes) at the time.

EquationActivationinterfaceSource ↗

A user click on one painted equation.

interface EquationActivation
MemberTypeSummary
equationSurfaceEquation
rect{ readonly left: number; readonly top: number; readonly right: number; readonly bottom: number; }

EquationChromeHandlersinterfaceSource ↗

Host chrome that edits a clicked Office Math equation.

interface EquationChromeHandlers
MemberTypeSummary
onPopover?(activation: EquationActivation) => void

ExtentinterfaceSource ↗

A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch.

interface Extent
MemberTypeSummary
heightEmunumber
widthEmunumber

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
MemberTypeSummary
defaultFont{ readonly family: string; readonly sizeHalfPoints: number; }
epochnumber
language?string
maxFontBytesnumber
sourcesreadonly FontSource[]
substitutions?readonly FontSourceSubstitution[]
supportedFamilies?readonly string[]Selectable provider families, independent of loaded bytes. Listing them performs no fetch.

FontConfigurationBaseinterfaceSource ↗

The base of a composition: everything a FontConfiguration carries, all optional. Omitted fields take the documented defaults (epoch 0, maxFontBytes at the engine hard maximum, defaultFont Calibri at 11pt — Word's own default face and size).

interface FontConfigurationBase extends FontConfigurationFragment
MemberTypeSummary
defaultFont?FontConfiguration['defaultFont']The face used when a run names no font. Defaults to Word's own: Calibri at 11pt.
epoch?numberIdentity of this configuration's byte set. The engine uses it to tell one resolved font set from another; leave it unset and the editor supplies the load sequence.
language?stringBCP-47 tag passed to the shaper for language-sensitive shaping.
maxFontBytes?numberPer-face byte ceiling. Defaults to the engine hard maximum; lower it to tighten intake.

FontConfigurationFragmentinterfaceSource ↗

A partial font configuration one origin contributes: sources, substitutions, or both. loadDefaultFonts() (the substitute package) and loadFonts() (the fetch helper) both return this shape, so every origin composes through composeFontConfiguration the same way.

interface FontConfigurationFragment
MemberTypeSummary
deferred?Promise<FontConfigurationFragment | undefined>Faces that arrive after the document first paints. The editor lays the document out with `sources` and `substitutions`, then lays it out again once this settles. Use it for large faces, such as CJK fonts, that would otherwise hold back the first paint.
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
MemberTypeSummary
embeddedboolean
familystring

FontFaceRequestinterfaceSource ↗

A concrete font face requested by authored document content.

interface FontFaceRequest
MemberTypeSummary
familystring
style'normal' | 'italic'
weightnumber

FontFailedDiagnosticinterfaceSource ↗

A font failed to load. The editor kept working with a substitute.

interface FontFailedDiagnostic extends DiagnosticBase
MemberTypeSummary
codeFontDiagnosticCode
kind'font.failed'

FontLoadFailureinterfaceSource ↗

One face that did not load, with whatever evidence the failure produced.

Non-fatal: [LoadFontsResult](LoadFontsResult) still carries every source that succeeded, and the affected family falls back to the engine's fixed measurement.

interface FontLoadFailure
MemberTypeSummary
actualHash?string
diagnostic?string
expectedHash?string
reasonFontLoadFailureReason
requestFontFaceRequest
status?numberHTTP status for `httpError`; hashes for `hashMismatch`.
urlstring

FontMeasurementStateinterfaceSource ↗

Which measurer the current document's layout runs on, and whether shaped resolution is still in flight. Returned by [DocxEditorInstance.fontMeasurement](DocxEditorInstance.fontMeasurement).

interface FontMeasurementState
MemberTypeSummary
measurer'fixed' | 'shaped'`fixed` estimates advance widths; `shaped` measures real font bytes with HarfBuzz.
producer?stringThe shaped measurer's identity (admitted face hashes); absent while fixed.
resolvingbooleanTrue while font resolution for the current document is still running.

FontOriginFailureinterfaceSource ↗

A failed font origin or a partial failure in an otherwise usable fragment.

interface FontOriginFailure
MemberTypeSummary
causeunknown
originIndexnumberZero-based position in the first-wins origin list.
originName?stringResolver function name when one is safely available.

FontResolutionRequestinterfaceSource ↗

What the document turned out to need, handed to an on-demand resolver.

The families are the ones the file actually names — already name-validated and capped, so a resolver may treat them as a list to look up, never as URLs or paths to build.

interface FontResolutionRequest
MemberTypeSummary
defaultFamilystringThe face a run naming no font resolves to, so a resolver can cover it too.
familiesreadonly string[]Families needed by the document, deduped and capped at [MAX_RESOLVER_FAMILIES](MAX_RESOLVER_FAMILIES). Order is deterministic but may express host priority; do not sort it before resolving.
resolvedFaces?readonly FontFaceRequest[]Faces an EARLIER origin in the same composition can already PAINT — either because it supplied the bytes, or because it mapped that face onto one it did supply.
signal?AbortSignalCancels document-scoped resolution; network-backed resolvers should pass it to fetch.

FontResolverMarkinterfaceSource ↗

The type-level half of the mark: what [defineFontResolver](defineFontResolver) adds to a function's type so a FontOrigin list can REQUIRE it.

Declared with a string key so @docx-editor.dev/fonts can declare an identical interface and have the two unify without importing anything from the engine. Set at runtime as well as in the type — non-enumerable, so it stays out of Object.keys and out of a host's own spread.

interface FontResolverMark
MemberTypeSummary
"docx-editor.dev/font-resolver"trueAlways `true`. Set non-enumerably by [defineFontResolver](defineFontResolver).

FontShapingOptionsinterfaceSource ↗

Host-selected execution limits, separate from font admission limits.

interface FontShapingOptions
MemberTypeSummary
maxFontBytes?numberPer-face shaping byte ceiling. Defaults to 16 MiB; the hard ceiling is 64 MiB.

FontSourceinterfaceSource ↗

Immutable, byte-backed font face supplied to layout and browser paint.

interface FontSource
MemberTypeSummary
availability?'available' | 'forbidden'
bytesUint8Array
faceIndexnumber
hashstring
idstring
requestFontFaceRequest

FontSourceSubstitutioninterfaceSource ↗

An explicit authored-font substitution. No implicit platform fallback is performed.

interface FontSourceSubstitution
MemberTypeSummary
fromFontFaceRequest
lineMetrics?{ readonly heightEm: number; readonly baselineEm: number; }Word line-box metrics for the requested face, expressed as em ratios.
toFontFaceRequest

FontUrlSourceinterfaceSource ↗

One URL to fetch and the face it claims to be.

interface FontUrlSource
MemberTypeSummary
faceIndex?number
familystring
hash?stringExpected `sha256:` content hash. When present, mismatching bytes are REFUSED — pin this for any URL not under the app's sole control.
style'normal' | 'italic'
urlstring
weightnumber

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
MemberTypeSummary
levelFormatPainterLevel
modeFormatPainterMode

GoToChromeHandlersinterfaceSource ↗

Host chrome for Go To: the Go to tab of DocxEditor.Navigation, or the host's own.

interface GoToChromeHandlers
MemberTypeSummary
onRequest?() => voidOpen the Go To UI: the `openGoTo` command, which its shortcut also sends.
shortcut?booleanWhether Ctrl+G (Cmd+Option+G on macOS) in the document opens this UI. Defaults to `true`. With `false` the chord is left to the browser; `openGoTo` still opens the UI. The most recent registration decides. It is read when the chord arrives, so a getter can follow a setting without registering again.

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
MemberTypeSummary
default?string
even?string
first?string

HeaderFooterSlotArgsinterfaceSource ↗

Optional slot targeting shared by remove / link / unlink furniture commands.

interface HeaderFooterSlotArgs
MemberTypeSummary
evenPage?boolean
firstPage?boolean
position?'header' | 'footer'
sectionIndex?number
variant?FurnitureVariantPrefer over `firstPage` / `evenPage` when selecting a furniture variant.

HeaderFooterStateinterfaceSource ↗

Header/footer editing state: which region is being edited, if any.

interface HeaderFooterState
MemberTypeSummary
editing'header' | 'footer' | null
evenAndOddHeaders?booleanDocument `w:evenAndOddHeaders` — even-page furniture is distinct when true.
footerDistanceTwips?numberSection footer distance from sheet edge, twips (`w:pgMar w:footer`).
headerDistanceTwips?numberSection header distance from sheet edge, twips (`w:pgMar w:header`).
inherited?booleanWhether the resolved part is inherited from a preceding section ("Same as Previous") rather than declared on this section.
partName?stringPackage part name of the open story.
rId?stringRelationship id of the open story (`EditorScope.rId`).
sectionIndexnumber
titlePage?booleanSection `w:titlePg` — first-page furniture is distinct when true.
variant?FurnitureVariantFurniture 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>
MemberTypeSummary
activebooleanWhether this range is the set's active range.
indexnumberIndex of the range in the array passed to `setHighlights()`.
lengthnumberCurrent length of the highlighted text.
namestringSet name passed to `setHighlights()`.
rangeRThe 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.
rectHighlightRectThe marked line box under the point, in client coordinates. Anchor popovers to it.
startnumberCurrent 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
MemberTypeSummary
activeColor?stringFill for the active range. Default: `var(--doc-text-highlight-active-color)`, orange.
activeIndex?numberIndex 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?stringSpace-separated CSS classes added to every mark of this set.
color?stringFill for every range: a CSS color or `var()` expression. Default: `var(--doc-text-highlight-color)`, a translucent yellow.
priority?numberStacking 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
MemberTypeSummary
blockIdstringParagraph that holds the range: `TextMatch.blockId`. IDs belong to the open document.
expectedText?stringModel 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.
lengthnumberRange length in the same units. A zero length marks nothing.
scope?ViewScopeStory that holds the paragraph. Informational; `blockId` already names the paragraph.
startnumberUTF-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
MemberTypeSummary
bottomnumber
heightnumber
leftnumber
rightnumber
topnumber
widthnumber
xnumber
ynumber

HighlightResultinterfaceSource ↗

What setHighlights() resolved against the open document.

interface HighlightResult
MemberTypeSummary
appliednumberRanges that resolve to their text in the open document and can paint.
unavailablenumberRanges 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
MemberTypeSummary
kind'split' | 'possible-ungrouped-gesture' | 'possible-fragmented-gesture'
reasonstring

HistoryDiagnosticEventinterfaceSource ↗

The undo history did not group edits as the gesture intended. Informational.

interface HistoryDiagnosticEvent extends DiagnosticBase
MemberTypeSummary
codeHistoryDiagnosticCode
kind'history'

HistoryGroupinterfaceSource ↗

interface HistoryGroup
MemberTypeSummary
[historyGroupBrand]true
endEnd this gesture without reverting any edits. Safe to call more than once.
lastOutcomeHistoryGroupOutcome | nullThe 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.

HistoryGroupBindinginterfaceSource ↗

Dispose when the element or editor changes.

interface HistoryGroupBinding
MemberTypeSummary
disposeClose the gesture and remove every listener; does not revert edits.
optionsOptions for the next synchronous formatting command.

HistoryGroupBindingOptionsinterfaceSource ↗

Native event policy for one continuous control gesture.

interface HistoryGroupBindingOptions
MemberTypeSummary
kind'native-color' | 'range' | 'repeat' | 'keyboard'

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
```
MemberTypeSummary
historyGroup?HistoryGroupAn open handle from [Editor.beginHistoryGroup](Editor.beginHistoryGroup) on this editor.

HistoryGroupOutcomeinterfaceSource ↗

The history authority's result for this frame.

interface HistoryGroupOutcome
MemberTypeSummary
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'

HyperlinkActivationinterfaceSource ↗

A click on a painted link, after native navigation was refused.

interface HyperlinkActivation
MemberTypeSummary
rect{ readonly left: number; readonly top: number; readonly bottom: number; readonly right: number; }The clicked line fragment's viewport rect, so a popover can be placed under it.

HyperlinkChromeHandlersinterfaceSource ↗

The host chrome that answers the engine's hyperlink gestures.

A CLICK on an external link and Ctrl/Cmd+K both mean "the user wants the link UI", and the engine deliberately does not know what that looks like. Registered rather than passed at construction because the chrome mounts after the editor does, and it survives a document reload — the surface is rebuilt, the handlers are not.

interface HyperlinkChromeHandlers
MemberTypeSummary
onPopover?(activation: HyperlinkActivation) => voidA plain click on an external or inert link: show the popover at `activation.rect`.
onRequest?() => voidCtrl/Cmd+K: open insert-or-edit for the selection.

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
MemberTypeSummary
hrefstring
rangeDocRange
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
MemberTypeSummary
bottomnumber
leftnumber
rightnumber
topnumber

ImageDecodePortinterfaceSource ↗

The injected image decoder.

A port rather than a direct Image/createImageBitmap call, so a worker or server runtime supplies its own and the engine never reaches for a browser global.

interface ImageDecodePort
MemberTypeSummary
convertPreservedOptional conversion of media an `<img>` cannot render (EMF/WMF metafiles, TIFF) into a renderable raster. The returned bytes are untrusted and re-enter the full raster validation path (sniff, header, pixel caps, decode) before they can become a ready resource. A null return declines the format and keeps the labelled placeholder; so does a throw, as `decode-failed`.
decode

ImageResourceLimitsinterfaceSource ↗

Trust-boundary caps specific to image decoding and embedding.

interface ImageResourceLimits
MemberTypeSummary
maxDecodedBytesnumber
maxDimensionnumber
maxEncodedBytesnumber
maxExternalRedirectsnumber
maxPixelsnumber
maxPolygonPointsnumber

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
MemberTypeSummary
firstLinenumberFirst-line offset from [left](left), signed. Negative is a hanging indent.
leftnumberLeading 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.
rightnumberTrailing indent (`w:right`), signed: the right one, or the left one right to left.
rtl?trueThe 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.

InvalidTextFormFieldChromeHandlersinterfaceSource ↗

Framework rendering for invalid protected-field acknowledgements.

interface InvalidTextFormFieldChromeHandlers
MemberTypeSummary
onRequest?(session: InvalidTextFormFieldSession) => void

InvalidTextFormFieldSessioninterfaceSource ↗

An invalid protected-field acknowledgement.

interface InvalidTextFormFieldSession
MemberTypeSummary
acknowledgeClear the unchanged invalid value, if the target still permits it.
cancelDismiss without clearing the authored value.
signalAbortSignal
type'number' | 'date'

LoadFontsRequestinterfaceSource ↗

What to fetch, and under what limits.

Only sources is required. Each carries its own expected hash, so bytes are trusted by CONTENT rather than by origin — a swapped asset fails admission even from a trusted host.

interface LoadFontsRequest
MemberTypeSummary
cacheName?stringCache API bucket name; default `docx-editor-fonts`.
fetcher?typeof fetchInjectable for tests and CSP-constrained hosts; defaults to global `fetch`.
maxFontBytes?numberPer-font byte ceiling; defaults to the engine hard maximum.
signal?AbortSignalCancels loading with `signal.reason`, without returning per-source failures.
sourcesreadonly FontUrlSource[]

LoadFontsResultinterfaceSource ↗

What one loadFonts call produced: the faces that arrived, plus the ones that did not.

A FontConfigurationFragment, so it composes straight into composeFontConfiguration alongside other font sources. Partial success is the normal case — compose it even with failures present.

interface LoadFontsResult extends FontConfigurationFragment
MemberTypeSummary
failuresreadonly FontLoadFailure[]
sourcesreadonly FontSource[]

NotePropertiesSideinterfaceSource ↗

One note kind's resolved + authored properties for the caret section.

interface NotePropertiesSide
MemberTypeSummary
documentAuthored?AuthoredNoteNumberingThe document settings (settings.xml) values. Only the endnote `pos` affects `resolved`; the other fields are kept for files that carry them.
resolvedResolvedNoteNumbering
sectionAuthored?AuthoredNoteNumberingThe 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
MemberTypeSummary
endnoteNotePropertiesSide
footnoteNotePropertiesSide
sectionIndexnumber

NumberingRefinterfaceSource ↗

A paragraph's list membership: which numbering.xml definition, and at which level.

interface NumberingRef
MemberTypeSummary
levelnumberZero-based. OOXML numbering has nine levels, 0 through 8.
numIdstring

OoxmlExternalTargetinterfaceSource ↗

An external relationship target. Retained verbatim as authored evidence, with the sink-safety verdict alongside it. Never resolved against the package, never fetched.

interface OoxmlExternalTarget
MemberTypeSummary
idstring
ownerPartstring
rawTargetstring
sinkSafebooleanFalse when the target is not a safe sink (javascript:, file:, ...). Still not fetched.
typestring

OoxmlPackageinterfaceSource ↗

A loaded package: every XML part as a canonical tree, plus the non-XML parts kept verbatim.

The preservation model in one value. Modelled parts re-emit normalized; everything else is byte-identical, which is why an unrecognized part never costs a document anything.

interface OoxmlPackage
MemberTypeSummary
contentTypesContentTypeIndex
externalTargetsreadonly OoxmlExternalTarget[]
mainDocumentPartstringCanonical name of the part the root `officeDocument` relationship points at.
partBytesReadonlyMap<string, Uint8Array>Raw bytes of every entry, including the non-XML parts that have no tree.
partsReadonlyMap<string, OoxmlPart>Canonical trees, keyed by canonical part name. Non-XML parts are absent by design.
relationshipsReadonlyMap<string, readonly RelationshipRecord[]>Internal relationships by owner part, in authored order.

PageMarginsinterfaceSource ↗

Page margins in twips.

interface PageMargins
MemberTypeSummary
bottomTwipsnumber
leftTwipsnumber
rightTwipsnumber
topTwipsnumber

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
MemberTypeSummary
gutterTwips?numberBinding 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'
pageHeightTwipsnumber
pageWidthTwipsnumber

ParagraphinterfaceSource ↗

One paragraph: its runs, the style it names, and its list membership.

interface Paragraph
MemberTypeSummary
kind'paragraph'
numbering?NumberingRef
paraId?string`w14:paraId`. The stable handle `DocAnchor` addresses.
runsreadonly Run[]
styleId?string

ParagraphDisagreementsinterfaceSource ↗

Which paragraph-level reads the selection disagrees about.

interface ParagraphDisagreements
MemberTypeSummary
alignmentboolean
directionbooleanThe selection mixes left-to-right and right-to-left paragraphs.
lineSpacingboolean
spaceAfterPtboolean
spaceBeforePtboolean
tabStopsboolean

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
MemberTypeSummary
contextualSpacingboolean | null
keepLinesboolean | null
keepNextboolean | null
pageBreakBeforeboolean | null
widowControlboolean | 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
MemberTypeSummary
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 | nullONE 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
MemberTypeSummary
paraId?string
styleId?string
textstring

ParagraphTabStopinterfaceSource ↗

One custom tab stop, as a command states it.

interface ParagraphTabStop
MemberTypeSummary
alignment'left' | 'center' | 'right' | 'decimal' | 'bar'
leader?'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot'
positionTwipsnumber

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
MemberTypeSummary
code?PerformanceDiagnosticCodePresent 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?TimingSummaryKey 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?TimingSummaryEngine 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?CountBucketPages in the document at the last paint.
paint?TimingSummaryEngine paints of the pages.
windowMsnumberMilliseconds 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
MemberTypeSummary
xnumber
ynumber

PopupChromeRegistrationOptionsinterfaceSource ↗

Priority of an editor-owned popup renderer.

interface PopupChromeRegistrationOptions
MemberTypeSummary
fallback?booleanUse only when no manually registered renderer exists.

RectinterfaceSource ↗

An axis-aligned rectangle in points, the unit layout works in throughout.

interface Rect
MemberTypeSummary
heightnumber
widthnumber
xnumber
ynumber

RelationshipRecordinterfaceSource ↗

One authored relationship, with nothing materialized away: owner part, id, type, raw target lexical form, mode, and position.

interface RelationshipRecord
MemberTypeSummary
idstring
ordernumber
ownerPartstring
rawTargetstring
targetModeTargetMode
typestring

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
MemberTypeSummary
numFmtstring
numRestartstring
numStartnumber
posstring

ResolvedReviewPaneinterfaceSource ↗

The review pane settings in force, with every field resolved.

interface ResolvedReviewPane
MemberTypeSummary
commentMarkersCommentMarkerStyleHow a collapsed comment marker looks.
openingReviewPaneOpeningWhen the pane opens by itself.
overflowReviewPaneOverflowWhat the open pane does when its card column does not fit beside the page.
revisionsInRevisionDisplayWhere tracked changes open.

ResolvedRevisionMarkupinterfaceSource ↗

Fully resolved, immutable viewer preferences.

interface ResolvedRevisionMarkup
MemberTypeSummary
cells{ readonly inserted: RevisionMarkupNamedColor | 'byAuthor' | 'none'; readonly deleted: RevisionMarkupNamedColor | 'byAuthor' | 'none'; readonly merged: RevisionMarkupNamedColor | 'byAuthor' | 'none'; readonly split: RevisionMarkupNamedColor | 'byAuthor' | 'none'; }
changedLinesRevisionMarkupStyle<RevisionChangedLinesMark>
deletionsRevisionMarkupTextStyle<RevisionDeletionMark>
formattingRevisionMarkupTextStyle
insertionsRevisionMarkupTextStyle
movedFromRevisionMarkupTextStyle<RevisionDeletionMark>
movedToRevisionMarkupTextStyle
trackFormattingboolean
trackMovesboolean

ResolveReviewChangesOptionsinterfaceSource ↗

Selection and unsupported-change policy for a bulk review decision.

interface ResolveReviewChangesOptions
MemberTypeSummary
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
MemberTypeSummary
announce?booleanWhether a successful activation fires the `reviewItemReveal` event. Default `false`.
reveal?ScrollPlacement | falseWhere the item lands, or `false` to open it without scrolling at all.

ReviewAuthorInfointerfaceSource ↗

One document author, resolved: who, which ramp slot, and what they draw in.

interface ReviewAuthorInfo
MemberTypeSummary
authorstringThe `w:author` string, exactly as the file carries it.
colorstringThe colour this author is DRAWN IN by the review chrome — their declared colour, or their ramp slot's token.
slotnumberStable session rank, seeded by order of first appearance — an UNBOUNDED index.
style?RevisionAuthorStyleThe host-supplied style, normalised; absent when the author rides the ramp.

ReviewChangesAttributioninterfaceSource ↗

Who and when a change of tracked-change author records. Shared by both selections.

interface ReviewChangesAttribution
MemberTypeSummary
author?stringThe 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?stringAn 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
MemberTypeSummary
action'accept' | 'reject'Whether the decision accepted or rejected the changes.
resolvedCountnumberHow many listed changes it resolved. The `exec` result lists them in `revisions.resolved`.
skippedreadonly { 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
MemberTypeSummary
commentCommentRecord
idstring
kind'comment'
orphanedbooleanTrue when the file gave this comment no usable range.
parentId?stringThe comment this replies to, absent for a top-level comment.
parentRevisionId?stringThe REVISION this comment answers, when it covers exactly that change's characters.
rangeReviewRange | null
replyIdsreadonly string[]Replies to this comment, in document order. Empty for a reply or a childless comment.
resolvedboolean

ReviewCommentPlacementinterfaceSource ↗

A comment thread's card.

interface ReviewCommentPlacement extends ReviewItemPlacementBase
MemberTypeSummary
itemReviewCommentItem
kind'comment'
parentId?stringThe comment this replies to, absent at the top of a thread.
parentRevisionId?stringThe REVISION this comment answers, absent unless it does.
resolvedbooleanWhether `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
MemberTypeSummary
attrsReadonly<Record<string, string>>Attrs decoded from the tag, after the definition's recognition hook. Untrusted input.
cardedbooleanWhether this node asked for a sidebar card.
data?unknownThe payload the node's control binds to, after the definition validated it.
detail?stringCard body, from the definition's `reviewCard` hook.
icon?stringGlyph for this node in the collapsed rail, as an SVG path in a `0 -960 960 960` viewBox.
idstringThe SDT node's stable id in the canonical tree.
kind'custom'
namestringThe definition's `name`.
rangeReviewRange | null
tagstringThe raw `w:tag` the node was recognized from. Untrusted input.
textstringThe SDT's literal content text. Untrusted input.
titlestringCard 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
MemberTypeSummary
itemReviewCustomItem
kind'custom'

ReviewItemHitinterfaceSource ↗

One review item under a client point.

interface ReviewItemHit
MemberTypeSummary
placementReviewItemPlacementThe item, as `getReviewItems()` with the same query returns it.
rectHighlightRectThe 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
MemberTypeSummary
activatablebooleanWhether [Editor.setActiveReviewItem](Editor.setActiveReviewItem) would take this key.
anchorYnumber | nullDocument-space Y of the anchor, or null when the item has no resolvable range.
authorstring
date?string`@w:date`, absent when the file omits it — Word does when date stamping is off.
idstringThe engine's own id for the comment, the revision, or the custom node.
initialsstringInitials for an avatar: `@w:initials` when the file carries one, else from the name.
isActiveboolean
keystringStable and unique per decision within this editor instance.
pageIndexnumber | null
readOnlybooleanTrue 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.
replyIdsreadonly string[]Replies to this item, in document order.
textstringThe 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
MemberTypeSummary
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?booleanWhether 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?booleanWhen false, skip layout geometry; metadata is unchanged and anchors are null. Default true.

ReviewItemRevealEventinterfaceSource ↗

The payload of the reviewItemReveal event.

interface ReviewItemRevealEvent
MemberTypeSummary
keystringThe 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?stringThe 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`.
sourceReviewItemRevealSourceWhat 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`.

ReviewModelInputinterfaceSource ↗

What the review queue derivation reads: one story part plus its comment parts.

interface ReviewModelInput
MemberTypeSummary
commentsExtendedPart?OoxmlPart | undefined`word/commentsExtended.xml`, absent when the package has none.
commentsPart?OoxmlPart | undefined`word/comments.xml`, absent when the package has none.
customNodePayloads?ReadonlyMap<string, { readonly nodeId: string; readonly label: string; readonly data: string; }> | undefinedThe payload each of the story's controls binds to, keyed by the control's node id.
customNodes?readonly unknown[] | undefinedCustom node definitions from the module registry, forwarded OPAQUELY.
furnitureParts?readonly OoxmlPart[] | undefinedHeader/footer story parts, in section order. Their revisions and comment anchors join the queue: a tracked change in a header is a pending decision like any other, and a queue that only walked the body silently hid it from the rail AND from Accept All.
reportCustomNodeDiagnostic?((diagnostic: unknown) => void) | undefinedWhere a capability package reports a node it could not read. Supplied per editor, so a page with two of them keeps their diagnostics apart.
storyPartOoxmlPartThe story the ranges live in — the main document, a header, a note.
stylesPart?OoxmlPart | undefinedShared style definitions. Their revisions have no paragraph range.

ReviewModuleContributioninterfaceSource ↗

What a review module contributes: the queue derivation, and the revision display modes the editor may enter beyond the free tier's final-state projection.

interface ReviewModuleContribution
MemberTypeSummary
collectReviewItemsCollectReviewItemsThe review queue derivation.
compareDocuments?CompareDocumentsEngineDocument compare. Absent, compare commands refuse.
compareDocumentsInBackground?CompareDocumentsBackgroundEngineThe same compare off the main thread. When present, the Compare documents dialog uses it, reports progress, and can stop a running compare. If it rejects before its first progress report, the dialog compares with `compareDocuments` instead. The `compareDocuments` command stays synchronous and uses `compareDocuments`.
createCompareDocumentsDialog?(host: CompareDocumentsDialogHost) => CompareDocumentsDialogCreate the Compare documents dialog when a host opens it.
createRevisionMarkupDialog?(host: RevisionMarkupDialogHost) => RevisionMarkupDialogCreate local review settings chrome when a host opens the dialog.
displayModesreadonly ReviewDisplayMode[]Display modes this module unlocks (the free engine renders `proposed` only).
pane?ReviewPaneOptionsThe review pane settings the editor starts with. `setReviewPaneOptions` changes them later.
revisionItemsOfParagraph(part: OoxmlPart, paragraphId: string) => readonly ReviewRevisionItem[]Revisions wholly inside one paragraph — for the conservative local review patch after a text-local body edit.

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
MemberTypeSummary
kind'revision' | 'comment' | 'custom'The item kind, as `ReviewItem.kind` gives it.
parentRevisionId?stringFor 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
MemberTypeSummary
commentMarkers?CommentMarkerStyleDefault `'icon'`.
opening?ReviewPaneOpeningDefault `'auto'`.
overflow?ReviewPaneOverflowDefault `'float'`.
revisionsIn?RevisionDisplayDefault `'pane'`.

ReviewPositioninterfaceSource ↗

A position in the model offset space of one story.

interface ReviewPosition
MemberTypeSummary
offsetnumber
paragraphIdstring

ReviewRangeinterfaceSource ↗

Where an item is anchored: a range in one story.

interface ReviewRange
MemberTypeSummary
endReviewPosition
partNamestring
startReviewPosition

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
MemberTypeSummary
addressRevisionAddressThe payload `acceptRevision` / `rejectRevision` take.
addressesreadonly RevisionAddress[]EVERY address this decision covers, `address` first.
authorstring
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?stringOOXML property-change element, used to resolve independently numbered formatting kinds.
formattingLanguages?readonly string[]Newly applied proofing language codes in a tracked formatting change.
idstringStable 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.
nestingnumberHow deeply this change is NESTED inside other changes, 0 for an unenclosed one.
pairedWith?stringThe other half of a move, or the other side of a delete/insert replacement.
rangesreadonly ReviewRange[]Every site this decision touches, in document order.
readOnlybooleanTrue when the engine cannot resolve this kind, so accept and reject must not be offered.
replacedRangeCount?numberHow many leading `ranges` are the STRUCK half of a replacement.
replacedTextstringThe words a replacement removes. Empty for every other kind.
replyIdsreadonly string[]Comments answering this change, in document order.
revisionKindReviewRevisionKind
structuralChanges?readonly ('rowInsert' | 'rowDelete' | 'cellInsert' | 'cellDelete' | 'cellMerge' | 'numberingInsert')[]Distinct structural operations covered by this decision, in document order.
textstringText the revision covers, for the card summary. Empty for changes with no characters.

ReviewRevisionPlacementinterfaceSource ↗

A tracked change's card.

interface ReviewRevisionPlacement extends ReviewItemPlacementBase
MemberTypeSummary
itemReviewRevisionItem
kind'revision'
replacedText?stringThe 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.
revisionKindReviewRevisionKindWhich 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
MemberTypeSummary
cause?stringThe 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?ReviewChangeKindThe kind of the skipped changes, absent when the change no longer exists.
codeReviewDiagnosticCode
countnumberHow many items were skipped for this code and kind in the one request.
formattingKind?FormattingChangeKindFor `changeKind: 'format'`, which property change it is.
kind'review.skipped'
operation?ReviewOperationWhat the request asked: accept, reject, or attribute to another author.
part?DocumentPartKindThe 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
MemberTypeSummary
authorstring
date?stringOPTIONAL. `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.
idnumberNumeric, and unique only WITHIN a part. Pair with `part` to address one.
partstringREQUIRED, and a canonical PART NAME rather than a three-value enum.
typeRevisionType

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
MemberTypeSummary
authorstring
date?stringAbsent when the file wrote no `@w:date`; part of the identity either way.
idstring

RevisionAuthorAssignmentsinterfaceSource ↗

Per-author style assignments.

Keys match w:author exactly; a value is a CSS colour or a full [RevisionAuthorStyle](RevisionAuthorStyle). others says what authors WITHOUT an entry take: the --doc-review-author-N ramp by default, or 'kind' to leave them on the kind colours — which is how "highlight these reviewers, leave everyone else green and red" is said.

interface RevisionAuthorAssignments
MemberTypeSummary
authorsReadonly<Record<string, string | RevisionAuthorStyle>>
others?'kind' | 'author'Authors without an entry: the ramp (default), or the `'kind'` colours.

RevisionAuthorEntryinterfaceSource ↗

One reattributed change. key and author describe the change after the update, because review keys include the author.

interface RevisionAuthorEntry extends RevisionBatchEntry
MemberTypeSummary
previousAuthorstringThe author the change had before the update.
previousKeystringThe 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
MemberTypeSummary
skippedreadonly { readonly key: string; readonly reason: RevisionAuthorSkipReason; readonly revision?: RevisionBatchEntry; }[]Requested changes that kept their attribution.
updatedreadonly RevisionAuthorEntry[]Changes that now carry the requested attribution, in selection order.

RevisionAuthorStyleinterfaceSource ↗

Everything a host can say about ONE author's presentation. Every field is optional and every field is presentation-only — nothing here is ever serialised into the document.

Deliberately about the PAINTED DOCUMENT (which only the painter can style) plus the author's identity data. Review-card DESIGN is not configured here: the review chrome follows color as its accent automatically, and everything further is composition — a custom card reading this style through the review surface's useReviewAuthor, or CSS on the cards' data-review-author/data-review-author-slot hooks.

interface RevisionAuthorStyle
MemberTypeSummary
activeBackground?stringBackground of the highlight band over this author's OPEN change — the one the caret is in. Applied inline, so it outranks the `--doc-revision-*-active-bg` kind tokens, and the kind-coloured rule under the band goes with it: a custom background with a green or red rule beneath it would contradict the decoration it sits behind, and a `transparent` that left a floating rule would not read as cleared at all.
avatarUrl?stringAvatar image for this author; the packaged card renders it in place of initials.
background?stringBackground wash behind this author's changes in the document.
color?stringInk and decoration colour of this author's changes in the document — and the accent the review chrome keys on (avatar disc, card variable, marker).
spanClassName?stringClass names added to every painted span of this author's changes, for styling the typed fields do not cover. Keep the rules metric-safe (outlines, shadows, accents): the engine measures the text it paints, and a class that resizes glyphs drifts the page from its layout.

RevisionBatchEntryinterfaceSource ↗

A canonical review decision. Keys are valid only in the open document.

interface RevisionBatchEntry
MemberTypeSummary
authorstring
formattingKind?stringFor a formatting change, its OOXML property-change element, as the review item has it.
keystring
partNamestring
revisionKindReviewRevisionItem['revisionKind']

RevisionBatchResultinterfaceSource ↗

Outcome of one selected-set decision. Counts refer to review decisions, not XML markers.

interface RevisionBatchResult
MemberTypeSummary
remainingnumberAll pending decisions in the addressed scope, including excluded and unsupported changes.
resolvedreadonly RevisionBatchEntry[]
skippedreadonly { readonly key: string; readonly reason: RevisionBatchSkipReason; readonly revision?: RevisionBatchEntry; readonly detail?: RevisionBatchSkipDetail; }[]

RevisionMarkupChromeHandlersinterfaceSource ↗

Host rendering for the Track changes options dialog.

interface RevisionMarkupChromeHandlers
MemberTypeSummary
onRequest?(session: RevisionMarkupDialogSession) => void

RevisionMarkupDialoginterfaceSource ↗

Viewer settings dialog supplied by the review module.

interface RevisionMarkupDialog
MemberTypeSummary
destroy
open

RevisionMarkupDialogHostinterfaceSource ↗

Local settings access for review chrome. No document mutations occur here.

interface RevisionMarkupDialogHost extends RevisionMarkupDialogSession
MemberTypeSummary
containerHTMLElement
translate?(key: string) => string | undefined

RevisionMarkupDialogSessioninterfaceSource ↗

A local settings draft owned by the editor.

interface RevisionMarkupDialogSession
MemberTypeSummary
applyCommit the draft and close. Returns false after cancellation.
canApply
cancelClose without committing the draft.
getRead the immutable draft.
resetRestore default preferences in the draft only.
setMerge validated options into the draft without committing preferences.
signalAbortSignalAborts on close, replacement, load, detach, destroy, or renderer disposal.
subscribeObserve draft changes, including effective external preference changes.

RevisionMarkupStyleinterfaceSource ↗

interface RevisionMarkupStyle<Mark extends string = RevisionMarkupMark>
MemberTypeSummary
colorRevisionMarkupColor
markMark

RevisionMarkupTextStyleinterfaceSource ↗

Viewer-only text styling. Document highlighting remains unchanged.

interface RevisionMarkupTextStyle<Mark extends string = RevisionMarkupMark> extends RevisionMarkupStyle<Mark>
MemberTypeSummary
backgroundRevisionMarkupNamedColor | 'byAuthor' | 'none'Background color behind revision text. Defaults to `none`.

RuninterfaceSource ↗

A stretch of text sharing one set of character properties.

interface Run
MemberTypeSummary
formatting?RunFormatting
revisionId?numberSet when the run carries a tracked change. Unique only within its part.
textstring

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
MemberTypeSummary
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?ParagraphDisagreementsWhich paragraph-level fields above are absent because the selection DISAGREES, as opposed to because nothing states them.
fontFamily?string
fontSizePt?number
highlight?string
indent?IndentFormattingThe 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?ParagraphFlagsThe paragraph flags the Paragraph dialog shows as checkboxes.
spaceAfterPt?number
spaceBeforePt?numberSpace above and below the paragraph at the selection, in points.
strike?boolean
styleId?stringParagraph 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
MemberTypeSummary
behavior?'instant' | 'smooth'Default: instant. Reduced motion uses instant even when smooth is requested.
block?ScrollPlacementTarget placement. The default depends on the method: `scrollToAnchor` uses `'centerIfNeeded'`, which keeps the viewport still for a visible target, and `scrollToBlock` uses `'start'`.
offsetPx?numberEdge 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
MemberTypeSummary
footersHeaderFooterSet
headersHeaderFooterSet
propertiesSectionProperties

SectionPropertiesinterfaceSource ↗

w:sectPr: the page a section lays out on. Twips throughout, as the file stores them.

interface SectionProperties
MemberTypeSummary
columns?{ count: number; gapTwips: number; }
marginsPageMargins
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
MemberTypeSummary
canChangeWrapbooleanWhether `setImageWrapType` applies: pictures only, never text boxes.
canCropbooleanWhether `setImageProperties` can crop: pictures only, never text boxes.
canMovebooleanWhether `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.
canResizebooleanWhether `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.
cropImageCropPercentCrop inset per edge in UI percent (0–100); OOXML stores permille (×1000).
descriptionstring
heightEmunumber
hiddenboolean
idstring
intrinsicReadonly<{ readonly pixelWidth: number; readonly pixelHeight: number; readonly dpiX: number; readonly dpiY: number; }> | null
kindDrawingKind
locksDrawingLocks
namestring
positionDrawingPositionInput | null
resourceStatusImageResourceState['kind']
rotationDegreesnumber
titlestring
widthEmunumber
wrapImageWrapTarget

SemanticIdentityinterfaceSource ↗

Model-derived stable identity within a scope. Positions resolve through this index, not accumulated display-item lengths or editing-engine coordinates.

interface SemanticIdentity
MemberTypeSummary
blockIdstring
storyIdstring

SemanticPositioninterfaceSource ↗

A caret position in the model.

interface SemanticPosition
MemberTypeSummary
offsetnumber
paragraphIdstring

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
MemberTypeSummary
anchorSemanticPosition
headSemanticPosition

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
MemberTypeSummary
activeMsnumberMilliseconds of use: the time between key presses, pointer presses and edits that are at most 30 seconds apart. A longer pause counts as idle.
automationEditsnumberEditing API batches that changed the document.
commandEditsnumberEditor commands, from `exec(...)` or the toolbar, that changed the document.
durationMsnumberFor `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.
inputEditsnumberEdits 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
MemberTypeSummary
basedOn?string`w:basedOn` — the style this one inherits from. Absent at the root of a chain.
idstring
namestring

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
MemberTypeSummary
characterReadonlyMap<string, StyleDefinition>
paragraphReadonlyMap<string, StyleDefinition>
tableReadonlyMap<string, StyleDefinition>

SurfaceEquationinterfaceSource ↗

One addressable inline equation and its compact editable projection.

interface SurfaceEquation
MemberTypeSummary
endnumber
fallbackTextstring
idstring
linearstring
paragraphIdstring
startnumber
supportedbooleanTrue when every source construct belongs to the editable subset.

A hyperlink as the surface reports it: its identity, where it sits, and the SANITIZED target. href: null is an inert link — a refused scheme or a dangling relationship — which a UI shows and offers to edit but must never offer to open.

interface SurfaceHyperlink
MemberTypeSummary

TableinterfaceSource ↗

A table: its rows, and the table style they resolve through.

interface Table
MemberTypeSummary
kind'table'
rowsreadonly TableRow[]
styleId?string

TableBorderSpecinterfaceSource ↗

Complete border spec for [EditorCommands.setTableBorders](EditorCommands.setTableBorders). Size is in eighths of a point.

interface TableBorderSpec
MemberTypeSummary
colorColorValue
sizenumber
styleTableBorderStyle

TableCellinterfaceSource ↗

One cell. Its content is ordinary blocks, so a cell may hold paragraphs, nested tables and content controls alike.

interface TableCell
MemberTypeSummary
colSpan?number`w:gridSpan`. Absent means 1.
contentreadonly Block[]
rowSpan?numberVertical 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
MemberTypeSummary
isHeaderRepeatboolean
leftGridColumnIdstring
rightGridColumnIdstring
sourceRevisionnumber
tableIdstring

TableColumnOccurrenceTargetinterfaceSource ↗

Explicit column occurrence. sourceRevision per [TableColumnDividerResizeTarget](TableColumnDividerResizeTarget).

interface TableColumnOccurrenceTarget
MemberTypeSummary
gridColumnIdstring
isHeaderRepeatboolean
sourceRevisionnumber
tableIdstring

TableContextinterfaceSource ↗

Where the caret sits inside a table: its shape and current cell.

interface TableContext
MemberTypeSummary
columnIndexnumberZero-based, within the row.
columnsnumber
rowIndexnumberZero-based, within the table.
rowsnumber

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
MemberTypeSummary
gridColumnIdstring
isHeaderRepeatboolean
sourceRevisionnumber
tableIdstring

TableRowinterfaceSource ↗

One table row. Cell count may vary between rows: colSpan and vertical merges reshape it.

interface TableRow
MemberTypeSummary
cellsreadonly TableCell[]

TableRowOccurrenceTargetinterfaceSource ↗

Explicit row occurrence. sourceRevision per [TableColumnDividerResizeTarget](TableColumnDividerResizeTarget).

interface TableRowOccurrenceTarget
MemberTypeSummary
isHeaderRepeatboolean
rowIdstring
sourceRevisionnumber
tableIdstring

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
MemberTypeSummary
blockIdstring
contextAfter?string
contextBefore?stringParagraph 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.
lengthnumber
paragraphIndexnumberParagraph ordinal within this match's story. Table and nested-table paragraphs count. Non-paragraph blocks add no ordinal.
runIndexnumberIndex of the run the match starts in, and the offset within that run.
runOffsetnumber
scope?ViewScopeStory containing the match. Absence means the body.
startnumberCharacter offset within the paragraph's concatenated run text.
textstringThe matched text as it appears in the document.

ThemeinterfaceSource ↗

theme1.xml — what a [ColorValue](ColorValue) of kind theme resolves against.

interface Theme
MemberTypeSummary
colorSchemeThemeColorScheme
fontScheme?Record<string, string>

TimingSummaryinterfaceSource ↗

Timings of one kind over a performance window. Every value is in milliseconds, rounded to whole milliseconds.

interface TimingSummary
MemberTypeSummary
bandsreadonly 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.
countnumberTimings measured in the window.
maxMsnumberThe slowest timing, always exact.
p50MsnumberMedian. Exact up to 2048 timings; above that, from a uniform sample of 2048.
p95Msnumber95th percentile, from the same sample as the median.

ToolbarCommandStateinterfaceSource ↗

Whether one control is enabled, and the engine's reason when it is not.

interface ToolbarCommandState
MemberTypeSummary
activebooleanWhether the command is currently APPLIED at the selection, from `Editor.isActive` — derived in the engine for marks and alignment, honest-false elsewhere.
disabledReasonstring | nullThe engine's reason when disabled — surfaced as a tooltip, never invented.
enabledboolean
idChromeSlotId
value?stringWhat the control currently SHOWS, for the slots whose answer is a value rather than a pressed state — the editing-mode pill, and image wrap when it lands.

ToolbarValueMapinterfaceSource ↗

Value types accepted by toolbar controls. Font size uses half-points.

interface ToolbarValueMap
MemberTypeSummary
"font.family"string
"font.size"number
"image.altText"string
"image.wrap"ImageWrapTarget
"list.lineSpacing"number
"review.editingMode"'editing' | 'suggesting' | 'viewing'
"styles.style"string
"text.color"string
"text.highlight"string

ValidatedImageBytesHandleinterfaceSource ↗

Opaque handle — bytes are reachable only through [mintValidatedImageBytes](mintValidatedImageBytes).

interface ValidatedImageBytesHandle
MemberTypeSummary
contentIdstring
generationnumber
registryIdnumber
resourceKeystring

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 } });
```
MemberTypeSummary
bold?booleanText: bold. Defaults to false.
color?stringText: the colour as `RRGGBB`. Defaults to `C0C0C0` (silver).
fontFamily?stringText: the font family. Defaults to `Calibri`.
fontSizePt?number | nullText: the size in points, from 1 to 1000. Omitted or null is Auto, which fills the page.
imageData?Uint8ArrayThe PNG, JPEG, GIF, BMP or WebP bytes of a picture watermark.
italic?booleanText: italic. Defaults to false.
layout?WatermarkLayoutText: the orientation. Defaults to `diagonal`.
scale?number | nullPicture: a factor of the picture's natural size. Omitted or null is Auto, which fits the page.
text?stringThe text of a text watermark, up to 256 characters on one line.
transparency?numberText: transparency from 0 (opaque) to 1. Defaults to 0.5.
washout?booleanPicture: 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
MemberTypeSummary
bold?boolean
color?string`RRGGBB`.
fontFamily?string
fontSizePt?number | nullNull for Auto size.
italic?boolean
kind'text' | 'image'
layout?WatermarkLayout
text?string
transparency?number
washout?boolean

Type aliases (133)

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;
};

ChromeExportFormattypeSource ↗

File menu conversion formats.

type ChromeExportFormat = 'markdown' | 'pdf';

ChromeMenuEntrytypeSource ↗

One row of a chrome menu.

type ChromeMenuEntry = ChromeMenuItemEntry | ChromeMenuSubmenuEntry | ChromeMenuSeparatorEntry;

ChromeMenuIdtypeSource ↗

Every menu id, as a literal union. Stable public API; renaming one is a breaking change, exactly like a group or slot id.

type ChromeMenuId = 'file' | 'format' | 'insert' | 'review' | 'help';

ChromePrintErrorCodetypeSource ↗

Why the browser could not print the converted PDF.

type ChromePrintErrorCode = 'pdf-viewer-unavailable' | 'pdf-load-failed' | 'print-refused' | 'print-ended';

ChromeSlotIdtypeSource ↗

The public slot vocabulary: ${groupId}.${controlId} for every control that actually exists — text.bold, font.family, alignment.left. THE stable contract a host composes against and commandForSlot resolves; renaming a slot is a breaking change.

type ChromeSlotId = 'history.undo' | 'history.redo' | 'zoom.level' | 'styles.style' | 'font.family' | 'font.size' | 'text.bold' | 'text.italic' | 'text.underline' | 'text.strike' | 'text.color' | 'text.highlight' | 'text.link' | 'script.super' | 'script.sub' | 'alignment.left' | 'alignment.center' | 'alignment.right' | 'alignment.justify' | 'direction.ltr' | 'direction.rtl' | 'list.bullet' | 'list.numbered' | 'list.outdent' | 'list.indent' | 'list.lineSpacing' | 'format.painter' | 'format.clear' | 'review.revisionMarkup' | 'review.comments' | 'review.addComment' | 'review.paragraphMarks' | 'review.bookmarks' | 'review.protectDocument' | 'review.compareDocuments' | 'review.simpleMarkup' | 'review.allMarkup' | 'review.noMarkup' | 'review.original' | 'review.previousChange' | 'review.nextChange' | 'review.acceptAllChanges' | 'review.rejectAllChanges' | 'review.authors' | 'review.editingMode' | 'contentControl.showAll' | 'contentControl.formFill' | 'contentControl.inspector' | 'contentControl.remove' | 'image.insert' | 'image.properties' | 'image.wrap' | 'image.altText' | 'table.insert' | 'table.borderTarget' | 'table.borderColor' | 'table.borderStyle' | 'table.borderWidth' | 'table.cellFill' | 'table.mergeCells' | 'table.splitCell' | 'file.open' | 'file.save' | 'file.exportMarkdown' | 'file.exportPdf' | 'file.print' | 'paragraph.dialog' | 'file.pageSetup' | 'insert.textBox' | 'insert.footnote' | 'insert.endnote' | 'insert.pageNumber' | 'insert.totalPages' | 'insert.sectionPages' | 'insert.pageXofY' | 'insert.pageBreak' | 'insert.sectionBreakNextPage' | 'insert.sectionBreakContinuous' | 'insert.toc' | 'insert.bookmark' | 'insert.goToBookmark' | 'insert.watermark';

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';

CollectReviewItemstypeSource ↗

Derives the review queue — every pending revision decision and comment thread — from one story part plus its comment parts. Implemented by the pro review module; the free engine has no implementation and reports an empty queue.

type CollectReviewItems = (input: ReviewModelInput) => readonly ReviewItem[];

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';

CompareDocumentsBackgroundEnginetypeSource ↗

Runs a compare off the page's main thread, for example in a worker. The editor's Compare documents dialog uses it when the review module provides one. It reports progress, and it stops when signal aborts: the promise then rejects with the signal's reason.

type CompareDocumentsBackgroundEngine = (original: Uint8Array, revised: Uint8Array, options: CompareDocumentsEngineOptions, control: {
    readonly signal: AbortSignal;
    readonly onProgress: (progress: CompareDocumentsProgress) => void;
}) => Promise<CompareDocumentsBackgroundResult>;

CompareDocumentsBackgroundResulttypeSource ↗

Result of one background compare: like [CompareDocumentsEngineResult](CompareDocumentsEngineResult), as bytes.

type CompareDocumentsBackgroundResult = {
    readonly ok: true;
    readonly bytes: Uint8Array | null;
    readonly revisionCount: number;
    readonly changed: boolean;
} | {
    readonly ok: false;
    readonly code: CompareDocumentsEngineErrorCode;
    readonly reason?: CompareDocumentsRefusalReason;
    readonly message: string;
};

CompareDocumentsEnginetypeSource ↗

Compares the open document (the original) with a revised DOCX and returns the original with the differences as tracked changes. Synchronous, DOM-free, and free of side effects.

type CompareDocumentsEngine = (original: OoxmlPackage, revised: Uint8Array, options: CompareDocumentsEngineOptions) => CompareDocumentsEngineResult;

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';

CompareDocumentsEngineResulttypeSource ↗

Result of one document compare.

type CompareDocumentsEngineResult = {
    readonly ok: true;
    readonly package: OoxmlPackage;
    readonly revisionCount: number;
    readonly changed: boolean;
} | {
    readonly ok: false;
    readonly code: CompareDocumentsEngineErrorCode;
    readonly reason?: CompareDocumentsRefusalReason;
    readonly message: string;
};

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+';

CustomFontsResolvertypeSource ↗

A font origin that supplies validated application font bytes on demand.

type CustomFontsResolver = MarkedFontResolver<(request: FontResolutionRequest) => Promise<LoadFontsResult>>;

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';

DocEdittypeSource ↗

One edit, as a discriminated union derived from [DocEdits](DocEdits).

Adding a key to DocEdits — including by declaration merging from a plugin — widens this automatically, so the union never drifts from the vocabulary it is built out of.

type DocEdit = {
    [K in keyof DocEdits]: {
        type: K;
    } & DocEdits[K];
}[keyof DocEdits];

DocQuerytypeSource ↗

One query, as a discriminated union derived from [DocQueries](DocQueries).

type DocQuery = {
    [K in keyof DocQueries]: {
        type: K;
    } & DocQueries[K];
}[keyof DocQueries];

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';

FieldResultsModetypeSource ↗

How saved field results are addressed.

- atomic: every closed field is one offset unit. - editable: the results of CREATEDATE, DATE, FILENAME, FILLIN, HYPERLINK, MERGEFIELD, PRINTDATE, QUOTE, SAVEDATE, SEQ, and TIME fields are text when their results are unnested. Simple fields inside complex field results are not supported in this mode. Other nested results, other field types, and legacy FORMTEXT inputs keep their existing addressing.

type FieldResultsMode = 'atomic' | 'editable';

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';

FontLoadFailureReasontypeSource ↗

Why one font did not load.

Distinguished rather than collapsed to "failed" because the responses differ: networkError and httpError are worth retrying, while hashMismatch and malformed mean the bytes were not what the source claimed and retrying will fetch the same wrong thing.

type FontLoadFailureReason = 'networkError' | 'httpError' | 'hashMismatch' | 'overLimit' | 'emptyResponse'
/** The declared face itself is unusable (empty family, out-of-range weight); nothing was fetched. */
 | 'invalidRequest'
/** The bytes are not a font at all — most often an HTML error page served with 200. */
 | 'malformed';

FontOrigintypeSource ↗

ONE font origin, in the one shape every origin takes: a finished configuration, a fragment, a promise for either, or a marked resolver that answers per document.

The point of the union is that packagedFonts(), googleFonts(), await defaultFonts() and a hand-built { sources } are all the same kind of thing, so a list of them needs no ordering rule beyond "first wins".

The resolver arm is [MarkedFontResolver](MarkedFontResolver), not bare FontResolver: a list may also hold a zero-argument loader, and only the mark separates the two.

type FontOrigin = FontConfiguration | FontConfigurationFragment | MarkedFontResolver | Promise<FontConfiguration | FontConfigurationFragment | undefined> | undefined;

FontResolvertypeSource ↗

Resolve fonts once the document's needs are known, instead of ahead of them.

Called after the file is mounted and again when editing requests a new family. Results compose with previously supplied faces; resolvedFaces identifies that coverage. Returning nothing is a valid answer — it means "I cover none of this", and the document stays on the fixed measurer.

A resolver that fetches makes opening a document perform network requests. That is a real change in posture and it must stay the APP's decision: the engine never supplies one, and the families here are file-derived, so a resolver must look them up in a set it shipped rather than interpolate them into a URL.

type FontResolver = (request: FontResolutionRequest) => FontConfiguration | FontConfigurationFragment | undefined | Promise<FontConfiguration | FontConfigurationFragment | undefined>;

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';

LockedControlNavigationtypeSource ↗

How the caret moves through an inline content control whose effective lock is contentLocked or sdtContentLocked.

- 'characters' (the default) — the caret walks through the control's characters, as in Word. - 'atomic' — the control is one caret unit, as a w:showingPlcHdr prompt already is. Arrows step over it, Shift+arrows select it whole, and a press or double click inside it selects it whole. A press on its edge still places a caret beside it.

It applies in the body, headers and footers; notes and text boxes publish no control boundaries, so they keep character navigation.

Navigation only: what a lock refuses does not change. The rule covers keyboard motions and the engine's own pointer gestures. A selection set in code (setSelection, find) is kept as given, and pointer: 'native' leaves caret placement to the browser.

type LockedControlNavigation = 'characters' | 'atomic';

MarkedFontResolvertypeSource ↗

A [FontResolver](FontResolver) that has been through [defineFontResolver](defineFontResolver).

This, not bare FontResolver, is what a FontOrigin list accepts. The mark is the only thing separating a resolver from a zero-argument loader, and getting that wrong loses every font silently, so the type asks for it up front.

type MarkedFontResolver<T extends FontResolver = FontResolver> = T & FontResolverMark;

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;

ResolvedChromePrintSettingstypeSource ↗

Print settings with every choice made.

type ResolvedChromePrintSettings = Required<ChromePrintSettings>;

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';

RevisionStylestypeSource ↗

How painted tracked changes are coloured.

- 'author' (the DEFAULT) — every change takes its author's colour from the --doc-review-author-N ramp. An attached document seeds slots by order of first appearance, then keeps those assignments stable for that session. Word's own default, and the reason it is this engine's: a paragraph three people edited has to read as three people. Restyle a slot under .docx-editor to change the ramp. - 'kind' — insertions and deletions take the two kind colours (--doc-revision-insertion / --doc-revision-deletion), so "added" and "removed" are what a reader tells apart at a glance, whoever proposed them. - [RevisionAuthorAssignments](RevisionAuthorAssignments) — style the named authors; others decides whether the rest take the ramp (the default) or the kind colours.

Presentation only: nothing here is ever serialised into the document.

type RevisionStyles = 'kind' | 'author' | RevisionAuthorAssignments;

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';

TableChromeSlotIdtypeSource ↗

The chrome slots that only exist while the caret is inside a table.

A subset of ChromeSlotId, so these names are public API on the same terms — renaming one is a breaking change.

type TableChromeSlotId = 'table.borderTarget' | 'table.borderColor' | 'table.borderStyle' | 'table.borderWidth' | 'table.cellFill';

TableInteractionLabelKeytypeSource ↗

Keys for the table furniture's accessible names, resolved by tableInteractionLabel.

type TableInteractionLabelKey = 'table.insertRowBelow' | 'table.insertColumnRight' | 'table.selectTable';

TargetModetypeSource ↗

Whether a relationship points inside the package or out of it.

The security-relevant distinction: an External target is retained VERBATIM and never owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click external fetch.

type TargetMode = 'Internal' | 'External';

ThemeColorSchemetypeSource ↗

Theme colour slots (accent1, dk1, lt2, …) to hex.

type ThemeColorScheme = Readonly<Record<string, string>>;

ToolbarValueSlottypeSource ↗

type ToolbarValueSlot = keyof ToolbarValueMap | TableChromeSlotId;

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 (12)

CHROME_GROUPSconstSource ↗

The complete chrome, in bar order. Literal-typed (as const) so the slot-id vocabulary below is derived from the data and cannot drift from it.

Taxonomy taste: ids are short, lowercaseCamel, and never repeat their group's name (alignment.left, not alignment.alignLeft; font.family, not font.fontFamily).

CHROME_GROUPS: readonly [{
    readonly id: 'history';
    readonly labelKey: 'formattingBar.groups.history';
    readonly controls: readonly [{
        readonly id: 'undo';
        readonly labelKey: 'formattingBar.undoShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'redo';
        readonly labelKey: 'formattingBar.redoShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'zoom';
    readonly labelKey: 'formattingBar.groups.zoom';
    readonly controls: readonly [{
        readonly id: 'level';
        readonly shape: 'stepper';
        readonly valueText: '100%';
        readonly labelKey: 'formattingBar.groups.zoom';
        readonly paths: null;
        readonly valueKey: 'zoom.zoomLevel';
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'styles';
    readonly labelKey: 'formattingBar.groups.styles';
    readonly controls: readonly [{
        readonly id: 'style';
        readonly shape: 'dropdown';
        readonly labelKey: 'styles.selectAriaLabel';
        readonly paths: null;
        readonly valueKey: 'styles.normalText';
        readonly state: {
            readonly kind: 'value';
        };
    }];
}, {
    readonly id: 'font';
    readonly labelKey: 'formattingBar.groups.font';
    readonly controls: readonly [{
        readonly id: 'family';
        readonly shape: 'dropdown';
        readonly labelKey: 'font.selectAriaLabel';
        readonly paths: null;
        readonly valueKey: 'font.sansSerif';
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'size';
        readonly shape: 'stepper';
        readonly valueText: '11';
        readonly labelKey: 'fontSize.listLabel';
        readonly paths: null;
        readonly valueKey: 'fontSize.label';
        readonly state: {
            readonly kind: 'value';
        };
    }];
}, {
    readonly id: 'text';
    readonly labelKey: 'formattingBar.groups.textFormatting';
    readonly controls: readonly [{
        readonly id: 'bold';
        readonly labelKey: 'formattingBar.boldShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'italic';
        readonly labelKey: 'formattingBar.italicShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'underline';
        readonly labelKey: 'formattingBar.underlineShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'strike';
        readonly labelKey: 'formattingBar.strikethrough';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'color';
        readonly shape: 'colorSplit';
        readonly swatch: '#ff0000';
        readonly labelKey: 'formattingBar.fontColor';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'highlight';
        readonly shape: 'colorSplit';
        readonly swatch: '#ffff00';
        readonly labelKey: 'formattingBar.highlightColor';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'link';
        readonly labelKey: 'formattingBar.insertLinkShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'script';
    readonly labelKey: 'formattingBar.groups.script';
    readonly controls: readonly [{
        readonly id: 'super';
        readonly labelKey: 'formattingBar.superscript';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'sub';
        readonly labelKey: 'formattingBar.subscript';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'alignment';
    readonly labelKey: 'formattingBar.groups.alignment';
    readonly controls: readonly [{
        readonly id: 'left';
        readonly labelKey: 'alignment.alignLeft';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'center';
        readonly labelKey: 'alignment.center';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'right';
        readonly labelKey: 'alignment.alignRight';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'justify';
        readonly labelKey: 'alignment.justify';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'direction';
    readonly labelKey: 'formattingBar.groups.direction';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'ltr';
        readonly labelKey: 'toolbar.leftToRight';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'rtl';
        readonly labelKey: 'toolbar.rightToLeft';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'list';
    readonly labelKey: 'formattingBar.groups.listFormatting';
    readonly controls: readonly [{
        readonly id: 'bullet';
        readonly labelKey: 'lists.bulletList';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'numbered';
        readonly labelKey: 'lists.numberedList';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'outdent';
        readonly labelKey: 'lists.decreaseIndent';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'indent';
        readonly labelKey: 'lists.increaseIndent';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'lineSpacing';
        readonly shape: 'dropdown';
        readonly labelKey: 'lineSpacing.label';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'format';
    readonly labelKey: 'formattingBar.groups.format';
    readonly controls: readonly [{
        readonly id: 'painter';
        readonly labelKey: 'formattingBar.formatPainterShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'clear';
        readonly labelKey: 'formattingBar.clearFormatting';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'review';
    readonly labelKey: 'formattingBar.commentsAndChanges';
    readonly controls: readonly [{
        readonly id: 'revisionMarkup';
        readonly shape: 'icon';
        readonly labelKey: 'revisionMarkup.title';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'simpleMarkup';
        readonly shape: 'icon';
        readonly labelKey: 'review.simpleMarkup';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'allMarkup';
        readonly shape: 'icon';
        readonly labelKey: 'review.allMarkup';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'noMarkup';
        readonly shape: 'icon';
        readonly labelKey: 'review.noMarkup';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'original';
        readonly shape: 'icon';
        readonly labelKey: 'review.original';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'previousChange';
        readonly shape: 'icon';
        readonly labelKey: 'review.previousChange';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'nextChange';
        readonly shape: 'icon';
        readonly labelKey: 'review.nextChange';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'acceptAllChanges';
        readonly shape: 'icon';
        readonly labelKey: 'review.acceptAllChanges';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'rejectAllChanges';
        readonly shape: 'icon';
        readonly labelKey: 'review.rejectAllChanges';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'paragraphMarks';
        readonly shape: 'icon';
        readonly labelKey: 'formattingBar.paragraphMarks';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'bookmarks';
        readonly shape: 'icon';
        readonly labelKey: 'formattingBar.showBookmarks';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'protectDocument';
        readonly shape: 'icon';
        readonly labelKey: 'review.protectDocument';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'compareDocuments';
        readonly shape: 'icon';
        readonly labelKey: 'review.compareDocuments';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'comments';
        readonly shape: 'icon';
        readonly labelKey: 'formattingBar.commentsAndChanges';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'addComment';
        readonly shape: 'icon';
        readonly labelKey: 'formattingBar.addComment';
        readonly defaultToolbar: false;
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'authors';
        readonly shape: 'dropdown';
        readonly labelKey: 'reviewers.label';
        readonly paths: readonly string[];
        readonly defaultToolbar: false;
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'editingMode';
        readonly shape: 'dropdown';
        readonly labelKey: 'editingMode.label';
        readonly valueKey: 'editingMode.editing';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'contentControl';
    readonly labelKey: 'contentControl.group';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'showAll';
        readonly labelKey: 'contentControl.showAll';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'formFill';
        readonly labelKey: 'contentControl.formFill';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'inspector';
        readonly labelKey: 'contentControl.inspector';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'remove';
        readonly labelKey: 'contentControl.remove';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'image';
    readonly labelKey: 'formattingBar.groups.image';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'insert';
        readonly labelKey: 'toolbar.image';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'properties';
        readonly labelKey: 'formattingBar.imagePropertiesShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'wrap';
        readonly shape: 'dropdown';
        readonly labelKey: 'formattingBar.imageWrap';
        readonly paths: readonly string[];
        readonly valueKey: 'imageWrap.inline';
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'altText';
        readonly shape: 'dropdown';
        readonly labelKey: 'formattingBar.altText';
        readonly paths: null;
        readonly valueKey: 'imageProperties.altText';
        readonly state: {
            readonly kind: 'value';
        };
    }];
}, {
    readonly id: 'table';
    readonly labelKey: 'formattingBar.groups.table';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'insert';
        readonly labelKey: 'toolbar.table';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'borderTarget';
        readonly shape: 'dropdown';
        readonly labelKey: 'table.borders.tooltip';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'borderColor';
        readonly shape: 'colorSplit';
        readonly swatch: '#000000';
        readonly labelKey: 'table.borderColor';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'borderStyle';
        readonly shape: 'dropdown';
        readonly labelKey: 'table.borders.styleAriaLabel';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'borderWidth';
        readonly shape: 'dropdown';
        readonly labelKey: 'table.borderWidth';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'cellFill';
        readonly shape: 'colorSplit';
        readonly swatch: '#ffffff';
        readonly labelKey: 'table.cellFillColor';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'value';
        };
    }, {
        readonly id: 'mergeCells';
        readonly labelKey: 'table.mergeCells';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'splitCell';
        readonly labelKey: 'table.splitCell';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'paragraph';
    readonly labelKey: 'dialogs.paragraph.title';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'dialog';
        readonly labelKey: 'lineSpacing.options';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'file';
    readonly labelKey: 'toolbar.file';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'open';
        readonly labelKey: 'toolbar.open';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'load';
        };
    }, {
        readonly id: 'save';
        readonly labelKey: 'toolbar.saveShortcut';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'save';
        };
    }, {
        readonly id: 'exportMarkdown';
        readonly labelKey: 'toolbar.exportMarkdown';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'export';
        };
    }, {
        readonly id: 'exportPdf';
        readonly labelKey: 'toolbar.exportPdf';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'export';
        };
    }, {
        readonly id: 'print';
        readonly labelKey: 'toolbar.print';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'export';
        };
    }, {
        readonly id: 'pageSetup';
        readonly labelKey: 'toolbar.pageSetup';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}, {
    readonly id: 'insert';
    readonly labelKey: 'toolbar.insert';
    readonly contextual: true;
    readonly controls: readonly [{
        readonly id: 'textBox';
        readonly labelKey: 'toolbar.insertTextBox';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'footnote';
        readonly labelKey: 'toolbar.insertFootnote';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'endnote';
        readonly labelKey: 'toolbar.insertEndnote';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'pageNumber';
        readonly labelKey: 'headerFooter.insertPageNumber';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'totalPages';
        readonly labelKey: 'headerFooter.insertTotalPages';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'sectionPages';
        readonly labelKey: 'headerFooter.insertSectionPages';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'pageXofY';
        readonly labelKey: 'headerFooter.insertPageXofY';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'pageBreak';
        readonly labelKey: 'toolbar.pageBreak';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'sectionBreakNextPage';
        readonly labelKey: 'toolbar.sectionBreakNextPage';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'sectionBreakContinuous';
        readonly labelKey: 'toolbar.sectionBreakContinuous';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'toc';
        readonly labelKey: 'toolbar.tableOfContents';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'bookmark';
        readonly labelKey: 'toolbar.bookmark';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'goToBookmark';
        readonly labelKey: 'toolbar.goToBookmark';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }, {
        readonly id: 'watermark';
        readonly labelKey: 'toolbar.watermark';
        readonly paths: readonly string[];
        readonly state: {
            readonly kind: 'command';
        };
    }];
}]

CHROME_MENUSconstSource ↗

The menu bar the chrome shows above the toolbar, in bar order: File, Format, Insert, Review, Help.

CHROME_MENUS: readonly ChromeMenu[]

CHROME_PRINT_DISPLAY_MODESconstSource ↗

The display modes a print form offers, in Review menu order, with their label keys.

CHROME_PRINT_DISPLAY_MODES: readonly {
    readonly mode: ReviewDisplayMode;
    readonly labelKey: 'review.simpleMarkup' | 'review.allMarkup' | 'review.noMarkup' | 'review.original';
}[]

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_FONTconstSource ↗

The document default font when nothing else says otherwise: Calibri at 11pt.

DEFAULT_FONT: FontConfiguration['defaultFont']

DEFAULT_REVIEW_PANEconstSource ↗

The settings an editor starts with when nothing sets them.

DEFAULT_REVIEW_PANE: ResolvedReviewPane

DEFAULT_REVISION_MARKUPconstSource ↗

Initial viewer preferences.

DEFAULT_REVISION_MARKUP: ResolvedRevisionMarkup

DIAGNOSTIC_SCHEMA_VERSIONconstSource ↗

Version of the [EditorDiagnostic](EditorDiagnostic) shape. Raised only when a field changes meaning.

DIAGNOSTIC_SCHEMA_VERSION = 1

FONT_RESOLVER_BRANDconstSource ↗

The runtime marker defineFontResolver sets and [isFontResolver](isFontResolver) reads.

Exported because a package mirroring the font contract structurally still has to mark the resolvers it builds. A package in that position sets Symbol.for('docx-editor.dev/font-resolver') itself; this constant is the same symbol, named, for everyone who can import it.

FONT_RESOLVER_BRAND: unique symbol

FONT_RESOLVER_MARK_KEYconstSource ↗

The namespaced key carrying the type-level half of the mark, and the runtime property name that backs it.

A plain string rather than a symbol on purpose: @docx-editor.dev/fonts has no runtime or type dependency on the engine, so it declares the same mark itself, and two unique symbols in two packages would not unify. Two identical string keys do.

FONT_RESOLVER_MARK_KEY = "docx-editor.dev/font-resolver"

REVISION_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']

WORD_DEFAULT_FONTconstSource ↗

Deprecated. Use [DEFAULT_FONT](DEFAULT_FONT).

WORD_DEFAULT_FONT: FontConfiguration['defaultFont']