@docx-editor.dev/core/contracts/editor
@docx-editor.dev/core/contracts/editor — the Editor contract adapters are written against.
Commands go through can before exec; queries answer against the live, laid-out document. Type-only where it can be, so an adapter can name the whole surface without importing the engine.
CONTRACT ONLY — declarations, not an implementation.
Classes (1)
EditorFontErrorclassSource ↗
Typed adapter error reported both through onFontError and accessible alert UI.
declare class EditorFontError extends Error| Member | Type | Summary |
|---|---|---|
| (constructor) | | Constructs a new instance of the `EditorFontError` class |
| code | EditorFontErrorCode | |
| diagnostic? | string | |
| name | string | |
| request? | FontFaceRequest |
Interfaces (87)
AuthoredNoteNumberinginterfaceSource ↗
Authored note-numbering fields as Word's properties dialog writes them.
interface AuthoredNoteNumbering| Member | Type | Summary |
|---|---|---|
| numFmt? | string | |
| numRestart? | string | |
| numStart? | number | |
| pos? | string |
CommentRecordinterfaceSource ↗
One comment as authored in word/comments.xml.
interface CommentRecord| Member | Type | Summary |
|---|---|---|
| author | string | |
| blocks | readonly OoxmlElement[] | Body paragraphs, as tree nodes, so the surface renders measured text rather than a string. |
| date? | string | |
| id | string | |
| initials? | string | |
| paraId? | string | `w14:paraId` of the first 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. |
ContentControlinterfaceSource ↗
Structured document tag (w:sdt).
interface ContentControl| Member | Type | Summary |
|---|---|---|
| alias? | string | |
| content | readonly Block[] | |
| controlType | ContentControlType | |
| id | string | |
| kind | 'contentControl' | |
| locked? | boolean | |
| tag? | string |
ContentControlFilterinterfaceSource ↗
Narrows a content-control query. Fields combine with AND; an empty filter matches every control.
interface ContentControlFilter| Member | Type | Summary |
|---|---|---|
| alias? | string | |
| controlType? | ContentControlType | |
| tag? | string |
ContentControlSummaryinterfaceSource ↗
A content control reduced to what a listing needs: its identity, kind, and lock state.
interface ContentControlSummary| Member | Type | Summary |
|---|---|---|
| alias? | string | |
| controlType | ContentControlType | |
| id | string | |
| locked? | boolean | |
| tag? | string |
DocAnchorinterfaceSource ↗
The LLM- and JSON-facing address for a piece of a document.
paraId is the 8-hex w14:paraId, matched case-insensitively. search is a phrase that must match EXACTLY ONCE inside that paragraph; ambiguous or missing matches fail with 'ambiguous' / 'notFound' rather than falling back to first-match.
Offset-based addressing was tried and abandoned: an agent cannot compute a character offset it has not seen, and offsets do not survive concurrent edits. Do not reintroduce { blockId, offset }.
interface DocAnchor| Member | Type | Summary |
|---|---|---|
| occurrence? | number | Opt-in disambiguation. Omit to require uniqueness. |
| paraId | string | |
| search? | string |
DocAnchorRangeinterfaceSource ↗
A position in one story: a paragraph and a UTF-16 offset inside it.
The same offset space the ops and the caret use, so an anchor read here can be handed straight back to a selection without re-deriving anything.
interface DocAnchorRange| Member | Type | Summary |
|---|---|---|
| endOffset | number | |
| endParagraphId | string | May sit in a later paragraph: the range markers are independent elements. |
| part | string | Canonical part name of the story the range lives in, e.g. `/word/document.xml`. |
| startOffset | number | |
| startParagraphId | string |
DocCommentinterfaceSource ↗
One comment or reply, as comments.xml records it.
A reply is a comment with a parentId; OOXML gives replies no separate element, so the thread is reconstructed from that link rather than from nesting.
interface DocComment| Member | Type | Summary |
|---|---|---|
| anchor? | DocAnchorRange | Where the comment is anchored, absent when the file gave it no usable range. |
| author | string | |
| date? | string | OPTIONAL, because `CT_Comment` makes `@w:date` optional and files omit it. A comment with no date is a comment, not a defect, and fabricating one is a content change. |
| id | string | |
| orphaned? | boolean | True when the file gave this comment no usable range — a reference with no markers, or a start with no end. Reported rather than dropped: a reviewer's remark vanishing silently is worse than one that says it lost its text. |
| parentId? | string | |
| resolved? | boolean | |
| text | string |
DocEditsinterfaceSource ↗
The document-executable edit vocabulary.
An interface rather than a closed union so extensions can widen it by declaration merging. A sealed union cannot be extended by a plugin, and the runtime dispatch is already registry-backed.
interface DocEdits| Member | Type | Summary |
|---|---|---|
| acceptAllRevisions | Record<never, never> | |
| acceptRevision | {
id: number;
part?: 'body' | 'footnote' | 'endnote';
noteId?: number;
} | |
| addComment | {
target: DocTarget;
text: string;
author: string;
} | |
| addRepeatingSectionItem | {
target: DocTarget;
index?: number;
} | |
| adjustIndent | {
target: DocTarget;
direction: 'increase' | 'decrease';
} | Word's Increase/Decrease Indent. |
| applyFormatting | {
target: DocTarget;
marks: RunFormatting;
} | |
| applyVariables | {
values: Record<string, string>;
} | |
| deleteText | {
target: DocTarget;
} | |
| insertBreak | {
target: DocTarget;
kind: 'page' | 'column' | 'line' | 'section';
} | |
| insertHyperlink | {
target: DocTarget;
href: string;
text?: string;
} | |
| insertImage | {
target: DocTarget;
data: Uint8Array;
extent?: Extent;
} | |
| insertTable | {
target: DocTarget;
rows: number;
cols: number;
} | |
| insertText | {
target: DocTarget;
text: string;
} | |
| mergeParagraphs | {
target: DocTarget;
} | |
| proposeDeletion | {
target: DocTarget;
author: string;
} | |
| proposeInsertion | {
target: DocTarget;
text: string;
author: string;
} | |
| proposeReplacement | {
target: DocTarget;
replaceWith: string;
author: string;
} | Authored family. `author` is required: tracked-ness is verb identity, not a boolean flag, so there is no global trackChanges toggle to forget. |
| rejectAllRevisions | Record<never, never> | |
| rejectRevision | {
id: number;
part?: 'body' | 'footnote' | 'endnote';
noteId?: number;
} | |
| removeContentControl | {
target: DocTarget;
} | |
| removeHyperlink | {
target: DocTarget;
} | |
| removeRepeatingSectionItem | {
target: DocTarget;
index: number;
} | |
| replaceText | {
target: DocTarget;
text: string;
} | |
| replyComment | {
commentId: string;
text: string;
author: string;
} | |
| resolveComment | {
commentId: string;
} | |
| setContentControlValue | {
target: DocTarget;
value: string;
} | |
| setParagraphStyle | {
target: DocTarget;
styleId: string;
} | |
| setVariable | {
name: string;
value: string;
} | |
| splitParagraph | {
target: DocTarget;
} | |
| toggleList | {
target: DocTarget;
kind: 'bullet' | 'ordered';
} | Word's Bullets and Numbering. |
DocLocationinterfaceSource ↗
Structural addressing for content the paraId map cannot reach.
interface DocLocation| Member | Type | Summary |
|---|---|---|
| container | ContainerRef | |
| offset? | number | |
| path | number[] | Block indices, descending into tables and content controls. |
DocQueriesinterfaceSource ↗
The document-readable query vocabulary, keyed identically to [DocQueryResults](DocQueryResults).
An interface rather than a closed union for the same reason [DocEdits](DocEdits) is: an extension widens it by declaration merging, and the runtime dispatch is registry-backed.
interface DocQueries| Member | Type | Summary |
|---|---|---|
| comments | {
resolved?: boolean;
} | |
| contentControls | {
filter?: ContentControlFilter;
} | |
| findText | {
text: string;
container?: ContainerRef;
} | |
| paragraphs | {
container?: ContainerRef;
} | |
| revisions | {
part?: 'body' | 'footnote' | 'endnote';
} | |
| styles | Record<never, never> | |
| variables | Record<never, never> |
DocQueryResultsinterfaceSource ↗
What each query returns. Keyed identically to DocQueries.
interface DocQueryResults| Member | Type | Summary |
|---|---|---|
| comments | readonly DocComment[] | |
| contentControls | readonly ContentControlSummary[] | |
| findText | readonly DocRange[] | |
| paragraphs | readonly ParagraphSummary[] | |
| revisions | readonly Revision[] | |
| styles | StyleDefinitions | |
| variables | Readonly<Record<string, string>> |
DocRangeinterfaceSource ↗
A span between two positions. The endpoints may be addressed either way, independently.
interface DocRange| Member | Type | Summary |
|---|---|---|
| from | DocAnchor | DocLocation | |
| to | DocAnchor | DocLocation |
DocumentBodyinterfaceSource ↗
The main story: its blocks in reading order, plus the sections derived from them.
interface DocumentBody| Member | Type | Summary |
|---|---|---|
| content | readonly Block[] | |
| sections | readonly Section[] | Derived, not stored: recomputed on read from section-break markers and section inheritance. Never treat it as a spreadable field. |
DocumentChangeinterfaceSource ↗
The payload of the change event / onChange. It carries revision + identity deltas, NOT serialized bytes: serializing a whole DOCX on every keystroke would be prohibitive for large documents. Call save() to get bytes on demand.
interface DocumentChange| Member | Type | Summary |
|---|---|---|
| created? | readonly string[] | Block ids created/deleted/edited by this change, when the engine reports them. |
| deleted? | readonly string[] | |
| dirty? | readonly string[] | |
| revision | number | The store revision after this change. |
DocumentHandleinterfaceSource ↗
An opaque handle to a loaded document — its stable identity and current revision. The canonical authored state is the engine's PackageModel, NOT a simplified tree; advanced automation (DocxEditor.run(handle, …)) addresses a document through this handle rather than a serialized structure. Kept deliberately minimal and open so it can carry more identity later without a breaking change.
interface DocumentHandle| Member | Type | Summary |
|---|---|---|
| revision | number | The document's current store revision. |
DocxDocumentinterfaceSource ↗
A parsed .docx.
NOT JSON-round-trippable: it holds Maps and Dates, plus an internal side-table of verbatim XML used for lossless round-tripping. Use toJSON / fromJSON before sending it over JSON-RPC or handing it to a model.
interface DocxDocument| Member | Type | Summary |
|---|---|---|
| body | DocumentBody | |
| comments | readonly DocComment[] | |
| revisions | readonly Revision[] | |
| styles | StyleDefinitions | |
| theme? | Theme |
DocxDocumentJSONinterfaceSource ↗
The JSON-safe projection of a document.
interface DocxDocumentJSON| Member | Type | Summary |
|---|---|---|
| (member-0) | |
DrawingLocksinterfaceSource ↗
What a drawing refuses: selection, movement, resizing, aspect change.
Read and honoured rather than advisory — chrome that offered a handle the store will refuse would promise an edit that cannot happen.
interface DrawingLocks| Member | Type | Summary |
|---|---|---|
| changeAspect | boolean | |
| move | boolean | |
| resize | boolean | |
| select | boolean |
DrawingPositionInputinterfaceSource ↗
An anchored drawing's position: offsets, and the frames they are relative to.
The relative-to bases matter as much as the offsets. Writing an offset without preserving its base re-anchors the drawing against a different reference and moves it somewhere nobody asked.
interface DrawingPositionInput| Member | Type | Summary |
|---|---|---|
| horizontalEmu? | number | |
| mode? | 'frame' | 'simple' | `'simple'` when `@simplePos="1"`: `horizontalEmu` / `verticalEmu` are authoritative `wp:simplePos` x/y. `'frame'` (default) uses positionH/V relative frames. |
| relativeToH? | DrawingHorizontalReferenceFrame | |
| relativeToV? | DrawingVerticalReferenceFrame | |
| verticalEmu? | number |
EditorinterfaceSource ↗
The engine's whole public surface: load and save, execute and query, observe and subscribe.
Commands go through can before exec — the same check chrome uses to decide whether a control is enabled, so a button and the engine never disagree about what is possible.
snapshot() is version-cached: the same reference until state actually moves, with reference-stable sub-objects, which is what makes it safe as a useSyncExternalStore source.
interface Editor```ts
const editor = createDocxEditor({ container });
editor.load(bytes);
if (editor.can({ type: 'toggleBold' }).ok) editor.exec({ type: 'toggleBold' });
const bytesOut = await editor.save();
```| Member | Type | Summary |
|---|---|---|
| acceptReviewItem | | Accept or reject the revision behind a card. |
| addComment | | Comment on the current selection. |
| can | | Dry run: reports whether `exec` would apply. Never reports `changed`. |
| canExecuteImageCommand | | Dry run for byte commands that require [Editor.executeImageCommand](Editor.executeImageCommand). Generic [Editor.can](Editor.can) on `insertImage` / `replaceImage` refuses with an async-path reason; this method answers whether async execution can proceed right now. |
| deleteReviewItem | | Discard the item behind a card: the destructive half of the review verbs. |
| destroy | | |
| exec | | |
| executeImageCommand | | Insert or replace picture bytes as one package undo unit. |
| findMatches | | Find matches for a query, for the find/replace dialog. |
| focus | | |
| getActiveScope | | |
| getAvailableFonts | | Every font family the editor can offer: 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 configured catalog rather than a dead picker. |
| getComments | | Comment threads anchored in the document. |
| getCurrentPage | | One-based page at the caret (default), or at the centre of the mounted scroll viewport. Viewport mode falls back to the caret when no measurable viewport is attached. |
| getCustomNodeDefinitions | | Custom-node definitions registered through `createDocxEditor({ modules })`, in registration order. |
| getDocumentFonts | | Font families the document actually uses, for the font picker. |
| getDocumentHandle | | An opaque handle to the current document (identity + revision). Replaces the former structured `getDocument()`; the canonical state is the engine `PackageModel`, not a tree. |
| getDocumentStyles | | Paragraph/character styles defined by the document, for the style picker. |
| getDocumentThemeColors | | The document theme's ten picker colours (`a:clrScheme`) in Word's column order (Background 1, Text 1, Background 2, Text 2, Accent 1-6), each a six-digit hex without '#'. Empty when the document has no complete scheme — the picker then falls back to a default palette. |
| getEditingMode | | How edits are written: directly, as suggestions, or not at all. |
| getHeaderFooterState | | Header/footer editing state: which region is being edited, if any. |
| getNotePreviewText | | Plain-text note preview for hover chrome. |
| getNotePropertiesState | | Resolved and authored note properties for the caret section — properties dialog read-model. |
| getOutline | | Heading outline for the navigation panel, in document order. |
| getPageGeometry | | Page boxes in stack coordinates, each with the text area the engine laid out. `contentBox` is the page inset by the section margin — rulers draw margin zones from it instead of assuming a default. The engine's margin is uniform on all four sides today, so this must not be presented as per-side fidelity it does not have. |
| getPageSetup | | Section page setup — size, orientation and margins — for the page-setup dialog. |
| getRenderScale | | Layout points to CSS pixels, zoom included. |
| getReviewItems | | Every pending decision in the document, with where its card belongs. |
| getReviewRevision | | A counter that changes exactly when [getReviewItems](getReviewItems) would return something new. |
| getSelectedImage | | The image at the selection, for the image toolbar and transform controls. |
| getSelectedTable | | The table containing the selection, for the table toolbar. `null` outside a table. |
| getSelectionFormatting | | Formatting at the current selection, for toolbar value display (font, size, colour, alignment, list state). `null` when nothing is selected or nothing is derivable. |
| getSelectionPlacement | | Where a comment on the current selection would sit, in the same space as [ReviewItemPlacement.anchorY](ReviewItemPlacement.anchorY), or null when nothing is selected. |
| getTableCellSelection | | Live rectangular cell selection, if any. `null` when the caret is not in a cell rectangle. |
| getTotalPages | | |
| getTrackedChanges | | Tracked changes in the document — body AND header/footer stories. |
| getWatermark | | The document watermark, for the watermark dialog. |
| getZoom | | |
| isActive | | Whether a formatting command is currently APPLIED at the selection — distinct from `can`, which answers whether it may run. |
| isReviewPaneOpen | | Whether the review pane is showing its cards. |
| load | | Load a new document (DOCX bytes or a handle), replacing the current one. |
| on | | |
| query | | |
| rejectReviewItem | | |
| relayout | | Replaces the module-scope cache-invalidation calls adapters make today. |
| replyToReviewItem | | Reply to a review item. |
| reportCustomNodeDiagnostic | | Report a custom-node diagnostic to the modules registered on THIS editor. |
| save | | Serialize the current canonical document to DOCX bytes — on demand, never per keystroke. |
| scrollToBlock | | |
| scrollToPage | | Scroll a page or a block into view. Returns false when the target does not exist or the host has no scroll container — a caller can tell "not found" from "scrolled". |
| selectMatch | | Move the selection to a found match — what a find dialog's next/previous do. |
| setActiveReviewItem | | Card to document: select the item's range and scroll to it. `null` clears the active item. |
| setActiveScope | | |
| setEditingMode | | |
| setReviewActivationExclusions | | Revision kinds the caret must never activate, or null for none. |
| setTableInteractionLabel | | Update table furniture aria labels without remounting the editor. |
| setZoom | | Set the display scale. Values outside a sane range are rejected rather than clamped silently, so a caller learns its input was refused. |
| snapshot | |
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| Member | Type | Summary |
|---|---|---|
| clearFormatting | Record<never, never> | Word's Clear All Formatting (Home Font the eraser). |
| commitTableColumnDividerResize | {
target: TableColumnDividerResizeTarget;
leftWidthTwips: number;
rightWidthTwips: number;
} | Commit an internal column-divider resize from an explicit pointer target. Widths are twips for the adjacent pair; their sum must match the pre-drag total. |
| commitTableRightEdgeResize | {
target: TableRightEdgeResizeTarget;
columnWidthTwips: number;
tableWidthTwips: number;
} | Commit an outer-right table-edge resize from an explicit pointer target. Updates the last grid column and overall table width together. |
| copy | Record<never, never> | Put the selected text on the clipboard. Reports `changed: false` — the document is untouched. |
| cut | Record<never, never> | Put the selected text on the clipboard and delete it. Refused at a collapsed selection, and — unlike `copy` — in a read-only document. |
| deleteColumn | {
target?: TableColumnOccurrenceTarget;
} | |
| deleteImage | {
drawingNodeId?: string;
expectedPackageRevision?: number;
} | Delete the selected picture drawing as one package undo unit. |
| deleteRow | {
target?: TableRowOccurrenceTarget;
} | |
| deleteTable | Record<never, never> | |
| insertColumn | {
where: 'left' | 'right';
target?: TableColumnOccurrenceTarget;
} | |
| insertImage | {
data: Uint8Array;
mime: SupportedImageMime;
widthPoints: number;
heightPoints: number;
expectedPackageRevision?: number;
title?: string;
description?: string;
hyperlink?: string;
} | Insert a raster image at the caret as one package undo unit. |
| insertRow | {
where: 'above' | 'below';
target?: TableRowOccurrenceTarget;
} | |
| insertToc | Record<never, never> | Insert a generated, hyperlink-enabled TOC for heading levels 1–3 at the selection. |
| mergeCells | Record<never, never> | |
| paste | {
text: string;
} | Insert `text` at the selection, replacing it, with newlines becoming real paragraph boundaries. |
| redo | Record<never, never> | |
| refreshToc | {
tocId?: string;
mode?: 'entire' | 'pageNumbers';
} | |
| removeTabMark | {
positionTwips: number;
} | Remove the tab stop at this position (twips) from the current paragraph. |
| 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 [TextMatch](TextMatch) rather than a `DocTarget` because that is what `findMatches` hands back, and re-deriving a target from it in the caller is where an off-by-one would come from. An empty `text` deletes the match, which is what a find/replace dialog means by replacing with nothing. |
| selectAll | Record<never, never> | Select the whole body. Word's Ctrl+A, as a command rather than only a keystroke. |
| selectTableRegion | {
region: 'table' | 'row' | 'column';
} | Select a table region — the whole table, the current row, or the current column. Legacy's table toolbar offers all three. |
| setAlignment | {
align: 'left' | 'center' | 'right' | 'justify';
} | |
| 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. |
| 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. |
| 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;
} | |
| splitCell | {
rows: number;
cols: number;
} | |
| toggleHeaderRow | Record<never, never> | |
| toggleList | {
kind: 'bullet' | 'ordered';
} | |
| toggleMark | {
mark: string;
} | |
| toggleReviewPane | Record<never, never> | Show or hide the review pane. |
| transformImage | {
drawingNodeId?: string;
expectedPackageRevision?: number;
action: 'rotateCW' | 'rotateCCW' | 'flipH' | 'flipV';
} | Rotate or flip the selected image. Legacy composed these into a CSS transform. |
| undo | Record<never, never> |
EditorErrorinterfaceSource ↗
An error the engine raised, carrying a machine-readable code alongside the message.
code is optional because an Error from deeper down (a parser, a codec) is surfaced as-is rather than wrapped in a fabricated code.
interface EditorError extends Error| Member | Type | Summary |
|---|---|---|
| code? | string |
EditorEventsinterfaceSource ↗
What editor.on(...) can be subscribed to, and what each handler receives.
These are PUSH notifications and are not interchangeable with reading snapshot(): a snapshot read cannot observe an event that was never emitted, which is why adapter behaviour is asserted against these rather than against the snapshot.
interface EditorEvents| Member | Type | Summary |
|---|---|---|
| change | (change: DocumentChange) => void | A document mutation committed, with the ids it touched. |
| error | (error: EditorError) => void | |
| selectionChange | (snapshot: EditorSnapshot) => void | The selection or its derived formatting moved. |
EditorHeaderFooterCommandsinterfaceSource ↗
Header/footer lifecycle and page-field commands on [EditorCommands](EditorCommands).
Kept as a mixin so editor.ts can extend it without inlining the furniture vocabulary.
interface EditorHeaderFooterCommands| Member | Type | Summary |
|---|---|---|
| editHeaderFooter | {
position: 'header' | 'footer';
variant?: FurnitureVariant;
firstPage?: boolean;
evenPage?: boolean;
sectionIndex?: number;
} | Open a header or footer for editing, materialising an empty one if the section has none — which is what a double-click on the header band means in Word. |
| exitHeaderFooter | Record<never, never> | Leave header/footer editing and return to the body. |
| insertPageField | {
field: 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES' | 'PAGE_X_OF_Y';
} | Insert an allowlisted page-number field at the caret. Only valid while a header or footer scope is open. `PAGE_X_OF_Y` writes PAGE + " of " + NUMPAGES as one undo unit. |
| linkHeaderFooterToPrevious | HeaderFooterSlotArgs | Turn on "Same as Previous" for a section's furniture slot (drop its declared ref). Refused on the first section. Omitted fields default to the active story when scoped. |
| removeHeaderFooter | HeaderFooterSlotArgs | Delete a declared header/footer reference (and GC the part when orphaned). When the editor is already in furniture scope, omitted fields default to the active story. |
| setHeaderFooterOptions | {
sectionIndex?: number;
titlePage?: boolean;
evenAndOddHeaders?: boolean;
headerDistanceTwips?: number;
footerDistanceTwips?: number;
} | Section/document furniture options: `titlePg` and header/footer distances on a section; `evenAndOddHeaders` document-wide in settings. |
| unlinkHeaderFooterFromPrevious | HeaderFooterSlotArgs | Turn off "Same as Previous": clone the inherited part into a declared reference. When the active scope was the inherited rId, the editor rebinds to the clone. |
EditorNoteCommandsinterfaceSource ↗
Footnote/endnote lifecycle and properties commands on [EditorCommands](EditorCommands).
interface EditorNoteCommands| Member | Type | Summary |
|---|---|---|
| convertAllNotes | {
fromKind: NoteKind;
} | Convert every note of one kind to the other in document order (one undo step). |
| convertNote | {
fromKind: NoteKind;
noteId: number;
} | Convert one note to the other kind. |
| deleteNote | {
noteKind: NoteKind;
noteId: number;
} | Delete a note and its body reference together. |
| insertNote | {
noteKind: NoteKind;
} | Insert a footnote or endnote reference at the caret (body only). |
| setNoteProperties | {
scope?: 'document' | 'section';
sectionIndex?: number;
footnote?: {
numFmt?: string;
numRestart?: string;
position?: string;
numStart?: number;
};
endnote?: {
numFmt?: string;
numRestart?: string;
position?: string;
numStart?: number;
};
} | Footnote and endnote properties for the section — numbering format, restart rule and position, as Word's dialog offers them. |
EditorQueriesinterfaceSource ↗
Every query the editor answers, keyed by name with its arguments as the value.
Extends [DocQueries](DocQueries) with the reads that only mean something against a live, laid-out document: the selection, its formatting, the table or hyperlink under the caret.
interface EditorQueries extends DocQueries| Member | Type | Summary |
|---|---|---|
| contentControlAt | {
filter?: ContentControlFilter;
} | |
| hyperlinkAt | {
pos?: number;
fallbackHref?: string;
} | |
| isInsideToc | {
pos: number;
} | |
| selectedText | Record<never, never> | |
| selection | Record<never, never> | |
| selectionFormatting | Record<never, never> | |
| splitCellConfig | Record<never, never> | |
| tableContext | Record<never, never> | |
| trackedChanges | Record<never, never> | |
| watermark | Record<never, never> |
EditorQueryResultsinterfaceSource ↗
What each editor query returns. Keyed identically to EditorQueries.
interface EditorQueryResults extends DocQueryResults| Member | Type | Summary |
|---|---|---|
| contentControlAt | ContentControlSummary | null | |
| hyperlinkAt | HyperlinkInfo | null | |
| isInsideToc | boolean | |
| selectedText | string | |
| selection | DocRange | null | |
| selectionFormatting | RunFormatting | null | |
| splitCellConfig | {
maxRows: number;
maxCols: number;
} | null | |
| tableContext | TableContext | null | |
| trackedChanges | readonly Revision[] | |
| watermark | Watermark | null |
EditorSnapshotinterfaceSource ↗
A read model of the current editor state, safe to hand to framework rendering. Named EditorSnapshot rather than EditorState so it never collides with an editing engine's own state type.
interface EditorSnapshot| Member | Type | Summary |
|---|---|---|
| canRedo? | boolean | |
| canUndo? | boolean | Whether undo/redo have anything to apply, derived from the session's history. Optional and additive: an implementation that has not derived them omits them, and a consumer treats absent as `false` — the honest empty answer. |
| editable | boolean | Whether the loaded document is being edited: a patchable document opened in edit mode. A read-only document (tables/SDTs/unpreservable) or `mode: 'view'` reports false. |
| editingMode? | DocumentEditingMode | How edits are written right now. |
| fontSubstitutions? | readonly string[] | Document font families rendering in a substitute face: declared by the document but not resolvable on this platform, not embedded in the file, and not supplied by the app's font configuration. Chrome shows a compatibility notice from this the way Word does. Optional and additive like `canUndo`: absent means the implementation has not derived it; empty means every family resolved (or no document is loaded). |
| formatting | RunFormatting | null | |
| hasReviewContent? | boolean | Whether the document carries review content — tracked changes or comment anchors — independent of any registered review module. |
| image | ImageContext | null | |
| isLoading | boolean | Whether the editor is still waiting for a document: no bytes handed over yet, and no parse failure. Bytes count from the moment they are supplied, not from the moment pages paint, so this stays false across a detach and remount. Safe to gate a mount point on — it never depends on one existing. |
| lastRejection? | string | null | Why the last edit was refused, or null. |
| page | {
readonly current: number;
readonly total: number;
} | |
| pageSetup? | PageSetup | null | The section's page setup, reference-stable across ticks that did not change it. Optional and additive like `canUndo`: absent means the implementation has not derived it, `null` means no document is loaded. |
| parseError | string | null | |
| reviewPaneOpen? | boolean | Whether the review pane is showing its cards. |
| scope | EditorScope | |
| selection | DocRange | null | |
| selectionCollapsed | boolean | Whether the selection is a CARET rather than a range. `true` when nothing is loaded. |
| table | TableContext | null | |
| tocContext | {
readonly id: string;
} | null | The table of contents the last right-click landed on, or null. |
| zoom | number |
ExtentinterfaceSource ↗
A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch.
interface Extent| Member | Type | Summary |
|---|---|---|
| heightEmu | number | |
| widthEmu | number |
FontConfigurationinterfaceSource ↗
Public font source configuration sampled when an adapter mounts. It must be immutable for that editor lifetime; remount the adapter to replace bytes or substitutions atomically.
interface FontConfiguration| Member | Type | Summary |
|---|---|---|
| defaultFont | {
readonly family: string;
readonly sizeHalfPoints: number;
} | |
| epoch | number | |
| language? | string | |
| maxFontBytes | number | |
| sources | readonly FontSource[] | |
| substitutions? | readonly FontSourceSubstitution[] |
FontDefinitioninterfaceSource ↗
A font the document names, and whether its bytes travel inside the package.
interface FontDefinition| Member | Type | Summary |
|---|---|---|
| embedded | boolean | |
| family | string |
FontFaceRequestinterfaceSource ↗
A concrete font face requested by authored document content.
interface FontFaceRequest| Member | Type | Summary |
|---|---|---|
| family | string | |
| style | 'normal' | 'italic' | |
| weight | number |
FontSourceinterfaceSource ↗
Immutable, byte-backed font face supplied to layout and browser paint.
interface FontSource| Member | Type | Summary |
|---|---|---|
| availability? | 'available' | 'forbidden' | |
| bytes | Uint8Array | |
| faceIndex | number | |
| hash | string | |
| id | string | |
| request | FontFaceRequest |
FontSourceSubstitutioninterfaceSource ↗
An explicit authored-font substitution. No implicit platform fallback is performed.
interface FontSourceSubstitution| Member | Type | Summary |
|---|---|---|
| from | FontFaceRequest | |
| to | FontFaceRequest |
HeaderFooterSetinterfaceSource ↗
A section's three header (or footer) variants, each a relationship id.
All optional: a variant a section does not declare inherits the previous section's, and one absent everywhere means the document simply has none.
interface HeaderFooterSet| Member | Type | Summary |
|---|---|---|
| default? | string | |
| even? | string | |
| first? | string |
HeaderFooterSlotArgsinterfaceSource ↗
Optional slot targeting shared by remove / link / unlink furniture commands.
interface HeaderFooterSlotArgs| Member | Type | Summary |
|---|---|---|
| evenPage? | boolean | |
| firstPage? | boolean | |
| position? | 'header' | 'footer' | |
| sectionIndex? | number | |
| variant? | FurnitureVariant | Prefer over `firstPage` / `evenPage` when selecting a furniture variant. |
HeaderFooterStateinterfaceSource ↗
Header/footer editing state: which region is being edited, if any.
interface HeaderFooterState| Member | Type | Summary |
|---|---|---|
| editing | 'header' | 'footer' | null | |
| evenAndOddHeaders? | boolean | Document `w:evenAndOddHeaders` — even-page furniture is distinct when true. |
| footerDistanceTwips? | number | Section footer distance from sheet edge, twips (`w:pgMar w:footer`). |
| headerDistanceTwips? | number | Section header distance from sheet edge, twips (`w:pgMar w:header`). |
| inherited? | boolean | Whether the resolved part is inherited from a preceding section ("Same as Previous") rather than declared on this section. |
| partName? | string | Package part name of the open story. |
| rId? | string | Relationship id of the open story (`EditorScope.rId`). |
| sectionIndex | number | |
| titlePage? | boolean | Section `w:titlePg` — first-page furniture is distinct when true. |
| variant? | FurnitureVariant | Furniture variant in effect on the page used to enter the scope. |
HyperlinkInfointerfaceSource ↗
The hyperlink under a position: where it points, how far it reaches, and what Word shows on hover.
href has already been through sanitizeHref — it comes from a file, so a javascript: or data: target is dropped at the parse boundary rather than here.
interface HyperlinkInfo| Member | Type | Summary |
|---|---|---|
| href | string | |
| range | DocRange | |
| tooltip? | string | `w:tooltip` on the `w:hyperlink` — the text Word shows on hover, and what the hyperlink dialog seeds its tooltip field with when editing an existing link. |
ImageCropPercentinterfaceSource ↗
Crop edge in UI percent (0–100).
interface ImageCropPercent| Member | Type | Summary |
|---|---|---|
| bottom | number | |
| left | number | |
| right | number | |
| top | number |
IndentFormattinginterfaceSource ↗
Indent at the selection, in twips.
Unlike every other field here, this does NOT go absent when the selection's paragraphs disagree. A ruler has to draw its handles somewhere, and Word draws them at the FIRST selected paragraph's values — Select All is the commonest indent gesture, and hiding the handles for it would be worse than showing one paragraph's truth. The values are therefore always the first touched paragraph's, and [mixed](mixed) records per field whether the rest agree.
firstLine is ONE SIGNED offset: negative is a hanging indent. OOXML spells it as two mutually exclusive attributes and this collapses them hanging-wins (§17.3.1.12), which is the model Word itself keeps.
Absent inside a table. The value would be correct there, but it is measured from the cell's content edge while a ruler is drawn against the page's margin, and the ruler does not know the cell.
interface IndentFormatting| Member | Type | Summary |
|---|---|---|
| firstLine | number | First-line offset from [left](left), signed. Negative is a hanging indent. |
| left | number | Left indent, signed. Negative pulls text into the margin, as Word allows. |
| mixed | {
readonly left: boolean;
readonly right: boolean;
readonly firstLine: boolean;
} | Per field, whether the selection's paragraphs disagree about it. |
| right | number | Right indent, signed. |
NotePropertiesSideinterfaceSource ↗
One note kind's resolved + authored properties for the caret section.
interface NotePropertiesSide| Member | Type | Summary |
|---|---|---|
| documentAuthored? | AuthoredNoteNumbering | |
| resolved | ResolvedNoteNumbering | |
| sectionAuthored? | AuthoredNoteNumbering |
NotePropertiesStateinterfaceSource ↗
Resolved and authored note properties for the caret section — properties dialog read-model.
interface NotePropertiesState| Member | Type | Summary |
|---|---|---|
| endnote | NotePropertiesSide | |
| footnote | NotePropertiesSide | |
| sectionIndex | number |
NumberingRefinterfaceSource ↗
A paragraph's list membership: which numbering.xml definition, and at which level.
interface NumberingRef| Member | Type | Summary |
|---|---|---|
| level | number | Zero-based. OOXML numbering has nine levels, 0 through 8. |
| numId | string |
PageMarginsinterfaceSource ↗
Page margins in twips.
interface PageMargins| Member | Type | Summary |
|---|---|---|
| bottomTwips | number | |
| leftTwips | number | |
| rightTwips | number | |
| topTwips | number |
PageSetupinterfaceSource ↗
Section page setup — size, orientation and margins, in twips — as getPageSetup() and snapshot().pageSetup report it and the setPageSetup command writes it. In a multi-section document this is the setup of the section the SELECTION is in, which is what a ruler or a dialog reflects — Word's behaviour.
interface PageSetup| Member | Type | Summary |
|---|---|---|
| gutterTwips? | number | Binding gutter (`w:gutter`), folded into the left margin by layout. |
| marginsTwips | {
readonly top: number;
readonly right: number;
readonly bottom: number;
readonly left: number;
} | |
| orientation | 'portrait' | 'landscape' | |
| pageHeightTwips | number | |
| pageWidthTwips | number |
ParagraphinterfaceSource ↗
One paragraph: its runs, the style it names, and its list membership.
interface Paragraph| Member | Type | Summary |
|---|---|---|
| kind | 'paragraph' | |
| numbering? | NumberingRef | |
| paraId? | string | `w14:paraId`. The stable handle `DocAnchor` addresses. |
| runs | readonly Run[] | |
| styleId? | string |
ParagraphSummaryinterfaceSource ↗
A paragraph reduced to what a listing needs: its stable handle, its text, and its style.
paraId is what a follow-up edit addresses, so a summary without one names a paragraph the file gave no w14:paraId and that a DocAnchor cannot reach.
interface ParagraphSummary| Member | Type | Summary |
|---|---|---|
| paraId? | string | |
| styleId? | string | |
| text | string |
PointinterfaceSource ↗
A position in points.
interface Point| Member | Type | Summary |
|---|---|---|
| x | number | |
| y | number |
RectinterfaceSource ↗
An axis-aligned rectangle in points, the unit layout works in throughout.
interface Rect| Member | Type | Summary |
|---|---|---|
| height | number | |
| width | number | |
| x | number | |
| y | number |
ResolvedNoteNumberinginterfaceSource ↗
Resolved note-numbering fields after document/section cascade.
interface ResolvedNoteNumbering| Member | Type | Summary |
|---|---|---|
| numFmt | string | |
| numRestart | string | |
| numStart | number | |
| pos | string |
ReviewActivationOptionsinterfaceSource ↗
How activating a review item places it in the viewport.
interface ReviewActivationOptions| Member | Type | Summary |
|---|---|---|
| reveal? | 'start' | 'center' | 'centerIfNeeded' | 'nearest' | false | Where the item lands, or `false` to select it without scrolling at all. |
ReviewCommentIteminterfaceSource ↗
One comment as a review card. A reply carries parentId; OOXML gives replies no separate element, so threads are reconstructed from that link.
interface ReviewCommentItem| Member | Type | Summary |
|---|---|---|
| comment | CommentRecord | |
| id | string | |
| kind | 'comment' | |
| orphaned | boolean | True when the file gave this comment no usable range. |
| parentId? | string | The comment this replies to, absent for a top-level comment. |
| parentRevisionId? | string | The REVISION this comment answers, when it covers exactly that change's characters. |
| range | ReviewRange | null | |
| replyIds | readonly string[] | Replies to this comment, in document order. Empty for a reply or a childless comment. |
| resolved | boolean |
ReviewCommentPlacementinterfaceSource ↗
A comment thread's card.
interface ReviewCommentPlacement extends ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| item | ReviewCommentItem | |
| kind | 'comment' | |
| parentId? | string | The comment this replies to, absent at the top of a thread. |
| parentRevisionId? | string | The REVISION this comment answers, absent unless it does. |
| resolved | boolean | Whether `w15:commentsEx` marks the thread done. |
ReviewCustomIteminterfaceSource ↗
A card contributed by a recognized custom node (defineCustomNode with a reviewCard hook), anchored at the node's range.
Informational, never resolvable: there is nothing to accept or reject, so the engine refuses those verbs on it. title and detail are HOST-authored (the definition's hook produced them), but attrs and text originate in a file an attacker controls — a surface renders every one of these as text, never markup.
interface ReviewCustomItem| Member | Type | Summary |
|---|---|---|
| attrs | Readonly<Record<string, string>> | Attrs decoded from the tag, after the definition's recognition hook. Untrusted input. |
| carded | boolean | Whether this node asked for a sidebar card. |
| data? | unknown | The payload the node's control binds to, after the definition validated it. |
| detail? | string | Card body, from the definition's `reviewCard` hook. |
| icon? | string | Glyph for this node in the collapsed rail, as an SVG path in a `0 -960 960 960` viewBox. |
| id | string | The SDT node's stable id in the canonical tree. |
| kind | 'custom' | |
| name | string | The definition's `name`. |
| range | ReviewRange | null | |
| tag | string | The raw `w:tag` the node was recognized from. Untrusted input. |
| text | string | The SDT's literal content text. Untrusted input. |
| title | string | Card title, from the definition's `reviewCard` hook. Empty when `carded` is false. |
ReviewCustomPlacementinterfaceSource ↗
A custom node's card (defineCustomNode with a reviewCard hook).
interface ReviewCustomPlacement extends ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| item | ReviewCustomItem | |
| kind | 'custom' |
ReviewItemPlacementBaseinterfaceSource ↗
What every review card carries, whatever kind of decision it represents.
Presentation-ready by design: author, initials, date and text are derived by the ENGINE, because deriving them means walking runs and reading w15:commentsEx. An adapter doing that walk would put document derivation in the host and would have to be written once per framework.
interface ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| activatable | boolean | Whether [Editor.setActiveReviewItem](Editor.setActiveReviewItem) would take this key. |
| anchorY | number | null | Document-space Y of the anchor, or null when the item has no resolvable range. |
| author | string | |
| date? | string | `@w:date`, absent when the file omits it — Word does when date stamping is off. |
| id | string | The engine's own id for the comment, the revision, or the custom node. |
| initials | string | Initials for an avatar: `@w:initials` when the file carries one, else from the name. |
| isActive | boolean | |
| key | string | Stable and unique per DECISION — a revision with three ranges is one entry. |
| pageIndex | number | null | |
| readOnly | boolean | True when the engine cannot resolve this kind structurally, so accept and reject must not be offered. A card offering a button the engine will refuse is worse than one that explains why it cannot. |
| replyIds | readonly string[] | Replies to this item, in document order. |
| text | string | The comment's body, the words the revision covers, or the custom card's detail. |
ReviewItemQueryinterfaceSource ↗
Narrows what getReviewItems returns.
Both fields exist to keep the review rail cheap: filtering revision kinds is how a host hides structural cards it has no UI for, and placement: false skips the layout pass entirely when only metadata is wanted.
interface ReviewItemQuery| Member | Type | Summary |
|---|---|---|
| excludeRevisionKinds? | readonly ReviewRevisionKind[] | |
| placement? | boolean | When false, skip layout geometry; metadata is unchanged and anchors are null. Default true. |
ReviewPositioninterfaceSource ↗
A position in the model offset space of one story.
interface ReviewPosition| Member | Type | Summary |
|---|---|---|
| offset | number | |
| paragraphId | string |
ReviewRangeinterfaceSource ↗
Where an item is anchored: a range in one story.
interface ReviewRange| Member | Type | Summary |
|---|---|---|
| end | ReviewPosition | |
| partName | string | |
| start | ReviewPosition |
ReviewRevisionIteminterfaceSource ↗
One tracked change as a review card.
Keyed per DECISION rather than per site: a revision spanning three ranges is one card, because accepting it accepts all three.
interface ReviewRevisionItem| Member | Type | Summary |
|---|---|---|
| address | RevisionAddress | The payload `acceptRevision` / `rejectRevision` take. |
| addresses | readonly RevisionAddress[] | EVERY address this decision covers, `address` first. |
| author | string | |
| date? | string | |
| id | string | Stable across renders and unique per DECISION, not per site. |
| kind | 'revision' | |
| pairedWith? | string | The other half of a move, or the other side of a delete/insert replacement. |
| ranges | readonly ReviewRange[] | Every site this decision touches, in document order. |
| readOnly | boolean | True when the engine cannot resolve this kind, so accept and reject must not be offered. |
| replacedRangeCount? | number | How many leading `ranges` are the STRUCK half of a replacement. |
| replacedText | string | The words a replacement removes. Empty for every other kind. |
| replyIds | readonly string[] | Comments answering this change, in document order. |
| revisionKind | ReviewRevisionKind | |
| text | string | Text the revision covers, for the card summary. Empty for changes with no characters. |
ReviewRevisionPlacementinterfaceSource ↗
A tracked change's card.
interface ReviewRevisionPlacement extends ReviewItemPlacementBase| Member | Type | Summary |
|---|---|---|
| item | ReviewRevisionItem | |
| kind | 'revision' | |
| replacedText? | string | The words a REPLACEMENT removes, when [revisionKind](revisionKind) is `'replace'`. |
| revisionKind | ReviewRevisionKind | Which decision this is. |
RevisioninterfaceSource ↗
One tracked change.
Addressing needs BOTH id and part: @w:id is unique only within a part, so an id alone names two revisions in any package that has a header or a comments part.
interface Revision| Member | Type | Summary |
|---|---|---|
| author | string | |
| date? | string | OPTIONAL. `CT_TrackChange` requires `@w:id` and `@w:author` and makes `@w:date` optional, and producers that omit it are ordinary. Requiring it here forced either a fabricated date — a content change — or dropping the revision from the list. |
| id | number | Numeric, and unique only WITHIN a part. Pair with `part` to address one. |
| part | string | REQUIRED, and a canonical PART NAME rather than a three-value enum. |
| type | RevisionType |
RevisionAddressinterfaceSource ↗
How a tracked change is addressed: its numeric id plus the PART it lives in.
Both, 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.
interface RevisionAddress| Member | Type | Summary |
|---|---|---|
| author | string | |
| date? | string | Absent when the file wrote no `@w:date`; part of the identity either way. |
| id | string |
RuninterfaceSource ↗
A stretch of text sharing one set of character properties.
interface Run| Member | Type | Summary |
|---|---|---|
| formatting? | RunFormatting | |
| revisionId? | number | Set when the run carries a tracked change. Unique only within its part. |
| text | string |
RunFormattinginterfaceSource ↗
Character formatting, and — at selection level — the paragraph properties a toolbar reads alongside it.
One type serves both roles so a toolbar reads alignment, style and script state from the same object as bold and italic. On a [Run](Run) the selection-level fields stay absent: a run has no alignment or paragraph style of its own.
interface RunFormatting| Member | Type | Summary |
|---|---|---|
| alignment? | 'left' | 'center' | 'right' | 'both' | Paragraph alignment at the selection. `both` is OOXML's spelling of justify. |
| bold? | boolean | |
| color? | ColorValue | |
| fontFamily? | string | |
| fontSizePt? | number | |
| highlight? | string | |
| indent? | IndentFormatting | The EFFECTIVE paragraph indent at the selection — cascade and numbering merge included, so a numbered item that authors no `w:ind` reports the indent its list definition gives it. Absent when nothing is loaded, or when the selection is inside a table (see [IndentFormatting](IndentFormatting)). |
| italic? | boolean | |
| lineSpacing? | {
readonly rule: 'multiple' | 'exact' | 'atLeast';
readonly value: number;
} | Line spacing at the selection, in the unit its rule implies — LINES for `multiple`, points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a control can show what it reads and send back what it shows. Absent when the selection's paragraphs disagree or state no line spacing. |
| spaceAfterPt? | number | |
| spaceBeforePt? | number | Space above and below the paragraph at the selection, in points. |
| strike? | boolean | |
| styleId? | string | Paragraph style id (`w:pStyle`) at the selection. |
| subscript? | boolean | |
| superscript? | boolean | |
| underline? | boolean |
SectioninterfaceSource ↗
One section: the page it lays out on, and the header/footer stories it declares.
interface Section| Member | Type | Summary |
|---|---|---|
| footers | HeaderFooterSet | |
| headers | HeaderFooterSet | |
| properties | SectionProperties |
SectionPropertiesinterfaceSource ↗
w:sectPr: the page a section lays out on. Twips throughout, as the file stores them.
interface SectionProperties| Member | Type | Summary |
|---|---|---|
| columns? | {
count: number;
gapTwips: number;
} | |
| margins | PageMargins | |
| pageSize | {
widthTwips: number;
heightTwips: number;
} | |
| titlePage? | boolean | `w:titlePg` — whether the section's first page takes the `first` header/footer variant. |
SelectedImageStateinterfaceSource ↗
Canonical selected-image read model shared by [EditorSnapshot.image](EditorSnapshot.image) and [Editor.getSelectedImage](Editor.getSelectedImage).
interface SelectedImageState| Member | Type | Summary |
|---|---|---|
| canChangeWrap | boolean | |
| canCrop | boolean | |
| canMove | boolean | |
| canResize | boolean | |
| crop | ImageCropPercent | Crop inset per edge in UI percent (0–100); OOXML stores permille (×1000). |
| description | string | |
| heightEmu | number | |
| hyperlink | string | null | |
| id | string | |
| intrinsic | Readonly<{
readonly pixelWidth: number;
readonly pixelHeight: number;
readonly dpiX: number;
readonly dpiY: number;
}> | null | |
| kind | DrawingKind | |
| locks | DrawingLocks | |
| name | string | |
| position | DrawingPositionInput | null | |
| resourceStatus | ImageResourceState['kind'] | |
| rotationDegrees | number | |
| title | string | |
| widthEmu | number | |
| wrap | ImageWrapTarget |
SemanticIdentityinterfaceSource ↗
Model-derived stable identity within a scope. Positions resolve through this index, not accumulated display-item lengths or editing-engine coordinates.
interface SemanticIdentity| Member | Type | Summary |
|---|---|---|
| blockId | string | |
| storyId | string |
SemanticPositioninterfaceSource ↗
A caret position in the model.
interface SemanticPosition| Member | Type | Summary |
|---|---|---|
| offset | number | |
| paragraphId | string |
SemanticSelectioninterfaceSource ↗
A selection as two semantic positions — never as DOM nodes.
anchor is where the selection started and head is where it currently ends, so head before anchor is an ordinary backwards selection rather than an error. Collapsed when the two are equal, which is what a caret is.
interface SemanticSelection| Member | Type | Summary |
|---|---|---|
| anchor | SemanticPosition | |
| head | SemanticPosition |
StyleDefinitioninterfaceSource ↗
One style: the ID content references, the name a reader sees, and its inheritance link.
interface StyleDefinition| Member | Type | Summary |
|---|---|---|
| basedOn? | string | `w:basedOn` — the style this one inherits from. Absent at the root of a chain. |
| id | string | |
| name | string |
StyleDefinitionsinterfaceSource ↗
styles.xml, split by the three style families that address separately.
Keyed by style ID rather than by the name a reader sees, because the ID is what a paragraph or run actually references.
interface StyleDefinitions| Member | Type | Summary |
|---|---|---|
| character | ReadonlyMap<string, StyleDefinition> | |
| paragraph | ReadonlyMap<string, StyleDefinition> | |
| table | ReadonlyMap<string, StyleDefinition> |
TableinterfaceSource ↗
A table: its rows, and the table style they resolve through.
interface Table| Member | Type | Summary |
|---|---|---|
| kind | 'table' | |
| rows | readonly TableRow[] | |
| styleId? | string |
TableBorderSpecinterfaceSource ↗
Complete border spec for [EditorCommands.setTableBorders](EditorCommands.setTableBorders). Size is in eighths of a point.
interface TableBorderSpec| Member | Type | Summary |
|---|---|---|
| color | ColorValue | |
| size | number | |
| style | TableBorderStyle |
TableCellinterfaceSource ↗
One cell. Its content is ordinary blocks, so a cell may hold paragraphs, nested tables and content controls alike.
interface TableCell| Member | Type | Summary |
|---|---|---|
| colSpan? | number | `w:gridSpan`. Absent means 1. |
| content | readonly Block[] | |
| rowSpan? | number | Vertical merge span. Absent means 1. |
TableColumnDividerResizeTargetinterfaceSource ↗
Adjacent grid columns addressed by an internal divider resize gesture.
sourceRevision is captured from the store revision when the target is built. Commit MUST refuse when it does not equal the current store revision, even if an older layout remains published for geometry.
interface TableColumnDividerResizeTarget| Member | Type | Summary |
|---|---|---|
| isHeaderRepeat | boolean | |
| leftGridColumnId | string | |
| rightGridColumnId | string | |
| sourceRevision | number | |
| tableId | string |
TableColumnOccurrenceTargetinterfaceSource ↗
Explicit column occurrence for furniture/context commands.
interface TableColumnOccurrenceTarget| Member | Type | Summary |
|---|---|---|
| gridColumnId | string | |
| isHeaderRepeat | boolean | |
| sourceRevision | number | |
| tableId | string |
TableContextinterfaceSource ↗
Where the caret sits inside a table: the table's shape, and the cell holding it.
Null from the tableContext query when the selection is not in a table at all, which is how table-only chrome decides whether to render.
interface TableContext| Member | Type | Summary |
|---|---|---|
| columnIndex | number | Zero-based, within the row. |
| columns | number | |
| rowIndex | number | Zero-based, within the table. |
| rows | number |
TableRightEdgeResizeTargetinterfaceSource ↗
Last grid column and table width addressed by an outer-right-edge resize gesture.
sourceRevision is captured from the store revision when the target is built. Commit MUST refuse when it does not equal the current store revision, even if an older layout remains published for geometry.
interface TableRightEdgeResizeTarget| Member | Type | Summary |
|---|---|---|
| gridColumnId | string | |
| isHeaderRepeat | boolean | |
| sourceRevision | number | |
| tableId | string |
TableRowinterfaceSource ↗
One table row. Cell count may vary between rows: colSpan and vertical merges reshape it.
interface TableRow| Member | Type | Summary |
|---|---|---|
| cells | readonly TableCell[] |
TableRowOccurrenceTargetinterfaceSource ↗
Explicit row occurrence for furniture/context commands.
interface TableRowOccurrenceTarget| Member | Type | Summary |
|---|---|---|
| isHeaderRepeat | boolean | |
| rowId | string | |
| sourceRevision | number | |
| tableId | string |
TextMatchinterfaceSource ↗
One occurrence of a search query in the document.
Carries TWO addresses on purpose. blockId + start is the engine's own: stable across edits and independent of ordering. paragraphIndex + runIndex + runOffset is the positional one a find/replace UI needs to show and navigate results, and it is derived from the same walk rather than left to the caller to reconstruct — a caller guessing at run boundaries would send the selection to the wrong place.
A match can span runs when formatting changes mid-word; the run address is where it STARTS.
interface TextMatch| Member | Type | Summary |
|---|---|---|
| blockId | string | |
| contextAfter? | string | |
| contextBefore? | string | Paragraph text immediately before and after the match, bounded at the derivation boundary. A results list shows the match in its sentence — "…as described in this **Exhi**bit A" — and nothing else in the contract can reach paragraph text, so a caller would otherwise have to re-read the document to render one row. |
| length | number | |
| paragraphIndex | number | Ordinal among PARAGRAPHS in the body, skipping tables and other non-paragraph blocks. |
| runIndex | number | Index of the run the match starts in, and the offset within that run. |
| runOffset | number | |
| start | number | Character offset within the paragraph's concatenated run text. |
| text | string | The matched text as it appears in the document. |
ThemeinterfaceSource ↗
theme1.xml — what a [ColorValue](ColorValue) of kind theme resolves against.
interface Theme| Member | Type | Summary |
|---|---|---|
| colorScheme | ThemeColorScheme | |
| fontScheme? | Record<string, string> |
ValidatedImageBytesHandleinterfaceSource ↗
Opaque handle — bytes are reachable only through [mintValidatedImageBytes](mintValidatedImageBytes).
interface ValidatedImageBytesHandle| Member | Type | Summary |
|---|---|---|
| contentId | string | |
| generation | number | |
| registryId | number | |
| resourceKey | string |
WatermarkinterfaceSource ↗
A watermark, which OOXML expresses as either text or an image — never both meaningfully.
interface Watermark| Member | Type | Summary |
|---|---|---|
| imageData? | Uint8Array | |
| text? | string |
Type aliases (44)
BlocktypeSource ↗
Anything that can sit at block level in a story. Discriminate on kind.
type Block = Paragraph | Table | ContentControl;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;
};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';
};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' | 'repeatingSection';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';DocumentSourcetypeSource ↗
What createDocxEditor/load accept as a document: raw DOCX bytes, or an existing in-memory DocumentHandle (shared/handed off). The engine is byte-native (PackageModel is canonical); there is intentionally no structured-tree input, which would be lossy against the canonical package.
type DocumentSource = ArrayBuffer | Uint8Array | DocumentHandle;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';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);
};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.
type EditorFontErrorCode = 'initializationFailed' | 'missing' | 'forbidden' | 'overLimit' | 'malformed' | 'hashMismatch' | 'metadataMismatch' | 'fontFaceLoadFailed' | 'unsupportedFaceIndex' | 'missingFont' | 'hashInvalid' | 'fontMismatch' | 'unsupportedFace' | 'loadFailed';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 say which one they target, or they silently hit the wrong surface when a header is focused.
Intentionally open-ended: this set is expected to grow (notes, frames, and whatever regions later prove addressable), so treat it as non-exhaustive rather than a closed enum.
type EditorScope = {
kind: 'body';
} | {
kind: 'headerFooter';
rId: string;
}
/**
* A footnote/endnote region.
*
* `id` encodes kind + signed note id as `footnote:<id>` or `endnote:<id>`
* (e.g. `footnote:2`). Use `formatNoteScopeId` / `parseNoteScopeId` from the
* store package. Do not invent a parallel `{ noteKind, noteId }` scope arm.
*/
| {
kind: 'note';
id: string;
}
/** A text box or floating frame with its own content, addressed by id. */
| {
kind: 'frame';
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;
};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;
} | {
ok: false;
code: ExecErrorCode;
reason: string;
target?: DocTarget;
};FurnitureVarianttypeSource ↗
Furniture variant selected by section title-page / even-and-odd flags.
type FurnitureVariant = 'default' | 'first' | 'even';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';InteractionAffinitytypeSource ↗
Bidi/grapheme affinity for a text caret or hit target.
type InteractionAffinity = 'upstream' | 'downstream';InteractionOutcometypeSource ↗
The result of one interaction attempt.
A rejection carries the ENGINE's own reason, which is what lets a caller surface why an interaction was refused instead of guessing.
type InteractionOutcome<T> = {
readonly ok: true;
readonly value: T;
} | {
readonly ok: false;
readonly code: InteractionOutcomeCode;
readonly reason: string;
};InteractionOutcomeCodetypeSource ↗
Typed rejection for pending, read-only, invalid, or unsupported interaction.
type InteractionOutcomeCode = 'pendingLayout' | 'pendingSelection' | 'readOnly' | 'invalidTarget' | 'unsupported';NoteKindtypeSource ↗
Footnote vs endnote — the public Editor vocabulary.
type NoteKind = 'footnote' | 'endnote';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;ReviewItemtypeSource ↗
One pending decision in the review queue: a tracked change, a comment thread, or a pro custom-node card. Discriminate on kind.
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;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 deletion and an insertion that are one edit: text typed over a selection.
*
* Word shows these as a single `Replaced "x" with "y"` card, and resolving one half
* without the other is never what the reviewer meant — accepting the deletion alone
* leaves the replacement text unproposed, rejecting it alone leaves both.
*/
| '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';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';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;
};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';ThemeColorSchemetypeSource ↗
Theme colour slots (accent1, dk1, lt2, …) to hex.
type ThemeColorScheme = Readonly<Record<string, string>>;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 — every scope except the read-only all aggregate.
type ViewScope = Exclude<EditorScope, {
kind: 'all';
}>;