Changelog#
0.4.1 - 2026-10-13#
0.4.0 was tagged but failed the release size check before publishing (the eager bundle was 63.27 kB against the 63 kB budget), so it never reached npm. 0.4.1 carries the same changes, with the vertical-toolbar code moved lazy: the eager closure is 62.97 kB. Nothing else differs.
0.4.0 - 2026-10-13#
Added#
- Toolbar on the left or right.
toolbar: { position: "left" | "right" }draws a vertical strip beside the surface in theclassic,bottom-bar,compact,document,minimalandsplitlayouts (other layouts keep their own position). Items flow down, separators are horizontal rules, the border is on the inner edge,aria-orientation="vertical"with ArrowUp / ArrowDown roving, and the overflow is measured by height (clientHeight, item heights, row gap) with the samecomputeOverflow/overflowHiddenmaths; the More menu opens beside the strip. The editor keeps--atm-side-min-height(15rem) so about six buttons and More fit.placeNeargainedbeside: "end" | "start". Horizontal toolbars are unchanged.
0.3.2 - 2026-10-03#
Fixed#
- Compact layout: pressing a control below the editor lost the click. The toolbar folded to one row on blur, so a button under the editor moved up between mousedown and mouseup and the release landed beside it. The fold now waits for the pointer release (and is skipped if focus returned).
0.3.1 - 2026-10-03#
Added#
- Chip cards everywhere.
enhanceChipCards(root, { getCard, ... })(advanced-texteditor-md/chips) gives the chips inside any read-only markup (renderHtmloutput, a framework's DOM) the same cards the editor andrenderDomalready had: hover, keyboard focus and a touch long-press (500 ms) open the card, Escape closes it, a tap elsewhere closes it, and the long-press does not also open the system menu. It returns{ refresh(), destroy() }and does nothing without a DOM element. - Interactive chips look interactive. A chip with something behind it carries
data-atm-interactive(set by the lazy card code, so the eagerindexdoes not grow) and getscursor: pointer, a hover tint and underline, an active tint and a:focus-visiblering; a chip the host has no card for keeps the default cursor. Honoursprefers-reduced-motionandforced-colors. createLinkAffordances(/links): Ctrl/Cmd+click opens a link from the editor (new tab,noopener, scheme allow-list;onOpencan take over), the cursor over links becomes a pointer while the key is held, and hovering or focusing a link shows its address in a tooltip (off when the editor haslinkPreview).createHeadingAnchors/enhanceHeadingAnchors(/links): an opt-in "copy link to this section" button on the headings of read-only views, shown on hover and keyboard focus, announced through a live region, ids generated GitHub-style (headingSlug).- Library tooltip for icon-only tools (
[data-atm-tip], CSS only): the image and table toolbars no longer use a nativetitle. e2e/affordances.spec.ts(computed cursor, hover, focus ring, disabled look, tooltip, reduced motion, forced colors) and a unit guard (test/styles/cursor-guard.test.ts) that fails when a class styled on:hoverhas nocursorrule.
Fixed#
- Escape on a view chip whose card a mouse had opened refocused the chip, which opened the card again.
- The editable surface shows the text cursor in every engine (WebKit showed the arrow over links), and footnote references in the editor show a pointer.
0.3.0 - 2026-10-03#
Added#
- Source pane (
advanced-texteditor-md/source):createSourcePanePluginturns the Markdown pane into a small source editor: syntax tint, line numbers that follow wrapped lines, soft-wrap toggle, current-line band, bracket and emphasis pairing, Tab / Shift+Tab indent, Alt+ArrowUp / Alt+ArrowDown move lines, Mod-D duplicate, and the find plugin's matches drawn over the tint. The stored Markdown is untouched. 11.6 kB gzip, lazy. Code folding is not offered. - Front matter (
advanced-texteditor-md/frontmatter): the---YAML block at the top of a document as a properties panel (text, number, date, switch and list fields), edited line by line so comments, order and anything the panel cannot edit are kept as written;getFrontMatter,setFrontMatter,writeFrontMatterover a safe YAML subset; read-only list in views. Built onBlockSyntax.match. 14.8 kB gzip, lazy. - Comments (
advanced-texteditor-md/comments):createCommentsPluginfor inline comments anchored to text and stored as[anchored text](comment:ID), with the threads kept by the host (onCreate,render,isResolved); highlight and resolved state, margin markers, a thread panel,Mod-Alt-M/Alt-F9/Shift-Alt-F9, read-only views;findComments,commentIds,removeCommentMarks. 21 kB gzip, lazy. - Wiki links and link manager (
advanced-texteditor-md/links):createWikiLinks([[picker, chips stored as[Title](wiki:id), broken-page marks through the host'sresolve, optional "Create page",onOpen) andcreateLinkManager(review, edit, remove, go to, hostcheck, upgradehttp:tohttps:in one undo step); purefindLinks,findWikiIds,findBacklinks. 13 kB gzip, lazy. - Snippets (
advanced-texteditor-md/snippets):createSnippetsfor text expanders (;sig+ Space / Tab / Enter) and templates with{{date}},{{time}},{{cursor}},{{selection}}and host variables; a Templates group in the slash menu and an "Insert template…" picker;localStorageSnippets/memorySnippets; JSONexportSnippets/importSnippetswith a per-entry report. 9.4 kB gzip, lazy.
0.2.1 - 2026-10-03#
Added#
softBreak: "br"(ParseOptions, sorenderHtml,renderDomandcreateEditorall take it): a single newline inside a paragraph renders as<br>(the editor's Write view too, and it is read back as the same single newline). Default"space"; the parsed document and the stored Markdown do not change.- Chip colour and badge per person. An item's own
color/badgenow stay with that person (ChipDefinition.styles, keyedkind:id, in memory per editor).mentions: { persistStyle: true }writes them into the chip link as_color/_badgeso they survive a reload; off by default, so the wire format is unchanged. The renderer readsattrs._color/attrs._badge. - Playwright checks for the toolbar in 480, 730 and 768 px containers (classic and compact).
Fixed#
- Body-level UI (mention menu, link-preview popover, lightbox, footnote tip, chip cards and pickers, view dialogs) now carries the editor's
data-atm-theme,data-atm-densityanddir, and followssetTheme(dark editor on a light page and the reverse). - Toolbar: never wraps (
flex-wrap: nowrap), and after the overflow pass the row is checked against its real layout; whatever still does not fit goes to More (no lone button on a second row, no Σ under the mode switch). getValue()always returns the current content: a document over 20 kB no longer reports a stale value for 120 to 300 ms after typing.insertMarkdown/insertTextwork when the editor has no focus or selection (they insert at the end).- Markdown-mode
insertChipescapes the label, soJo [a](b)cannot break out of the link.
Changed#
insertTextis documented as literal andinsertMarkdownas parsing.- To stay inside the 63 kB eager budget: dropped the Safari < 14
matchMedialistener fallback (theautotheme keeps the theme it started with there) and the unused internalSurface.getDoc.
0.2.0 - 2026-10-02#
Added#
Definition lists (
advanced-texteditor-md/deflists):Term+: Definitionas a plugin block syntax onBlockSyntax.match/serialize(no parser change, the entry does not grow), an editor plugin with Enter / Backspace flow,/definitionand thedefinitionListcommand, andupgradeDefinitionListsfor real<dl>in views.advanced-texteditor-md/tasks: due-date chips on task items with overdue / today marks drawn at render time, assignees as mentions, a::: progressblock with a bar and a sentence kept true in the same undo step as a checkbox click, "move completed to bottom" (WYSIWYG and Markdown pane), an All / Open / Done / Overdue filter for views and read-only editors, shortcuts Mod-Alt-Shift-D / A / M, and the server-safetaskItems,tasksSummaryandprogressBlocks.Dictation and read aloud (
advanced-texteditor-md/speech):createDictationPlugin(Web SpeechSpeechRecognition, interim words as ghost text, final words inserted as text with smart spacing and capitals, optional spoken "new line" / "period" commands, language-aware, accessible status and errors) andcreateReadAloudPlugin(speechSynthesis, reads the selection or the document from the caret, word highlighting with the CSS Custom Highlight API and an overlay fallback, pause / resume / stop). Both are feature-detected and never start on their own.Present and reader views (
advanced-texteditor-md/present,/reader):createPresentViewturns a document into slides (split on---,h1,h2or automatically;::: notesbecome speaker notes; keyboard, swipe, fullscreen, speaker panel with timer, RTL aware,#slide-nhash) andcreateReaderViewinto a clean article (outline, reading progress and time,::: notesshown or hidden). Both are read-only and take the renderer options;createPresentPlugin/createReaderPluginadd a toolbar command that opens the view in a full-window dialog. Nothing is stored in the Markdown; GitHub shows::: notesas plain text.Chrome v2: seven new layouts:
ribbon(tabbed, grouped, labelled; collapsible),sidebar(outline + inspector around a page),focus(fading chrome, immersive mode, typewriter scrolling),tabs(Write / Preview / Markdown),compact,mobile(keyboard-pinned toolbar, bottom sheets) andauto(mobile below a breakpoint).layoutOptionsconfigures them. Each is a lazy chunk.Command palette (Mod-Shift-P): fuzzy search over every command, categories, recent commands, an ARIA combobox.
commandPalette: false | { recent }.Keyboard shortcuts sheet (Mod-/) built from the live keymap.
Context menu (right-click, Shift+F10, the ContextMenu key) for text, links, images, tables, code and chips, with a "Turn into" submenu.
contextMenu: falseturns it off.Settings popover (
exec("settings")): density, text size, line width, spelling, line numbers, typewriter, visible whitespace;settings: { storage, key, defaults }keeps them;settings:changeevent.Toolbar model: named groups (
TOOLBAR_GROUPS,toolbar.groups), inline items, item typestoggle,dropdown,splitandcolor,priorityfor overflow,toolbar.labels(hover/always/never),iconsoverrides.Status bar v2:
statusBar: { items, wordsPerMinute }with reading time, selection, cursor position, save status (exec("setSaveStatus", …)), zoom and a direction toggle.Slash menu v2: sections, recent items, descriptions, shortcuts, a preview column, nested submenus (table size, embeds).
Density (
density: "compact" | "comfortable" | "spacious"), public spacing / type / elevation / motion tokens, tooltips (on focus, after 500 ms of hover), split buttons, menu arrows, empty-state hints, caret and selection colours, scrollbars, the sticky toolbar's shadow, block chrome and loading skeletons.Themes
ocean,forestandrose, selectable by name, AA-checked like the others.Code blocks keep their info string:
codeBlock.metaholds everything after the language (title="a.ts" {1,3-5}), round-trips, renders asdata-metaon<pre>.GitHub alerts (
advanced-texteditor-md/alerts):> [!NOTE],[!TIP],[!IMPORTANT],[!WARNING],[!CAUTION]and custom kinds render as coloured callouts with icons (CSS alone styles static pages), round-trip unescaped, and are edited in place: a[!completion list, slash items, a toolbar type switcher,alert/insertAlertcommands (also in the Markdown pane).Code blocks v2 (
advanced-texteditor-md/code-blocks,highlight/diff): file-name titles, highlighted lines{1,3-5}, line numbers, wrap toggle and tab size from the info string; a code bar in the editor (searchable language, file name, Copy, Wrap, Line numbers, Format JSON; Alt+F10); auto-indent, Tab / Shift+Tab, bracket and quote pairing; view headers with Copy;diffcolouring.Tables v2 (
advanced-texteditor-md/tables): column resizing by drag or keyboard (view-only widths, never stored), opt-in sortable columns in read-only views witharia-sort, spreadsheet paste (TSV and spreadsheet HTML become a GFM table, or fill cells), CSV / TSV import (csvToTable,tableImport, limits with a clear refusal), row and column moves by drag and Mod-Alt-Shift-arrows, a header-row toggle, alignment shortcuts; also in the Markdown pane.Diagrams and embeds from fenced code blocks (
advanced-texteditor-md/diagrams):createDiagramsPlugin({ renderers })draws```mermaid,```chart,```tex(any language the host registers) with host-supplied renderers (no diagram library bundled), a live debounced preview under the block in the editor that never enters the Markdown, read-only views with a "Show source" toggle (renderDiagrams,postRender), lazy rendering, an LRU cache, aborted in-flight renders, untrusted string output in<iframe sandbox="">, and aninsertDiagramcommand.Compare and version history (
advanced-texteditor-md/diff): a dependency-free, bounded Myers diff (diffArrays,diffWordswith per-character CJK tokens,diffBlockson the library's own parser),createDiffView(side by side or inline, word or block granularity, keyboard navigation, per-change accept / reject,getMerged()computed from the Markdown source), andcreateHistoryStore/createHistoryPlugin(versioned snapshots, compare, restore, optional automatic snapshots).Export and import (
advanced-texteditor-md/export): copy as Markdown, HTML, plain or rich text (with a copy-event fallback), download.md/.html,exportHtml(fragment or a self-contained standalone document with a CSP and the editor's tokens), print only the document, import.md/.txt/.htmlby picker or by dropping a file, with an accessible confirm bar.Mentions v2 and chips v2 (
advanced-texteditor-md/chips): hover cards for chips (mouse, the caret beside a chip, focus in read-only views; tooltip or non-modal dialog, cached, abortable),@teamgroup mentions (createGroupMentions,expandGroupMentions, CSS-only group styling), tag / channel / command presets (tags created on space), recent-and-frequent ranking (rankMentions,createMentionRanker), the mention typeahead in the Markdown pane, chip icons, avatars, remove buttons and label editing (one undo step each), and a toolbar chip picker. The wire format is unchanged.Content blocks (
advanced-texteditor-md/blocks):::: columns/::: collayouts with insert, add/remove-column commands and safe Enter/Backspace at column edges; a footnote dialog (insert and edit, one undo step) plus back links per reference and tooltips in views; document-level rule styles (line,dots,fade,ornament,wave);createShortcodes/mergeShortcodesto clean a host emoji table;[2026-10-02](date:2026-10-02)date chips with@today, a/dateitem and a native date picker; file cards for uploaded files with the size stored in the link title; and image galleries for a paragraph of images.createContentBlocksPluginsbuilds them all.Writing aids (
advanced-texteditor-md/writing), all driven by host functions with nothing bundled: ghost-text completion (createSuggestPlugin: Tab accepts in one undo step, Mod-ArrowRight one word, Escape dismisses, abortable, WYSIWYG and Markdown pane), selection actions (createSelectionActionsPlugin: commands and toolbar items, busy state with Cancel, replaces the saved selection or offers the result to copy), spellcheck and language (createLanguagePlugin), the purereadingStatshelper (CJK by character) and a word goal (createWordGoalPlugin), and lint hooks (createLintPlugin: Highlight API squiggles with an overlay fallback, fix popover, Alt+F8 navigation).Languages and right-to-left text (
advanced-texteditor-md/i18n,advanced-texteditor-md/i18n/<code>): complete label bundles for English, Spanish, French, German, Portuguese, Italian, Dutch, Russian, Japanese, Chinese, Arabic, Hindi and Turkish (each at most 1.5 kB gzip, one lazy chunk per language,loadLabelswith BCP 47 fallback),resolveLocale,isRtl, andcreateBidiPlugin(dir, per-block direction,setDirection/toggleDirection, theplugin:i18n:directionevent, no writes during an IME composition). Wording is not native-reviewed.Images:
stores alignment (left,center,right; none = inline) and a pixel width in the alt text, which every Markdown viewer still shows as an image. A paragraph holding only a captioned image renders as<figure class="atm-figure"><img><figcaption class="atm-caption">. In the editor a selected image gets a frame with corner handles (drag, or Shift+Arrow; aspect kept; minimum 32 px; Escape cancels a drag) and a toolbar (Alt+F10): inline, left, centre, right, caption, alt text, zoom, open, remove.images: { tools, zoom }options.Lightbox:
images.zoom("readonly"by default,true,false) opens a modal image viewer with previous/next, a count, focus trap and focus return. New subpathadvanced-texteditor-md/lightbox(attachLightbox,LIGHTBOX_LABELS) for pages built withrenderHtml/renderDom.Collapsible sections:
::: details Summary…:::(and::: details open Summary) render as<details><summary>. Built in;features.details: false/ParseOptions.details: falseturn it off. Editable summary, Enter or a marker click toggles, slash item "Collapsible section",exec("details"). The open state while editing is never stored.Block handles (
features.blockHandles): a handle beside the hovered or focused top-level block or list item; drag with a drop indicator; Alt+Shift+H focuses it, Alt+ArrowUp/Down move (announced, one undo step), and its menu has Move up, Move down, Duplicate, Delete and Turn into. Hidden on touch screens unless focused. Never in the Markdown.Table toolbar (
features.tableToolbar): add a row below or a column to the right, delete the row or column, align the column, delete the table; Alt+F10 focuses it. Every button is a command:tableAddRow,tableAddColumn,tableDeleteRow,tableDeleteColumn,tableAlignLeft,tableAlignCenter,tableAlignRightandtableDeleteTable.onSubmit(markdown, editor)andexec("submit").RenderOptions.labels.detailsand.task.Firefox and WebKit Playwright projects, a generated axe and keyboard matrix over every theme and layout (
e2e/a11y-matrix.spec.ts), a 120+ vector XSS corpus over every input path (test/security/) and its real-browser replay (e2e/security.spec.ts), and a consumer bundling test (test/consumer/bundle.test.ts).
Changed#
- Toolbar tooltips are drawn on demand, not as native
titles. Buttons carryaria-label,aria-keyshortcutsanddata-sc(the formatted shortcut); the tooltip (role="tooltip",aria-describedby) comes from thetoolbar-menuchunk. - The default toolbar order is derived from groups (
text,blocks,insert,history,plugins);DEFAULT_ITEM_ORDERis gone. Plugin items without agroupstill come last. - Menus enter with movement only, never opacity, so their text is at full contrast from the first frame.
- The
mentionslazy chunk is nowmention-glue(the typeahead and the editor's wiring in one chunk). layoutOptions.focus.dimis off by default and only dims while typing: dimmed text is below WCAG AA by design.- Right-to-left chrome: logical properties throughout, mirrored arrows and chevrons; code blocks stay left to right.
- The bottom-bar submit event is now
atm:submit, notsubmit. AsubmitCustomEvent bubbled into a surrounding<form>'s submit listeners. Listen foratm:submit(samedetail: { value, editor }, cancelable) or passonSubmit. chipsaccepts an array or a record keyed by scheme in bothEditorOptionsandRenderOptions, normalised in one place. A scheme declared inchipsparses as a chip without also listing it inchipSchemes(before,renderHtml("[Task 12](task:issue/12)", { chips: [{ scheme: "task", className: "task-chip" }] })rendered a plain link).- New lazy chunks:
image-tools,table-tools,block-handles,zoom,bubble(the bubble layout's floating toolbar) andtoolbar-menu(the toolbar's dropdowns), each with a 12 kB budget. The caret mapping between the rich-text and Markdown panes moved into themarkdown-panechunk. The eagerindexis 61.5 kB gzip (budget 62). - Link-preview cards and the hover popover follow every theme. Each theme in
themes.csssets a private layer,--atm-th-preview-*(bg, border, fg, muted, accent, skeleton, skeleton-hi, embed-bg, shadow), for light, dark,sepia,slate,contrastand the dark-OS fallback;link-preview.cssholds no palette of its own and reads the public--atm-preview-*/--atm-embed-bgfirst, then that layer. Before,sepia,slateandcontrastshowed a light (or dark-OS) card. A unit test checks AA contrast of every card colour;e2e/a11y-matrix.spec.tsruns axe on a card and the hover popover in all six themes in all four browser projects and checks that each card wears its theme's palette. - Rendered task-list checkboxes have an accessible name (
aria-label, default "Task"). trapTab(dialogs, popovers, forms, the lightbox) moves focus itself on every Tab, so Safari's button-skipping Tab order cannot leave a dialog.
Fixed#
- List bullets and numbers vanished under a CSS reset (Tailwind's preflight sets
list-style: none).surface.cssnow setsdisc/circle/squareanddecimalon the editing surface (and so read-only editors) and on rendered output (.atm-ul,.atm-ol:renderHtml, the preview pane), with the room they need; task items stay marker-less. A host's ownul { list-style-type }still wins by coming later at the same specificity. - A plain-text paste of several lines is checked for Markdown in the lazy
pastechunk (single lines are unchanged); a cold first multi-line paste waits for that chunk like an HTML paste does. - Adjacent bold (or italic, strike, code) was saved as escaped underscores.
**a**then**b**then plain text came back as**a**\_\_b\_\_start. Adjacent same-type marks now merge before saving (editor andstringify), the_delimiter is never used beside a letter or digit, and punctuation-ended marks next to a letter (**Note:**text) keep their formatting.stringifyof*a*_b_is now*ab*. - The text-colour button (any
ToolbarItem.renderitem) did nothing from the More menu on a narrow toolbar. The menu now hosts the item's own element, and function-command items run from it too. - Bundlers no longer warn about ignored bare imports (
import "./chunk-X.js"): the build removes them after proving each such chunk has no side effects (scripts/strip-bare-imports.mjs), andnpm run check:packagefails if a split bundle warns again. - Link-preview card styles were written against the bare
.atm-previewclass, which is also the editor's read-only preview pane, so in theslateandcontrastthemes the split preview drew light-theme text on a dark background. Card rules are now scoped to[data-atm-preview-card]. - After "Turn into" from the block menu the caret is left at the end of the converted block, not at the top of the editor.
- Firefox and WebKit editing gaps (the specs that were
test.fixme; all pass now in thefirefoxandwebkitprojects):- Gecko put a click past a chip at the end of a line INSIDE the
contenteditable=falsechip, where typing was refused. The surface moves a collapsed caret out of an inline atom to its nearer edge onselectionchange. - WebKit reports Shift+Enter as
insertParagraph; it now inserts a hard line break, as in Chromium and Gecko. - WebKit fires no
beforeinputfor Backspace when nothing editable precedes the caret, so a first heading, list item or quote could not be lifted and an embed (or rule) before a paragraph could not be removed. The keydown handles that case. - Text colour: WebKit drops the document selection when a toolbar button takes keyboard focus, so a swatch chosen by keyboard coloured nothing.
textStylefocuses the editor first, which restores the last selection.
- Gecko put a click past a chip at the end of a line INSIDE the
- HTML pasted before the paste chunk had loaded was inserted where the caret was when the chunk ARRIVED (a drop or click in between moved it); it now lands where it was pasted.
0.1.0#
First release.
Editor#
- WYSIWYG surface that stores Markdown; Write, Markdown and Split modes over one document; six layouts (classic, minimal, bubble, bottom-bar, split, document); five themes plus
auto; toolbar with overflow menu, slash menu, popovers for links, images and tables, status bar, undo and redo, configurable keymap. - Mentions with badges, palette colours and merged identities (one chip, several ids), several triggers,
classesfor the menu slots, and a combobox ARIA pattern verified with axe. - Chips with
onClickin the editor and in the split preview. - Uploads: paste, drop and picker; allow and deny lists; three uploader factories plus a data-URL one; placeholders with progress; URL checks before insertion.
- Link previews (card and hover card) and embeds (sandboxed iframe blocks with a "Convert to link" action), wired into the surface, the split preview and the renderer.
RenderOptions.embedsand.linkPreview, andEmbedProvider.embedHosts. - Plugins (
definePlugin), custom inline and block syntax, andInlineSyntax.serialize, whichstringifynow calls for pattern-only syntaxes. - Math (a TeX subset to MathML), code highlighting with eleven small language modules, i18n labels, read-only and disabled states, form integration through a hidden input.
Parser and renderer#
- Hand-written GFM-compatible parser with a stable
stringify(a fixed point for every input), reference links, footnotes, math, chips, custom syntax. Linear time on large documents. - Server-safe
renderHtml,renderDomandrenderMarkdown. Code blocks are keyboard-focusable regions with a label.
Packaging#
- ESM and CJS with types for 11 subpaths (
.,/parser,/render,/math,/highlight,/uploaders,/plugins,/mentions,/paste,/link-preview,/embeds),highlight/<lang>,style.css,style.min.cssandtailwind.css.sideEffectsis CSS only; the build is annotated for tree-shaking. - Lazy chunks for popovers, slash menu, mentions, uploads, the Markdown pane, math, HTML paste and rich links;
preloadChunks()loads them all. The main entry no longer re-exports math, uploaders, mentions, paste, link previews, embeds or the ready-made plugins; import them from their subpaths. - Size budgets enforced by
npm run size: editor entry 62 kB gzip (target 48 kB), parser 14, render 14, math 5, each language 2, each lazy chunk 15. npm run check:packageverifies the exports map, a consumer type-check (bundlerandnode16resolution), loading every subpath in ESM and CJS without a DOM, tree-shaking probes and the minified CSS.
Feature plugins (advanced-texteditor-md/plugins)#
createFindReplacePlugin(find and replace; Replace all is one undo step),createDraftsPlugin(autosave and restore),createTocPlugin(a::: tocblock that is never stored),createTextStylePlugin([text]{.c-red}colour and highlight, optional++underline++),createSmartTypographyPluginandcreateShortcodesPlugin, with their pure helpers, option and label types and CSS strings.advanced-texteditor-md/plugins.cssis the stylesheet of all of them for hosts that bundle CSS themselves.hydrateAll(root, plugins, doc)fills in generated content (a table of contents) in a read-only view built fromrenderHtml.
Editor API for plugin authors#
editor.transact(fn): many edits, one undo step, onechange/onChange.editor.getPane()and thepaneevent ("wysiwyg" | "markdown"), fired when the active pane is (re)mounted, including after the lazily loaded Markdown pane arrives. Find-replace no longer polls for the textarea.- Plugin-defined events:
editor.emit("plugin:<name>:<event>", payload)andeditor.on(type, fn)with a string type. Built-in names are reserved. The drafts plugin emitsplugin:drafts:status(its DOMatm-draft-statusevent is kept). editor.isReadOnly(),editor.getSelectionMarkdown()andeditor.replaceSelectionMarkdown(md).- Plugin fields
keydown(ev, editor)(before the keymap;trueconsumes),afterInput(editor, info?)(after every content change, including characters the surface inserts itself) andpostRender(root, { doc, mode });RenderOptions.postRenderforrenderDom. MentionOptions.hideWhenEmpty: no "No results" row while nothing matches (used by shortcodes).InlineSyntax.serialize(inner, data)now documents and guarantees thatinneris Markdown whennested !== falseand the literal text whennested: false(a pattern syntax withnested: falseno longer gets escaped text, which grew on every save).- Text colour spans hold Markdown: bold inside a colour and a colour inside bold both survive, and colouring a selection keeps its inline formatting.
- Find highlights are registered per editor (
atm-find-<id>,atm-find-<id>-current), so two editors on a page do not clobber each other.
Changed in this release#
kbdnow uses[[Ctrl]], not++Ctrl++.++text++is the underline of the text-style plugin and one marker cannot serve both. Existing documents with++Ctrl++are not converted: they show as plain text (or as underline when the text-style plugin hasunderline: true). The text between[[and]]is literal.- Plugin CSS strings no longer contain the
::highlight(atm-find...)rules (the find plugin injects them per editor). PanegainedgetSelectionMarkdown,replaceSelectionMarkdownandtransact;SurfaceOptions.afterInputreceives an optional info argument andSurfaceOptions.postRenderexists. These are internal seams, listed for anyone who implements a pane.- The shortcodes
noResultslabel is accepted but no longer shown.
Fixes in this release#
- A paragraph with many soft line breaks parsed in quadratic time; now linear.
setValuekeeps the string verbatim, so typing@afterccopens the mention menu.- One
isAppleanddetectPlatformfor the keymap and the surface. - Chip palette and syntax colours each have one source (
themes.css,highlight.css). - A key consumed by
beforeKeyDownis cancelled by the pane itself.