Skip to content

InkKit 0.1.0

Choose a tag to compare

@aicayzer aicayzer released this 15 Oct 15:44
· 86 commits to main since this release
a0768b5

InkKit 0.1.0 is the first release for apps to adopt: every call and output names its document, every failure is a coded InkKitError, the styling contract uses only inkkit- names, and tables, saving and long notes work better. It breaks the host API and CSS, so read "Moving from 0.0.x" before you update.

For people

  • Tables. Tables draw borders, padded cells, a shaded header row and a scroller for wide tables. Controls on the active column and row align, add, delete and move them, by pointer or keyboard.
  • Source stays as authored. Setext headings, the indentation of a paragraph's other lines, list and quote items before a split or join, and formatting around an inline comment keep their bytes. A block the parser cannot build opens as literal source, and typing into a literal block saves what you typed.
  • Long notes. Enter, Backspace and paste across blocks cost about what typing a character costs. Code blocks over 5,000 characters stay unhighlighted so a note cannot freeze the editor.
  • Callouts. Enter and Backspace in a callout work as in a quote.
  • Comments. Hidden author comments survive Backspace and Delete beside them.
  • Links. Mod-click opens Markdown and wiki links (Command on Apple platforms, Control elsewhere), a click never makes the web view follow a link, and a link keeps the form it was written in when you edit it.
  • Paste and input. Text pasted inside a sentence joins the paragraph, pasted HTML imports only what it shows, and multi-character input inserts exactly its text.
  • Accessibility. File cards, footnote definitions, author comments and preserved Markdown blocks have roles and names.

For hosts

  • Document identity. DocumentVersion (documentId, generation, revision) is on every output, and changed receives a full DocumentSnapshot. Most calls take expectedGeneration and throw stale-document when it is not the loaded one.
  • One error type. Every failure is an InkKitError with a code from one closed list. The API reference documents each code, where it arrives and whether to retry.
  • Settled signatures. format, keyDown, insertImages, insertPaths, clipboardSnapshot and Keymap have typed, validated arguments, and format reports whether it applied.
  • Styling. Every class InkKit draws and every custom property it reads begins inkkit-. New tokens are --inkkit-column-inset and --inkkit-surface-focus-width, -color and -offset.
  • Files. FileReference.target is the reference without its fragment.
  • Labels. comment and preservedMarkdown are new labels.
  • Dependencies. The package bundles Milkdown, ProseMirror and every other runtime dependency except Mermaid, so a host runs the tree InkKit tested. Mermaid 12.1.0, pinned exactly, is the one runtime dependency.
  • Engines. WebKit 17.5, Chromium 123 and Firefox 125 (untested) are the supported engines. Without the Custom Highlight API, the editor now mounts and uses the browser's selection.

Moving from 0.0.x

Each line is a change a host must make. The API reference describes every member named here.

Mounting and events

  • Remove unknown names. mount rejects with invalid-argument for an unknown events name, an unknown labels key and an unknown option, so delete anything that is not in EditorEvents, EditorLabels or EditorOptions.
  • stateChanged is gone. Read caret state from commandStateChanged(state) as state.caret; passing stateChanged makes mount reject.
  • changed(markdown, generation) is now changed(snapshot). Read snapshot.text, snapshot.generation and snapshot.revision.
  • openLink and copy are optional. Without copy, InkKit draws no Copy button, and without openLink, links do not open. Delete stub handlers you added for them.
  • Your handlers' exceptions go to reportError(). An exception from changed, commandStateChanged, openLink, copy or error no longer fails the InkKit call that raised it.

Documents and generations

  • Use a greater generation on every load. loadDocument and reloadDocument throw invalid-argument unless generation is greater than the loaded one, and the first load accepts any integer.
  • Pass expectedGeneration last. Replace hand-written generation checks and commandState(expected) calls with the parameter on reloadDocument, paste, pasteAsPlainText, format, table, insertPaths, insertImages, insertFootnote, navigateFootnote, editReferenceDefinition, clipboardSnapshot, focus and blur.
  • Replace .ProseMirror blur code with blur(expected).

