JavaScript API
Most programmatic control happens through the tiptap
Editor instance, plus the element's own properties and
events.
const el = document.querySelector('jinn-tap');
const editor = el.tiptap; // Tiptap Editor
Loading and reading content
// Load a fragment (custom-element form)
el.content = '<tei-div><tei-p>Hello</tei-p></tei-div>';
// Load a whole document
el.xml = '<TEI xmlns="http://www.tei-c.org/ns/1.0">…</TEI>';
// Read the document as XML
const xml = el.xml;
// React to edits
el.addEventListener('content-change', ({ detail }) => {
save(detail.xml);
});
Local document store (IndexedDB)
Optional module: @jinntec/jinntap/storage (re-exported from @jinntec/jinntap).
Keeps full document XML in the browser's IndexedDB — nothing is uploaded. Not used
by <jinn-tap> itself; hosts opt in.
See the Local document storage guide for behaviour, record shape, naming, restore prompts, and when to use it vs. server save.
import { attachLocalStore, DocumentStore } from '@jinntec/jinntap/storage';
import { jinnToastConfirm } from '@jinntec/jinntap/jinn-toast';
const handle = await attachLocalStore(el, {
onDraftAvailable: async (record) =>
jinnToastConfirm(`Restore local draft “${record.name}”?`, {
confirmLabel: 'Restore',
cancelLabel: 'Keep current',
}),
onRestore: (record) => console.log('Restored', record.name),
});
await handle.rename('My letter'); // lock display title
await handle.clear();
el.newDocument();
attachLocalStore(editor, options?) → handle or null (skipped during collab
unless { force: true }).
| Option | Default | Description |
|---|---|---|
documentId |
current-<format> |
IndexedDB key |
debounceMs |
500 |
Autosave delay (ms) |
autoRestore |
false |
Restore without prompting |
onDraftAvailable |
— | (record) => boolean | Promise<boolean> (false deletes the draft) |
onRestore |
— | After restore |
onNameChange |
— | Display title changed |
Handle: restore(), saveNow(), rename(name), loadDocument(xml, { filename? }),
clear(), getRecord(), detach(), restored, pendingDraft, store.
DocumentStore: open(), list(), get(id), put(doc), delete(id).
Utilities: deduceDocumentName, extractTitleFromXml, isGenericTitle,
isProvisionalTitle, truncateTitle.
Assets
import { IndexedDbAssetStore, attachAssetStore } from '@jinntec/jinntap/storage';
await attachAssetStore(el, new IndexedDbAssetStore());
// el.assets.list / get / put / delete / resolve
For TEI Publisher / Jinks, use HttpAssetStore or the convenience helper
attachPublisherAssetStore (same module) against /api/jinntap/assets.
Graphic url / xlink:href accept relative paths (myimage.png) or absolute
http(s): URLs (typed in the field). With a store attached, the attribute panel
also shows an image picker when editor.assets is set. See
Local document storage → Assets.
Export helpers: collectReferencedAssets(xml, store), downloadXml,
downloadDocumentZip — when local images are referenced, hosts can offer a ZIP
bundle (see Exporting with images).
Commands
The tiptap editor exposes ProseMirror commands. The command names correspond to the
schema (toggleMark uses a mark's name, wrapping commands are declared per element):
// Toggle an inline mark with attributes
editor.chain().focus().toggleMark('hi', { rend: 'b' }).run();
// Set a text selection, then apply
editor.commands.setTextSelection({ from: 10, to: 20 });
editor.commands.toggleMark('rs', { type: 'gnd' });
// Focus the editor
editor.commands.focus();
Which commands exist is driven by the schema: each element's toolbar and keyboard entries name the command that creates it.
Selection and state
const { state } = editor;
const { from, to } = state.selection;
const isBold = editor.isActive('hi', { rend: 'b' });
For the full command and state API, see the Tiptap documentation.