Ciphon host API
The Ciphon add-in is a set of web pages served from the Ciphon domain. A host application embeds them and drives them through JSON messages.
Pages
| Page | Use |
|---|---|
/taskpane.html |
Main page. Load it in a sidebar or window of the host. |
/taskpane.html?hide=extract,match,docs |
Main page with those action buttons hidden (any subset). |
/taskpane.html?dock |
Main page for a host with a dock. See Dock. |
/auth.html, /workspace.html, /extract.html, /match.html, /sourcedocs.html |
Dialogs, opened by the main page with window.open. See Dialogs. |
/match.html?dock=<channel> |
Dock page. Load the url of the dock event. |
Parameters combine: /taskpane.html?dock&hide=match.
Channel
Define window.ciphonHost before the main page's scripts run.
interface CiphonHost {
postMessage(message: object): void // page → host
addEventListener(type: 'message', listener: (event: { data: object }) => void): void // host → page
}
Messages are JSON-serialisable objects in both directions. event.data is the message object.
Lifecycle
- The host defines
window.ciphonHostand loads/taskpane.html. - The page sends
{event: "ready"}. - The page sends
{event: "session", signedIn}, and again on every change. - Signed out, the page opens the sign-in and workspace dialogs.
- The page calls methods. The host replies to each request.
- A reload starts again at step 2.
Messages
type MethodName =
| 'getActiveCell' | 'getSelection' | 'readRange' | 'readUsedRange' | 'getDocumentKey'
| 'writeRange' | 'clearRange' | 'insertColumns' | 'deleteColumns' | 'autofitColumns'
| 'setActiveCell' | 'selectRange'
// page → host
type Request = { id: number; method: MethodName; args: unknown[] }
type PageEvent =
| { event: 'ready' }
| { event: 'session'; signedIn: boolean }
| { event: 'dock'; open: boolean; expanded: boolean; url: string }
// host → page
type Reply = { id: number; result: unknown } | { id: number; error: string }
type HostEvent = { event: 'selectionChanged' }
type Command = { command: 'extract' | 'match' | 'docs' | 'signIn' }
type Hide = { hide: ('extract' | 'match' | 'docs')[] }
argsare positional, in the order shown under Methods. Trailing optional arguments may be absent.- Reply to every request with its
id.resultisnullfor methods that return nothing. errortext is shown to the user.- Accept messages only from pages on the add-in origin.
Types
type SheetRef = string | null // worksheet name; null = active sheet
type CellValue = number | string | boolean | null
interface CellAddress { row: number; col: number } // 0-based
interface RangeAddress extends CellAddress { rowCount: number; colCount: number }
interface LocatedCell extends CellAddress {
sheet: string // worksheet name
sheetName: string
address: string // display only, e.g. 'Trial Balance'!B4
}
interface LocatedRange extends LocatedCell { rowCount: number; colCount: number }
interface RangeContents {
values: CellValue[][] // rowCount x colCount
text: string[][]
formulas: (string | null)[][]
styles: (StylePatch | null)[][]
}
interface UsedRange extends RangeContents {
sheet: string
sheetName: string
origin: CellAddress
rowCount: number
colCount: number
}
interface RangeWrite {
formulas?: (string | null)[][]
values?: (CellValue | null)[][]
numberFormat?: (string | null)[][]
style?: StylePatch | (StylePatch | null)[][]
}
interface StylePatch {
backColor?: string // '#RRGGBB' or CSS name; '' clears the fill
foreColor?: string // '' resets to automatic
font?: string // CSS shorthand, e.g. 'bold 11pt Calibri'
formatter?: string // number format
hAlign?: 'left' | 'center' | 'right' | 'general'
}
interface ClearTargets { data?: boolean; style?: boolean } // both default to true
Cell values
| Field | Content |
|---|---|
values |
Number, string, boolean, or null when empty. Dates are serial numbers. Errors are their text, e.g. "#DIV/0!". |
text |
Formatted display text; "" when empty. |
formulas |
Formula with its leading =; null for a literal or empty cell. |
styles |
The cell's format as a StylePatch: backColor only when filled, foreColor only when not automatic, font, formatter (the number format), hAlign. null when not known. |
Methods
Errors: unknown sheet → No such sheet: <name>; unknown method → Unknown method: <name>.
getActiveCell
getActiveCell(): LocatedCell
The active cell on the active sheet.
getSelection
getSelection(): LocatedRange
The first area of the selection on the active sheet.
readRange
readRange(sheet: SheetRef, range: RangeAddress): RangeContents
Dense matrices of range.rowCount x range.colCount.
readUsedRange
readUsedRange(sheet: SheetRef): UsedRange
Bounding box of cells holding a value or formula, with the same matrices as readRange;
formatting-only cells are excluded. Empty sheet: origin {row: 0, col: 0}, rowCount 0, colCount 0,
empty matrices.
getDocumentKey
getDocumentKey(): string
An identifier for the open document: the same for every page on it, and across sessions. Saved match
reviews are stored under <key>/<sheet>; a document whose key changes starts without them.
writeRange
writeRange(sheet: SheetRef, at: CellAddress, write: RangeWrite): null
| Rule | Behaviour |
|---|---|
| Rectangle | Largest row count x largest column count across the supplied matrices. None supplied: no-op. |
| Holes | null, a missing row or a missing column leaves the cell untouched. |
formulas |
Starts with =: set as formula. Otherwise: set as a literal. Wins over values for the same cell. |
values |
Literal. "" blanks the cell. A string starting with = stays literal. |
Leading ' |
Text prefix: store the rest as literal text, e.g. '-150.00 → -150.00. Applies to values and non-= formulas. |
numberFormat |
Per cell. |
style |
One patch for the whole rectangle, or a per-cell matrix. Omitted fields are unchanged. |
| Limits | Negative coordinates, or past row 1,048,576 / column 16,384 → error. |
clearRange
clearRange(sheet: SheetRef, range: RangeAddress, targets?: ClearTargets): null
data clears contents, style clears formats, both clear everything.
insertColumns
insertColumns(sheet: SheetRef, startCol: number, count: number): null
Inserts entire columns at startCol, shifting right. count <= 0: no-op.
deleteColumns
deleteColumns(sheet: SheetRef, startCol: number, count: number): null
Deletes entire columns from startCol, shifting left. count <= 0: no-op.
autofitColumns
autofitColumns(sheet: SheetRef, range: RangeAddress): null
Autofits the range's columns to its cells.
setActiveCell
setActiveCell(sheet: SheetRef, at: CellAddress): null
Activates the sheet and selects the cell.
selectRange
selectRange(sheet: SheetRef, range: RangeAddress): null
Activates the sheet and selects the range.
Events
| Message | Direction | Sent | Host |
|---|---|---|---|
{event: "ready"} |
page → host | Every page load, once the page listens | Flush queued commands; resend the current hide list. |
{event: "session", signedIn} |
page → host | After ready, and on every change |
signedIn: signed in with a workspace selected. Show the main page only while true. |
{event: "dock", open, expanded, url} |
page → host | Main page with ?dock: after ready, and on every change |
See Dock. |
{event: "selectionChanged"} |
host → page | After any selection or active-sheet change | Send while the page is ready, including while the main page is hidden. |
Commands
| Message | Signed in | Signed out |
|---|---|---|
{command: "extract"} |
Opens the extract wizard. | Opens sign-in, then runs. |
{command: "match"} |
Reruns the saved match under the active cell, otherwise opens the match wizard. | Opens sign-in, then runs. |
{command: "docs"} |
Opens the source document browser. | Opens sign-in, then runs. |
{command: "signIn"} |
No-op. | Opens sign-in. |
{hide: [...]} |
Replaces the hidden action buttons; [] shows all. |
Same. |
- Queue commands and
hideuntilready. - A hidden action still runs by command.
- While a Ciphon dialog is open, commands are dropped with a message in the main page.
- Signed out, only the latest command received during sign-in runs. Closing a sign-in dialog drops it.
hidelasts until the page reloads; the URL?hide=then applies.
Dialogs
For window.open calls to the add-in origin, the host:
- Opens a separate window, sized from the requested width and height, including when no user gesture preceded the call.
- Keeps
window.opener, so the dialog and the main page canpostMessageeach other. - Shares cookies and storage with the main page.
- Closes the window when the dialog calls
window.close().
Open other URLs outside the host.
Dock
The match review shows in a dialog while expanded, and as a banner in the main page while collapsed. A
host with a dock loads /taskpane.html?dock, and the review shows in the dock instead.
| Field | Host |
|---|---|
open |
true: show the dock, loading url unless it is already loaded. false: hide it. |
expanded |
true: size the dock to show the review, 300 CSS px or more. false: size it to the review's two header rows, 82 CSS px. |
url |
The dock page for this main page. A new URL after every main page load. |
- The dock page talks to the main page directly. It needs no
window.ciphonHost.
Host requirements
- Every main page, dialog and dock page shares one cookie and storage profile.
- No user edit interleaves with a method call.
- The document is marked modified only after
writeRange,clearRange,insertColumns,deleteColumns,autofitColumns. valuesof a formula cell hold its calculated result.formulasreturn exactly what was written, including text literals longer than 255 characters. Ciphon stores provenance as=IF("<escaped JSON>"="", 0, <value>);IFandDATE(y,m,d)evaluate.- Sheets the host does not expose return
No such sheet. - Date-like strings in messages stay strings.