Calls

  • format('heading', n) is format('heading' + n). Use heading1 to heading6, and read commands.format.heading1 to heading6 instead of commands.format.heading.
  • format takes an options object. Use format('link', { destination }) and format('codeBlock', { language }); format('link') without a destination now only removes a link, and the call returns whether it applied.
  • keyDown takes one object. Change keyDown(key, code, meta, ctrl, alt, shift, generation) to keyDown({ key, code, metaKey, ctrlKey, altKey, shiftKey }, generation).
  • insertImages takes references and a point. Change insertImages([{ path, alt }], x, y) to insertImages([{ reference, alt, title? }], { clientX, clientY }?, generation?); it returns false instead of throwing image-unavailable, and works with only a FileAdapter.
  • insertPaths takes a point. Change insertPaths(paths, x, y) to insertPaths(paths, { clientX, clientY }, generation?).
  • clipboardSnapshot takes a scope. Change clipboardSnapshot(true) to clipboardSnapshot('document', generation) and clipboardSnapshot(false) to clipboardSnapshot('selection', generation).
  • Two members are removed. Use pasteAsPlainText(text, generation) instead of paste({ text, plainText: true }), and textRangesRects([range])[0] instead of textRangeRects(range).
  • Type keymaps as Keymap. An unknown shortcut name now throws invalid-argument in setKeymap and EditorOptions.keymap.

Errors

  • Branch on error.code only. There is one InkKitError with a closed list of codes; stop matching messages or classes, and treat any code except destroyed and internal as an editor that still works.
  • A refused facade edit throws. insertText, pasteAsPlainText, format, table, replaceTextRange and paste throw or reject with preservation and no longer also call events.error; edits the person makes still arrive there.
  • Replace RangeError and TypeError handling with invalid-argument. Four codes are new: invalid-argument, file-unavailable, clipboard-unavailable and internal.
  • Match file and clipboard failures by code. File and wiki-link failures are file-unavailable, and a copy without events.clipboard or a rejected handler is clipboard-unavailable.
  • clipboardSnapshot() sends no error events for degraded output. Read images[].error and diagrams[].error.
  • Drop ?? undefined shims. null counts as omitted for an optional argument.
  • A failed call changes nothing and sends nothing. The changed and commandStateChanged events a successful call raises arrive when it returns.

Files and links

  • Read FileReference.target. Stop slicing the fragment off reference yourself, and set target on any FileReference your tests build.
  • Delete your meta class code. InkKit tracks Mod itself and no longer reads a meta class on an ancestor; do not open links on Control-click yourself.
  • Expect fewer openable links. Only relative, fragment, query, http, https, mailto and tel addresses render and open, so ftp: no longer does, and openLink is never called with an empty address.

CSS

  • Rename seven classes. .copy, .empty, .image, .image-handle, .image-absent, .literal-markdown and .hljs-* are now .inkkit-copy, .inkkit-empty, .inkkit-image, .inkkit-image-handle, .inkkit-image-absent, .inkkit-literal-markdown and .inkkit-hljs-*.
  • Rename the custom properties. --accent, --text, --muted, --rule, --code-bg, --mono and --reading-width are now --inkkit-accent-color, --inkkit-text-color, --inkkit-muted-color, --inkkit-rule-color, --inkkit-code-background, --inkkit-monospace-font and --inkkit-reading-width, and the old names are no longer read.
  • Set --inkkit-column-inset instead of overriding .ProseMirror padding. Delete host rules that restyle .ProseMirror, the renamed classes or .hljs-*, and check host table rules, because tables now draw their own borders and padding.

Verification

2,187 unit tests, 378 Chromium and 375 WebKit browser tests, and clean packed and registry consumers in Chromium and WebKit passed on the release commit. The native WKWebView runner was not run on this release, and browser WebKit does not prove WKWebView behavior, so check your bridge when you adopt it. Synthetic composition tests do not establish every operating-system input method.