@dxos/ui-editor 0.0.0 → 0.8.4-main.03d5cd7b56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/index.mjs +8633 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/types/index.mjs +33 -0
- package/dist/lib/browser/types/index.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +8635 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/types/index.mjs +35 -0
- package/dist/lib/node-esm/types/index.mjs.map +7 -0
- package/dist/types/src/defaults.d.ts +6 -0
- package/dist/types/src/defaults.d.ts.map +1 -0
- package/dist/types/src/extensions/annotations.d.ts +9 -0
- package/dist/types/src/extensions/annotations.d.ts.map +1 -0
- package/dist/types/src/extensions/auto-scroll.d.ts +18 -0
- package/dist/types/src/extensions/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts +17 -0
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts +5 -0
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts +13 -0
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts +23 -0
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts +10 -0
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts +4 -0
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts +2 -0
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts +4 -0
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/defs.d.ts +17 -0
- package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/index.d.ts +2 -0
- package/dist/types/src/extensions/automerge/index.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/sync.d.ts +17 -0
- package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts +6 -0
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts +5 -0
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts +31 -0
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts +46 -0
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -0
- package/dist/types/src/extensions/awareness/index.d.ts +3 -0
- package/dist/types/src/extensions/awareness/index.d.ts.map +1 -0
- package/dist/types/src/extensions/blast.d.ts +25 -0
- package/dist/types/src/extensions/blast.d.ts.map +1 -0
- package/dist/types/src/extensions/blocks.d.ts +2 -0
- package/dist/types/src/extensions/blocks.d.ts.map +1 -0
- package/dist/types/src/extensions/bookmarks.d.ts +12 -0
- package/dist/types/src/extensions/bookmarks.d.ts.map +1 -0
- package/dist/types/src/extensions/comments.d.ts +90 -0
- package/dist/types/src/extensions/comments.d.ts.map +1 -0
- package/dist/types/src/extensions/debug.d.ts +3 -0
- package/dist/types/src/extensions/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/dnd.d.ts +9 -0
- package/dist/types/src/extensions/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.d.ts +88 -0
- package/dist/types/src/extensions/factories.d.ts.map +1 -0
- package/dist/types/src/extensions/factories.test.d.ts +2 -0
- package/dist/types/src/extensions/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/focus.d.ts +7 -0
- package/dist/types/src/extensions/focus.d.ts.map +1 -0
- package/dist/types/src/extensions/folding.d.ts +6 -0
- package/dist/types/src/extensions/folding.d.ts.map +1 -0
- package/dist/types/src/extensions/hashtag.d.ts +3 -0
- package/dist/types/src/extensions/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +32 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/extensions/json.d.ts +7 -0
- package/dist/types/src/extensions/json.d.ts.map +1 -0
- package/dist/types/src/extensions/listener.d.ts +13 -0
- package/dist/types/src/extensions/listener.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/action.d.ts +12 -0
- package/dist/types/src/extensions/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts +25 -0
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.d.ts +10 -0
- package/dist/types/src/extensions/markdown/changes.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/debug.d.ts +11 -0
- package/dist/types/src/extensions/markdown/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts +25 -0
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts +63 -0
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts +3 -0
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts +37 -0
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/image.d.ts +7 -0
- package/dist/types/src/extensions/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/index.d.ts +10 -0
- package/dist/types/src/extensions/markdown/index.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/link.d.ts +7 -0
- package/dist/types/src/extensions/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts +2 -0
- package/dist/types/src/extensions/markdown/parser.test.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/styles.d.ts +4 -0
- package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -0
- package/dist/types/src/extensions/markdown/table.d.ts +8 -0
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/mention.d.ts +7 -0
- package/dist/types/src/extensions/mention.d.ts.map +1 -0
- package/dist/types/src/extensions/modal.d.ts +7 -0
- package/dist/types/src/extensions/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/modes.d.ts +10 -0
- package/dist/types/src/extensions/modes.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/commands.d.ts +10 -0
- package/dist/types/src/extensions/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.d.ts +5 -0
- package/dist/types/src/extensions/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/index.d.ts +4 -0
- package/dist/types/src/extensions/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/menu.d.ts +8 -0
- package/dist/types/src/extensions/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts +11 -0
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/selection.d.ts +12 -0
- package/dist/types/src/extensions/outliner/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.d.ts +79 -0
- package/dist/types/src/extensions/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts +2 -0
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/index.d.ts +2 -0
- package/dist/types/src/extensions/preview/index.d.ts.map +1 -0
- package/dist/types/src/extensions/preview/preview.d.ts +34 -0
- package/dist/types/src/extensions/preview/preview.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.d.ts +21 -0
- package/dist/types/src/extensions/replacer.d.ts.map +1 -0
- package/dist/types/src/extensions/replacer.test.d.ts +2 -0
- package/dist/types/src/extensions/replacer.test.d.ts.map +1 -0
- package/dist/types/src/extensions/scroll-past-end.d.ts +3 -0
- package/dist/types/src/extensions/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/scroller.d.ts +68 -0
- package/dist/types/src/extensions/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/selection.d.ts +24 -0
- package/dist/types/src/extensions/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/snippets.d.ts +10 -0
- package/dist/types/src/extensions/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/state.d.ts +2 -0
- package/dist/types/src/extensions/state.d.ts.map +1 -0
- package/dist/types/src/extensions/submit.d.ts +10 -0
- package/dist/types/src/extensions/submit.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts +10 -0
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/fader.d.ts +12 -0
- package/dist/types/src/extensions/tags/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/index.d.ts +7 -0
- package/dist/types/src/extensions/tags/index.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts +43 -0
- package/dist/types/src/extensions/tags/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +31 -0
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts +24 -0
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts +117 -0
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts +10 -0
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +1 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts +2 -0
- package/dist/types/src/extensions/tags/xml-util.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +8 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/styles/index.d.ts +2 -0
- package/dist/types/src/styles/index.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts +58 -0
- package/dist/types/src/styles/theme.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +2 -0
- package/dist/types/src/types/index.d.ts.map +1 -0
- package/dist/types/src/types/types.d.ts +21 -0
- package/dist/types/src/types/types.d.ts.map +1 -0
- package/dist/types/src/util/cursor.d.ts +31 -0
- package/dist/types/src/util/cursor.d.ts.map +1 -0
- package/dist/types/src/util/debug.d.ts +17 -0
- package/dist/types/src/util/debug.d.ts.map +1 -0
- package/dist/types/src/util/decorations.d.ts +4 -0
- package/dist/types/src/util/decorations.d.ts.map +1 -0
- package/dist/types/src/util/dom.d.ts +10 -0
- package/dist/types/src/util/dom.d.ts.map +1 -0
- package/dist/types/src/util/facet.d.ts +3 -0
- package/dist/types/src/util/facet.d.ts.map +1 -0
- package/dist/types/src/util/index.d.ts +7 -0
- package/dist/types/src/util/index.d.ts.map +1 -0
- package/dist/types/src/util/util.d.ts +8 -0
- package/dist/types/src/util/util.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +42 -43
- package/src/defaults.ts +33 -20
- package/src/extensions/annotations.ts +1 -1
- package/src/extensions/auto-scroll.ts +234 -0
- package/src/extensions/autocomplete/placeholder.ts +37 -18
- package/src/extensions/automerge/automerge.test.tsx +37 -11
- package/src/extensions/automerge/automerge.ts +5 -7
- package/src/extensions/blocks.ts +5 -5
- package/src/extensions/comments.ts +5 -6
- package/src/extensions/dnd.ts +2 -2
- package/src/extensions/factories.test.ts +88 -0
- package/src/extensions/factories.ts +32 -15
- package/src/extensions/folding.ts +5 -22
- package/src/extensions/index.ts +4 -3
- package/src/extensions/markdown/action.ts +0 -1
- package/src/extensions/markdown/bundle.ts +23 -9
- package/src/extensions/markdown/decorate.ts +15 -12
- package/src/extensions/markdown/formatting.ts +5 -10
- package/src/extensions/markdown/highlight.ts +15 -7
- package/src/extensions/markdown/link.ts +27 -33
- package/src/extensions/markdown/parser.test.ts +0 -1
- package/src/extensions/markdown/styles.ts +42 -9
- package/src/extensions/markdown/table.ts +24 -2
- package/src/extensions/outliner/outliner.test.ts +0 -1
- package/src/extensions/outliner/outliner.ts +3 -4
- package/src/extensions/outliner/tree.test.ts +0 -1
- package/src/extensions/preview/preview.ts +62 -15
- package/src/extensions/scroll-past-end.ts +32 -0
- package/src/extensions/scroller.ts +256 -0
- package/src/extensions/selection.ts +1 -1
- package/src/extensions/snippets.ts +67 -0
- package/src/extensions/tags/extended-markdown.test.ts +120 -2
- package/src/extensions/tags/extended-markdown.ts +80 -1
- package/src/extensions/tags/fader.ts +195 -0
- package/src/extensions/tags/index.ts +4 -1
- package/src/extensions/tags/testing/text.md +36 -0
- package/src/extensions/tags/testing/text.txt +35 -0
- package/src/extensions/tags/typewriter.test.ts +65 -0
- package/src/extensions/tags/typewriter.ts +594 -0
- package/src/extensions/tags/xml-block-decoration.ts +123 -0
- package/src/extensions/tags/xml-formatting.ts +125 -0
- package/src/extensions/tags/xml-tags.ts +186 -35
- package/src/extensions/tags/xml-util.test.ts +199 -24
- package/src/extensions/tags/xml-util.ts +62 -5
- package/src/index.ts +0 -1
- package/src/styles/index.ts +0 -2
- package/src/styles/theme.ts +124 -33
- package/src/types/types.ts +10 -2
- package/src/typings.d.ts +8 -0
- package/src/util/cursor.ts +1 -2
- package/src/extensions/autoscroll.ts +0 -165
- package/src/extensions/scrolling.ts +0 -189
- package/src/extensions/tags/streamer.ts +0 -243
- package/src/extensions/typewriter.ts +0 -68
- package/src/styles/markdown.ts +0 -26
- package/src/styles/tokens.ts +0 -17
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/index.ts", "../../../src/defaults.ts", "../../../src/extensions/annotations.ts", "../../../src/extensions/autocomplete/autocomplete.ts", "../../../src/extensions/autocomplete/match.ts", "../../../src/extensions/autocomplete/placeholder.ts", "../../../src/util/facet.ts", "../../../src/util/cursor.ts", "../../../src/util/decorations.ts", "../../../src/util/debug.ts", "../../../src/util/dom.ts", "../../../src/util/util.ts", "../../../src/extensions/autocomplete/typeahead.ts", "../../../src/extensions/auto-scroll.ts", "../../../src/extensions/scroller.ts", "../../../src/extensions/automerge/automerge.ts", "../../../src/extensions/state.ts", "../../../src/extensions/automerge/cursor.ts", "../../../src/extensions/automerge/defs.ts", "../../../src/extensions/automerge/sync.ts", "../../../src/extensions/automerge/update-automerge.ts", "../../../src/extensions/automerge/update-codemirror.ts", "../../../src/extensions/awareness/awareness.ts", "../../../src/extensions/awareness/awareness-provider.ts", "../../../src/extensions/blast.ts", "../../../src/extensions/blocks.ts", "../../../src/extensions/bookmarks.ts", "../../../src/extensions/comments.ts", "../../../src/extensions/selection.ts", "../../../src/extensions/debug.ts", "../../../src/extensions/dnd.ts", "../../../src/extensions/factories.ts", "../../../src/styles/theme.ts", "../../../src/extensions/focus.ts", "../../../src/extensions/scroll-past-end.ts", "../../../src/extensions/folding.ts", "../../../src/extensions/hashtag.ts", "../../../src/extensions/json.ts", "../../../src/extensions/listener.ts", "../../../src/extensions/markdown/formatting.ts", "../../../src/extensions/markdown/action.ts", "../../../src/extensions/markdown/bundle.ts", "../../../src/extensions/markdown/highlight.ts", "../../../src/extensions/markdown/debug.ts", "../../../src/extensions/markdown/decorate.ts", "../../../src/extensions/markdown/changes.ts", "../../../src/extensions/markdown/image.ts", "../../../src/extensions/markdown/styles.ts", "../../../src/extensions/markdown/table.ts", "../../../src/extensions/markdown/link.ts", "../../../src/extensions/mention.ts", "../../../src/extensions/modal.ts", "../../../src/extensions/modes.ts", "../../../src/extensions/outliner/commands.ts", "../../../src/extensions/outliner/selection.ts", "../../../src/extensions/outliner/tree.ts", "../../../src/extensions/outliner/outliner.ts", "../../../src/extensions/outliner/editor.ts", "../../../src/extensions/outliner/menu.ts", "../../../src/extensions/preview/preview.ts", "../../../src/extensions/replacer.ts", "../../../src/extensions/snippets.ts", "../../../src/extensions/submit.ts", "../../../src/extensions/tags/extended-markdown.ts", "../../../src/extensions/tags/fader.ts", "../../../src/extensions/tags/typewriter.ts", "../../../src/extensions/tags/xml-block-decoration.ts", "../../../src/extensions/tags/xml-formatting.ts", "../../../src/extensions/tags/xml-tags.ts", "../../../src/extensions/tags/xml-util.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport { type Extension, EditorState } from '@codemirror/state';\nexport { EditorView, keymap } from '@codemirror/view';\nexport { tags } from '@lezer/highlight';\n\nexport { TextKind } from '@dxos/protocols/proto/dxos/echo/model/text';\n\nexport * from './defaults';\nexport * from './extensions';\nexport * from './util';\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { mx } from '@dxos/ui-theme';\n\nimport { type ThemeExtensionsOptions } from './extensions';\n\n// NOTE: Padding is added to the editor to account for the focus ring (since otherwise the CM gutter will clip it)\nexport const editorClassNames = (role?: string) =>\n mx(\n 'dx-attention-surface p-0.5 data-[toolbar=disabled]:pt-2 dx-focus-ring-inset',\n role === 'section' ? '[&_.cm-scroller]:overflow-hidden [&_.cm-scroller]:min-h-24' : 'dx-container overflow-hidden',\n );\n\nexport const documentSlots: ThemeExtensionsOptions['slots'] = {\n content: {\n /**\n * CodeMirror content width.\n * 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)\n * 50rem = 800px. Maximum content width for solo mode.\n * NOTE: Max width - 4rem = 2rem left/right margin (or 2rem gutter plus 1rem left/right margin).\n */\n className: mx(\n // Inline-size container for widget sizing (children use `max-w-[100cqi]`).\n // NOTE: Use inline-size, not full size containment — `container-type: size` on the\n // editor content breaks CodeMirror's viewport measurement, leaving blank gaps during\n // scroll until a click forces a re-measure.\n 'dx-inline-size-container',\n // Wider margin for web (vs. mobile).\n 'pointer-fine:max-w-[min(50rem,100%-4rem)] pointer-coarse:max-w-[min(50rem,100%-2rem)]',\n 'mx-auto! w-full',\n ),\n },\n};\n\nexport const compactSlots: ThemeExtensionsOptions['slots'] = {\n content: {\n className: 'mx-2!',\n },\n};\n\nexport const mobileSlots: ThemeExtensionsOptions['slots'] = {\n content: {\n className: 'mx-2!',\n },\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Extension, RangeSetBuilder } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\nconst annotationMark = Decoration.mark({ class: 'cm-annotation' });\n\nexport type AnnotationOptions = {\n match?: RegExp; // TODO(burdon): Update via hook (e.g., for search).\n};\n\n/**\n *\n */\nexport const annotations = ({ match }: AnnotationOptions = {}): Extension => {\n return [\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet = Decoration.none;\n update(update: ViewUpdate) {\n const builder = new RangeSetBuilder<Decoration>();\n if (match) {\n // Only process visible lines.\n const { from, to } = update.view.viewport;\n const text = update.state.doc.sliceString(from, to);\n const matches = text.matchAll(match);\n for (const m of matches) {\n if (m.index !== undefined) {\n // Adjust match position relative to viewport.\n const start = from + m.index;\n const end = start + m[0].length;\n builder.add(start, end, annotationMark);\n }\n }\n }\n\n this.decorations = builder.finish();\n }\n },\n {\n decorations: (v) => v.decorations,\n },\n ),\n\n EditorView.theme({\n '.cm-annotation': {\n textDecoration: 'underline',\n textDecorationStyle: 'wavy',\n textDecorationColor: 'var(--color-error-text)',\n },\n }),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, Prec } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n WidgetType,\n keymap,\n} from '@codemirror/view';\n\nexport type AutocompleteOptions = {\n /**\n * Function that returns a list of suggestions based on the current text.\n * @param text The current text before the cursor\n * @returns Array of suggestion strings\n */\n onSuggest?: (text: string) => string[];\n};\n\n/**\n * Creates an autocomplete extension that shows inline suggestions.\n * Pressing Tab will complete the suggestion.\n *\n * @deprecated Use typeahead.\n */\nexport const autocomplete = ({ onSuggest }: AutocompleteOptions = {}): Extension => {\n const suggest = ViewPlugin.fromClass(\n class {\n _decorations: DecorationSet;\n _currentSuggestion: string | null = null;\n\n constructor(view: EditorView) {\n this._decorations = this.computeDecorations(view);\n }\n\n update(update: ViewUpdate) {\n if (update.docChanged || update.selectionSet) {\n this._decorations = this.computeDecorations(update.view);\n }\n }\n\n private computeDecorations(view: EditorView): DecorationSet {\n const text = view.state.doc.toString();\n const suggestions = onSuggest?.(text) ?? [];\n if (!suggestions.length) {\n this._currentSuggestion = null;\n return Decoration.none;\n }\n\n // Get the first suggestion.\n this._currentSuggestion = suggestions[0];\n const suffix = this._currentSuggestion.slice(text.length);\n if (!suffix) {\n return Decoration.none;\n }\n\n // Always show ghost text at the end of the document.\n return Decoration.set([\n Decoration.widget({\n widget: new InlineSuggestionWidget(suffix),\n side: 1,\n }).range(view.state.doc.length),\n ]);\n }\n\n completeSuggestion(view: EditorView): boolean {\n if (!this._currentSuggestion) {\n return false;\n }\n\n const text = view.state.doc.toString();\n const suffix = this._currentSuggestion.slice(text.length);\n if (!suffix) {\n return false;\n }\n\n view.dispatch({\n changes: {\n from: view.state.doc.length,\n insert: suffix,\n },\n selection: {\n anchor: view.state.doc.length + suffix.length,\n },\n });\n\n return true;\n }\n },\n {\n decorations: (v) => v._decorations,\n },\n );\n\n return [\n suggest,\n EditorView.theme({\n '.cm-inline-suggestion': {\n opacity: 0.4,\n },\n }),\n\n Prec.highest(\n keymap.of([\n {\n key: 'Tab',\n preventDefault: true,\n run: (view) => {\n const plugin = view.plugin(suggest);\n return plugin?.completeSuggestion(view) ?? false;\n },\n },\n {\n key: 'ArrowRight',\n preventDefault: true,\n run: (view) => {\n // Only complete if cursor is at the end\n if (view.state.selection.main.head !== view.state.doc.length) {\n return false;\n }\n\n const plugin = view.plugin(suggest);\n return plugin?.completeSuggestion(view) ?? false;\n },\n },\n ]),\n ),\n ];\n};\n\nclass InlineSuggestionWidget extends WidgetType {\n constructor(private suffix: string) {\n super();\n }\n\n override eq(other: this) {\n return this.suffix === other.suffix;\n }\n\n override toDOM() {\n const span = document.createElement('span');\n span.textContent = this.suffix;\n span.className = 'cm-inline-suggestion';\n return span;\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nexport type CompoetionContext = { line: string };\n\nexport type CompletionOptions = {\n default?: string;\n minLength?: number;\n};\n\n/**\n * Util to match current line to a static list of completions.\n */\nexport const staticCompletion =\n (completions: string[], options: CompletionOptions = {}) =>\n ({ line }: CompoetionContext) => {\n if (line.length === 0 && options.default) {\n return options.default;\n }\n\n const parts = line.split(/\\s+/).filter(Boolean);\n if (parts.length) {\n const str = parts.at(-1)!;\n if (str.length >= (options.minLength ?? 0)) {\n for (const completion of completions) {\n const match = matchCompletion(completion, str);\n if (match) {\n return match;\n }\n }\n }\n }\n };\n\nexport const matchCompletion = (completion: string, str: string, minLength = 0): string | undefined => {\n if (\n str.length >= minLength &&\n completion.length > str.length &&\n completion.startsWith(str)\n // TODO(burdon): If case insensitive, need to replace existing chars.\n // completion.toLowerCase().startsWith(str.toLowerCase())\n ) {\n return completion.slice(str.length);\n }\n};\n", "//\n// Copyright 2025 DXOS.org\n// Based on https://github.com/codemirror/view/blob/main/src/placeholder.ts\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { Decoration, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from '@codemirror/view';\n\nimport { clientRectsFor, flattenRect } from '../../util';\n\ntype Content = string | HTMLElement | ((view: EditorView) => HTMLElement);\n\nexport type PlaceholderOptions = {\n content: Content;\n delay?: number;\n focusOnly?: boolean;\n};\n\n/**\n * Shows a transient placeholder at the current cursor position. When\n * `focusOnly` is set the placeholder is suppressed unless the editor has DOM\n * focus, and is hidden again when focus is lost.\n */\nexport const placeholder = ({ content, delay = 3_000, focusOnly = false }: PlaceholderOptions): Extension => {\n const plugin = ViewPlugin.fromClass(\n class {\n _timeout: ReturnType<typeof setTimeout> | undefined;\n _decorations = Decoration.none;\n\n update(update: ViewUpdate) {\n // React to actual user activity only. The empty `view.update([])`\n // dispatched from the timeout below carries no doc/selection/focus\n // change, so it falls through here as a no-op — that's how the\n // freshly-set widget survives long enough for the decoration\n // provider to read it. Without this gate, the unconditional reset\n // would clobber the decoration in the same tick and the placeholder\n // would never visibly render.\n if (!update.docChanged && !update.selectionSet && !update.focusChanged) {\n return;\n }\n\n if (this._timeout) {\n window.clearTimeout(this._timeout);\n this._timeout = undefined;\n }\n this._decorations = Decoration.none;\n\n // Honour `focusOnly`: when the option is set and the editor isn't\n // focused, leave the placeholder hidden and skip rescheduling. The\n // next `focusChanged` update reschedules once focus returns.\n if (focusOnly && !update.view.hasFocus) {\n return;\n }\n\n const activeLine = update.view.state.doc.lineAt(update.view.state.selection.main.head);\n if (activeLine.text.trim() !== '') {\n return;\n }\n\n const lineStart = activeLine.from;\n const view = update.view;\n this._timeout = setTimeout(() => {\n this._decorations = Decoration.set([\n Decoration.widget({\n widget: new PlaceholderWidget(content),\n side: 1,\n }).range(lineStart),\n ]);\n view.update([]);\n }, delay);\n }\n\n destroy() {\n if (this._timeout) {\n clearTimeout(this._timeout);\n }\n }\n },\n {\n provide: (plugin) => {\n return [EditorView.decorations.of((view) => view.plugin(plugin)?._decorations ?? Decoration.none)];\n },\n },\n );\n\n return typeof content === 'string'\n ? [plugin, EditorView.contentAttributes.of({ 'aria-placeholder': content })]\n : plugin;\n};\n\nexport class PlaceholderWidget extends WidgetType {\n constructor(readonly content: Content) {\n super();\n }\n\n toDOM(view: EditorView) {\n const wrap = document.createElement('span');\n wrap.className = 'cm-placeholder';\n wrap.style.pointerEvents = 'none';\n wrap.setAttribute('aria-hidden', 'true');\n wrap.appendChild(\n typeof this.content === 'string'\n ? document.createTextNode(this.content)\n : typeof this.content === 'function'\n ? this.content(view)\n : this.content.cloneNode(true),\n );\n\n return wrap;\n }\n\n override coordsAt(dom: HTMLElement) {\n const rects = dom.firstChild ? clientRectsFor(dom.firstChild) : [];\n if (!rects.length) {\n return null;\n }\n\n const style = getComputedStyle(dom.parentNode as HTMLElement);\n const rect = flattenRect(rects[0], style.direction !== 'rtl');\n const lineHeight = parseInt(style.lineHeight);\n if (rect.bottom - rect.top > lineHeight * 1.5) {\n return {\n left: rect.left,\n right: rect.right,\n top: rect.top,\n bottom: rect.top + lineHeight,\n };\n }\n\n return rect;\n }\n\n override ignoreEvent() {\n return false;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Facet } from '@codemirror/state';\n\nexport const singleValueFacet = <I, O = I>(defaultValue?: O) =>\n Facet.define<I, O>({\n // Called immediately.\n combine: (providers) => {\n return (providers[0] ?? defaultValue) as O;\n },\n });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type EditorState } from '@codemirror/state';\n\nimport { type Range } from '../types';\nimport { singleValueFacet } from './facet';\n\n/**\n * Determines if two ranges overlap.\n * A range is considered to overlap if there is any intersection\n * between the two ranges, inclusive of their boundaries.\n */\nexport const overlap = (a: Range, b: Range): boolean => a.from <= b.to && a.to >= b.from;\n\n/**\n * Converts indexes into the text document into stable peer-independent cursors.\n *\n * See:\n * - https://automerge.org/automerge/api-docs/js/functions/next.getCursor.html\n * - https://github.com/yjs/yjs?tab=readme-ov-file#relative-positions\n *\n * @param {assoc} number Negative values will associate the cursor with the previous character\n * while positive - with the next one.\n */\nexport interface CursorConverter {\n toCursor(position: number, assoc?: -1 | 1): string;\n fromCursor(cursor: string): number;\n}\n\nconst defaultCursorConverter: CursorConverter = {\n toCursor: (position) => position.toString(),\n fromCursor: (cursor) => parseInt(cursor),\n};\n\nexport class Cursor {\n static readonly converter = singleValueFacet(defaultCursorConverter);\n\n static readonly getCursorFromRange = (state: EditorState, range: Range) => {\n const cursorConverter = state.facet(Cursor.converter);\n const from = cursorConverter.toCursor(range.from);\n const to = cursorConverter.toCursor(range.to, -1);\n return [from, to].join(':');\n };\n\n static readonly getRangeFromCursor = (state: EditorState, cursor: string) => {\n const cursorConverter = state.facet(Cursor.converter);\n\n const parts = cursor.split(':');\n const from = cursorConverter.fromCursor(parts[0]);\n const to = cursorConverter.fromCursor(parts[1]);\n return from !== undefined && to !== undefined ? { from, to } : undefined;\n };\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Range } from '@codemirror/state';\nimport { type Decoration, type DecorationSet } from '@codemirror/view';\n\nexport const decorationSetToArray = (deco: DecorationSet): readonly Range<Decoration>[] => {\n const ranges: Range<Decoration>[] = [];\n const iter = deco.iter();\n while (iter.value) {\n ranges.push({\n from: iter.from,\n to: iter.to,\n value: iter.value,\n });\n iter.next();\n }\n\n return ranges;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Transaction } from '@codemirror/state';\nimport { type EditorView } from '@codemirror/view';\n\nimport { log } from '@dxos/log';\n\nexport const join = (...lines: string[]) => lines.join('\\n');\n\n/**\n * CodeMirror callbacks swallow errors so wrap handlers.\n */\nexport const wrapWithCatch = (fn: (...args: any[]) => any, label?: string) => {\n return (...args: any[]) => {\n try {\n return fn(...args);\n } catch (err) {\n log.catch(err, { label });\n }\n };\n};\n\n/**\n * Log all changes before dispatching them to the view.\n * https://codemirror.net/docs/ref/#view.EditorView.dispatch\n */\nexport const debugDispatcher = (trs: readonly Transaction[], view: EditorView) => {\n logChanges(trs);\n view.update(trs);\n};\n\n/**\n * Util to log transactions in update listener.\n */\nexport const logChanges = (trs: readonly Transaction[]) => {\n const changes = trs\n .flatMap((tr) => {\n if (tr.changes.empty) {\n return undefined;\n }\n\n const changes: any[] = [];\n tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) =>\n changes.push(JSON.stringify({ fromA, toA, fromB, toB, inserted: inserted.toString() })),\n );\n\n return changes;\n })\n .filter(Boolean);\n\n if (changes.length) {\n log('changes', { changes });\n }\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\n// TODO(burdon): Factor out to @dxos/ui\n\nexport type Rect = {\n readonly left: number;\n readonly right: number;\n readonly top: number;\n readonly bottom: number;\n};\n\nexport const flattenRect = (rect: Rect, left: boolean): Rect => {\n const x = left ? rect.left : rect.right;\n return { left: x, right: x, top: rect.top, bottom: rect.bottom };\n};\n\nlet scratchRange: Range | null;\n\nexport const textRange = (node: Text, from: number, to = from): Range => {\n const range = scratchRange || (scratchRange = document.createRange());\n range.setEnd(node, to);\n range.setStart(node, from);\n return range;\n};\n\nexport const clientRectsFor = (dom: Node): DOMRectList => {\n if (dom.nodeType === 3) {\n return textRange(dom as Text, 0, dom.nodeValue!.length).getClientRects();\n } else if (dom.nodeType === 1) {\n return (dom as HTMLElement).getClientRects();\n } else {\n return [] as any as DOMRectList;\n }\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type EditorView } from '@codemirror/view';\n\nexport const insertAtCursor = (view: EditorView, from: number, insert: string) => {\n view.dispatch({\n changes: { from, to: from, insert },\n selection: { anchor: from + insert.length, head: from + insert.length },\n });\n};\n\n/**\n * If the cursor is at the start of a line, insert the text at the cursor.\n * Otherwise, insert the text on a new line.\n */\nexport const insertAtLineStart = (view: EditorView, from: number, insert: string) => {\n const line = view.state.doc.lineAt(from);\n if (line.from === from) {\n insertAtCursor(view, from, insert);\n } else {\n insert = '\\n' + insert;\n view.dispatch({\n changes: { from: line.to, to: line.to, insert },\n selection: { anchor: line.to + insert.length, head: line.to + insert.length },\n });\n }\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { EditorSelection, type Extension, Prec, RangeSetBuilder } from '@codemirror/state';\nimport {\n type Command,\n Decoration,\n type DecorationSet,\n type EditorView,\n ViewPlugin,\n type ViewUpdate,\n keymap,\n} from '@codemirror/view';\n\nimport { type CompoetionContext } from './match';\nimport { PlaceholderWidget } from './placeholder';\n\n// TODO(burdon): Option to complete only at end of line.\nexport type TypeaheadOptions = {\n onComplete?: (context: CompoetionContext) => string | undefined;\n};\n\n/**\n * Shows a completion placeholder.\n */\nexport const typeahead = ({ onComplete }: TypeaheadOptions = {}): Extension => {\n let hint: string | undefined;\n\n const complete: Command = (view: EditorView) => {\n if (!hint) {\n return false;\n }\n\n const selection = view.state.selection.main;\n view.dispatch({\n changes: [{ from: selection.from, to: selection.to, insert: hint }],\n selection: EditorSelection.cursor(selection.from + hint.length),\n });\n\n return true;\n };\n\n return [\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet = Decoration.none;\n update(update: ViewUpdate) {\n const builder = new RangeSetBuilder<Decoration>();\n const selection = update.view.state.selection.main;\n const line = update.view.state.doc.lineAt(selection.from);\n\n // TODO(burdon): Check at end of line and matches start of previous word.\n // TODO(burdon): Context grammar.\n if (selection.from === selection.to && selection.from === line.to) {\n const str = update.state.sliceDoc(line.from, selection.from);\n hint = onComplete?.({ line: str });\n if (hint) {\n builder.add(selection.from, selection.to, Decoration.widget({ widget: new PlaceholderWidget(hint) }));\n }\n }\n\n this.decorations = builder.finish();\n }\n },\n {\n decorations: (v) => v.decorations,\n },\n ),\n\n // Keys.\n Prec.highest(\n keymap.of([\n {\n key: 'Tab',\n preventDefault: true,\n run: complete,\n },\n {\n key: 'ArrowRight',\n preventDefault: true,\n run: complete,\n },\n ]),\n ),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { StateEffect } from '@codemirror/state';\nimport { EditorView, ViewPlugin } from '@codemirror/view';\n\nimport { addEventListener, combine, throttle } from '@dxos/async';\nimport { Domino } from '@dxos/ui';\nimport { getSize } from '@dxos/ui-theme';\n\nimport { scrollerCrawlEffect, scrollerLineEffect } from './scroller';\n\n/** Enable or disable autoscroll. */\nexport const autoScrollEffect = StateEffect.define<boolean>();\n\nexport type AutoScrollProps = {\n /**\n * If true, immediately jump to the bottom and re-pin whenever the size of the\n * document view (the scroll container) changes — e.g. when a sidebar toggles\n * or the window is resized. This avoids the visible \"stuck near bottom\" gap\n * that otherwise appears because the previous `scrollTop` no longer reaches\n * the new content height.\n * @default true\n */\n scrollOnResize?: boolean;\n};\n\n/**\n * Extension that supports pinning the scroll position and automatically scrolls to the bottom when content is added.\n */\nexport const autoScroll = ({ scrollOnResize = true }: AutoScrollProps = {}) => {\n let buttonContainer: HTMLDivElement | undefined;\n let isPinned = true;\n let jumpPending = false;\n let enabled = true;\n let firstUpdate = true;\n\n const setPinned = (pinned: boolean) => {\n buttonContainer?.classList.toggle('opacity-0', pinned);\n isPinned = pinned;\n };\n\n return [\n // Update listener for scrolling when content changes.\n EditorView.updateListener.of((update) => {\n const { view, heightChanged, state, startState } = update;\n\n // Handle enable/disable effect.\n for (const tr of update.transactions) {\n for (const effect of tr.effects) {\n if (effect.is(autoScrollEffect)) {\n enabled = effect.value;\n if (enabled) {\n setPinned(true);\n view.dispatch({\n effects: scrollerCrawlEffect.of(true),\n });\n } else {\n view.dispatch({\n effects: scrollerCrawlEffect.of(false),\n });\n }\n }\n }\n }\n\n if (!enabled) {\n return;\n }\n\n // Jump to bottom instantly when content first appears (either inserted into\n // an empty doc, or present as initialValue when the editor is created).\n if (isPinned && (firstUpdate || startState.doc.length === 0) && state.doc.length > 0) {\n firstUpdate = false;\n jumpPending = true;\n requestAnimationFrame(() => {\n view.scrollDOM.scrollTop = view.scrollDOM.scrollHeight;\n jumpPending = false;\n });\n return;\n }\n firstUpdate = false;\n\n // Suppress crawl while the initial jump is pending.\n if (jumpPending) {\n return;\n }\n\n // Maybe scroll if doc changed and pinned.\n // NOTE: Geometry changed is triggered when widgets change height (e.g., toggle tool block).\n if (heightChanged) {\n if (isPinned) {\n // NOTE: Use scroll geometry instead of coordsAtPos to avoid forced layout/scroll side-effects.\n const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;\n const delta = scrollHeight - scrollTop - clientHeight;\n if (delta > 0) {\n setPinned(true);\n view.dispatch({ effects: scrollerCrawlEffect.of(true) });\n } else if (delta < -1) {\n setPinned(false);\n }\n } else {\n // TODO(burdon): Should re-pin if content shrinks.\n if (state.doc.length === 0) {\n setPinned(true);\n }\n }\n }\n }),\n\n // Re-pin and jump to bottom when the scroll container itself resizes (e.g. sidebar toggle,\n // window resize). Doc-driven height changes are handled by the updateListener above; this\n // observer covers the case where the viewport changes while the doc length is unchanged.\n scrollOnResize\n ? ViewPlugin.fromClass(\n class {\n private readonly observer: ResizeObserver;\n private firstObservation = true;\n private destroyed = false;\n constructor(view: EditorView) {\n // Throttle so a continuous drag-resize (or a flurry of layout changes) coalesces\n // into a single re-pin per ~50ms instead of dispatching every frame.\n const onResize = throttle(() => {\n if (this.destroyed || !enabled) {\n return;\n }\n\n setPinned(true);\n requestAnimationFrame(() => {\n if (this.destroyed) {\n return;\n }\n\n view.scrollDOM.scrollTo({ top: view.scrollDOM.scrollHeight, behavior: 'instant' });\n view.dispatch({ effects: scrollerCrawlEffect.of(false) });\n });\n }, 50);\n\n this.observer = new ResizeObserver(() => {\n // Skip the initial fire that ResizeObserver emits on `observe()`.\n if (this.firstObservation) {\n this.firstObservation = false;\n return;\n }\n onResize();\n });\n\n this.observer.observe(view.scrollDOM);\n }\n destroy() {\n this.destroyed = true;\n this.observer.disconnect();\n }\n },\n )\n : [],\n\n // Detect user scroll and unpin (or re-pin if scrolled to the bottom).\n ViewPlugin.fromClass(\n class {\n private readonly cleanup: () => void;\n constructor(view: EditorView) {\n this.cleanup = createUserScrollDetector(\n view.scrollDOM,\n throttle(() => {\n requestAnimationFrame(() => {\n const { scrollTop, scrollHeight, clientHeight } = view.scrollDOM;\n const delta = scrollHeight - scrollTop - clientHeight;\n const pinned = delta === 0;\n setPinned(pinned);\n if (!pinned) {\n view.dispatch({ effects: scrollerCrawlEffect.of(false) });\n }\n });\n }, 500),\n );\n }\n destroy() {\n this.cleanup();\n }\n },\n ),\n\n // Scroll button.\n ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n const icon = Domino.of('dx-icon' as any)\n .classNames(getSize(4))\n .attributes({ icon: 'ph--arrow-down--regular' });\n const button = Domino.of('button')\n .classNames('dx-button bg-accent-surface')\n .attributes({ 'data-density': 'fine' })\n .append(icon)\n .on('click', () => {\n setPinned(true);\n view.dispatch({\n effects: scrollerLineEffect.of({ line: -1, position: 'end', behavior: 'smooth' }),\n });\n });\n\n buttonContainer = Domino.of('div')\n .classNames('cm-scroll-button transition-opacity duration-300 opacity-0')\n .append(button).root as HTMLDivElement;\n\n view.scrollDOM.parentElement!.appendChild(buttonContainer);\n }\n },\n ),\n ];\n};\n\n/**\n * Attaches listeners to detect genuine user-initiated scrolling on an element.\n * Two sources are covered:\n * - `wheel`: fires only from physical mouse wheel / trackpad gestures.\n * - `pointerdown` on the scrollbar gutter: detected by comparing clientX to\n * the element's clientWidth (the content area, excluding the scrollbar).\n * Returns a cleanup function that removes the listeners.\n */\n// TODO(burdon): Still jumps when widgets are rendered.\n// - Track position of specific element/line in document and scroll relative to that.\nfunction createUserScrollDetector(element: HTMLElement, onUserScroll: () => void): () => void {\n return combine(\n addEventListener(element, 'wheel', () => onUserScroll(), { passive: true }),\n addEventListener(element, 'pointerdown', (event) => {\n // If the pointer lands beyond the content width it hit the scrollbar gutter.\n if (event.clientX > element.getBoundingClientRect().right - (element.offsetWidth - element.clientWidth)) {\n onUserScroll();\n }\n }),\n );\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { StateEffect } from '@codemirror/state';\nimport { EditorView, ViewPlugin } from '@codemirror/view';\n\nimport { log } from '@dxos/log';\n\n/**\n * Parameters for the scroll to line effect.\n */\nexport type ScrollToProps = {\n /**\n * Zero-based line number; -1 for end of document.\n * NOTE: view.state.doc.lineAt() uses 1-based line numbers.\n */\n line: number;\n\n /**\n * Additional offset from the target line in pixels.\n * Positive values scroll past the line, negative values stop before it.\n * @default 0\n */\n offset?: number;\n\n /**\n * Position of the target line in the viewport.\n * - 'start': Line appears at the start (top) of the screen\n * - 'end': Line appears at the end (bottom) of the screen\n * @default 'start'\n */\n position?: 'start' | 'end';\n\n /**\n * Whether to use smooth scrolling.\n * @default 'instant'\n */\n behavior?: ScrollBehavior;\n};\n\n/** Scroll to a specific line. */\nexport const scrollerLineEffect = StateEffect.define<ScrollToProps>();\n\n/** Start/stop crawling the end of the document. */\nexport const scrollerCrawlEffect = StateEffect.define<boolean>();\n\n/**\n * Helper function to scroll to a specific line.\n * This is a convenience function that can be used directly with an EditorView.\n */\nexport const scrollToLine = (view: EditorView, options: ScrollToProps) => {\n view.dispatch({\n effects: scrollerLineEffect.of(options),\n });\n};\n\nexport type ScrollerOptions = {\n /** Threshold in px to trigger scroll from bottom. */\n overScroll?: number;\n};\n\n/**\n * Extension that provides smooth scrolling to specific lines in the editor.\n */\nexport const scroller = ({ overScroll = 0 }: ScrollerOptions = {}) => {\n // ViewPlugin to manage scroll animations.\n const scrollPlugin = ViewPlugin.fromClass(\n class ScrollerPlugin {\n private readonly crawler: ReturnType<typeof createCrawler>;\n constructor(private readonly view: EditorView) {\n this.crawler = createCrawler(this.view);\n }\n\n // No-op.\n destroy() {\n this.crawler.cancel();\n }\n\n cancel() {\n this.crawler.cancel();\n }\n\n crawl(start = false) {\n if (start) {\n this.crawler.scroll();\n } else {\n this.crawler.cancel();\n }\n }\n\n scroll({ line, offset = 0, position, behavior = 'instant' }: ScrollToProps) {\n const { scrollTop, scrollHeight, clientHeight } = this.view.scrollDOM;\n const scrollerRect = this.view.scrollDOM.getBoundingClientRect();\n const doc = this.view.state.doc;\n\n let targetScrollTop = scrollHeight - clientHeight + offset;\n if (line >= 0 && line <= doc.lines - 1) {\n const lineStart = doc.line(line + 1).from;\n const coords = this.view.coordsAtPos(lineStart);\n if (coords) {\n // Calculate target scroll position based on position option.\n const currentScrollTop = scrollTop;\n const maxScrollTop = scrollHeight - clientHeight;\n\n if (position === 'end') {\n // Position line at end (bottom) of viewport.\n // Calculate how far down we need to scroll so the line's bottom aligns with viewport bottom.\n targetScrollTop = currentScrollTop + coords.bottom - scrollerRect.bottom + offset;\n } else {\n // Default: position line at start (top) of viewport.\n targetScrollTop = currentScrollTop + coords.top - scrollerRect.top + offset;\n }\n\n // Clamp to valid scroll range.\n targetScrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));\n }\n }\n\n // TODO(burdon): Smooth scrolling doesn't work when the document is being streamed into.\n requestAnimationFrame(() => {\n this.view.scrollDOM.scrollTo({ top: targetScrollTop }); //, behavior });\n });\n }\n },\n );\n\n return [\n scrollPlugin,\n\n // Listen for effect.\n EditorView.updateListener.of((update) => {\n update.transactions.forEach((transaction) => {\n try {\n const plugin = update.view.plugin(scrollPlugin);\n if (plugin) {\n for (const effect of transaction.effects) {\n if (effect.is(scrollerCrawlEffect)) {\n plugin.crawl(effect.value);\n } else if (effect.is(scrollerLineEffect)) {\n plugin.scroll(effect.value);\n }\n }\n }\n } catch (err) {\n log.catch(err);\n }\n });\n }),\n\n // Styles.\n EditorView.theme({\n '.cm-scroller': {\n overflowY: 'scroll',\n // Browser scroll-anchoring: when widgets above the viewport resize (e.g. tool blocks\n // expanding their TogglePanel), the browser picks a stable element near the viewport\n // top and adjusts `scrollTop` so the user's view doesn't jump. Auto-scroll's pinning\n // logic still has the final word when pinned (forces scrollTop to scrollHeight).\n overflowAnchor: 'auto',\n },\n '.cm-scroller.cm-hide-scrollbar::-webkit-scrollbar': {\n display: 'none',\n },\n '.cm-scroller::-webkit-scrollbar-thumb': {\n background: 'transparent',\n transition: 'background 0.15s',\n },\n '&:hover .cm-scroller::-webkit-scrollbar-thumb': {\n background: 'var(--color-scrollbar-thumb)',\n },\n // Spacer below the last text line. Implemented as a real block pseudo-element\n // (rather than `padding-bottom` on `.cm-content`) so it materializes in the\n // scroller's `scrollHeight` regardless of how `padding` is reset by the base\n // theme or downstream classes — this is what gives auto-scroll its head-room\n // so the last line stays `overScroll` px above the viewport bottom.\n '.cm-content::after': {\n content: '\"\"',\n display: 'block',\n height: `${overScroll}px`,\n },\n '.cm-scroll-button': {\n position: 'absolute',\n bottom: '0.5rem',\n right: '1rem',\n },\n }),\n ];\n};\n\n/**\n * Creates a smooth crawler that follows the live bottom of a CodeMirror 6 EditorView.\n *\n * Uses a critically-damped spring: each frame applies a restoring force toward the\n * target and a damping force opposing current velocity. With damping = 2·ω, the\n * system is critically damped — fastest approach without overshoot. The spring\n * naturally sprints when far behind and eases as it approaches, so streaming\n * content is followed tightly without the jerk of explicit accel/decel state.\n *\n * Integration uses real elapsed wall-clock time so the perceived speed stays\n * constant when requestAnimationFrame is throttled (e.g. low-power mode dropping\n * from 60Hz to 30Hz).\n *\n * @param omega Spring stiffness in rad/s. Higher = snappier follow. ~12–18 feels good.\n * @param snapThreshold Snap-to-target distance threshold in px.\n * @param snapVelocity Snap-to-target velocity threshold in px/s.\n */\nexport function createCrawler(view: EditorView, omega = 5, snapThreshold = 5, snapVelocity = 50) {\n const el = view.scrollDOM;\n\n let currentTop = 0;\n let velocity = 0;\n let rafId: number | null = null;\n let lastTime = 0;\n\n function frame(now: number) {\n // Clamp dt to handle long pauses (tab backgrounded) and the first frame.\n const dt = lastTime === 0 ? 1 / 60 : Math.min(0.1, (now - lastTime) / 1000);\n lastTime = now;\n\n const targetTop = el.scrollHeight - el.clientHeight;\n const delta = targetTop - currentTop;\n if (Math.abs(delta) < snapThreshold && Math.abs(velocity) < snapVelocity) {\n el.scrollTop = targetTop;\n currentTop = targetTop;\n velocity = 0;\n rafId = null;\n lastTime = 0;\n return;\n }\n\n // Critically-damped spring: a = ω²·delta − 2ω·v.\n const accel = omega * omega * delta - 2 * omega * velocity;\n velocity += accel * dt;\n currentTop += velocity * dt;\n el.scrollTop = currentTop;\n rafId = requestAnimationFrame(frame);\n }\n\n return {\n scroll: () => {\n if (rafId === null) {\n currentTop = el.scrollTop;\n lastTime = 0;\n rafId = requestAnimationFrame(frame);\n }\n },\n cancel: () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n velocity = 0;\n lastTime = 0;\n rafId = null;\n }\n },\n };\n}\n", "//\n// Copyright 2024 DXOS.org\n// Copyright 2024 Automerge\n// Ref: https://github.com/automerge/automerge-codemirror\n//\n\nimport { next as A } from '@automerge/automerge';\nimport { type Extension, StateField, Transaction } from '@codemirror/state';\nimport { EditorView, ViewPlugin } from '@codemirror/view';\n\nimport { DocAccessor } from '@dxos/echo-db';\n\nimport { Cursor } from '../../util';\nimport { initialSync } from '../state';\nimport { cursorConverter } from './cursor';\nimport { type State, isReconcile, reconcileAnnotation, updateHeadsEffect } from './defs';\nimport { Syncer } from './sync';\n\nexport const automerge = (accessor: DocAccessor): Extension => {\n const syncState = StateField.define<State>({\n create: () => {\n return {\n path: accessor.path.slice(),\n lastHeads: A.getHeads(accessor.handle.doc()!),\n unreconciledTransactions: [],\n };\n },\n\n update: (value, tr) => {\n const result: State = {\n path: accessor.path.slice(),\n lastHeads: value.lastHeads,\n unreconciledTransactions: value.unreconciledTransactions.slice(),\n };\n\n let clearUnreconciled = false;\n for (const effect of tr.effects) {\n if (effect.is(updateHeadsEffect)) {\n result.lastHeads = effect.value.newHeads;\n clearUnreconciled = true;\n }\n }\n\n if (clearUnreconciled) {\n result.unreconciledTransactions = [];\n } else {\n if (!isReconcile(tr)) {\n result.unreconciledTransactions.push(tr);\n }\n }\n\n return result;\n },\n });\n\n const syncer = new Syncer(accessor.handle, syncState);\n\n return [\n Cursor.converter.of(cursorConverter(accessor)),\n\n // Track heads.\n syncState,\n\n // Reconcile external updates.\n ViewPlugin.fromClass(\n class {\n constructor(private readonly _view: EditorView) {\n accessor.handle.addListener('change', this._handleChange);\n\n requestAnimationFrame(() => {\n const value = DocAccessor.getValue<string>(accessor);\n const current = this._view.state.doc.toString();\n if (value !== current) {\n this._view.dispatch({\n changes: { from: 0, to: this._view.state.doc.length, insert: value },\n annotations: [initialSync, reconcileAnnotation.of(true)],\n });\n }\n });\n }\n\n destroy() {\n accessor.handle.removeListener('change', this._handleChange);\n }\n\n readonly _handleChange = () => {\n syncer.reconcile(this._view, false);\n };\n },\n ),\n\n // Reconcile local updates.\n EditorView.updateListener.of(({ view, changes, transactions }) => {\n if (!changes.empty) {\n // Only reconcile if it's not an initial sync (to avoid loops)\n const isInitialSync = transactions.some((tr) => tr.annotation(Transaction.userEvent) === initialSync.value);\n if (!isInitialSync) {\n syncer.reconcile(view, true);\n }\n }\n }),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Transaction } from '@codemirror/state';\n\nexport const initialSync = Transaction.userEvent.of('initial.sync');\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type DocAccessor, fromCursor, toCursor } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\n\nimport { type CursorConverter } from '../../util';\n\nexport const cursorConverter = (accessor: DocAccessor): CursorConverter => ({\n toCursor: (pos, assoc) => {\n try {\n return toCursor(accessor, pos, assoc);\n } catch (err) {\n log.catch(err);\n return ''; // In case of invalid request (e.g., wrong document).\n }\n },\n\n fromCursor: (cursor) => {\n try {\n return fromCursor(accessor, cursor);\n } catch (err) {\n log.catch(err);\n return 0; // In case of invalid request (e.g., wrong document).\n }\n },\n});\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2024 Automerge\n// Ref: https://github.com/automerge/automerge-codemirror\n//\n\nimport { type Heads, type Prop } from '@automerge/automerge';\nimport { Annotation, type EditorState, StateEffect, type StateField, type Transaction } from '@codemirror/state';\n\nexport type State = {\n path: Prop[];\n lastHeads: Heads;\n unreconciledTransactions: Transaction[];\n};\n\nexport const getPath = (state: EditorState, field: StateField<State>): Prop[] => state.field(field).path;\nexport const getLastHeads = (state: EditorState, field: StateField<State>): Heads => state.field(field).lastHeads;\n\nexport type UpdateHeads = {\n newHeads: Heads;\n};\n\nexport const updateHeadsEffect = StateEffect.define<UpdateHeads>({});\n\nexport const updateHeads = (newHeads: Heads): StateEffect<UpdateHeads> => updateHeadsEffect.of({ newHeads });\n\nexport const reconcileAnnotation = Annotation.define<boolean>();\n\nexport const isReconcile = (tr: Transaction): boolean => {\n return !!tr.annotation(reconcileAnnotation);\n};\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2024 Automerge\n// Ref: https://github.com/automerge/automerge-codemirror\n//\n\nimport { next as A } from '@automerge/automerge';\nimport { type StateField } from '@codemirror/state';\nimport { type EditorView } from '@codemirror/view';\n\nimport { type IDocHandle } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\n\nimport { type State, getLastHeads, getPath, isReconcile, reconcileAnnotation, updateHeads } from './defs';\nimport { updateAutomerge } from './update-automerge';\nimport { updateCodeMirror } from './update-codemirror';\n\n/**\n * Implements three-way merge (on each mutation).\n */\nexport class Syncer {\n private _pending = false;\n\n // prettier-ignore\n constructor(\n private readonly _handle: IDocHandle,\n private readonly _state: StateField<State>\n ) {}\n\n reconcile(view: EditorView, editor: boolean): void {\n if (this._pending) {\n return;\n }\n\n this._pending = true;\n if (editor) {\n this.onEditorChange(view);\n } else {\n this.onAutomergeChange(view);\n }\n this._pending = false;\n }\n\n private onEditorChange(view: EditorView): void {\n log('onEditorChange');\n\n // Apply the unreconciled transactions to the document.\n const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));\n const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);\n\n if (newHeads) {\n view.dispatch({\n effects: updateHeads(newHeads),\n annotations: reconcileAnnotation.of(false),\n });\n }\n }\n\n private onAutomergeChange(view: EditorView): void {\n log('onAutomergeChange');\n\n // Get the diff between the updated state of the document and the heads and apply that to the codemirror doc.\n const oldHeads = getLastHeads(view.state, this._state);\n const newHeads = A.getHeads(this._handle.doc()!);\n const diff = A.equals(oldHeads, newHeads) ? [] : A.diff(this._handle.doc()!, oldHeads, newHeads);\n\n const selection = view.state.selection;\n const path = getPath(view.state, this._state);\n updateCodeMirror(view, selection, path, diff);\n\n // TODO(burdon): Test conflicts?\n // A.getConflicts(this._handle.doc()!, path[0]);\n\n view.dispatch({\n effects: updateHeads(newHeads),\n annotations: reconcileAnnotation.of(false),\n });\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2024 Automerge\n// Ref: https://github.com/automerge/automerge-codemirror\n//\n\nimport { next as A, type Heads } from '@automerge/automerge';\nimport { type EditorState, type StateField, type Text, type Transaction } from '@codemirror/state';\n\nimport { type IDocHandle } from '@dxos/echo-db';\n\nimport { type State } from './defs';\n\nexport const updateAutomerge = (\n field: StateField<State>,\n handle: IDocHandle,\n transactions: Transaction[],\n state: EditorState, // TODO(burdon): Just pass in the state field value?\n): Heads | undefined => {\n const { lastHeads, path } = state.field(field);\n\n // We don't want to call `automerge.updateAt` if there are no changes.\n // Otherwise, later on `automerge.diff` will return empty patches that result in a no-op but still mess up the selection.\n let hasChanges = false;\n for (const tr of transactions) {\n tr.changes.iterChanges(() => {\n hasChanges = true;\n });\n }\n\n if (!hasChanges) {\n return undefined;\n }\n\n const newHeads = handle.changeAt(lastHeads, (doc: A.Doc<unknown>) => {\n const invertedTransactions: { from: number; del: number; insert: Text }[] = [];\n for (const tr of transactions) {\n tr.changes.iterChanges((fromA, toA, _fromB, _toB, insert) => {\n invertedTransactions.push({ from: fromA, del: toA - fromA, insert });\n });\n }\n\n // TODO(burdon): Hack to apply in reverse order to properly apply range.\n invertedTransactions.reverse().forEach(({ from, del, insert }) => {\n A.splice(doc, path.slice(), from, del, insert.toString());\n });\n });\n\n return newHeads ?? undefined;\n};\n", "//\n// Copyright 2023 DXOS.org\n// Copyright 2024 Automerge\n// Ref: https://github.com/automerge/automerge-codemirror\n//\n\nimport {\n type DelPatch,\n type InsertPatch,\n type Patch,\n type Prop,\n type PutPatch,\n type SpliceTextPatch,\n} from '@automerge/automerge';\nimport { ChangeSet, type ChangeSpec, type EditorSelection, type EditorState } from '@codemirror/state';\nimport { type EditorView } from '@codemirror/view';\n\nimport { reconcileAnnotation } from './defs';\n\nexport const updateCodeMirror = (view: EditorView, selection: EditorSelection, target: Prop[], patches: Patch[]) => {\n for (const patch of patches) {\n const changeSpec = handlePatch(patch, target, view.state);\n if (changeSpec != null) {\n const changeSet = ChangeSet.of(changeSpec, view.state.doc.length, '\\n');\n selection = selection.map(changeSet, 1);\n view.dispatch({\n changes: changeSet,\n annotations: reconcileAnnotation.of(false),\n });\n }\n }\n\n view.dispatch({\n selection,\n annotations: reconcileAnnotation.of(false),\n });\n};\n\nconst handlePatch = (patch: Patch, target: Prop[], state: EditorState): ChangeSpec | null => {\n if (patch.action === 'insert') {\n return handleInsert(target, patch);\n } else if (patch.action === 'splice') {\n return handleSplice(target, patch);\n } else if (patch.action === 'del') {\n return handleDel(target, patch);\n } else if (patch.action === 'put') {\n return handlePut(target, patch, state);\n } else {\n return null;\n }\n};\n\nconst handleInsert = (target: Prop[], patch: InsertPatch): Array<ChangeSpec> => {\n const index = charPath(target, patch.path);\n if (index == null) {\n return [];\n }\n\n const text = patch.values.map((value) => (value ? value.toString() : '')).join('');\n return [{ from: index, to: index, insert: text }];\n};\n\nconst handleSplice = (target: Prop[], patch: SpliceTextPatch): Array<ChangeSpec> => {\n const index = charPath(target, patch.path);\n if (index == null) {\n return [];\n }\n\n return [{ from: index, insert: patch.value }];\n};\n\nconst handleDel = (target: Prop[], patch: DelPatch): Array<ChangeSpec> => {\n const index = charPath(target, patch.path);\n if (index == null) {\n return [];\n }\n\n const length = patch.length || 1;\n return [{ from: index, to: index + length }];\n};\n\nconst handlePut = (target: Prop[], patch: PutPatch, state: EditorState): Array<ChangeSpec> => {\n const index = charPath(target, [...patch.path, 0]);\n if (index == null) {\n return [];\n }\n\n const length = state.doc.length;\n if (typeof patch.value !== 'string') {\n return []; // TODO(dmaretskyi): How to handle non-string values?\n }\n\n return [{ from: 0, to: length, insert: patch.value as any }];\n};\n\n// If the path of the patch is of the form [path, <index>] then we know this is a path to a character\n// within the sequence given by path.\nconst charPath = (textPath: Prop[], candidatePath: Prop[]): number | null => {\n if (candidatePath.length !== textPath.length + 1) {\n return null;\n }\n\n for (let i = 0; i < textPath.length; i++) {\n if (textPath[i] !== candidatePath[i]) {\n return null;\n }\n }\n\n const index = candidatePath[candidatePath.length - 1];\n if (typeof index === 'number') {\n return index;\n }\n\n return null;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { Annotation, type Extension, type Range, RangeSet } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n type PluginValue,\n ViewPlugin,\n type ViewUpdate,\n WidgetType,\n} from '@codemirror/view';\n\nimport { Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\n\nimport { Cursor, type CursorConverter, singleValueFacet } from '../../util';\n\nexport interface AwarenessProvider {\n remoteStateChange: Event<void>;\n\n open(): void;\n close(): void;\n\n getRemoteStates(): AwarenessState[];\n update(position: AwarenessPosition | undefined): void;\n}\n\nconst dummyProvider: AwarenessProvider = {\n remoteStateChange: new Event(),\n\n open: () => {},\n close: () => {},\n\n getRemoteStates: () => [],\n update: () => {},\n};\n\nexport const awarenessProvider = singleValueFacet<AwarenessProvider>(dummyProvider);\n\n// TODO(dmaretskyi): Specify the users that actually changed. Currently, we recalculate positions for every user.\nconst RemoteSelectionChangedAnnotation = Annotation.define();\n\nexport type AwarenessPosition = {\n anchor?: string;\n head?: string;\n};\n\nexport type AwarenessInfo = {\n displayName: string;\n darkColor: string;\n lightColor: string;\n};\n\nexport type AwarenessState = {\n position?: AwarenessPosition;\n peerId: string;\n info: AwarenessInfo;\n};\n\n/**\n * Extension provides presence information about other peers.\n */\nexport const awareness = (provider = dummyProvider): Extension => {\n return [\n awarenessProvider.of(provider),\n ViewPlugin.fromClass(RemoteSelectionsDecorator, {\n decorations: (value) => value.decorations,\n }),\n styles,\n ];\n};\n\n/**\n * Generates selection decorations from remote peers.\n */\nexport class RemoteSelectionsDecorator implements PluginValue {\n private readonly _ctx = new Context();\n private readonly _cursorConverter: CursorConverter;\n private readonly _provider: AwarenessProvider;\n\n private _lastAnchor?: number;\n private _lastHead?: number;\n\n public decorations: DecorationSet = RangeSet.of([]);\n\n constructor(view: EditorView) {\n this._cursorConverter = view.state.facet(Cursor.converter);\n this._provider = view.state.facet(awarenessProvider);\n this._provider.open();\n this._provider.remoteStateChange.on(this._ctx, () => {\n view.dispatch({ annotations: [RemoteSelectionChangedAnnotation.of([])] });\n });\n }\n\n destroy(): void {\n void this._ctx.dispose();\n this._provider.close();\n }\n\n update(update: ViewUpdate): void {\n this._updateLocalSelection(update.view);\n this._updateRemoteSelections(update.view);\n }\n\n private _updateLocalSelection(view: EditorView): void {\n const hasFocus = view.hasFocus && view.dom.ownerDocument.hasFocus();\n const { anchor = undefined, head = undefined } = hasFocus ? view.state.selection.main : {};\n if (this._lastAnchor === anchor && this._lastHead === head) {\n return;\n }\n\n this._lastAnchor = anchor;\n this._lastHead = head;\n\n this._provider.update(\n anchor !== undefined && head !== undefined\n ? {\n anchor: this._cursorConverter.toCursor(anchor),\n head: this._cursorConverter.toCursor(head, -1),\n }\n : undefined,\n );\n }\n\n private _updateRemoteSelections(view: EditorView): void {\n const decorations: Range<Decoration>[] = [\n // TODO(burdon): Factor out for testing.\n // {\n // from: 0,\n // to: 0,\n // value: Decoration.widget({ side: 0, block: false, widget: new RemoteCaretWidget('Test', 'red') }),\n // },\n ];\n\n const awarenessStates = this._provider.getRemoteStates();\n for (const state of awarenessStates) {\n const anchor = state.position?.anchor ? this._cursorConverter.fromCursor(state.position.anchor) : null;\n const head = state.position?.head ? this._cursorConverter.fromCursor(state.position.head) : null;\n if (anchor == null || head == null) {\n continue;\n }\n\n const start = Math.min(Math.min(anchor, head), view.state.doc.length);\n const end = Math.min(Math.max(anchor, head), view.state.doc.length);\n\n const startLine = view.state.doc.lineAt(start);\n const endLine = view.state.doc.lineAt(end);\n\n const darkColor = state.info.darkColor;\n const lightColor = state.info.lightColor;\n\n if (startLine.number === endLine.number) {\n // Selected content in a single line.\n decorations.push({\n from: start,\n to: end,\n value: Decoration.mark({\n attributes: { style: `background-color: ${lightColor}` },\n class: 'cm-collab-selection',\n }),\n });\n } else {\n // Selected content in multiple lines; first, render text-selection in the first line.\n decorations.push({\n from: start,\n to: startLine.from + startLine.length,\n value: Decoration.mark({\n attributes: { style: `background-color: ${lightColor}` },\n class: 'cm-collab-selection',\n }),\n });\n\n // Render text-selection in the last line.\n decorations.push({\n from: endLine.from,\n to: end,\n value: Decoration.mark({\n attributes: { style: `background-color: ${lightColor}` },\n class: 'cm-collab-selection',\n }),\n });\n\n for (let i = startLine.number + 1; i < endLine.number; i++) {\n const linePos = view.state.doc.line(i).from;\n decorations.push({\n from: linePos,\n to: linePos,\n value: Decoration.line({\n attributes: { style: `background-color: ${lightColor}`, class: 'cm-collab-selectionLine' },\n }),\n });\n }\n }\n\n decorations.push({\n from: head,\n to: head,\n value: Decoration.widget({\n side: head - anchor > 0 ? -1 : 1, // The local cursor should be rendered outside the remote selection.\n block: false,\n widget: new RemoteCaretWidget(state.info.displayName ?? 'Anonymous', darkColor),\n }),\n });\n }\n\n this.decorations = Decoration.set(decorations, true);\n }\n}\n\nclass RemoteCaretWidget extends WidgetType {\n constructor(\n private readonly _name: string,\n private readonly _color: string,\n ) {\n super();\n }\n\n override toDOM(): HTMLElement {\n const span = document.createElement('span');\n span.className = 'cm-collab-selectionCaret';\n span.style.backgroundColor = this._color;\n span.style.borderColor = this._color;\n\n const dot = document.createElement('div');\n dot.className = 'cm-collab-selectionCaretDot';\n\n const info = document.createElement('div');\n info.className = 'cm-collab-selectionInfo';\n info.innerText = this._name;\n\n span.appendChild(document.createTextNode('\\u2060'));\n span.appendChild(dot);\n span.appendChild(document.createTextNode('\\u2060'));\n span.appendChild(info);\n span.appendChild(document.createTextNode('\\u2060'));\n return span;\n }\n\n override updateDOM(): boolean {\n return false;\n }\n\n override eq(widget: this): boolean {\n return widget._color === this._color;\n }\n\n override get estimatedHeight() {\n return -1;\n }\n\n override ignoreEvent(): boolean {\n return true;\n }\n}\n\nconst styles = EditorView.theme({\n '.cm-collab-selection': {},\n '.cm-collab-selectionLine': {\n padding: 0,\n margin: '0px 2px 0px 4px',\n },\n '.cm-collab-selectionCaret': {\n position: 'relative',\n borderLeft: '1px solid black',\n borderRight: '1px solid black',\n marginLeft: '-1px',\n marginRight: '-1px',\n boxSizing: 'border-box',\n display: 'inline',\n cursor: 'pointer',\n },\n '.cm-collab-selectionCaretDot': {\n borderRadius: '50%',\n position: 'absolute',\n width: '.5em',\n height: '.5em',\n top: '-.25em',\n left: '-.25em',\n backgroundColor: 'inherit',\n transition: 'transform .3s ease-in-out',\n boxSizing: 'border-box',\n },\n '.cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot': {\n transform: 'scale(0)',\n transformOrigin: 'center',\n },\n '.cm-collab-selectionInfo': {\n position: 'absolute',\n transform: 'translate(-50%, 0)',\n top: '-20px',\n left: 0,\n fontSize: '.75em',\n fontFamily: 'sans-serif',\n fontStyle: 'normal',\n fontWeight: 'normal',\n lineHeight: 'normal',\n userSelect: 'none',\n color: 'white',\n padding: '2px 6px',\n zIndex: 101,\n transition: 'opacity .3s ease-in-out',\n backgroundColor: 'inherit',\n borderRadius: '2px',\n opacity: 0,\n transitionDelay: '0s',\n whiteSpace: 'nowrap',\n },\n '.cm-collab-selectionCaret:hover > .cm-collab-selectionInfo': {\n opacity: 1,\n transitionDelay: '0s',\n },\n});\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { DeferredTask, Event, sleep } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { type Messenger } from '@dxos/protocols';\nimport { type GossipMessage } from '@dxos/protocols/proto/dxos/mesh/teleport/gossip';\n\nimport { type AwarenessInfo, type AwarenessPosition, type AwarenessProvider, type AwarenessState } from './awareness';\n\ntype ProtocolMessage =\n | {\n kind: 'query';\n }\n | {\n kind: 'post';\n state: AwarenessState;\n };\n\nconst DEBOUNCE_INTERVAL = 100; // ms\n\nexport type AwarenessProviderProps = {\n messenger: Messenger;\n channel: string;\n peerId: string;\n info: AwarenessInfo;\n};\n\n/**\n * Receives and broadcasts profile and cursor position.\n */\nexport class SpaceAwarenessProvider implements AwarenessProvider {\n private readonly _remoteStates = new Map<string, AwarenessState>();\n\n private readonly _messenger: Messenger;\n private readonly _channel: string;\n private readonly _peerId: string;\n private readonly _info: AwarenessInfo;\n\n private _ctx?: Context;\n private _postTask?: DeferredTask;\n private _localState?: AwarenessState;\n\n public readonly remoteStateChange = new Event<void>();\n\n constructor({ messenger, channel, peerId, info }: AwarenessProviderProps) {\n this._messenger = messenger;\n this._channel = channel;\n this._peerId = peerId;\n this._info = info;\n }\n\n open(): void {\n this._ctx = new Context();\n this._postTask = new DeferredTask(this._ctx, async () => {\n if (this._localState) {\n await this._messenger.postMessage(this._channel, {\n kind: 'post',\n state: this._localState,\n } satisfies ProtocolMessage);\n\n // TODO(burdon): Replace with throttle.\n // TODO(burdon): Send heads?\n await sleep(DEBOUNCE_INTERVAL);\n }\n });\n\n this._ctx.onDispose(\n this._messenger.listen(this._channel, (message: GossipMessage) => {\n switch (message.payload.kind) {\n case 'query': {\n this._handleQueryMessage();\n break;\n }\n case 'post': {\n this._handlePostMessage(message.payload);\n break;\n }\n }\n }),\n );\n\n void this._messenger\n .postMessage(this._channel, {\n kind: 'query',\n } satisfies ProtocolMessage)\n .catch((err) => {\n log.debug('failed to query awareness', { err });\n });\n }\n\n close(): void {\n void this._ctx?.dispose();\n this._ctx = undefined;\n this._postTask = undefined;\n }\n\n getRemoteStates(): AwarenessState[] {\n return Array.from(this._remoteStates.values());\n }\n\n update(position: AwarenessPosition | undefined): void {\n invariant(this._postTask);\n this._localState = {\n peerId: this._peerId,\n position,\n info: this._info,\n };\n\n this._postTask.schedule();\n }\n\n private _handleQueryMessage(): void {\n invariant(this._postTask);\n this._postTask.schedule();\n }\n\n private _handlePostMessage(message: ProtocolMessage): void {\n invariant(message.kind === 'post');\n // TODO(wittjosiah): Is it helpful or confusing to show cursors for self on other devices?\n this._remoteStates.set(message.state.peerId, message.state);\n this.remoteStateChange.emit();\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n// Based on a demo by Joel Besada and Kushagra Gour.\n// https://twitter.com/JoelBesada/status/670343885655293952\n// https://github.com/chinchang/code-blast-codemirror/blob/master/code-blast.js\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { EditorView, keymap } from '@codemirror/view';\nimport defaultsDeep from 'lodash.defaultsdeep';\n\nimport { throttle } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\n\nexport type BlastOptions = {\n effect?: number;\n maxParticles: number;\n particleGravity: number;\n particleAlphaFadeout: number;\n particleSize: { min: number; max: number };\n particleNumRange: { min: number; max: number };\n particleVelocityRange: { x: [number, number]; y: [number, number] };\n particleShrinkRate: number;\n shakeIntensity: number;\n color?: () => number[];\n};\n\nexport const defaultOptions: BlastOptions = {\n effect: 2,\n maxParticles: 200,\n particleGravity: 0.08,\n particleAlphaFadeout: 0.996,\n particleSize: { min: 2, max: 8 },\n particleNumRange: { min: 5, max: 10 },\n particleVelocityRange: { x: [-1, 1], y: [-3.5, -1.5] },\n particleShrinkRate: 0.95,\n shakeIntensity: 5,\n};\n\nexport const blast = (options: Partial<BlastOptions> = defaultOptions): Extension => {\n let blaster: Blaster | undefined;\n let last = 0;\n\n const getPoint = (view: EditorView, pos: number) => {\n const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};\n const element = document.elementFromPoint(x, y);\n\n const { offsetLeft: left = 0, offsetTop: top = 0 } = view.scrollDOM.parentElement ?? {};\n const point = { x: x - left, y: y - top };\n\n return { element, point };\n };\n\n return [\n // Cursor moved.\n EditorView.updateListener.of((update) => {\n // NOTE: The MarkdownEditor may recreated the EditorView.\n if (blaster?.node !== update.view.scrollDOM) {\n if (blaster) {\n blaster.destroy();\n }\n\n blaster = new Blaster(\n update.view.scrollDOM,\n defaultsDeep(\n {\n particleGravity: 0.2,\n particleShrinkRate: 0.995,\n color: () => [100 + Math.random() * 100, 0, 0],\n },\n options,\n defaultOptions,\n ),\n );\n blaster.initialize();\n blaster.start(); // TODO(burdon): Stop/clean-up.\n } else {\n blaster.resize();\n }\n\n const current = update.state.selection.main.head;\n if (current !== last) {\n last = current;\n // TODO(burdon): Null if end of line.\n const { element, point } = getPoint(update.view, current - 1);\n if (element && point) {\n blaster.spawn({ element, point });\n }\n }\n }),\n\n keymap.of([\n {\n any: (_, event) => {\n if (blaster) {\n if (event.key === 'Enter' && event.shiftKey) {\n blaster.shake({ time: 0.8 });\n return true;\n }\n }\n\n return false;\n },\n },\n ]),\n ];\n};\n\n//\n// Blaster (no CM deps).\n//\n\nclass Blaster {\n private readonly _effect: Effect;\n\n _canvas: HTMLCanvasElement | undefined;\n _ctx: CanvasRenderingContext2D | undefined | null;\n\n _running = false;\n _lastTime: number | undefined;\n _shakeTime = 0;\n _shakeTimeMax = 0;\n\n _particles: Particle[] = [];\n _particlePointer = 0;\n\n _lastPoint = { x: 0, y: 0 };\n\n constructor(\n private readonly _node: HTMLElement,\n private readonly _options: BlastOptions,\n ) {\n this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);\n }\n\n get node() {\n return this._node;\n }\n\n initialize(): void {\n // console.log('initialize');\n invariant(!this._canvas && !this._ctx);\n\n this._canvas = document.createElement('canvas');\n this._canvas.id = 'code-blast-canvas';\n this._canvas.style.position = 'absolute';\n this._canvas.style.zIndex = '0';\n this._canvas.style.pointerEvents = 'none';\n // this._canvas.style.border = '2px dashed red';\n\n this._ctx = this._canvas.getContext('2d');\n\n const parent = this._node.parentElement?.parentElement;\n parent?.appendChild(this._canvas);\n\n this.resize();\n }\n\n destroy(): void {\n this.stop();\n // console.log('destroy');\n if (this._canvas) {\n this._canvas.remove();\n this._canvas = undefined;\n this._ctx = undefined;\n }\n }\n\n resize(): void {\n if (this._node.parentElement && this._canvas) {\n const { offsetLeft: x, offsetTop: y, offsetWidth: width, offsetHeight: height } = this._node.parentElement;\n this._canvas.style.top = `${y}px`;\n this._canvas.style.left = `${x}px`;\n this._canvas.width = width;\n this._canvas.height = height;\n }\n }\n\n start(): void {\n // console.log('start');\n invariant(this._canvas && this._ctx);\n this._running = true;\n this.loop();\n }\n\n stop(): void {\n // console.log('stop');\n this._running = false;\n this._node.style.transform = 'translate(0px, 0px)';\n }\n\n loop(): void {\n if (!this._running || !this._canvas || !this._ctx) {\n return;\n }\n\n this._ctx.clearRect(0, 0, this._canvas.width ?? 0, this._canvas.height ?? 0);\n\n // Calculate the delta from the previous frame.\n const now = new Date().getTime();\n this._lastTime ??= now;\n const dt = (now - this._lastTime) / 1000;\n this._lastTime = now;\n\n if (this._shakeTime > 0) {\n this._shakeTime -= dt;\n const magnitude = (this._shakeTime / this._shakeTimeMax) * this._options.shakeIntensity;\n const shakeX = random(-magnitude, magnitude);\n const shakeY = random(-magnitude, magnitude);\n this._node!.style.transform = `translate(${shakeX}px,${shakeY}px)`;\n }\n\n this.drawParticles();\n\n requestAnimationFrame(this.loop.bind(this));\n }\n\n shake = throttle(({ time }: { time: number }) => {\n this._shakeTime = this._shakeTimeMax || time;\n this._shakeTimeMax = time;\n }, 100);\n\n spawn = throttle(({ element, point }: { element: Element; point: { x: number; y: number } }) => {\n const color = getRGBComponents(element, this._options.color);\n const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);\n const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;\n this._lastPoint = point;\n for (let i = numParticles; i--; i > 0) {\n this._particles[this._particlePointer] = this._effect.create(point.x - dir * 16, point.y, color);\n this._particlePointer = (this._particlePointer + 1) % this._options.maxParticles;\n }\n }, 100);\n\n drawParticles(): void {\n for (let i = this._particles.length; i--; i > 0) {\n const particle = this._particles[i];\n if (!particle) {\n continue;\n }\n\n if (particle.alpha < 0.01 || particle.size <= 0.5) {\n continue;\n }\n\n this._effect.update(this._ctx!, particle);\n }\n }\n}\n\n//\n// Effects\n//\n\ntype Particle = {\n x: number;\n y: number;\n vx: number;\n vy: number;\n size: number;\n color: (string | number)[];\n alpha: number;\n theta?: number;\n drag?: number;\n wander?: number;\n};\n\nabstract class Effect {\n constructor(protected readonly _options: BlastOptions) {}\n abstract create(x: number, y: number, color: Particle['color']): Particle;\n abstract update(ctx: CanvasRenderingContext2D, particle: Particle): void;\n}\n\nclass Effect1 extends Effect {\n create(x: number, y: number, color: Particle['color']) {\n return {\n x,\n y: y + 10,\n vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),\n vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),\n size: random(this._options.particleSize.min, this._options.particleSize.max),\n color,\n alpha: 1,\n };\n }\n\n update(ctx: CanvasRenderingContext2D, particle: Particle): void {\n particle.vy += this._options.particleGravity;\n particle.x += particle.vx;\n particle.y += particle.vy;\n particle.alpha *= this._options.particleAlphaFadeout;\n\n ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;\n ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);\n }\n}\n\n/**\n * Based on Soulwire's demo.\n * http://codepen.io/soulwire/pen/foktm\n */\nclass Effect2 extends Effect {\n create(x: number, y: number, color: Particle['color']) {\n return {\n x,\n y: y + 10,\n vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),\n vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),\n size: random(this._options.particleSize.min, this._options.particleSize.max),\n color,\n alpha: 1,\n theta: (random(0, 360) * Math.PI) / 180,\n drag: 0.92,\n wander: 0.15,\n };\n }\n\n update(ctx: CanvasRenderingContext2D, particle: Particle): void {\n particle.vy += this._options.particleGravity;\n particle.x += particle.vx;\n particle.y += particle.vy;\n particle.vx *= particle.drag!;\n particle.vy *= particle.drag!;\n particle.theta! += random(-0.5, 0.5);\n particle.vx += Math.sin(particle.theta!) * 0.1;\n particle.vy += Math.cos(particle.theta!) * 0.1;\n particle.size *= this._options.particleShrinkRate;\n particle.alpha *= this._options.particleAlphaFadeout;\n\n ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;\n ctx.beginPath();\n ctx.arc(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, 0, 2 * Math.PI);\n ctx.fill();\n }\n}\n\n//\n// Utils\n//\n\nconst getRGBComponents = (node: Element, color: BlastOptions['color']): Particle['color'] => {\n if (typeof color === 'function') {\n return color();\n }\n\n const bgColor = getComputedStyle(node).color;\n if (bgColor) {\n const x = bgColor.match(/(\\d+), (\\d+), (\\d+)/)?.slice(1);\n if (x) {\n return x;\n }\n }\n\n return [50, 50, 50];\n};\n\nconst random = (min: number, max: number) => {\n if (!max) {\n max = min;\n min = 0;\n }\n\n return min + ~~(Math.random() * (max - min + 1));\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { RangeSetBuilder } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\nimport { mx } from '@dxos/ui-theme';\n\nconst paragraphBlockPlugin = ViewPlugin.fromClass(\n class {\n decorations: DecorationSet;\n\n constructor(view: EditorView) {\n this.decorations = this.build(view);\n }\n\n update(update: ViewUpdate) {\n if (update.docChanged || update.viewportChanged) {\n this.decorations = this.build(update.view);\n }\n }\n\n build({ state }: EditorView) {\n const builder = new RangeSetBuilder<Decoration>();\n\n // Helper: commit a block from blockStart to endLine (inclusive).\n const pushBlock = (fromLine: number, toLine: number) => {\n // Add line decorations for each line in the block.\n for (let lineNum = fromLine; lineNum <= toLine; lineNum++) {\n const line = state.doc.line(lineNum);\n builder.add(\n line.from,\n line.from,\n Decoration.line({\n class: mx(\n 'block-line',\n fromLine === toLine && 'block-single',\n lineNum === fromLine && 'block-first',\n lineNum > fromLine && lineNum < toLine && 'block-middle',\n lineNum === toLine && 'block-last',\n ),\n }),\n );\n }\n };\n\n let blockStart: number | null = null;\n let consecutiveBlankLines = 0;\n const totalLines = state.doc.lines;\n for (let i = 1; i <= totalLines; i++) {\n const line = state.doc.line(i);\n const isBlank = /^\\s*$/.test(line.text);\n\n if (!isBlank) {\n // Reset blank line counter.\n consecutiveBlankLines = 0;\n // Start a new block if we're not already in one.\n if (blockStart === null) {\n blockStart = i;\n }\n } else {\n // Increment blank line counter.\n consecutiveBlankLines++;\n\n // End the current block if we have 2+ consecutive blank lines.\n if (consecutiveBlankLines >= 2 && blockStart !== null) {\n pushBlock(blockStart, i - consecutiveBlankLines);\n blockStart = null;\n }\n }\n }\n\n // Handle any remaining block at the end of the document.\n if (blockStart !== null) {\n // Find the last non-blank line for the block end.\n let lastNonBlankLine = totalLines;\n while (lastNonBlankLine >= blockStart) {\n const line = state.doc.line(lastNonBlankLine);\n if (!/^\\s*$/.test(line.text)) {\n break;\n }\n lastNonBlankLine--;\n }\n if (lastNonBlankLine >= blockStart) {\n pushBlock(blockStart, lastNonBlankLine);\n }\n }\n\n return builder.finish();\n }\n },\n {\n decorations: (v) => v.decorations,\n },\n);\n\nexport const blocks = () => [\n paragraphBlockPlugin,\n EditorView.baseTheme({\n '.cm-line.block-line': {\n paddingLeft: '0.75rem',\n paddingRight: '0.75rem',\n borderLeft: '1px solid var(--color-subdued-separator)',\n borderRight: '1px solid var(--color-subdued-separator)',\n },\n '.cm-line.block-single': {\n border: '1px solid var(--color-subdued-separator)',\n borderRadius: '6px',\n paddingTop: '0.5rem',\n paddingBottom: '0.5rem',\n marginTop: '0.5rem',\n marginBottom: '0.5rem',\n },\n '.cm-line.block-first': {\n borderTop: '1px solid var(--color-subdued-separator)',\n borderTopLeftRadius: '6px',\n borderTopRightRadius: '6px',\n paddingTop: '0.5rem',\n marginTop: '0.5rem',\n },\n '.cm-line.block-middle': {},\n '.cm-line.block-last': {\n borderBottom: '1px solid var(--color-subdued-separator)',\n borderBottomLeftRadius: '6px',\n borderBottomRightRadius: '6px',\n paddingBottom: '0.5rem',\n marginBottom: '0.5rem',\n },\n }),\n];\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, Prec, StateEffect, StateField } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\n\nimport { log } from '@dxos/log';\n\ntype Bookmark = {\n id: string;\n pos: number;\n name: string;\n};\n\nexport const addBookmark = StateEffect.define<Bookmark>();\nexport const removeBookmark = StateEffect.define<string>();\nexport const clearBookmarks = StateEffect.define<void>();\n\nexport const bookmarks = (): Extension => {\n return [\n bookmarksField,\n Prec.highest(\n keymap.of([\n {\n key: 'Mod-ArrowUp',\n run: (view) => {\n const bookmarks = view.state.field(bookmarksField);\n log('up', bookmarks);\n return true;\n },\n },\n {\n key: 'Mod-ArrowDown',\n run: (view) => {\n const bookmarks = view.state.field(bookmarksField);\n log('down', bookmarks);\n return true;\n },\n },\n ]),\n ),\n ];\n};\n\ntype BookmarkFieldState = {\n bookmarks: Bookmark[];\n};\n\nconst bookmarksField = StateField.define<BookmarkFieldState>({\n create: (): BookmarkFieldState => ({\n bookmarks: [],\n }),\n\n update: (value: BookmarkFieldState, tr): BookmarkFieldState => {\n // Map bookmark positions through document changes.\n let bookmarks = value.bookmarks.map((bookmark) => ({\n ...bookmark,\n pos: tr.changes.mapPos(bookmark.pos),\n }));\n\n // Process effects.\n for (const effect of tr.effects) {\n if (effect.is(addBookmark)) {\n bookmarks = [...bookmarks, effect.value];\n } else if (effect.is(removeBookmark)) {\n bookmarks = bookmarks.filter((b) => b.id !== effect.value);\n } else if (effect.is(clearBookmarks)) {\n bookmarks = [];\n }\n }\n\n // Sort bookmarks by position.\n bookmarks.sort(({ pos: a }, { pos: b }) => a - b);\n return { bookmarks };\n },\n});\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { invertedEffects } from '@codemirror/commands';\nimport { type ChangeDesc, type Extension, StateEffect, StateField, type Text } from '@codemirror/state';\nimport {\n type Command,\n Decoration,\n EditorView,\n type PluginValue,\n type Rect,\n ViewPlugin,\n hoverTooltip,\n keymap,\n} from '@codemirror/view';\nimport sortBy from 'lodash.sortby';\n\nimport { type CleanupFn, debounce } from '@dxos/async';\nimport { log } from '@dxos/log';\nimport { isNonNullable } from '@dxos/util';\n\nimport { type Comment, type Range, type RenderCallback } from '../types';\nimport { Cursor, singleValueFacet, wrapWithCatch } from '../util';\nimport { documentId } from './selection';\n\n//\n// State management.\n//\n\ntype CommentState = {\n comment: Comment;\n range: Range;\n location?: Rect | null;\n};\n\ntype SelectionState = {\n current?: string;\n closest?: string;\n};\n\nexport type CommentsState = {\n id?: string;\n comments: CommentState[];\n selection: SelectionState;\n};\n\nexport const setComments = StateEffect.define<{ id: string; comments: Comment[] }>();\n\nexport const setSelection = StateEffect.define<SelectionState>();\n\nconst setCommentState = StateEffect.define<CommentsState>();\n\n/**\n * State field (reducer) that tracks comment ranges.\n * The ranges are tracked as Automerge cursors from which the absolute indexed ranges can be computed.\n */\nexport const commentsState = StateField.define<CommentsState>({\n create: (state) => ({\n id: state.facet(documentId),\n comments: [],\n selection: {},\n }),\n update: (value, tr) => {\n for (const effect of tr.effects) {\n // Update selection.\n if (effect.is(setSelection)) {\n return { ...value, selection: effect.value };\n }\n\n // Update range from store.\n if (effect.is(setComments)) {\n const { comments } = effect.value;\n const commentStates: CommentState[] = comments\n .map((comment) => {\n // Skip cut/deleted comments.\n if (!comment.cursor) {\n return undefined;\n }\n\n const range = Cursor.getRangeFromCursor(tr.state, comment.cursor);\n return range && { comment, range };\n })\n .filter(isNonNullable);\n\n return { ...value, comments: commentStates };\n }\n\n // Update entire state.\n if (effect.is(setCommentState)) {\n return effect.value;\n }\n }\n\n return value;\n },\n});\n\n/**\n * NOTE: Matches search.\n */\nconst styles = EditorView.theme({\n '.cm-comment, .cm-comment-current': {\n padding: '3px 0',\n color: 'var(--color-cm-comment-text)',\n backgroundColor: 'var(--color-cm-comment-surface)',\n },\n '.cm-comment > span, .cm-comment-current > span': {\n boxDecorationBreak: 'clone',\n boxShadow: '0 0 1px 3px var(--color-cm-comment-surface)',\n backgroundColor: 'var(--color-cm-comment-surface)',\n color: 'var(--color-cm-comment-text)',\n cursor: 'pointer',\n },\n});\n\nconst createCommentMark = (id: string, isCurrent: boolean) =>\n Decoration.mark({\n class: isCurrent ? 'cm-comment-current' : 'cm-comment',\n attributes: {\n 'data-testid': 'cm-comment',\n 'data-comment-id': id,\n },\n });\n\n/**\n * Decorate ranges.\n */\nconst commentsDecorations = EditorView.decorations.compute([commentsState], (state) => {\n const {\n selection: { current },\n comments,\n } = state.field(commentsState);\n\n const decorations = sortBy(comments ?? [], (range) => range.range.from)\n ?.flatMap((comment) => {\n const range = comment.range;\n if (!range) {\n log.warn('Invalid range:', range);\n return undefined;\n } else if (range.from === range.to) {\n // Skip empty ranges. This can happen when a comment is cut or deleted.\n return undefined;\n }\n\n const mark = createCommentMark(comment.comment.id, comment.comment.id === current);\n return mark.range(range.from, range.to);\n })\n .filter(isNonNullable);\n\n return Decoration.set(decorations);\n});\n\nexport const commentClickedEffect = StateEffect.define<string>();\n\nconst handleCommentClick = EditorView.domEventHandlers({\n click: (event, view) => {\n let target = event.target as HTMLElement;\n const editorRoot = view.dom;\n\n // Traverse up the DOM tree looking for an element with data-comment-id\n // Stop if we reach the editor root or find the comment id\n while (target && target !== editorRoot && !target.hasAttribute('data-comment-id')) {\n target = target.parentElement as HTMLElement;\n }\n\n // Check if we found a comment id and are still within the editor\n if (target && target !== editorRoot) {\n const commentId = target.getAttribute('data-comment-id');\n if (commentId) {\n view.dispatch({ effects: commentClickedEffect.of(commentId) });\n return true;\n }\n }\n\n return false;\n },\n});\n\n//\n// Cut-and-paste.\n//\n\ntype TrackedComment = { id: string; from: number; to: number };\n\nconst trackPastedComments = (onUpdate: NonNullable<CommentsOptions['onUpdate']>) => {\n // Tracks indexed selections within text.\n let tracked: { text: Text; comments: TrackedComment[] } | null = null;\n\n // Track cut or copy (enables cut-and-paste and copy-delete-paste to restore comment selection).\n const handleTrack = (event: Event, view: EditorView) => {\n const comments = view.state.field(commentsState);\n const { main } = view.state.selection;\n const selectedRanges = comments.comments.filter(\n ({ range }) => range.from >= main.from && range.to <= main.to && range.from < range.to,\n );\n\n if (!selectedRanges.length) {\n tracked = null;\n } else {\n tracked = {\n text: view.state.doc.slice(main.from, main.to),\n comments: selectedRanges.map(({ comment, range }) => ({\n id: comment.id,\n from: range.from - main.from,\n to: range.to - main.from,\n })),\n };\n }\n };\n\n return [\n EditorView.domEventHandlers({\n cut: handleTrack,\n copy: handleTrack,\n }),\n\n // Track deleted comments.\n invertedEffects.of((tr) => {\n const { comments } = tr.startState.field(commentsState);\n const effects: StateEffect<any>[] = [];\n tr.changes.iterChangedRanges((fromA, toA) => {\n for (const {\n comment: { id },\n range: { from, to },\n } of comments) {\n if (from < to && from >= fromA && to <= toA) {\n effects.push(restoreCommentEffect.of({ id, from, to }));\n }\n }\n });\n\n return effects;\n }),\n\n // Handle paste or the undo of comment deletion.\n EditorView.updateListener.of((update) => {\n const restore: TrackedComment[] = [];\n\n for (let i = 0; i < update.transactions.length; i++) {\n const tr = update.transactions[i];\n for (let j = 0; j < restore.length; j++) {\n restore[j] = mapTrackedComment(restore[j], tr.changes);\n }\n for (const effect of tr.effects) {\n if (effect.is(restoreCommentEffect)) {\n restore.push(effect.value);\n }\n }\n }\n\n if (tracked) {\n const paste = update.transactions.find((tr) => tr.isUserEvent('input.paste'));\n if (paste) {\n let found = -1;\n paste.changes.iterChanges((fromA, toA, fromB, toB, text) => {\n if (text.eq(tracked!.text)) {\n for (let i = update.transactions.indexOf(paste!) + 1; i < update.transactions.length; i++) {\n fromB = update.transactions[i].changes.mapPos(fromB);\n }\n\n found = fromB;\n }\n });\n\n if (found > -1) {\n for (const moved of tracked.comments) {\n restore.push({ id: moved.id, from: found + moved.from, to: found + moved.to });\n }\n }\n\n tracked = null;\n }\n }\n\n for (const comment of restore) {\n const { comments } = update.startState.field(commentsState);\n const exists = comments.some((c) => c.comment.id === comment.id && c.range.from < c.range.to);\n if (!exists) {\n const cursor = Cursor.getCursorFromRange(update.state, comment);\n onUpdate({ id: comment.id, cursor });\n }\n }\n }),\n ];\n};\n\nconst mapTrackedComment = (comment: TrackedComment, changes: ChangeDesc) => ({\n id: comment.id,\n from: changes.mapPos(comment.from, 1),\n to: changes.mapPos(comment.to, 1),\n});\n\n/**\n * These are attached to undone/redone transactions in the editor for the purpose of restoring comments\n * that were deleted by the original changes.\n */\nconst restoreCommentEffect = StateEffect.define<TrackedComment>({ map: mapTrackedComment });\n\n/**\n * Create comment thread action.\n */\nexport const createComment: Command = (view) => {\n const options = view.state.facet(optionsFacet);\n const { from, to } = view.state.selection.main;\n if (from === to) {\n return false;\n }\n\n // Don't allow selection at end of document.\n if (to === view.state.doc.length) {\n view.dispatch({\n changes: {\n from: to,\n insert: '\\n',\n },\n });\n }\n\n const cursor = Cursor.getCursorFromRange(view.state, { from, to });\n if (cursor) {\n // Create thread via callback.\n options.onCreate?.({ cursor, from, location: view.coordsAtPos(from) });\n return true;\n }\n\n return false;\n};\n\n//\n// Options\n//\n\nexport type CommentsOptions = {\n /**\n * Document id.\n */\n id?: string;\n /**\n * Key shortcut to create a new thread.\n */\n key?: string;\n /**\n * Called to render tooltip.\n */\n renderTooltip?: RenderCallback<{ shortcut: string }>;\n /**\n * Called to create a new thread and return the thread id.\n */\n onCreate?: (params: { cursor: string; from: number; location?: Rect | null }) => void;\n /**\n * Selection cut/deleted.\n */\n onDelete?: (params: { id: string }) => void;\n /**\n * Called when a comment is moved.\n */\n onUpdate?: (params: { id: string; cursor: string }) => void;\n /**\n * Called to notify which thread is currently closest to the cursor.\n */\n onSelect?: (state: CommentsState) => void;\n};\n\nconst optionsFacet = singleValueFacet<CommentsOptions>();\n\n/**\n * Comment threads.\n * 1). Updates the EditorModel to store relative selections for a set of comments threads.\n * Since the selections are relative, they do not need to be updated when the document is edited.\n * 2). Implements a StateField to track absolute selections corresponding to the comments (i.e., when the document is edited).\n * 3). Creates decoration marks to apply classes to each selection.\n * 4). Tracks the current cursor position to:\n * a). Update the decoration to show if the cursor is within a current selection.\n * b). Calls a handler to indicate which is the closest selection (e.g., to update the thread sidebar).\n * 5). Optionally, implements a hoverTooltip to show hints when creating a selection range.\n */\nexport const comments = (options: CommentsOptions = {}): Extension => {\n const { key: shortcut = \"meta-'\" } = options;\n\n const handleSelect = debounce((state: CommentsState) => options.onSelect?.(state), 200);\n\n return [\n optionsFacet.of(options),\n options.id ? documentId.of(options.id) : undefined,\n commentsState,\n commentsDecorations,\n handleCommentClick,\n styles,\n\n //\n // Keymap.\n //\n options.onCreate &&\n keymap.of([\n {\n key: shortcut,\n run: wrapWithCatch(createComment),\n },\n ]),\n\n //\n // Hover tooltip (for key shortcut hints, etc.)\n // TODO(burdon): Factor out to generic hints extension for current selection/line.\n //\n options.renderTooltip &&\n hoverTooltip(\n (view, pos) => {\n const selection = view.state.selection.main;\n if (selection && pos >= selection.from && pos <= selection.to) {\n return {\n pos: selection.from,\n end: selection.to,\n above: true,\n create: () => {\n const el = document.createElement('div');\n options.renderTooltip!(el, { shortcut }, view);\n return { dom: el, offset: { x: 0, y: 8 } };\n },\n };\n }\n\n return null;\n },\n {\n // TODO(burdon): Hide on change triggered immediately?\n // hideOnChange: true,\n hoverTime: 1_000,\n },\n ),\n\n //\n // Track deleted ranges and update ranges for decorations.\n //\n EditorView.updateListener.of(({ view, state, changes }) => {\n let mod = false;\n const { comments, ...value } = state.field(commentsState);\n changes.iterChanges((from, to, from2, to2) => {\n comments.forEach(({ comment, range }) => {\n // Test if range deleted.\n if (from2 === to2) {\n const newRange = Cursor.getRangeFromCursor(view.state, comment.cursor!);\n if (!newRange || newRange.to - newRange.from === 0) {\n options.onDelete?.({ id: comment.id });\n }\n }\n\n // Update range.\n if (from <= range.to) {\n const newRange = Cursor.getRangeFromCursor(view.state, comment.cursor!);\n Object.assign(range, newRange);\n mod = true;\n }\n });\n });\n\n if (mod) {\n view.dispatch({ effects: setCommentState.of({ comments, ...value }) });\n }\n }),\n\n //\n // Track selection/proximity.\n //\n EditorView.updateListener.of(({ view, state }) => {\n let min = Infinity;\n const {\n selection: { current, closest },\n comments,\n } = state.field(commentsState);\n\n const { head } = state.selection.main;\n const selection: SelectionState = {};\n comments.forEach(({ comment, range }) => {\n if (head >= range.from && head <= range.to) {\n selection.current = comment.id;\n selection.closest = undefined;\n }\n\n if (!selection.current) {\n const d = Math.min(Math.abs(head - range.from), Math.abs(head - range.to));\n if (d < min) {\n selection.closest = comment.id;\n min = d;\n }\n }\n });\n\n if (selection.current !== current || selection.closest !== closest) {\n view.dispatch({ effects: setSelection.of(selection) });\n\n // Update callback.\n handleSelect({\n selection,\n id: state.facet(documentId),\n comments: comments.map(({ comment, range }) => ({\n comment,\n range,\n location: view.coordsAtPos(range.from),\n })),\n });\n }\n }),\n\n options.onUpdate && trackPastedComments(options.onUpdate),\n ].filter(isNonNullable);\n};\n\n//\n// Utils.\n//\n\nexport const scrollThreadIntoView = (view: EditorView, id: string, center = true) => {\n const comment = view.state.field(commentsState).comments.find((range) => range.comment.id === id);\n if (!comment?.comment.cursor) {\n return;\n }\n const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);\n if (range) {\n const currentSelection = view.state.selection.main;\n const currentScrollPosition = view.scrollDOM.scrollTop;\n const targetScrollPosition = view.coordsAtPos(range.from)?.top;\n\n const needsScroll =\n targetScrollPosition !== undefined &&\n (targetScrollPosition < currentScrollPosition ||\n targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);\n\n const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;\n\n if (needsScroll || needsSelectionUpdate) {\n view.dispatch({\n selection: needsSelectionUpdate ? { anchor: range.from } : undefined,\n effects: [\n needsScroll ? EditorView.scrollIntoView(range.from, center ? { y: 'center' } : undefined) : [],\n needsSelectionUpdate ? setSelection.of({ current: id }) : [],\n ].flat(),\n });\n }\n }\n};\n\n/**\n * Manages external comment synchronization for the editor.\n * This class subscribes to external comment updates and applies them to the editor view.\n */\nclass ExternalCommentSync implements PluginValue {\n private readonly unsubscribe: () => void;\n\n constructor(view: EditorView, id: string, subscribe: (sink: () => void) => CleanupFn, getComments: () => Comment[]) {\n const updateComments = () => {\n const comments = getComments();\n if (id === view.state.facet(documentId)) {\n queueMicrotask(() => view.dispatch({ effects: setComments.of({ id, comments }) }));\n }\n };\n\n this.unsubscribe = subscribe(updateComments);\n }\n\n destroy = () => {\n this.unsubscribe();\n };\n}\n\n// TODO(burdon): Needs comment.\nexport const createExternalCommentSync = (\n id: string,\n subscribe: (sink: () => void) => CleanupFn,\n getComments: () => Comment[],\n): Extension =>\n ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n return new ExternalCommentSync(view, id, subscribe, getComments);\n }\n },\n );\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Extension, Transaction, type TransactionSpec } from '@codemirror/state';\nimport { EditorView, keymap } from '@codemirror/view';\n\nimport { debounce } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { isTruthy } from '@dxos/util';\n\nimport { singleValueFacet } from '../util';\n\n/**\n * Currently edited document id as FQ string.\n */\nexport const documentId = singleValueFacet<string>();\n\nexport type EditorSelection = {\n anchor: number;\n head?: number;\n};\n\nexport type EditorSelectionState = {\n scrollTo?: number;\n selection?: EditorSelection;\n};\n\nexport type EditorStateStore = {\n setState: (id: string, state: EditorSelectionState) => void;\n getState: (id: string) => EditorSelectionState | undefined;\n};\n\nconst stateRestoreAnnotation = 'org.dxos.cm.state-restore';\n\nexport const createEditorStateTransaction = ({ scrollTo, selection }: EditorSelectionState): TransactionSpec => {\n return {\n selection,\n scrollIntoView: !scrollTo,\n effects: scrollTo ? EditorView.scrollIntoView(scrollTo, { yMargin: 96 }) : undefined,\n annotations: Transaction.userEvent.of(stateRestoreAnnotation),\n };\n};\n\nexport const createEditorStateStore = (keyPrefix: string): EditorStateStore => ({\n getState: (id) => {\n invariant(id);\n const state = localStorage.getItem(`${keyPrefix}/${id}`);\n return state ? JSON.parse(state) : undefined;\n },\n\n setState: (id, state) => {\n invariant(id);\n localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));\n },\n});\n\n/**\n * Track scrolling and selection state to be restored when switching to document.\n */\nexport const selectionState = ({ getState, setState }: Partial<EditorStateStore> = {}): Extension => {\n const setStateDebounced = debounce(setState!, 1_000);\n\n return [\n // TODO(burdon): Track scrolling (currently only updates when cursor moves).\n // EditorView.domEventHandlers({\n // scroll: (event) => {\n // setStateDebounced(id, {});\n // },\n // }),\n EditorView.updateListener.of(({ view, transactions }) => {\n const id = view.state.facet(documentId);\n if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {\n return;\n }\n\n if (setState) {\n const { scrollTop } = view.scrollDOM;\n const pos = view.posAtCoords({ x: 0, y: scrollTop });\n if (pos !== null) {\n const { anchor, head } = view.state.selection.main;\n setStateDebounced(id, { scrollTo: pos, selection: { anchor, head } });\n }\n }\n }),\n getState &&\n keymap.of([\n {\n key: 'Ctrl-r', // TODO(burdon): Setting to jump back to selection.\n run: (view) => {\n const state = getState(view.state.facet(documentId));\n if (state) {\n view.dispatch(createEditorStateTransaction(state));\n }\n return true;\n },\n },\n ]),\n ].filter(isTruthy);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, type RangeSet, StateField, type Transaction } from '@codemirror/state';\n\n// eslint-disable-next-line no-console\nexport const debugNodeLogger = (log: (...args: any[]) => void = console.log): Extension => {\n const logTokens = (state: EditorState) => syntaxTree(state).iterate({ enter: (node) => log(node.type) });\n return StateField.define<any>({\n create: (state) => logTokens(state),\n update: (_: RangeSet<any>, tr: Transaction) => logTokens(tr.state),\n });\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport type { Extension } from '@codemirror/state';\nimport { EditorView, dropCursor } from '@codemirror/view';\n\nexport type DropOptions = {\n onDrop?: (view: EditorView, event: { files: FileList }) => void;\n};\n\nexport const dropFile = (options: DropOptions = {}): Extension => {\n return [\n styles,\n dropCursor(),\n EditorView.domEventHandlers({\n drop: (event, view) => {\n event.preventDefault();\n const files = event.dataTransfer?.files;\n const pos = view.posAtCoords(event);\n if (files?.length && pos !== null) {\n view.dispatch({ selection: { anchor: pos } });\n options.onDrop?.(view, { files });\n }\n },\n }),\n ];\n};\n\nconst styles = EditorView.theme({\n '.cm-dropCursor': {\n borderLeft: '2px solid var(--color-accent-text)',\n color: 'var(--color-accent-text)',\n padding: '0 4px',\n },\n '.cm-dropCursor:after': {\n content: '\"←\"',\n },\n});\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';\nimport { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from '@codemirror/commands';\nimport { HighlightStyle, bracketMatching, syntaxHighlighting } from '@codemirror/language';\nimport { searchKeymap } from '@codemirror/search';\nimport { type ChangeSpec, EditorState, type Extension, type TransactionSpec } from '@codemirror/state';\nimport {\n EditorView,\n type KeyBinding,\n ViewPlugin,\n drawSelection,\n dropCursor,\n highlightActiveLine,\n keymap,\n lineNumbers,\n placeholder,\n} from '@codemirror/view';\nimport { vscodeDarkStyle, vscodeLightStyle } from '@uiw/codemirror-theme-vscode';\nimport defaultsDeep from 'lodash.defaultsdeep';\n\nimport { generateName } from '@dxos/display-name';\nimport { type DocAccessor } from '@dxos/echo-db';\nimport { log } from '@dxos/log';\nimport { type Messenger } from '@dxos/protocols';\nimport { type Identity } from '@dxos/protocols/proto/dxos/client/services';\nimport { type ChromaticPalette, type ThemeMode } from '@dxos/ui-types';\nimport { hexToHue, isTruthy } from '@dxos/util';\n\nimport { baseTheme, createFontTheme, editorGutter } from '../styles';\nimport { automerge } from './automerge';\nimport { SpaceAwarenessProvider, awareness } from './awareness';\nimport { focus } from './focus';\nimport { scrollPastEnd } from './scroll-past-end';\n\n//\n// Basic\n//\n\n/**\n * Enable tabbing into editor (required for tabster to work).\n */\nexport const tabbable = EditorView.contentAttributes.of({ tabindex: '0' });\n\nexport const filterChars = (chars: RegExp) => {\n return EditorState.transactionFilter.of((transaction) => {\n if (!transaction.docChanged) {\n return transaction;\n }\n\n const changes: ChangeSpec[] = [];\n transaction.changes.iterChanges((fromA, toA, fromB, toB, text) => {\n const inserted = text.toString();\n const filtered = inserted.replace(chars, '');\n if (inserted !== filtered) {\n changes.push({\n from: fromB,\n to: toB,\n insert: filtered,\n });\n }\n });\n\n if (changes.length) {\n return [transaction, { changes, sequential: true } as TransactionSpec];\n }\n\n return transaction;\n });\n};\n\n/**\n * https://codemirror.net/docs/extensions\n * https://github.com/codemirror/basic-setup\n * https://github.com/codemirror/basic-setup/blob/main/src/codemirror.ts\n * https://github.com/codemirror/theme-one-dark\n */\nexport type BasicExtensionsOptions = {\n allowMultipleSelections?: boolean;\n bracketMatching?: boolean;\n closeBrackets?: boolean;\n dropCursor?: boolean;\n drawSelection?: boolean;\n editable?: boolean;\n focus?: boolean;\n highlightActiveLine?: boolean;\n history?: boolean;\n indentWithTab?: boolean;\n keymap?: null | 'default' | 'standard';\n lineNumbers?: boolean;\n /** If false then do not set a max-width or side margin on the editor. */\n lineWrapping?: boolean;\n placeholder?: string;\n /** If true user cannot edit the text, but they can still select and copy it. */\n readOnly?: boolean;\n search?: boolean;\n /** NOTE: Do not use with stack sections. */\n scrollPastEnd?: boolean;\n standardKeymap?: boolean;\n tabbable?: boolean;\n tabSize?: number;\n};\n\nconst defaultBasicOptions: BasicExtensionsOptions = {\n allowMultipleSelections: true,\n bracketMatching: true,\n closeBrackets: true,\n drawSelection: true,\n focus: true,\n history: true,\n keymap: 'standard',\n lineWrapping: true,\n search: false,\n} as const;\n\nconst keymaps: { [key: string]: readonly KeyBinding[] } = {\n // https://codemirror.net/docs/ref/#commands.standardKeymap\n standard: standardKeymap,\n // https://codemirror.net/docs/ref/#commands.defaultKeymap\n default: defaultKeymap,\n};\n\nexport const createBasicExtensions = (propsProp?: BasicExtensionsOptions): Extension => {\n const props = defaultsDeep({}, propsProp, defaultBasicOptions);\n return [\n // NOTE: Doesn't catch errors in keymap functions.\n EditorView.exceptionSink.of((err) => {\n log.catch(err);\n }),\n\n props.allowMultipleSelections && EditorState.allowMultipleSelections.of(true),\n props.bracketMatching && bracketMatching(),\n props.closeBrackets && closeBrackets(),\n props.dropCursor && dropCursor(),\n props.drawSelection && drawSelection({ cursorBlinkRate: 1_200 }),\n props.editable !== undefined && EditorView.editable.of(props.editable),\n props.focus && focus,\n props.highlightActiveLine && highlightActiveLine(),\n props.history && history(),\n props.lineNumbers && [lineNumbers(), editorGutter],\n props.lineWrapping && EditorView.lineWrapping,\n props.placeholder && placeholder(props.placeholder),\n props.readOnly !== undefined && EditorState.readOnly.of(props.readOnly),\n // `EditorState.readOnly` is advisory — CodeMirror doesn't auto-reject doc-changing\n // transactions. Some extensions (e.g. `@codemirror/lang-markdown`'s Enter handler that\n // continues a list) dispatch programmatic edits regardless. Drop user-initiated edits\n // (`input` / `delete` keymap dispatches plus `undo` / `redo` from the history extension)\n // but pass programmatic dispatches — streaming `MarkdownStream` and similar consumers\n // depend on being able to populate the doc themselves.\n props.readOnly &&\n EditorState.transactionFilter.of((tr) =>\n tr.docChanged &&\n (tr.isUserEvent('input') || tr.isUserEvent('delete') || tr.isUserEvent('undo') || tr.isUserEvent('redo'))\n ? []\n : tr,\n ),\n props.scrollPastEnd && scrollPastEnd(),\n props.tabbable && tabbable,\n props.tabSize && EditorState.tabSize.of(props.tabSize),\n\n // https://codemirror.net/docs/ref/#view.KeyBinding\n keymap.of(\n [\n ...((props.keymap && keymaps[props.keymap]) ?? []),\n // NOTE: Tabs are also configured by markdown extension.\n // https://codemirror.net/docs/ref/#commands.indentWithTab\n ...(props.indentWithTab ? [indentWithTab] : []),\n // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap\n ...(props.closeBrackets ? closeBracketsKeymap : []),\n // https://codemirror.net/docs/ref/#commands.historyKeymap\n ...(props.history ? historyKeymap : []),\n // https://codemirror.net/docs/ref/#search.searchKeymap\n ...(props.search ? searchKeymap : []),\n // Disable bindings that conflict with system shortcuts.\n // TODO(burdon): Catalog global shortcuts.\n {\n key: 'Mod-Shift-k',\n preventDefault: true,\n run: () => true,\n },\n ].filter(isTruthy),\n ),\n ].filter(isTruthy);\n};\n\n//\n// Theme\n//\n\nexport type ThemeExtensionsOptions = {\n monospace?: boolean;\n themeMode?: ThemeMode;\n scrollbarThin?: boolean;\n slots?: {\n editor?: {\n className?: string;\n };\n scroller?: {\n className?: string;\n };\n content?: {\n className?: string;\n };\n };\n syntaxHighlighting?: boolean;\n};\n\nexport const grow: ThemeExtensionsOptions['slots'] = {\n editor: {\n className: 'h-full w-full',\n },\n} as const;\n\nexport const fullWidth: ThemeExtensionsOptions['slots'] = {\n editor: {\n className: 'w-full',\n },\n} as const;\n\nexport const defaultThemeSlots = grow;\n\nexport const defaultStyles = {\n dark: vscodeDarkStyle,\n light: vscodeLightStyle,\n};\n\n/**\n * https://codemirror.net/examples/styling\n */\nexport const createThemeExtensions = ({\n monospace,\n scrollbarThin,\n slots: slotsProp,\n syntaxHighlighting: syntaxHighlightingProp,\n themeMode,\n}: ThemeExtensionsOptions = {}): Extension => {\n const slots: NonNullable<ThemeExtensionsOptions['slots']> = defaultsDeep({}, slotsProp, defaultThemeSlots);\n return [\n baseTheme,\n EditorView.darkTheme.of(themeMode === 'dark'),\n createFontTheme({ monospace }),\n syntaxHighlightingProp &&\n syntaxHighlighting(HighlightStyle.define(themeMode === 'dark' ? defaultStyles.dark : defaultStyles.light)),\n slots.editor?.className && EditorView.editorAttributes.of({ class: slots.editor.className }),\n slots.content?.className && EditorView.contentAttributes.of({ class: slots.content.className }),\n (slots.scroller?.className || scrollbarThin) &&\n ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n if (slots.scroller?.className) {\n view.scrollDOM.classList.add(...slots.scroller.className.split(/\\s+/));\n }\n if (scrollbarThin) {\n view.scrollDOM.style.setProperty('--scrollbar-size', '4px');\n }\n }\n },\n ),\n ].filter(isTruthy);\n};\n\n//\n// Data\n//\n\nexport type DataExtensionsProps<T> = {\n id: string;\n text?: DocAccessor<T>;\n messenger?: Messenger;\n identity?: Identity | null;\n};\n\nexport const createDataExtensions = <T>({ id, text, messenger, identity }: DataExtensionsProps<T>): Extension[] => {\n const extensions: Extension[] = [];\n if (text) {\n extensions.push(automerge(text));\n }\n\n if (messenger && identity) {\n const peerId = identity?.identityKey.toHex();\n const hue = (identity?.profile?.data?.hue as ChromaticPalette | undefined) ?? hexToHue(peerId ?? '0');\n extensions.push(\n awareness(\n new SpaceAwarenessProvider({\n messenger,\n channel: `awareness.${id}`,\n peerId: identity.identityKey.toHex(),\n info: {\n darkColor: `var(--color-${hue}-border)`,\n lightColor: `var(--color-${hue}-border)`,\n displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),\n },\n }),\n ),\n );\n }\n\n return extensions;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { EditorView } from '@codemirror/view';\n\nimport { mx } from '@dxos/ui-theme';\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\n// https://tailwindcss.com/docs/font-weight\nconst headings: Record<HeadingLevel, { className: string; fontSize: string; lineHeight: string }> = {\n 1: {\n className: 'text-3xl',\n fontSize: 'var(--text-3xl)',\n lineHeight: 'var(--text-4xl--line-height)',\n },\n 2: {\n className: 'text-2xl',\n fontSize: 'var(--text-2xl)',\n lineHeight: 'var(--text-3xl--line-height)',\n },\n 3: {\n className: 'text-xl',\n fontSize: 'var(--text-xl)',\n lineHeight: 'var(--text-2xl--line-height)',\n },\n 4: {\n className: 'text-lg',\n fontSize: 'var(--text-lg)',\n lineHeight: 'var(--text-xl--line-height)',\n },\n 5: {\n className: 'text-base',\n fontSize: 'var(--text-base)',\n lineHeight: 'var(--text-lg--line-height)',\n },\n 6: {\n className: 'text-base',\n fontSize: 'var(--text-base)',\n lineHeight: 'var(--text-base--line-height)',\n },\n};\n\n// Font families matching --font-body and --font-mono in theme.css.\nexport const fontBody = '\"Inter Variable\", ui-sans-serif, system-ui, sans-serif';\nexport const fontMono = '\"JetBrains Mono Variable\", ui-monospace, \"Cascadia Code\", \"Source Code Pro\", monospace';\n\nexport const markdownTheme = {\n code: 'font-mono! cm-code-inline',\n codeMark: 'font-mono! cm-code-mark',\n mark: 'font-mono!',\n heading: (level: HeadingLevel) => ({\n className: mx(headings[level].className, 'font-light text-(--color-cm-heading-number)'),\n color: 'var(--color-cm-heading) !important',\n lineHeight: headings[level].lineHeight,\n fontSize: headings[level].fontSize,\n fontWeight: '100 !important',\n }),\n};\n\n/**\n * Global base theme.\n *\n * NOTE: The base theme is GLOBAL and is applied to ALL editors.\n * NOTE: `light` and `dark` selectors are preprocessed by CodeMirror and can only be in the base theme.\n * NOTE: Use 'unset' to remove default CM style.\n *\n * Examples:\n * - https://codemirror.net/examples/styling\n * - https://github.com/codemirror/view/blob/main/src/theme.ts\n * - https://github.com/codemirror/theme-one-dark/blob/main/src/one-dark.ts\n *\n * Main layout:\n * - https://codemirror.net/examples/styling\n * - https://codemirror.net/docs/guide (DOM Structure).\n *\n * <div class=\"cm-editor [cm-focused] [generated classes]\">\n * <div class=\"cm-scroller\">\n * <div class=\"cm-gutters\">\n * <div class=\"cm-gutter [...]\">\n * <div class=\"cm-gutterElement\">...</div>\n * </div>\n * </div>\n * <div class=\"cm-content\" role=\"textbox\" contenteditable=\"true\">\n * <div class=\"cm-line\"></div>\n * </div>\n * <div class=\"cm-selectionLayer\">\n * <div class=\"cm-selectionBackground\"></div>\n * </div>\n * <div class=\"cm-cursorLayer\">\n * <div class=\"cm-cursor\"></div>\n * </div>\n * </div>\n * </div>\n */\nexport const baseTheme = EditorView.baseTheme({\n /**\n * Outer frame.\n */\n '&': {},\n '&.cm-focused': {\n outline: 'none',\n },\n\n /**\n * Scroller\n */\n '.cm-scroller': {\n // Browser scroll-anchoring: see comment in `scroller.ts`. `auto` lets the browser pin a\n // stable element near the viewport top so widget resizes (e.g. tool-block TogglePanel\n // open/close) don't jump the user's view.\n overflowAnchor: 'auto',\n },\n '.cm-scroller::-webkit-scrollbar': {\n width: 'var(--scrollbar-size,8px)',\n height: 'var(--scrollbar-size,8px)',\n },\n '.cm-scroller::-webkit-scrollbar-corner': {\n background: 'transparent',\n },\n '.cm-scroller::-webkit-scrollbar-track': {\n background: 'transparent',\n },\n '.cm-scroller::-webkit-scrollbar-thumb': {\n background: 'transparent',\n transition: 'background 0.15s',\n },\n '&:hover .cm-scroller::-webkit-scrollbar-thumb': {\n background: 'var(--color-scrollbar-thumb)',\n },\n\n /**\n * Content\n * NOTE: Apply margins to content so that scrollbar is at the edge of the container.\n */\n '.cm-content': {\n padding: 'unset',\n color: 'unset',\n },\n\n /**\n * Gutters\n * NOTE: Gutters should have the same top margin as the content.\n */\n '.cm-gutters': {\n background: 'transparent',\n borderRight: 'none',\n },\n '.cm-gutter': {},\n '.cm-gutter.cm-lineNumbers': {\n paddingRight: '4px',\n borderRight: '1px solid var(--color-subdued-separator)',\n color: 'var(--color-subdued)',\n },\n '.cm-gutter.cm-lineNumbers .cm-gutterElement': {\n minWidth: '40px',\n },\n /**\n * Height is set to match the corresponding line (which may have wrapped).\n */\n '.cm-gutterElement': {\n lineHeight: '24px',\n fontSize: '12px',\n },\n\n /**\n * Line.\n */\n '.cm-line': {\n lineHeight: 1.5,\n paddingInline: 0,\n },\n /**\n * Force all inline children to inherit line-height to prevent monospace font metrics\n * (JetBrains Mono ascent/descent) from inflating the line box beyond 24px.\n */\n '.cm-line *': {\n lineHeight: 'inherit',\n },\n '.cm-activeLine': {\n background: 'var(--color-cm-active-line)',\n },\n\n /**\n * Cursor (layer).\n */\n '.cm-cursor, .cm-dropCursor': {\n borderLeft: '2px solid var(--color-cm-cursor)',\n },\n '.cm-placeholder': {\n color: 'var(--color-placeholder)',\n },\n\n /**\n * Selection (layer).\n */\n '.cm-selectionBackground': {\n background: 'var(--color-cm-selection)',\n },\n '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground': {\n background: 'var(--color-cm-focused-selection)',\n },\n\n /**\n * Search.\n * NOTE: Matches comment.\n */\n '.cm-searchMatch': {\n margin: '0 -3px',\n padding: '3px',\n borderRadius: '3px',\n background: 'var(--color-cm-highlight-surface)',\n color: 'var(--color-cm-highlight)',\n },\n '.cm-searchMatch-selected': {\n textDecoration: 'underline',\n },\n\n /**\n * Link.\n */\n '.cm-link': {\n textDecorationLine: 'underline',\n textDecorationThickness: '1px',\n textDecorationColor: 'var(--color-separator)',\n textUnderlineOffset: '2px',\n borderRadius: '.125rem',\n },\n '.cm-link > span': {\n color: 'var(--color-accent-text)',\n },\n '.cm-link > span:hover': {\n color: 'var(--color-accent-text-hover)',\n },\n\n /**\n * Tooltip.\n */\n '.cm-tooltip': {\n background: 'var(--color-modal-surface)',\n },\n '.cm-tooltip-below': {},\n '.cm-tooltip-hover': {\n background: 'var(--color-modal-surface)',\n border: '1px solid var(--color-separator)',\n borderRadius: '4px',\n overflow: 'hidden',\n },\n\n /**\n * Autocomplete.\n * https://github.com/codemirror/autocomplete/blob/main/src/completion.ts\n */\n '.cm-tooltip.cm-tooltip-autocomplete': {\n marginTop: '6px',\n marginLeft: '-10px',\n border: '2px solid var(--color-separator)',\n borderRadius: '4px',\n },\n '.cm-tooltip.cm-tooltip-autocomplete > ul': {\n maxHeight: '20em',\n },\n '.cm-tooltip.cm-tooltip-autocomplete > ul > li': {\n padding: '4px',\n },\n '.cm-tooltip.cm-tooltip-autocomplete > ul > li[aria-selected]': {\n background: 'var(--color-active-surface)',\n color: 'var(--color-base-surface-text)',\n },\n '.cm-tooltip.cm-tooltip-autocomplete > ul > completion-section': {\n paddingLeft: '4px !important',\n color: 'var(--color-base-surface-text)',\n },\n\n /**\n * Completion info.\n */\n '.cm-completionInfo': {\n width: '360px !important',\n margin: '-10px 1px 0 1px',\n padding: '8px !important',\n borderColor: 'var(--color-separator)',\n },\n '.cm-completionIcon': {\n display: 'none',\n },\n '.cm-completionLabel': {\n color: 'var(--color-description)',\n padding: '0 4px',\n },\n '.cm-completionMatchedText': {\n color: 'var(--color-base-surface-text)',\n textDecoration: 'none !important',\n },\n\n /**\n * Panels\n * https://github.com/codemirror/search/blob/main/src/search.ts#L745\n *\n * Find/replace panel.\n * <div class=\"cm-announced\">...</div>\n * <div class=\"cm-scroller\">...</div>\n * <div class=\"cm-panels cm-panels-bottom\">\n * <div class=\"cm-search cm-panel\">\n * <input class=\"cm-textfield\" />\n * <button class=\"cm-button\">...</button>\n * <label><input type=\"checkbox\" />...</label>\n * </div>\n * </div\n */\n // TODO(burdon): Implement custom panel (with icon buttons).\n '.cm-panels': {},\n '.cm-panel': {\n backgroundColor: 'var(--surface-bg)',\n },\n '.cm-panel input, .cm-panel button, .cm-panel label': {\n color: 'var(--color-subdued)',\n fontSize: '14px',\n all: 'unset',\n margin: '3px !important',\n padding: '2px 6px !important',\n outline: '1px solid transparent',\n },\n '.cm-panel input, .cm-panel button': {\n backgroundColor: 'var(--color-input-surface)',\n },\n '.cm-panel input:focus, .cm-panel button:focus': {\n outline: '1px solid var(--color-neutral-focus-indicator)',\n },\n '.cm-panel label': {\n display: 'inline-flex',\n alignItems: 'center',\n cursor: 'pointer',\n },\n '.cm-panel input.cm-textfield': {},\n '.cm-panel input[type=checkbox]': {\n width: '8px',\n height: '8px',\n marginRight: '6px !important',\n padding: '2px !important',\n color: 'var(--color-neutral-focus-indicator)',\n },\n '.cm-panel button': {\n '&:hover': {\n // TODO(burdon): Replace with layer and @apply bg-accent-surface-hover\n backgroundColor: 'var(--color-accent-surface-hover) !important',\n },\n '&:active': {\n backgroundColor: 'var(--color-accent-surface-hover)',\n },\n },\n '.cm-panel.cm-search': {\n padding: '4px',\n borderTop: '1px solid var(--color-separator)',\n },\n});\n\nexport const editorGutter: Extension = EditorView.theme({\n '.cm-gutters': {\n // NOTE: Non-transparent background required to cover content if scrolling horizontally.\n background: 'var(--color-base-surface) !important',\n paddingRight: '1rem',\n },\n});\n\nexport type FontOptions = {\n monospace?: boolean;\n};\n\nexport const createFontTheme = ({ monospace }: FontOptions = {}) =>\n EditorView.theme({\n // Main content.\n '.cm-scroller': {\n fontFamily: monospace ? fontMono : fontBody,\n },\n\n // Maintain defaults for UI components.\n '.cm-content, .cm-gutters, .cm-panel': {\n fontFamily: 'inherit',\n fontSize: 'inherit',\n },\n });\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { StateEffect, StateField } from '@codemirror/state';\nimport { EditorView } from '@codemirror/view';\n\nconst focusEffect = StateEffect.define<boolean>();\n\nexport const focusField = StateField.define<boolean>({\n create: () => false,\n update: (value, tr) => {\n for (const effect of tr.effects) {\n if (effect.is(focusEffect)) {\n return effect.value;\n }\n }\n\n return value;\n },\n});\n\n/**\n * Manage focus.\n */\nexport const focus = [\n focusField,\n EditorView.domEventHandlers({\n focus: (_event, view) => {\n requestAnimationFrame(() => view.dispatch({ effects: focusEffect.of(true) }));\n },\n blur: (_event, view) => {\n requestAnimationFrame(() => view.dispatch({ effects: focusEffect.of(false) }));\n },\n }),\n];\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { EditorView, ViewPlugin } from '@codemirror/view';\n\n/**\n * Custom scroll-past-end extension that accounts for the actual height of the last line.\n * The built-in CodeMirror `scrollPastEnd` uses `defaultLineHeight` which doesn't account\n * for taller elements like headings, block widgets, etc.\n */\nconst scrollPastEndPlugin = ViewPlugin.fromClass(\n class {\n height = 1000;\n attrs: { style: string } | null = { style: 'padding-bottom: 1000px' };\n\n update({ view }: { view: EditorView }) {\n const lastLineBlock = view.lineBlockAt(view.state.doc.length);\n const height = view.dom.clientHeight - lastLineBlock.height - view.documentPadding.top - 0.5;\n if (height >= 0 && height !== this.height) {\n this.height = height;\n this.attrs = { style: `padding-bottom: ${height}px` };\n }\n }\n },\n);\n\nexport const scrollPastEnd = (): Extension => [\n scrollPastEndPlugin,\n EditorView.contentAttributes.of((view) => view.plugin(scrollPastEndPlugin)?.attrs ?? null),\n];\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { codeFolding, foldGutter } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { EditorView } from '@codemirror/view';\n\nimport { Domino, mx } from '@dxos/ui';\n\n/**\n * https://codemirror.net/examples/gutter\n */\nexport const folding = (): Extension => {\n return [\n codeFolding({\n placeholderDOM: () => Domino.of('span').root,\n }),\n foldGutter({\n // NOTE: We can't animate since the element is remounted on state change.\n markerDOM: (open) => {\n return Domino.of('div')\n .classNames('flex h-full justify-center items-center')\n .append(\n Domino.of('svg', Domino.SVG)\n .classNames(mx('w-4 h-4 cursor-pointer', open && 'rotate-90'))\n .append(\n Domino.of('use', Domino.SVG).attributes({\n href: Domino.icon('ph--caret-right--regular'),\n }),\n ),\n ).root;\n },\n }),\n EditorView.theme({\n '.cm-foldGutter': {\n opacity: 0.3,\n transition: 'opacity 0.3s',\n width: '32px',\n },\n '.cm-foldGutter:hover': {\n opacity: 1,\n },\n }),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n MatchDecorator,\n ViewPlugin,\n type ViewUpdate,\n WidgetType,\n} from '@codemirror/view';\n\nimport { getHashStyles, mx } from '@dxos/ui-theme';\n\nclass TagWidget extends WidgetType {\n constructor(private _text: string) {\n super();\n }\n\n toDOM(): HTMLSpanElement {\n const span = document.createElement('span');\n span.className = mx('cm-tag', getHashStyles(this._text).surface);\n span.textContent = this._text;\n return span;\n }\n}\n\nconst tagMatcher = new MatchDecorator({\n regexp: /#(\\w+)\\W/g,\n decoration: (match) =>\n Decoration.replace({\n widget: new TagWidget(match[1]),\n }),\n});\n\n// TODO(burdon): Autocomplete from existing tags?\nexport const hashtag = (): Extension => [\n ViewPlugin.fromClass(\n class {\n tags: DecorationSet;\n constructor(view: EditorView) {\n this.tags = tagMatcher.createDeco(view);\n }\n\n update(update: ViewUpdate) {\n this.tags = tagMatcher.updateDeco(update, this.tags);\n }\n },\n {\n decorations: (instance) => instance.tags,\n provide: (plugin) =>\n EditorView.atomicRanges.of((view) => {\n return view.plugin(plugin)?.tags || Decoration.none;\n }),\n },\n ),\n\n EditorView.theme({\n '.cm-tag': {\n borderRadius: '4px',\n marginRight: '6px',\n padding: '2px 6px',\n },\n }),\n];\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\nimport { type LintSource, linter } from '@codemirror/lint';\nimport { type Extension } from '@codemirror/state';\nimport Ajv, { type ValidateFunction } from 'ajv';\n\nimport { type JsonSchemaType } from '@dxos/echo/internal';\n\nexport type JsonExtensionsOptions = {\n schema?: JsonSchemaType;\n};\n\nexport const createJsonExtensions = ({ schema }: JsonExtensionsOptions = {}): Extension => {\n let lintSource: LintSource = jsonParseLinter();\n if (schema) {\n // NOTE: Relaxing strict mode to allow additional custom schema properties.\n const ajv = new Ajv({ allErrors: false, strict: false });\n const validate = ajv.compile(schema);\n lintSource = schemaLinter(validate);\n }\n\n return [json(), linter(lintSource)];\n};\n\nconst schemaLinter =\n (validate: ValidateFunction): LintSource =>\n (view) => {\n try {\n const jsonText = view.state.doc.toString();\n const jsonData = JSON.parse(jsonText);\n const valid = validate(jsonData);\n if (valid) {\n return [];\n }\n\n return (\n validate.errors?.map((err: any) => ({\n from: 0,\n to: jsonText.length,\n severity: 'error',\n message: `${err.instancePath || '(root)'} ${err.message}`,\n })) ?? []\n );\n } catch (err: unknown) {\n return [\n {\n from: 0,\n to: view.state.doc.length,\n severity: 'error',\n message: 'Invalid JSON: ' + (err as Error).message,\n },\n ];\n }\n };\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { EditorView } from '@codemirror/view';\n\nimport { isNonNullable } from '@dxos/util';\n\nimport { documentId } from './selection';\n\nexport type ListenerOptions = {\n onFocus?: (event: { id: string; focusing: boolean }) => void;\n onChange?: (event: { id: string; text: string }) => void;\n};\n\nexport const listener = ({ onFocus, onChange }: ListenerOptions): Extension => {\n return [\n onFocus &&\n EditorView.focusChangeEffect.of((state, focusing) => {\n onFocus({ id: state.facet(documentId), focusing });\n return null;\n }),\n\n onChange &&\n EditorView.updateListener.of(({ state, docChanged }) => {\n if (docChanged) {\n onChange({ id: state.facet(documentId), text: state.doc.toString() });\n }\n }),\n ].filter(isNonNullable);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { snippet } from '@codemirror/autocomplete';\nimport { syntaxTree } from '@codemirror/language';\nimport {\n type ChangeSpec,\n EditorSelection,\n type EditorState,\n type Extension,\n type Line,\n type StateCommand,\n type Text,\n} from '@codemirror/state';\nimport { EditorView, type ViewUpdate, keymap } from '@codemirror/view';\nimport { type SyntaxNode, type SyntaxNodeRef } from '@lezer/common';\n\nimport { debounceAndThrottle } from '@dxos/async';\n\n// Markdown refs:\n// https://github.github.com/gfm\n// https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax\n\n// Describes the formatting situation of the selection in an editor state.\n// For inline styles `strong`, `emphasis`, `strikethrough`, and `code`,\n// the field only holds true when *all* selected text has the style,\n// or when the selection is a cursor inside such a style.\nexport type Formatting = Partial<{\n blankLine: boolean;\n // The type of the block at the selection.\n // If multiple different block types are selected, this will hold null.\n blockType:\n | 'codeblock'\n | 'heading1'\n | 'heading2'\n | 'heading3'\n | 'heading4'\n | 'heading5'\n | 'heading6'\n | 'paragraph'\n | 'tablecell'\n | null;\n // Whether all selected text is wrapped in a blockquote.\n blockQuote: boolean;\n // Whether the selected text is strong.\n strong: boolean;\n // Whether the selected text is emphasized.\n emphasis: boolean;\n // Whether the selected text is stricken through.\n strikethrough: boolean;\n // Whether the selected text is inline code.\n code: boolean;\n // Whether there are links in the selected text.\n link: boolean;\n // If all selected blocks have the same (innermost) list style, that is indicated here.\n listStyle: null | 'ordered' | 'bullet' | 'task';\n}>;\n\nexport const formattingEquals = (a: Formatting, b: Formatting) =>\n a.blockType === b.blockType &&\n a.strong === b.strong &&\n a.emphasis === b.emphasis &&\n a.strikethrough === b.strikethrough &&\n a.code === b.code &&\n a.link === b.link &&\n a.listStyle === b.listStyle &&\n a.blockQuote === b.blockQuote;\n\nexport enum Inline {\n Strong = 0,\n Emphasis = 1,\n Strikethrough = 2,\n Code = 3,\n}\n\nexport enum List {\n Ordered,\n Bullet,\n Task,\n}\n\n//\n// Headings\n//\n\nexport const setHeading = (level: number): StateCommand => {\n return ({ state, dispatch }) => {\n const {\n selection: { ranges },\n doc,\n } = state;\n const changes: ChangeSpec[] = [];\n let prevBlock = -1;\n for (const range of ranges) {\n let sawBlock = false;\n syntaxTree(state).iterate({\n from: range.from,\n to: range.to,\n enter: (node) => {\n if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {\n return;\n }\n sawBlock = true;\n prevBlock = node.from;\n const blockType = Textblocks[node.name];\n const isHeading = /heading(\\d)/.exec(blockType);\n const curLevel = isHeading ? +isHeading[1] : node.name === 'Paragraph' ? 0 : -1;\n if (curLevel < 0 || curLevel === level) {\n return;\n }\n if (curLevel === 0) {\n changes.push({ from: node.from, insert: '#'.repeat(level) + ' ' });\n } else if (node.name === 'SetextHeading1' || node.name === 'SetextHeading2') {\n // Change Setext heading to regular one.\n const nextLine = doc.lineAt(node.to);\n if (level) {\n changes.push({ from: node.from, insert: '#'.repeat(level) + ' ' });\n }\n changes.push({ from: nextLine.from - 1, to: nextLine.to });\n } else {\n // Adjust the level of an ATX heading.\n if (level === 0) {\n changes.push({ from: node.from, to: Math.min(node.to, node.from + curLevel + 1) });\n } else if (level < curLevel) {\n changes.push({ from: node.from, to: node.from + (curLevel - level) });\n } else {\n changes.push({ from: node.from, insert: '#'.repeat(level - curLevel) });\n }\n }\n },\n });\n let line;\n if (!sawBlock && range.empty && level > 0 && !/\\S/.test((line = state.doc.lineAt(range.from)).text)) {\n changes.push({ from: line.from, to: line.to, insert: '#'.repeat(level) + ' ' });\n }\n }\n\n if (!changes.length) {\n return false;\n }\n\n const changeSet = state.changes(changes);\n dispatch(\n state.update({\n changes: changeSet,\n selection: state.selection.map(changeSet, 1),\n userEvent: 'format.setHeading',\n scrollIntoView: true,\n }),\n );\n return true;\n };\n};\n\n//\n// Styles\n//\n\nexport const setStyle = (type: Inline, enable: boolean): StateCommand => {\n return ({ state, dispatch }) => {\n const marker = inlineMarkerText(type);\n const changes = state.changeByRange((range) => {\n // Special case for markers directly around the cursor, which will often not be parsed as valid styling.\n if (!enable && range.empty) {\n const after = state.doc.sliceString(range.head, range.head + 6);\n const found = after.indexOf(marker);\n if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {\n const before = state.doc.sliceString(range.head - 6, range.head);\n if (\n before.slice(before.length - found - marker.length, before.length - found) === marker &&\n [...before.slice(before.length - found)].reverse().join('') === after.slice(0, found)\n ) {\n return {\n changes: [\n { from: range.head - marker.length - found, to: range.head - found },\n { from: range.head + found, to: range.head + found + marker.length },\n ],\n range: EditorSelection.cursor(range.from - marker.length),\n };\n }\n }\n }\n\n const changes: ChangeSpec[] = [];\n // Used to add insertions that should happen *after* any other insertions at the same position.\n const changesAtEnd: ChangeSpec[] = [];\n let blockStart = -1;\n let blockEnd = -1;\n let startCovered: boolean | { from: number; to: number } = false;\n let endCovered: boolean | { from: number; to: number } = false;\n let { from, to } = range;\n\n // Iterate the selected range. For each textblock, determine a start and end position,\n // the overlap of the selected range and the block's extent, that should be styled/unstyled.\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n const { name } = node;\n if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== 'codeblock') {\n // Set up for this textblock.\n blockStart = blockContentStart(node);\n blockEnd = blockContentEnd(node, state.doc);\n startCovered = endCovered = false;\n } else if (name === 'Link' || (name === 'Image' && enable)) {\n // If the range partially overlaps a link or image, expand it to cover it.\n if (from < node.from && to > node.from && to <= node.to) {\n to = node.to;\n } else if (to > node.to && from >= node.from && from < node.to) {\n from = node.from;\n }\n } else if (IgnoreInline.has(name) && enable) {\n // Move endpoints out of markers.\n if (node.from < from && node.to > from) {\n if (to === from) {\n to = node.to;\n }\n from = node.to;\n }\n if (node.from < to && node.to > to) {\n to = node.from;\n }\n } else if (Object.hasOwn(InlineMarker, name)) {\n // This is an inline marker node.\n const markType = InlineMarker[name];\n const size = inlineMarkerText(markType).length;\n const openEnd = node.from + size;\n const closeStart = node.to - size;\n // Determine whether the start/end of the range is covered\n // by this.\n if (markType === type) {\n if (openEnd <= from && closeStart >= from) {\n startCovered =\n !enable && openEnd === skipMarkers(from, node.node, -1, openEnd)\n ? { from: node.from, to: openEnd }\n : true;\n }\n if (openEnd <= to && closeStart >= to) {\n endCovered =\n !enable && closeStart === skipMarkers(to, node.node, 1, closeStart)\n ? { from: closeStart, to: node.to }\n : true;\n }\n }\n // Marks of the same type in range, or any mark if we're adding code style, need to be removed.\n if (markType === type || (type === Inline.Code && enable)) {\n if (node.from >= from && openEnd <= to) {\n changes.push({ from: node.from, to: openEnd });\n if (markType !== type && closeStart >= to) {\n // End marker outside, move start\n changesAtEnd.push({\n from: skipSpaces(Math.min(to, blockEnd), state.doc, 1, blockEnd),\n insert: inlineMarkerText(markType),\n });\n }\n }\n if (closeStart >= from && node.to <= to) {\n changes.push({ from: closeStart, to: node.to });\n if (markType !== type && openEnd <= from) {\n // Start marker outside, move end\n changes.push({\n from: skipSpaces(Math.max(from, blockStart), state.doc, -1, blockStart),\n insert: inlineMarkerText(markType),\n });\n }\n }\n }\n }\n },\n leave: (node) => {\n if (Object.hasOwn(Textblocks, node.name) && Textblocks[node.name] !== 'codeblock') {\n // Finish opening/closing the marks for this textblock.\n const rangeStart = Math.max(from, blockStart);\n const rangeEnd = Math.min(to, blockEnd);\n if (enable) {\n if (!startCovered) {\n changes.push({ from: rangeStart, insert: marker });\n }\n if (!endCovered) {\n changes.push({ from: rangeEnd, insert: marker });\n }\n } else {\n if (typeof startCovered === 'object') {\n changes.push(startCovered);\n } else if (startCovered) {\n changes.push({ from: skipSpaces(rangeStart, state.doc, -1, blockStart), insert: marker });\n }\n if (typeof endCovered === 'object') {\n changes.push(endCovered);\n } else if (endCovered) {\n changes.push({ from: skipSpaces(rangeEnd, state.doc, 1, blockEnd), insert: marker });\n }\n }\n }\n },\n });\n\n if (blockStart < 0 && range.empty && enable && !/\\S/.test(state.doc.lineAt(range.from).text)) {\n return {\n changes: { from: range.head, insert: marker + marker },\n range: EditorSelection.cursor(range.head + marker.length),\n };\n }\n\n const changeSet = state.changes(changes.concat(changesAtEnd));\n return {\n changes: changeSet,\n range:\n range.empty && !changeSet.empty\n ? EditorSelection.cursor(range.head + marker.length)\n : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1)),\n };\n });\n\n dispatch(\n state.update(changes, {\n userEvent: enable ? 'format.style.add' : 'format.style.remove',\n scrollIntoView: true,\n }),\n );\n\n return true;\n };\n};\n\nexport const addStyle = (style: Inline): StateCommand => setStyle(style, true);\n\nexport const removeStyle = (style: Inline): StateCommand => setStyle(style, false);\n\nexport const toggleStyle = (style: Inline): StateCommand => {\n return (arg) => {\n const form = getFormatting(arg.state);\n return setStyle(\n style,\n style === Inline.Strong\n ? !form.strong\n : style === Inline.Emphasis\n ? !form.emphasis\n : style === Inline.Strikethrough\n ? !form.strikethrough\n : !form.code,\n )(arg);\n };\n};\n\nexport const toggleStrong = toggleStyle(Inline.Strong);\nexport const toggleEmphasis = toggleStyle(Inline.Emphasis);\nexport const toggleStrikethrough = toggleStyle(Inline.Strikethrough);\nexport const toggleInlineCode = toggleStyle(Inline.Code);\n\nconst inlineMarkerText = (type: Inline) =>\n type === Inline.Strong ? '**' : type === Inline.Strikethrough ? '~~' : type === Inline.Emphasis ? '*' : '`';\n\n//\n// Utils\n//\n\nconst blockContentStart = (node: SyntaxNodeRef) => {\n const atx = /^ATXHeading(\\d)/.exec(node.name);\n if (atx) {\n return Math.min(node.to, node.from + +atx[1] + 1);\n }\n return node.from;\n};\n\nconst blockContentEnd = (node: SyntaxNodeRef, doc: Text) => {\n const setext = /^SetextHeading(\\d)/.exec(node.name);\n const lastLine = doc.lineAt(node.to);\n if (setext || /^[\\s>]*$/.exec(lastLine.text)) {\n return lastLine.from - 1;\n }\n return node.to;\n};\n\nconst skipSpaces = (pos: number, doc: Text, dir: -1 | 1, limit?: number) => {\n const line = doc.lineAt(pos);\n while (pos !== limit && line.text[pos - line.from - (dir < 0 ? 1 : 0)] === ' ') {\n pos += dir;\n }\n return pos;\n};\n\nconst skipMarkers = (pos: number, tree: SyntaxNode, dir: -1 | 1, limit?: number) => {\n for (;;) {\n const next = tree.resolve(pos, dir);\n if (!IgnoreInline.has(next.name)) {\n return pos;\n }\n const moveTo = dir < 0 ? next.from : next.to;\n if (limit != null && (dir < 0 ? moveTo < limit : moveTo > limit)) {\n return pos;\n }\n pos = moveTo;\n }\n};\n\n// TODO(burdon): Define and trigger snippets for codeblock, table, etc.\nconst snippets = {\n codeblock: snippet(\n [\n //\n '```#{}',\n '',\n '```',\n ].join('\\n'),\n ),\n table: snippet(\n [\n //\n '| #{col1} | #{col2} |',\n '| ---- | ---- |',\n '| #{val1} | #{val2} |',\n '| #{val3} | #{val4} |',\n '',\n ].join('\\n'),\n ),\n};\n\n//\n// Table\n//\n\nexport const insertTable = (view: EditorView) => {\n const {\n selection: { main },\n doc,\n } = view.state;\n const { number } = doc.lineAt(main.anchor);\n const { from } = doc.line(number);\n\n snippets.table(view, null, from, from);\n};\n\n//\n// Links\n//\n\n// For each link in the given range, remove the link markup\nconst removeLinkInner = (from: number, to: number, changes: ChangeSpec[], state: EditorState) => {\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n if (node.name === 'Link' && node.from < to && node.to > from) {\n node.node.cursor().iterate((node) => {\n const { name } = node;\n if (name === 'LinkMark' || name === 'LinkLabel') {\n changes.push({ from: node.from, to: node.to });\n } else if (name === 'LinkTitle' || name === 'URL') {\n changes.push({ from: skipSpaces(node.from, state.doc, -1), to: skipSpaces(node.to, state.doc, 1) });\n }\n });\n return false;\n }\n },\n });\n};\n\n// Remove all links touching the selection\nexport const removeLink: StateCommand = ({ state, dispatch }) => {\n const changes: ChangeSpec[] = [];\n for (const { from, to } of state.selection.ranges) {\n removeLinkInner(from, to, changes, state);\n }\n if (!changes) {\n return false;\n }\n dispatch(state.update({ changes, userEvent: 'format.link.remove', scrollIntoView: true }));\n return true;\n};\n\n// Add link markup around the selection.\nexport const addLink = ({ url, image }: { url?: string; image?: boolean } = {}): StateCommand => {\n return ({ state, dispatch }) => {\n const changes = state.changeByRange((range) => {\n let { from, to } = range;\n const cutStyles: SyntaxNode[] = [];\n let okay: boolean | null = null;\n // Check whether this range is in a position where a link makes sense.\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n if (Object.hasOwn(Textblocks, node.name)) {\n // If the selection spans multiple textblocks or is in a code block, abort.\n okay =\n Textblocks[node.name] !== 'codeblock' &&\n from >= blockContentStart(node) &&\n to <= blockContentEnd(node, state.doc);\n } else if (Object.hasOwn(InlineMarker, node.name)) {\n // Look for inline styles that partially overlap the range.\n // Expand the range over them if they start directly outside, otherwise mark them for later.\n const sNode = node.node;\n if (node.from < from && node.to <= to) {\n if (sNode.firstChild!.to === from) {\n from = node.from;\n } else {\n cutStyles.push(sNode);\n }\n } else if (node.from >= from && node.to > to) {\n if (sNode.lastChild!.from === to) {\n to = node.to;\n } else {\n cutStyles.push(sNode);\n }\n }\n }\n },\n });\n\n if (okay === null) {\n // No textblock found around selection. Check if the rest of the line is empty.\n const line = state.doc.lineAt(from);\n okay = to <= line.to && !/\\S/.test(line.text.slice(from - line.from));\n }\n if (!okay) {\n return { range };\n }\n\n const changes: ChangeSpec[] = [];\n // Some changes must be moved to end of change array so that they are applied in the right order.\n const changesAfter: ChangeSpec[] = [];\n // Clear existing links.\n removeLinkInner(from, to, changesAfter, state);\n let cursorOffset = 1;\n // Close and reopen inline styles that partially overlap the range.\n for (const style of cutStyles) {\n const type = InlineMarker[style.name];\n const mark = inlineMarkerText(type);\n if (style.from < from) {\n // Extends before.\n changes.push({ from: skipSpaces(from, state.doc, -1), insert: mark });\n changesAfter.push({ from: skipSpaces(from, state.doc, 1, to), insert: mark });\n } else {\n changes.push({ from: skipSpaces(to, state.doc, -1, from), insert: mark });\n const after = skipSpaces(to, state.doc, 1);\n if (after === to) {\n cursorOffset += mark.length;\n }\n changesAfter.push({ from: after, insert: mark });\n }\n }\n\n // Add the link markup.\n changes.push({ from, insert: image ? '` });\n const changeSet = state.changes(changes.concat(changesAfter));\n // Put the cursor between the title or parenthesis.\n return {\n changes: changeSet,\n range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0)),\n };\n });\n\n if (changes.changes.empty) {\n return false;\n }\n\n dispatch(\n state.update(changes, {\n userEvent: 'format.link.add',\n scrollIntoView: true,\n }),\n );\n return true;\n };\n};\n\n//\n// Lists\n//\n\nexport const addList = (type: List): StateCommand => {\n return ({ state, dispatch }) => {\n let lastBlock = -1;\n let counter = 1;\n let first = true;\n let parentColumn: number | null = null;\n\n // Scan the syntax tree to locate textblocks that can be wrapped.\n const blocks: { node: SyntaxNode; counter: number; parentColumn: number | null }[] = [];\n for (const { from, to } of state.selection.ranges) {\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n if ((Object.hasOwn(Textblocks, node.name) && node.name !== 'TableCell') || node.name === 'Table') {\n if (first) {\n // For the first block, see if it follows a list,\n // so we can take indentation and numbering information from that one.\n let before = node.node.prevSibling;\n while (before && /Mark$/.test(before.name)) {\n before = before.prevSibling;\n }\n if (before?.name === (type === List.Ordered ? 'OrderedList' : 'BulletList')) {\n const item = before.lastChild!;\n const itemLine = state.doc.lineAt(item.from);\n const itemText = itemLine.text.slice(item.from - itemLine.from);\n parentColumn = item.from - itemLine.from + /^\\s*/.exec(itemText)![0].length;\n if (type === List.Ordered) {\n const mark = /^\\s*(\\d+)[.)]/.exec(itemText);\n if (mark) {\n parentColumn += mark[1].length;\n counter = +mark[1] + 1;\n }\n }\n }\n first = false;\n }\n if (node.from === lastBlock) {\n return;\n }\n\n lastBlock = node.from;\n blocks.push({ node: node.node, counter, parentColumn });\n counter++;\n return false;\n }\n },\n leave: (node) => {\n // When exiting block-level markup, reset the indentation and counter.\n if (node.name === 'BulletList' || node.name === 'OrderedList' || node.name === 'Blockquote') {\n counter = 1;\n parentColumn = null;\n }\n },\n });\n }\n\n if (!blocks.length) {\n // Insert a new list item if the selection is empty.\n const { from, to } = state.doc.lineAt(state.selection.main.anchor);\n if (from === to) {\n const insert = type === List.Bullet ? '- ' : type === List.Ordered ? '1. ' : '- [ ] ';\n dispatch(\n state.update({\n changes: [\n {\n from,\n insert,\n },\n ],\n selection: { anchor: from + insert.length },\n userEvent: 'format.list.add',\n scrollIntoView: true,\n }),\n );\n return true;\n }\n\n return false;\n }\n\n const changes: ChangeSpec[] = [];\n for (let i = 0; i < blocks.length; i++) {\n const { node, counter, parentColumn } = blocks[i];\n const nodeFrom = node.name === 'CodeBlock' ? node.from - 4 : node.from;\n // Compute a padding based on whether we are after whitespace.\n let padding = nodeFrom > 0 && !/\\s/.test(state.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;\n // On ordered lists, the number is counted in the padding.\n if (type === List.Ordered) {\n padding += String(counter).length;\n }\n let line = state.doc.lineAt(nodeFrom);\n const column = nodeFrom - line.from;\n // Align to the list above if possible.\n if (parentColumn !== null && parentColumn > column) {\n padding = Math.max(padding, parentColumn - column);\n }\n\n let mark;\n if (type === List.Ordered) {\n // Scan ahead to find the max number we're adding, adjust padding for that.\n let max = counter;\n for (let j = i + 1; j < blocks.length; j++) {\n if (blocks[j].counter !== max + 1) {\n break;\n }\n max++;\n }\n const num = String(counter);\n padding = Math.max(String(max).length, padding);\n mark = ' '.repeat(Math.max(0, padding - num.length)) + num + '. ';\n } else {\n mark = ' '.repeat(padding) + '- ' + (type === List.Task ? '[ ] ' : '');\n }\n\n changes.push({ from: nodeFrom, insert: mark });\n // Add indentation for the other lines in this block.\n while (line.to < node.to) {\n line = state.doc.lineAt(line.to + 1);\n const open = /^[\\s>]*/.exec(line.text)![0].length;\n changes.push({ from: line.from + Math.min(open, column), insert: ' '.repeat(mark.length) });\n }\n }\n\n // If we are inserting an ordered list and there is another one right after the last selected block,\n // renumber that one to match the new order.\n if (type === List.Ordered) {\n const last = blocks[blocks.length - 1];\n let next = last.node.nextSibling;\n while (next && /Mark$/.test(next.name)) {\n next = next.nextSibling;\n }\n if (next?.name === 'OrderedList') {\n renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);\n }\n }\n const changeSet = state.changes(changes);\n dispatch(\n state.update({\n changes: changeSet,\n selection: state.selection.map(changeSet, 1),\n userEvent: 'format.list.add',\n scrollIntoView: true,\n }),\n );\n return true;\n };\n};\n\nexport const removeList = (type: List): StateCommand => {\n return ({ state, dispatch }) => {\n let lastBlock = -1;\n const changes: ChangeSpec[] = [];\n const stack: string[] = [];\n const targetNodeType = type === List.Ordered ? 'OrderedList' : type === List.Bullet ? 'BulletList' : 'TaskList';\n // Scan the syntax tree to locate list items that can be unwrapped.\n for (const { from, to } of state.selection.ranges) {\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n const { name } = node;\n if (name === 'BulletList' || name === 'OrderedList' || name === 'Blockquote') {\n // Maintain block context.\n stack.push(name);\n } else if (name === 'Task' && stack[stack.length - 1] === 'BulletList') {\n stack[stack.length - 1] = 'TaskList';\n }\n },\n leave: (node) => {\n const { name } = node;\n if (name === 'BulletList' || name === 'OrderedList' || name === 'Blockquote') {\n stack.pop();\n } else if (name === 'ListItem' && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {\n lastBlock = node.from;\n let line = state.doc.lineAt(node.from);\n const mark = /^\\s*(\\d+[.)] |[-*+] (\\[[ x]\\] )?)/.exec(line.text.slice(node.from - line.from));\n if (!mark) {\n return false;\n }\n const column = node.from - line.from;\n // Delete the marker on the first line.\n changes.push({ from: node.from, to: node.from + mark[0].length });\n // and indentation on subsequent lines.\n while (line.to < node.to) {\n line = state.doc.lineAt(line.to + 1);\n const open = /^[\\s>]*/.exec(line.text)![0].length;\n if (open > column) {\n changes.push({ from: line.from + column, to: line.from + Math.min(column + mark[0].length, open) });\n }\n }\n if (node.to >= to) {\n renumberListItems(node.node.nextSibling, 1, changes, state.doc);\n }\n return false;\n }\n },\n });\n }\n if (!changes.length) {\n return false;\n }\n\n dispatch(\n state.update({\n changes,\n userEvent: 'format.list.remove',\n scrollIntoView: true,\n }),\n );\n return true;\n };\n};\n\nexport const toggleList = (type: List): StateCommand => {\n return (target) => {\n const formatting = getFormatting(target.state);\n const active =\n formatting.listStyle === (type === List.Bullet ? 'bullet' : type === List.Ordered ? 'ordered' : 'task');\n return (active ? removeList(type) : addList(type))(target);\n };\n};\n\nconst renumberListItems = (item: SyntaxNode | null, counter: number, changes: ChangeSpec[], doc: Text) => {\n for (; item; item = item.nextSibling) {\n if (item.name === 'ListItem') {\n const number = /(\\s*)(\\d+)[.)]/.exec(doc.sliceString(item.from, item.from + 10));\n if (!number || +number[2] === counter) {\n break;\n }\n const size = number[1].length + number[2].length;\n const newNum = String(counter);\n changes.push({ from: item.from + Math.max(0, size - newNum.length), to: item.from + size, insert: newNum });\n counter++;\n }\n }\n};\n\n//\n// Block quotes\n//\n\nexport const setBlockquote = (enable: boolean): StateCommand => {\n return ({ state, dispatch }) => {\n const lines: Line[] = [];\n let lastBlock = -1;\n for (const { from, to } of state.selection.ranges) {\n const sawBlock = false;\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n if (Object.hasOwn(Textblocks, node.name) || node.name === 'Table') {\n if (node.from === lastBlock) {\n return false;\n }\n lastBlock = node.from;\n let line = state.doc.lineAt(node.from);\n if (line.number > 1) {\n const prevLine = state.doc.line(line.number - 1);\n if (/^[>\\s]*$/.test(prevLine.text)) {\n if (!enable || (lines.length && lines[lines.length - 1].number === prevLine.number - 1)) {\n lines.push(prevLine);\n }\n }\n }\n for (;;) {\n lines.push(line);\n if (line.to >= node.to) {\n break;\n }\n line = state.doc.line(line.number + 1);\n }\n if (!enable && line.number < state.doc.lines) {\n const nextLine = state.doc.line(line.number + 1);\n if (/^[>\\s]*$/.test(nextLine.text)) {\n lines.push(nextLine);\n }\n }\n return false;\n }\n },\n });\n let line;\n if (!sawBlock && enable && from === to && !/\\S/.test((line = state.doc.lineAt(from)).text)) {\n lines.push(line);\n }\n }\n\n const changes: ChangeSpec[] = [];\n for (const line of lines) {\n if (enable) {\n changes.push({ from: line.from, insert: /\\S/.test(line.text) ? '> ' : '>' });\n } else {\n const quote = /((?:[\\s>\\-+*]|\\d+[.)])*?)> ?/.exec(line.text);\n if (quote) {\n changes.push({ from: line.from + quote[1].length, to: line.from + quote[0].length });\n }\n }\n }\n if (!changes.length) {\n return false;\n }\n\n const changeSet = state.changes(changes);\n dispatch(\n state.update({\n changes: changeSet,\n selection: state.selection.map(changeSet, 1),\n userEvent: enable ? 'format.blockquote.add' : 'format.blockquote.remove',\n scrollIntoView: true,\n }),\n );\n return true;\n };\n};\n\nexport const addBlockquote = setBlockquote(true);\n\nexport const removeBlockquote = setBlockquote(false);\n\nexport const toggleBlockquote: StateCommand = (target) => {\n return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);\n};\n\n//\n// Code block\n//\n\nexport const addCodeblock: StateCommand = (target) => {\n const { state, dispatch } = target;\n const { selection } = state;\n // If on a blank line, use the code block snippet.\n if (selection.ranges.length === 1 && selection.main.empty) {\n const { head } = selection.main;\n const line = state.doc.lineAt(head);\n if (!/\\S/.test(line.text) && head === line.from) {\n snippets.codeblock(target, null, line.from, line.to);\n return true;\n }\n }\n\n // Otherwise, wrap any selected blocks in triple backticks.\n const ranges: { from: number; to: number }[] = [];\n for (const { from, to } of selection.ranges) {\n let blockFrom = from;\n let blockTo = to;\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n if (Object.hasOwn(Textblocks, node.name)) {\n if (from >= node.from && to <= node.to) {\n // Selection in a single block.\n blockFrom = node.from;\n blockTo = node.to;\n } else {\n // Expand to cover whole lines.\n blockFrom = Math.min(blockFrom, state.doc.lineAt(node.from).from);\n blockTo = Math.max(blockTo, state.doc.lineAt(node.to).to);\n }\n }\n },\n });\n if (ranges.length && ranges[ranges.length - 1].to >= blockFrom - 1) {\n ranges[ranges.length - 1].to = blockTo;\n } else {\n ranges.push({ from: blockFrom, to: blockTo });\n }\n }\n if (!ranges.length) {\n return false;\n }\n\n const changes: ChangeSpec[] = ranges.map(({ from, to }) => {\n const column = from - state.doc.lineAt(from).from;\n return [\n { from, insert: '```\\n' + ' '.repeat(column) },\n { from: to, insert: '\\n' + ' '.repeat(column) + '```' },\n ];\n });\n\n dispatch(\n state.update({\n changes,\n userEvent: 'format.codeblock.add',\n scrollIntoView: true,\n }),\n );\n\n return true;\n};\n\nexport const removeCodeblock: StateCommand = ({ state, dispatch }) => {\n let lastBlock = -1;\n\n // Find all code blocks, remove their markup.\n const changes: ChangeSpec[] = [];\n for (const { from, to } of state.selection.ranges) {\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n if (Textblocks[node.name] === 'codeblock' && lastBlock !== node.from) {\n lastBlock = node.from;\n const firstLine = state.doc.lineAt(node.from);\n if (node.name === 'FencedCode') {\n changes.push({ from: node.from, to: firstLine.to + 1 + node.from - firstLine.from });\n const lastLine = state.doc.lineAt(node.to);\n if (/^([\\s>]|[-*+] |\\d+[).])*`+$/.test(lastLine.text)) {\n changes.push({\n from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),\n to: lastLine.to,\n });\n }\n } else {\n // Indented code block.\n const column = node.from - firstLine.from;\n for (let line = firstLine; ; line = state.doc.line(line.number + 1)) {\n changes.push({ from: line.from + column - 4, to: line.from + column });\n if (line.to >= node.to) {\n break;\n }\n }\n }\n }\n },\n });\n }\n if (!changes.length) {\n return false;\n }\n\n dispatch(state.update({ changes, userEvent: 'format.codeblock.remove', scrollIntoView: true }));\n return true;\n};\n\nexport const toggleCodeblock: StateCommand = (target) => {\n return (getFormatting(target.state).blockType === 'codeblock' ? removeCodeblock : addCodeblock)(target);\n};\n\n//\n// Formatting extension.\n//\n\nexport type FormattingOptions = {};\n\nexport const formattingKeymap = (_options: FormattingOptions = {}): Extension => {\n return [\n keymap.of([\n {\n key: 'meta-b',\n run: toggleStrong,\n },\n {\n key: 'meta-i',\n run: toggleEmphasis,\n },\n ]),\n ];\n};\n\nconst InlineMarker: { [name: string]: number } = {\n Emphasis: Inline.Emphasis,\n StrongEmphasis: Inline.Strong,\n InlineCode: Inline.Code,\n Strikethrough: Inline.Strikethrough,\n};\n\nconst IgnoreInline = new Set([\n 'Autolink',\n 'CodeMark',\n 'CodeText',\n 'Comment',\n 'EmphasisMark',\n 'Hardbreak',\n 'HeaderMark',\n 'HTMLTag',\n 'LinkMark',\n 'ListMark',\n 'ProcessingInstruction',\n 'QuoteMark',\n 'StrikethroughMark',\n 'SubscriptMark',\n 'SuperscriptMark',\n 'TaskMarker',\n]);\n\nconst Textblocks: { [name: string]: NonNullable<Formatting['blockType']> } = {\n ATXHeading1: 'heading1',\n ATXHeading2: 'heading2',\n ATXHeading3: 'heading3',\n ATXHeading4: 'heading4',\n ATXHeading5: 'heading5',\n ATXHeading6: 'heading6',\n CodeBlock: 'codeblock',\n FencedCode: 'codeblock',\n Paragraph: 'paragraph',\n SetextHeading1: 'heading1',\n SetextHeading2: 'heading2',\n TableCell: 'tablecell',\n Task: 'paragraph',\n};\n\n/**\n * Query the editor state for the active formatting at the selection.\n */\nexport const getFormatting = (state: EditorState): Formatting => {\n // These will track the formatting we've seen so far.\n // False indicates mixed block types.\n let blockType: Formatting['blockType'] | false = null;\n // Indexed by the Inline enum, tracks inline markup.\n // null = no text seen, true = all text had the mark, false = saw text without it.\n const inline: (boolean | null)[] = [null, null, null, null];\n let link: boolean = false;\n let blockQuote: boolean | null = null;\n // False indicates mixed list styles.\n let listStyle: Formatting['listStyle'] | null | false = null;\n\n // Track block context for list/blockquote handling.\n const stack: ('BulletList' | 'OrderedList' | 'Blockquote' | 'TaskList')[] = [];\n // This is set when entering a textblock (paragraph, heading, etc.)\n // and cleared when exiting again. It is used to track inline style.\n // `active` holds an array that indicates, for the various style (`Inline` enum) whether they are currently active.\n let currentBlock: { pos: number; end: number; active: boolean[] } | null = null;\n // Advance over regular inline text. Will update `inline` depending on what styles are active.\n const advanceInline = (upto: number) => {\n if (!currentBlock) {\n return;\n }\n upto = Math.min(upto, currentBlock.end);\n if (upto <= currentBlock.pos) {\n return;\n }\n for (let i = 0; i < currentBlock.active.length; i++) {\n if (inline[i] === false) {\n continue;\n } else if (currentBlock.active[i]) {\n inline[i] = true;\n } else if (/\\S/.test(state.doc.sliceString(currentBlock.pos, upto))) {\n inline[i] = false;\n }\n }\n currentBlock.pos = upto;\n };\n\n // Skip markup that shouldn't be treated as inline text for style-tracking purposes.\n const skipInline = (upto: number) => {\n if (currentBlock && upto > currentBlock.pos) {\n currentBlock.pos = Math.min(upto, currentBlock.end);\n }\n };\n\n const { selection } = state;\n for (const range of selection.ranges) {\n if (range.empty && inline.some((v) => v === null)) {\n // Check for markers directly around the cursor (which, not being valid Markdown, the syntax tree won't pick up).\n const contextSize = Math.min(range.head, 6);\n const contextBefore = state.doc.sliceString(range.head - contextSize, range.head);\n let contextAfter = state.doc.sliceString(range.head, range.head + contextSize);\n for (let i = 0; i < contextSize; i++) {\n const ch = contextAfter[i];\n if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {\n contextAfter = contextAfter.slice(0, i);\n break;\n }\n }\n for (let i = 0; i < inline.length; i++) {\n const mark = inlineMarkerText(i);\n const found = contextAfter.indexOf(mark);\n if (found > -1) {\n contextAfter = contextAfter.slice(0, found) + contextAfter.slice(found + mark.length);\n if (inline[i] === null) {\n inline[i] = true;\n }\n }\n }\n }\n\n syntaxTree(state).iterate({\n from: range.from,\n to: range.to,\n enter: (node) => {\n advanceInline(node.from);\n const { name } = node;\n if (name === 'BulletList' || name === 'OrderedList' || name === 'Blockquote') {\n // Maintain block context.\n stack.push(name);\n } else if (name === 'Link') {\n link = true;\n } else if (Object.hasOwn(Textblocks, name) && (range.empty || node.to > range.from || node.from < range.to)) {\n if (name === 'Task' && stack[stack.length - 1] === 'BulletList') {\n stack[stack.length - 1] = 'TaskList';\n }\n const blockCode = Textblocks[name];\n if (blockType === null) {\n blockType = blockCode;\n } else if (blockType !== blockCode) {\n blockType = false;\n }\n if (blockCode !== 'codeblock' && inline.some((i) => i !== false)) {\n // Set up inline content tracking for non-code textblocks.\n currentBlock = {\n pos: Math.max(range.from, node.from),\n end: Math.min(range.to, node.to),\n active: [false, false, false, false],\n };\n }\n } else if (Object.hasOwn(InlineMarker, name) && currentBlock) {\n const index = InlineMarker[name];\n // Cursors selections always count as active.\n if (range.empty && inline[index] === null) {\n inline[index] = true;\n }\n currentBlock.active[index] = true;\n } else if (IgnoreInline.has(name)) {\n skipInline(node.to);\n }\n },\n leave: (node) => {\n advanceInline(node.to);\n const { name } = node;\n if (name === 'BulletList' || name === 'OrderedList' || name === 'Blockquote') {\n // Track block context.\n stack.pop();\n } else if (Object.hasOwn(Textblocks, name)) {\n // Scan the stack for blockquote/list context.\n // Done at end of node because task lists aren't recognized until a task is seen\n let hasList: Formatting['listStyle'] | false = false;\n let hasQuote = false;\n for (let i = stack.length - 1; i >= 0; i--) {\n if (stack[i] === 'Blockquote') {\n hasQuote = true;\n } else if (!hasList) {\n hasList = stack[i] === 'TaskList' ? 'task' : stack[i] === 'BulletList' ? 'bullet' : 'ordered';\n }\n }\n if (blockQuote === null) {\n blockQuote = hasQuote;\n } else if (!hasQuote && blockQuote) {\n blockQuote = false;\n }\n if (listStyle === null) {\n listStyle = hasList;\n } else if (listStyle !== hasList) {\n listStyle = false;\n }\n\n // End textblock.\n currentBlock = null;\n } else if (Object.hasOwn(InlineMarker, name) && currentBlock) {\n // Track markup in textblock.\n currentBlock.active[InlineMarker[name]] = false;\n }\n },\n });\n }\n\n const { from, to } = state.doc.lineAt(selection.main.anchor);\n const blankLine = from === to;\n\n return {\n blankLine,\n blockType: blockType || null,\n blockQuote: blockQuote ?? false,\n code: inline[Inline.Code] ?? false,\n emphasis: inline[Inline.Emphasis] ?? false,\n strong: inline[Inline.Strong] ?? false,\n strikethrough: inline[Inline.Strikethrough] ?? false,\n link,\n listStyle: listStyle || null,\n };\n};\n\n/**\n * Extension to compute and publish the current formatting state.\n * @param onStateChange - Callback invoked with the current formatting state when the editor state changes.\n * @param delay - Debounce/throttle delay in ms.\n */\nexport const formattingListener = (onStateChange: (state: Formatting) => void, delay = 100): Extension => {\n return EditorView.updateListener.of(\n debounceAndThrottle((update: ViewUpdate) => {\n if (update.docChanged || update.selectionSet) {\n onStateChange(getFormatting(update.state));\n }\n }, delay),\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type EditorView } from '@codemirror/view';\n\nimport { type Node } from '@dxos/app-graph';\nimport { type MenuActionProperties } from '@dxos/ui-types';\n\nimport { createComment } from '../comments';\nimport {\n Inline,\n List,\n addBlockquote,\n addCodeblock,\n addLink,\n addList,\n insertTable,\n removeBlockquote,\n removeCodeblock,\n removeLink,\n removeList,\n setHeading,\n setStyle,\n toggleBlockquote,\n toggleList,\n toggleStyle,\n} from './formatting';\n\nexport type PayloadType =\n | 'view-mode'\n | 'blockquote'\n | 'strong'\n | 'codeblock'\n | 'comment'\n | 'heading'\n | 'image'\n | 'emphasis'\n | 'code'\n | 'link'\n | 'list-bullet'\n | 'list-ordered'\n | 'list-task'\n | 'mention'\n | 'prompt'\n | 'search'\n | 'strikethrough'\n | 'table';\n\nexport type EditorActionPayload = {\n type: PayloadType;\n data?: any;\n};\n\nexport type EditorAction = Node.Action<MenuActionProperties & EditorActionPayload>;\n\nexport type EditorPayloadHandler = (view: EditorView, payload: EditorActionPayload) => void;\n\nexport const processEditorPayload: EditorPayloadHandler = (view, { type, data }) => {\n let inlineType, listType;\n switch (type) {\n case 'heading':\n setHeading(parseInt(data))(view);\n break;\n\n case 'strong':\n case 'emphasis':\n case 'strikethrough':\n case 'code':\n inlineType =\n type === 'strong'\n ? Inline.Strong\n : type === 'emphasis'\n ? Inline.Emphasis\n : type === 'strikethrough'\n ? Inline.Strikethrough\n : Inline.Code;\n (typeof data === 'boolean' ? setStyle(inlineType, data) : toggleStyle(inlineType))(view);\n break;\n\n case 'list-ordered':\n case 'list-bullet':\n case 'list-task':\n listType = type === 'list-ordered' ? List.Ordered : type === 'list-bullet' ? List.Bullet : List.Task;\n (data === false ? removeList(listType) : data === true ? addList(listType) : toggleList(listType))(view);\n break;\n\n case 'blockquote':\n (data === false ? removeBlockquote : data === true ? addBlockquote : toggleBlockquote)(view);\n break;\n case 'codeblock':\n (data === false ? removeCodeblock : addCodeblock)(view);\n break;\n case 'table':\n insertTable(view);\n break;\n\n case 'link':\n (data === false ? removeLink : addLink())(view);\n break;\n\n case 'image':\n addLink({ url: data, image: true })(view);\n break;\n\n case 'comment':\n createComment(view);\n break;\n }\n\n requestAnimationFrame(() => {\n if (!view.hasFocus) {\n view.focus();\n }\n });\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { completionKeymap } from '@codemirror/autocomplete';\nimport { defaultKeymap, indentWithTab } from '@codemirror/commands';\nimport { jsonLanguage } from '@codemirror/lang-json';\nimport { markdown, markdownLanguage } from '@codemirror/lang-markdown';\nimport { type LanguageDescription, foldNodeProp, syntaxHighlighting } from '@codemirror/language';\nimport { languages } from '@codemirror/language-data';\nimport { type Extension } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport { type MarkdownConfig } from '@lezer/markdown';\n\nimport { isTruthy } from '@dxos/util';\n\nimport { markdownHighlightStyle, markdownTagsExtensions } from './highlight';\n\nexport type MarkdownBundleOptions = {\n /** Additional fenced-code languages prepended to the standard language-data list. */\n codeLanguages?: LanguageDescription[];\n extensions?: MarkdownConfig[];\n indentWithTab?: boolean;\n setextHeading?: boolean;\n};\n\n/**\n * Creates markdown extensions.\n * To be used in conjunction with createBasicExtensions.\n *\n * Refs:\n * https://codemirror.net/docs/community\n * https://codemirror.net/docs/ref/#codemirror.basicSetup\n */\nexport const createMarkdownExtensions = (options: MarkdownBundleOptions = {}): Extension[] => {\n return [\n // Main extension.\n // https://github.com/codemirror/lang-markdown\n // https://codemirror.net/5/mode/markdown/index.html (demo).\n markdown({\n // GRM by default (vs strict CommonMark):\n // Table, TaskList, Strikethrough, and Autolink.\n // NOTE: This extends the parser; it doesn't affect rendering.\n // https://github.github.com/gfm\n // https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown\n base: markdownLanguage,\n\n // Languages for syntax highlighting fenced code blocks.\n // Caller-supplied languages are checked first so they can override defaults.\n defaultCodeLanguage: jsonLanguage,\n codeLanguages: [...(options.codeLanguages ?? []), ...languages],\n\n // Don't complete HTML tags.\n completeHTMLTags: false,\n\n // Parser extensions.\n extensions: [\n // GFM provided by default.\n markdownTagsExtensions,\n ...(options.extensions ?? defaultExtensions()),\n // Disable folding for fenced code blocks by overriding foldNodeProp.\n // Note: returning null from foldService does not prevent syntaxFolding fallback,\n // so we must override the node prop directly on the FencedCode node type.\n noFencedCodeFolding,\n ],\n }),\n\n // Custom styles.\n syntaxHighlighting(markdownHighlightStyle()),\n\n keymap.of(\n [\n // https://codemirror.net/docs/ref/#commands.indentWithTab\n options.indentWithTab !== false && indentWithTab,\n\n // https://codemirror.net/docs/ref/#commands.defaultKeymap\n ...defaultKeymap,\n\n // TODO(burdon): Remove?\n ...completionKeymap,\n ].filter(isTruthy),\n ),\n ];\n};\n\n/**\n * Disables folding for fenced code blocks.\n *\n * foldService cannot block folding because returning null just defers to the next service,\n * and CodeMirror always falls back to syntaxFolding (which reads foldNodeProp).\n * The only reliable fix is to override foldNodeProp on FencedCode to return null.\n */\nconst noFencedCodeFolding: MarkdownConfig = {\n props: [\n foldNodeProp.add({\n FencedCode: () => null,\n }),\n ],\n};\n\n/**\n * Default customizations.\n * https://github.com/lezer-parser/markdown/blob/main/src/markdown.ts\n */\nexport const defaultExtensions = (): MarkdownConfig[] => [noSetExtHeading, noHtml];\n\n/**\n * Remove SetextHeading (e.g., headings created from \"---\").\n */\nconst noSetExtHeading: MarkdownConfig = {\n remove: ['SetextHeading'],\n};\n\n/**\n * Remove HTML and XML parsing.\n */\nconst noHtml: MarkdownConfig = {\n // remove: ['HTMLBlock', 'HTMLTag'],\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { markdownLanguage } from '@codemirror/lang-markdown';\nimport { HighlightStyle } from '@codemirror/language';\nimport { Tag, styleTags, tags } from '@lezer/highlight';\nimport { type MarkdownConfig, Table } from '@lezer/markdown';\n\nimport { fontBody, markdownTheme } from '../../styles';\n\n/**\n * Custom tags defined and processed by the GFM lezer extension.\n * https://github.com/lezer-parser/markdown\n * https://github.com/lezer-parser/markdown/blob/main/src/markdown.ts\n */\nexport const markdownTags = {\n Blockquote: Tag.define(),\n CodeMark: Tag.define(),\n CodeText: Tag.define(),\n EmphasisMark: Tag.define(),\n HeaderMark: Tag.define(),\n InlineCode: Tag.define(),\n LinkLabel: Tag.define(),\n LinkReference: Tag.define(),\n ListMark: Tag.define(),\n QuoteMark: Tag.define(),\n URL: Tag.define(),\n\n // Custom.\n TableCell: Tag.define(),\n};\n\n// TODO(burdon): Customize table parser (make all content monospace).\n// https://github.com/lezer-parser/markdown/blob/main/src/extension.ts\nTable.defineNodes?.forEach((node: any) => {\n switch (node?.name) {\n case 'TableCell': {\n node.style = markdownTags.TableCell;\n break;\n }\n }\n});\n\nexport const markdownTagsExtensions: MarkdownConfig[] = [\n Table,\n {\n props: [styleTags(markdownTags)],\n },\n];\n\nexport type HighlightOptions = {};\n\n/**\n * Styling based on `lezer` parser tags.\n * https://codemirror.net/examples/styling\n * https://github.com/lezer-parser/highlight\n * https://github.com/lezer-parser/highlight/blob/main/src/highlight.ts#L427\n * https://lezer.codemirror.net/docs/ref/#highlight.tags (list of tags)\n *\n * Examples:\n * - https://github.com/codemirror/language/blob/main/src/highlight.ts#L194\n * - https://github.com/codemirror/theme-one-dark/blob/main/src/one-dark.ts#L115\n */\nexport const markdownHighlightStyle = (_options: HighlightOptions = {}) => {\n return HighlightStyle.define(\n [\n {\n tag: [\n tags.keyword,\n tags.name,\n tags.deleted,\n tags.character,\n tags.propertyName,\n tags.macroName,\n tags.color,\n tags.constant(tags.name),\n tags.standard(tags.name),\n tags.definition(tags.name),\n tags.separator,\n tags.typeName,\n tags.className,\n tags.number,\n tags.changed,\n tags.annotation,\n tags.modifier,\n tags.self,\n tags.namespace,\n tags.operator,\n tags.operatorKeyword,\n tags.escape,\n tags.regexp,\n tags.special(tags.string),\n tags.meta,\n tags.comment,\n tags.atom,\n tags.bool,\n tags.special(tags.variableName),\n tags.processingInstruction,\n tags.string,\n tags.inserted,\n tags.invalid,\n ],\n // TODO(burdon): Explain.\n color: 'inherit !important',\n },\n\n // Markdown marks.\n {\n tag: [\n tags.meta,\n tags.processingInstruction,\n markdownTags.LinkLabel,\n markdownTags.LinkReference,\n markdownTags.ListMark,\n ],\n class: markdownTheme.mark,\n },\n\n // Markdown marks.\n {\n tag: [\n //\n markdownTags.CodeMark,\n markdownTags.HeaderMark,\n markdownTags.QuoteMark,\n markdownTags.EmphasisMark,\n ],\n class: markdownTheme.mark,\n },\n\n // E.g., code block language (after ```).\n {\n tag: [\n //\n tags.function(tags.variableName),\n tags.labelName,\n ],\n class: markdownTheme.codeMark,\n },\n\n // Fonts.\n {\n tag: [tags.monospace, tags.comment],\n class: 'font-mono',\n },\n\n // Headings — use CSS properties only (no class:) so CodeMirror generates scoped CSS via\n // StyleModule that overrides vscodeDarkStyle's t.heading rule. When class: is present,\n // HighlightStyle silently ignores all other CSS properties (they're mutually exclusive).\n // Font sizes use Tailwind v4 CSS variables so nothing is hardcoded.\n {\n tag: tags.heading,\n color: 'var(--color-cm-heading) !important',\n fontWeight: '300',\n },\n { tag: tags.heading1, ...markdownTheme.heading(1) },\n { tag: tags.heading2, ...markdownTheme.heading(2) },\n { tag: tags.heading3, ...markdownTheme.heading(3) },\n { tag: tags.heading4, ...markdownTheme.heading(4) },\n { tag: tags.heading5, ...markdownTheme.heading(5) },\n { tag: tags.heading6, ...markdownTheme.heading(6) },\n\n // Emphasis.\n { tag: tags.emphasis, class: 'italic' },\n { tag: tags.strong, class: 'font-bold' },\n { tag: tags.strikethrough, class: 'line-through' },\n\n // NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).\n // However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,\n // when a language is specified. In this case, the syntax highlighting extensions will colorize\n // the code, but all other CSS properties will be inherited.\n // IMPORTANT: Therefore, the fenced code block will use the base editor font unless changed by an extension.\n {\n tag: [markdownTags.CodeText, markdownTags.InlineCode],\n class: markdownTheme.code,\n },\n\n {\n tag: [markdownTags.TableCell],\n class: 'font-mono',\n },\n ],\n {\n scope: markdownLanguage,\n all: {\n fontFamily: fontBody,\n },\n },\n );\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, StateField } from '@codemirror/state';\nimport { type TreeCursor } from '@lezer/common';\n\nexport const debugTree = (cb: (tree: DebugNode) => void): Extension =>\n StateField.define({\n create: (state) => cb(convertTreeToJson(state)),\n update: (value, tr) => cb(convertTreeToJson(tr.state)),\n });\n\nexport type DebugNode = {\n type: string;\n from: number;\n to: number;\n text: string;\n children: DebugNode[];\n};\n\nexport const convertTreeToJson = (state: EditorState): DebugNode => {\n const treeToJson = (cursor: TreeCursor): DebugNode => {\n const node: DebugNode = {\n type: cursor.type.name,\n from: cursor.from,\n to: cursor.to,\n text: state.doc.slice(cursor.from, cursor.to).toString(),\n children: [],\n };\n\n if (cursor.firstChild()) {\n do {\n node.children.push(treeToJson(cursor));\n } while (cursor.nextSibling());\n cursor.parent();\n }\n\n return node;\n };\n\n return treeToJson(syntaxTree(state).cursor());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, Prec, RangeSetBuilder, StateEffect } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from '@codemirror/view';\nimport { type SyntaxNodeRef } from '@lezer/common';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { type HeadingLevel, markdownTheme } from '../../styles';\nimport { type RenderCallback } from '../../types';\nimport { wrapWithCatch } from '../../util';\nimport { adjustChanges } from './changes';\nimport { image } from './image';\nimport { bulletListIndentationWidth, formattingStyles, orderedListIndentationWidth } from './styles';\nimport { table } from './table';\n\n/**\n * Unicode characters.\n * NOTE: Depends on font.\n * https://www.compart.com/en/unicode (nice resource).\n * https://en.wikipedia.org/wiki/List_of_Unicode_characters\n */\nconst Unicode = {\n emDash: '\\u2014',\n bullet: '\\u2022',\n bulletSmall: '\\u2219',\n bulletSquare: '\\u2b1d',\n};\n\n//\n// Widgets\n//\n\nclass HorizontalRuleWidget extends WidgetType {\n override toDOM(): HTMLSpanElement {\n const el = document.createElement('span');\n el.className = 'cm-hr';\n return el;\n }\n}\n\nclass LinkButton extends WidgetType {\n constructor(\n private readonly url: string,\n private readonly render: RenderCallback<{ url: string }>,\n ) {\n super();\n }\n\n override eq(other: this) {\n return this.url === other.url;\n }\n\n override toDOM(view: EditorView) {\n const el = document.createElement('span');\n this.render(el, { url: this.url }, view);\n return el;\n }\n}\n\nclass CheckboxWidget extends WidgetType {\n constructor(private _checked: boolean) {\n super();\n }\n\n override eq(other: this) {\n return this._checked === other._checked;\n }\n\n override ignoreEvent() {\n return false;\n }\n\n override toDOM(view: EditorView) {\n const input = document.createElement('input');\n input.className = 'cm-task-checkbox dx-checkbox';\n input.type = 'checkbox';\n input.tabIndex = -1;\n input.checked = this._checked;\n if (view.state.readOnly) {\n input.setAttribute('disabled', 'true');\n } else {\n input.onmousedown = (event: Event) => {\n // Could be beginning of line.\n const line = view.state.doc.lineAt(view.posAtDOM(span));\n const text = view.state.sliceDoc(line.from, line.to);\n const match = text.match(/^\\s*- (\\[[xX ]]).*/);\n if (match) {\n const [, checked] = match;\n const pos = line.from + text.indexOf(checked);\n this._checked = checked !== '[ ]';\n view.dispatch({\n changes: { from: pos + 1, to: pos + 2, insert: this._checked ? ' ' : 'x' },\n });\n\n event.preventDefault();\n }\n };\n }\n\n const span = document.createElement('span');\n span.className = 'cm-task';\n span.appendChild(input);\n return span;\n }\n}\n\nclass TextWidget extends WidgetType {\n constructor(\n private readonly text: string,\n private readonly className?: string,\n ) {\n super();\n }\n\n override toDOM(): HTMLSpanElement {\n const el = document.createElement('span');\n if (this.className) {\n el.className = this.className;\n }\n el.innerText = this.text;\n return el;\n }\n}\n\nconst hide = Decoration.replace({});\nconst blockQuote = Decoration.line({ class: 'cm-blockquote' });\nconst fencedCodeLine = Decoration.line({ class: 'cm-code cm-codeblock-line' });\nconst fencedCodeLineFirst = Decoration.line({ class: 'cm-code cm-codeblock-line cm-codeblock-start' });\nconst fencedCodeLineLast = Decoration.line({ class: 'cm-code cm-codeblock-line cm-codeblock-end' });\nconst commentBlockLine = fencedCodeLine;\nconst commentBlockLineFirst = fencedCodeLineFirst;\nconst commentBlockLineLast = fencedCodeLineLast;\nconst horizontalRule = Decoration.replace({ widget: new HorizontalRuleWidget() });\nconst checkedTask = Decoration.replace({ widget: new CheckboxWidget(true) });\nconst uncheckedTask = Decoration.replace({ widget: new CheckboxWidget(false) });\n\n/**\n * Checks if cursor is inside text.\n */\nconst editingRange = (state: EditorState, range: { from: number; to: number }, focus: boolean) => {\n const {\n readOnly,\n selection: {\n main: { head },\n },\n } = state;\n return focus && !readOnly && head >= range.from && head <= range.to;\n};\n\nconst autoHideTags = new Set([\n 'CodeMark',\n 'CodeInfo',\n 'EmphasisMark',\n 'StrikethroughMark',\n 'SubscriptMark',\n 'SuperscriptMark',\n]);\n\n/**\n * Markdown list level.\n */\ntype NumberingLevel = { type: string; from: number; to: number; level: number; number: number };\n\nconst buildDecorations = (view: EditorView, options: DecorateOptions, focus: boolean) => {\n const decoRanges: { from: number; to: number; deco: Decoration }[] = [];\n const atomicDecoRanges: { from: number; to: number; deco: Decoration }[] = [];\n const { state } = view;\n\n // Header numbering.\n // TODO(burdon): Pre-parse headers to allow virtualization.\n const headerLevels: (NumberingLevel | null)[] = [];\n const getHeaderLevels = (node: SyntaxNodeRef, level: number): (NumberingLevel | null)[] => {\n invariant(level > 0);\n if (level > headerLevels.length) {\n const len = headerLevels.length;\n headerLevels.length = level;\n headerLevels.fill(null, len);\n headerLevels[level - 1] = { type: node.name, from: node.from, to: node.to, level, number: 0 };\n } else {\n headerLevels.splice(level);\n }\n\n return headerLevels.slice(0, level);\n };\n\n // List numbering and indentation.\n const listLevels: NumberingLevel[] = [];\n const enterList = (node: SyntaxNodeRef) => {\n listLevels.push({ type: node.name, from: node.from, to: node.to, level: listLevels.length, number: 0 });\n };\n const leaveList = () => {\n listLevels.pop();\n };\n const getCurrentListLevel = (): NumberingLevel => {\n invariant(listLevels.length);\n return listLevels[listLevels.length - 1];\n };\n\n // let count = 0;\n const enterNode = (node: SyntaxNodeRef) => {\n // console.log(`[${count++}]`, { node: node.name, from: node.from, to: node.to });\n switch (node.name) {\n // ATXHeading > HeaderMark > Paragraph\n // NOTE: Numbering requires processing the entire document since otherwise only the visible range will be\n // processed and the numbering will be incorrect.\n case 'ATXHeading1':\n case 'ATXHeading2':\n case 'ATXHeading3':\n case 'ATXHeading4':\n case 'ATXHeading5':\n case 'ATXHeading6': {\n const level = parseInt(node.name['ATXHeading'.length]) as HeadingLevel;\n const headers = getHeaderLevels(node, level);\n if (options.numberedHeadings?.from !== undefined) {\n const header = headers[level - 1];\n // TODO(burdon): Header will be missing if headers are out of order (e.g., ## header then # header).\n if (header) {\n header.number++;\n }\n }\n\n const editing = editingRange(state, node, focus);\n if (editing) {\n break;\n }\n\n const mark = node.node.firstChild!;\n if (mark?.name === 'HeaderMark') {\n const { from, to = 6 } = options.numberedHeadings ?? {};\n const text = state.sliceDoc(node.from, node.to);\n const len = text.match(/[#\\s]+/)![0].length;\n if (!from || level < from || level > to) {\n atomicDecoRanges.push({ from: mark.from, to: mark.from + len, deco: hide });\n } else {\n // TODO(burdon): Number format/style.\n const num =\n headers\n .slice(from - 1)\n .map((level) => level?.number ?? 0)\n .join('.') + '). ';\n\n if (num.length) {\n atomicDecoRanges.push({\n from: mark.from,\n to: mark.from + len,\n deco: Decoration.replace({\n widget: new TextWidget(num, markdownTheme.heading(level).className),\n }),\n });\n }\n }\n }\n\n return false;\n }\n\n //\n // Lists.\n // [BulletList | OrderedList] > (ListItem > ListMark) > (Task > TaskMarker)?\n //\n\n case 'BulletList':\n case 'OrderedList': {\n enterList(node);\n break;\n }\n\n case 'ListItem': {\n const line = state.doc.lineAt(node.from);\n\n // Set indentation.\n const list = getCurrentListLevel();\n const width = list.type === 'OrderedList' ? orderedListIndentationWidth : bulletListIndentationWidth;\n const offset = (options?.listPaddingLeft ?? 0) + ((list.level ?? 0) + 1) * width;\n if (node.from === line.to - 1) {\n // Abort if only the hyphen is typed.\n return false;\n }\n\n // Add line decoration for the continuation indent.\n // TODO(burdon): Bug if indentation is more than one indentation unit (e.g., 4 spaces) from the previous line.\n decoRanges.push({\n from: line.from,\n to: line.from,\n deco: Decoration.line({\n class: 'cm-list-item',\n attributes: {\n style: `padding-left: ${offset}px; text-indent: -${width}px;`,\n },\n }),\n });\n\n break;\n }\n\n case 'ListMark': {\n const list = getCurrentListLevel();\n\n // Look-ahead for task marker.\n // NOTE: Requires space to exist (otherwise the text is parsed as the start of a link).\n const next = tree.resolve(node.to + 1, 1);\n if (next?.name === 'TaskMarker') {\n break;\n }\n\n // TODO(burdon): Option to make hierarchical; or a), i), etc.\n const label = list.type === 'OrderedList' ? `${++list.number}.` : Unicode.bulletSmall;\n const line = state.doc.lineAt(node.from);\n const to = state.doc.sliceString(node.to, node.to + 1) === ' ' ? node.to + 1 : node.to;\n atomicDecoRanges.push({\n from: line.from,\n to,\n deco: Decoration.replace({\n widget: new TextWidget(\n label,\n list.type === 'OrderedList' ? 'cm-list-mark cm-list-mark-ordered' : 'cm-list-mark cm-list-mark-bullet',\n ),\n }),\n });\n break;\n }\n\n case 'TaskMarker': {\n const checked = state.doc.sliceString(node.from + 1, node.to - 1) === 'x';\n // Check if the next character is a space and if so, include it in the replacement.\n const line = state.doc.lineAt(node.from);\n const to = state.doc.sliceString(node.to, node.to + 1) === ' ' ? node.to + 1 : node.to;\n atomicDecoRanges.push({ from: line.from, to, deco: checked ? checkedTask : uncheckedTask });\n break;\n }\n\n //\n // Blockquote > QuoteMark > Paragraph\n //\n\n case 'Blockquote': {\n const editing = editingRange(state, node, focus);\n const quoteMark = node.node.getChild('QuoteMark');\n const paragraph = node.node.getChild('Paragraph');\n if (!editing && quoteMark && paragraph) {\n atomicDecoRanges.push({ from: quoteMark.from, to: paragraph.from, deco: hide });\n }\n\n for (const block of view.viewportLineBlocks) {\n if (block.to < node.from) {\n continue;\n }\n if (block.from > node.to) {\n break;\n }\n\n decoRanges.push({ from: block.from, to: block.from, deco: blockQuote });\n }\n\n break;\n }\n\n //\n // CommentBlock\n //\n\n case 'CommentBlock': {\n const editing = editingRange(state, node, focus);\n for (const block of view.viewportLineBlocks) {\n if (block.to < node.from) {\n continue;\n }\n if (block.from > node.to) {\n break;\n }\n\n const isFirst = block.from <= node.from;\n const isLast = block.to >= node.to && /^(\\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));\n\n decoRanges.push({\n from: block.from,\n to: block.from,\n deco: isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine,\n });\n\n if (!editing && (isFirst || isLast)) {\n atomicDecoRanges.push({ from: block.from, to: block.to, deco: hide });\n }\n }\n break;\n }\n\n //\n // FencedCode > CodeMark > [CodeInfo] > CodeText > CodeMark\n //\n\n case 'FencedCode': {\n for (const block of view.viewportLineBlocks) {\n if (block.to < node.from) {\n continue;\n }\n if (block.from > node.to) {\n break;\n }\n\n const first = block.from <= node.from;\n const last = block.to >= node.to && /```$/.test(state.doc.sliceString(block.from, block.to));\n decoRanges.push({\n from: block.from,\n to: block.from,\n deco: first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine,\n });\n\n const editing = editingRange(state, node, focus);\n if (!editing && (first || last)) {\n atomicDecoRanges.push({ from: block.from, to: block.to, deco: hide });\n }\n }\n return false;\n }\n\n //\n // Link > [LinkMark, URL]\n //\n\n case 'Link': {\n const marks = node.node.getChildren('LinkMark');\n const urlNode = node.node.getChild('URL');\n const editing = editingRange(state, node, focus);\n if (urlNode && marks.length >= 2) {\n const url = state.sliceDoc(urlNode.from, urlNode.to);\n if (options.skip?.({ name: 'Link', url })) {\n break;\n }\n if (!editing) {\n atomicDecoRanges.push({ from: node.from, to: marks[0].to, deco: hide });\n }\n\n decoRanges.push({\n from: marks[0].to,\n to: !editing && options.renderLinkButton ? node.to : marks[1].from,\n deco: Decoration.mark({\n tagName: 'a',\n attributes: {\n class: options.renderLinkButton ? 'cm-link cm-link-with-button' : 'cm-link',\n href: url,\n rel: 'noreferrer',\n target: '_blank',\n },\n }),\n });\n\n if (!editing) {\n atomicDecoRanges.push({\n from: marks[1].from,\n to: node.to,\n deco: options.renderLinkButton\n ? Decoration.replace({\n widget: new LinkButton(url, options.renderLinkButton),\n })\n : hide,\n });\n }\n }\n break;\n }\n\n //\n // HR\n //\n\n case 'HorizontalRule': {\n if (!editingRange(state, node, focus)) {\n decoRanges.push({ from: node.from, to: node.to, deco: horizontalRule });\n }\n break;\n }\n\n default: {\n if (autoHideTags.has(node.name)) {\n if (!editingRange(state, node.node.parent!, focus)) {\n atomicDecoRanges.push({ from: node.from, to: node.to, deco: hide });\n }\n }\n }\n }\n };\n\n const leaveNode = (node: SyntaxNodeRef) => {\n switch (node.name) {\n case 'BulletList':\n case 'OrderedList': {\n leaveList();\n break;\n }\n }\n };\n\n const tree = syntaxTree(state);\n if (options.numberedHeadings?.from === undefined) {\n for (const { from, to } of view.visibleRanges) {\n tree.iterate({\n from,\n to,\n enter: wrapWithCatch(enterNode, 'decorate.enter'),\n leave: wrapWithCatch(leaveNode, 'decorate.leave'),\n });\n }\n } else {\n // NOTE: If line numbering then we must iterate from the start of document.\n tree.iterate({\n enter: wrapWithCatch(enterNode, 'decorate.enter'),\n leave: wrapWithCatch(leaveNode, 'decorate.leave'),\n });\n }\n\n // Sort and build decoration sets.\n const sortRanges = (a: { from: number; to: number }, b: { from: number; to: number }) =>\n a.from - b.from || a.to - b.to;\n\n decoRanges.sort(sortRanges);\n atomicDecoRanges.sort(sortRanges);\n\n const deco = new RangeSetBuilder<Decoration>();\n for (const { from, to, deco: d } of decoRanges) {\n deco.add(from, to, d);\n }\n\n const atomicDeco = new RangeSetBuilder<Decoration>();\n for (const { from, to, deco } of atomicDecoRanges) {\n // Skip replace decorations that span line breaks (not allowed by CodeMirror plugins).\n if (from < to && state.doc.lineAt(from).number !== state.doc.lineAt(to).number) {\n continue;\n }\n atomicDeco.add(from, to, deco);\n }\n\n return {\n deco: deco.finish(),\n atomicDeco: atomicDeco.finish(),\n };\n};\n\nconst forceUpdate = StateEffect.define<null>();\n\nexport type NodeData = { name: 'Link'; url: string } | { name: 'Image'; url: string };\n\nexport interface DecorateOptions {\n /**\n * Prevents triggering decorations as the cursor moves through the document.\n */\n selectionChangeDelay?: number;\n numberedHeadings?: { from: number; to?: number };\n // TODO(burdon): Additional padding for each line.\n listPaddingLeft?: number;\n // TODO(burdon): Use consistently.\n skip?: (node: NodeData) => boolean;\n // TODO(burdon): Remove.\n renderLinkButton?: RenderCallback<{ url: string }>;\n}\n\nexport const decorateMarkdown = (options: DecorateOptions = {}) => {\n return [\n ViewPlugin.fromClass(\n class {\n deco: DecorationSet;\n atomicDeco: DecorationSet;\n pendingUpdate?: NodeJS.Timeout;\n\n constructor(view: EditorView) {\n ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));\n }\n\n update(update: ViewUpdate) {\n if (\n update.docChanged ||\n update.viewportChanged ||\n update.focusChanged ||\n update.transactions.some((tr) => tr.effects.some((effect) => effect.is(forceUpdate))) ||\n (update.selectionSet && !options.selectionChangeDelay)\n ) {\n ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(\n update.view,\n options,\n update.view.hasFocus,\n ));\n\n this.clearUpdate();\n } else if (update.selectionSet) {\n this.scheduleUpdate(update.view);\n }\n }\n\n // Defer update in case moving through the document.\n scheduleUpdate(view: EditorView) {\n this.clearUpdate();\n this.pendingUpdate = setTimeout(() => {\n view.dispatch({ effects: forceUpdate.of(null) });\n }, options.selectionChangeDelay);\n }\n\n clearUpdate() {\n if (this.pendingUpdate) {\n clearTimeout(this.pendingUpdate);\n this.pendingUpdate = undefined;\n }\n }\n\n destroy() {\n this.clearUpdate();\n }\n },\n {\n provide: (plugin) => [\n Prec.low(EditorView.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration.none)),\n EditorView.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration.none),\n EditorView.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration.none),\n ],\n },\n ),\n image(),\n table(),\n adjustChanges(),\n formattingStyles,\n ];\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type ChangeSpec, Transaction } from '@codemirror/state';\nimport { type PluginValue, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\n/**\n * Monitors and augments changes.\n */\n// TODO(burdon): Tests.\nexport const adjustChanges = () => {\n return ViewPlugin.fromClass(\n class implements PluginValue {\n update(update: ViewUpdate) {\n const tree = syntaxTree(update.state);\n const adjustments: ChangeSpec[] = [];\n\n for (const tr of update.transactions) {\n const event = tr.annotation(Transaction.userEvent);\n switch (event) {\n //\n // Enter\n //\n case 'input': {\n const changes = tr.changes;\n if (changes.empty) {\n break;\n }\n\n changes.iterChanges((fromA) => {\n const node = tree.resolveInner(fromA, 1);\n if (node?.name === 'BulletList') {\n // Add space to previous line if an empty list item (otherwise it is not interpreted as a Task).\n const { text } = update.state.doc.lineAt(fromA);\n if (text.endsWith(']')) {\n adjustments.push({ from: fromA, to: fromA, insert: ' ' });\n }\n }\n });\n\n break;\n }\n\n //\n // Paste\n //\n case 'input.paste': {\n const changes = tr.changes;\n if (changes.empty) {\n break;\n }\n\n changes.iterChanges((fromA, toA, fromB, toB, text) => {\n // Check for URL.\n const url = getValidUrl(update.view.state.sliceDoc(fromB, toB));\n if (url) {\n // Check if pasting inside existing link.\n const node = tree.resolveInner(fromA, -1);\n const invalidPositions = new Set(['Code', 'CodeText', 'FencedCode', 'Link', 'LinkMark', 'URL']);\n if (!invalidPositions.has(node?.name)) {\n const replacedText = tr.startState.sliceDoc(fromA, toA);\n adjustments.push({ from: fromA, to: toB, insert: createLink(url, replacedText) });\n }\n } else {\n const node = tree.resolveInner(fromA, 1);\n switch (node?.name) {\n case 'Task': {\n // Remove task marker if pasting into task list.\n const str = text.toString();\n const match = str.match(/\\s*- \\[[ xX]\\]\\s*(.+)/);\n if (match) {\n const [, replacement] = match;\n adjustments.push({ from: fromA, to: toB, insert: replacement });\n }\n break;\n }\n }\n }\n });\n\n break;\n }\n }\n }\n\n // TODO(burdon): Is this the right way to augment changes? Alt: EditorState.transactionFilter\n if (adjustments.length) {\n setTimeout(() => {\n update.view.dispatch(\n update.view.state.update({\n changes: adjustments,\n }),\n );\n });\n }\n }\n },\n );\n};\n\n//\n// Links\n//\n\nexport const createLink = (url: URL, label: string): string => {\n // Check if image.\n // Example: https://dxos.network/dxos-logotype-blue.png\n const { host, pathname } = url;\n const [, extension] = pathname.split('.');\n const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'webp'];\n if (imageExtensions.includes(extension)) {\n return ``;\n }\n\n if (!label) {\n label = createLinkLabel(url);\n }\n\n return `[${label}](${url})`;\n};\n\nexport const createLinkLabel = (url: URL): string => {\n let { protocol, host, pathname } = url;\n if (protocol === 'http:' || protocol === 'https:') {\n protocol = '';\n }\n\n // NOTE(Zan): Consult: https://github.com/dxos/dxos/issues/7331 before changing this.\n // Remove 'www.' if at the beginning of the URL\n host = host.replace(/^www\\./, '');\n\n return [protocol, host].filter(Boolean).join('//') + (pathname !== '/' ? pathname : '');\n};\n\nconst getValidUrl = (str: string): URL | undefined => {\n const validProtocols = ['http:', 'https:', 'mailto:', 'tel:'];\n try {\n const url = new URL(str);\n if (!validProtocols.includes(url.protocol)) {\n return undefined;\n }\n\n return url;\n } catch (_err) {\n return undefined;\n }\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, type Range, StateField, type Transaction } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, WidgetType } from '@codemirror/view';\n\nimport { focusField } from '../focus';\n\nexport type ImageOptions = {};\n\n/**\n * Create image decorations.\n */\nexport const image = (_options: ImageOptions = {}): Extension => {\n return [\n StateField.define<DecorationSet>({\n create: (state) => {\n return Decoration.set(buildDecorations(state, 0, state.doc.length));\n },\n update: (value: DecorationSet, tr: Transaction) => {\n if (!tr.docChanged && !tr.selection) {\n return value;\n }\n\n // Find range of changes and cursor changes.\n const cursor = tr.state.selection.main.head;\n const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);\n let from = Math.min(cursor, oldCursor);\n let to = Math.max(cursor, oldCursor);\n tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {\n from = Math.min(from, fromB);\n to = Math.max(to, toB);\n });\n\n // Expand to cover lines.\n from = tr.state.doc.lineAt(from).from;\n to = tr.state.doc.lineAt(to).to;\n\n return value.map(tr.changes).update({\n filterFrom: from,\n filterTo: to,\n filter: () => false,\n add: buildDecorations(tr.state, from, to),\n });\n },\n provide: (field) => EditorView.decorations.from(field),\n }),\n ];\n};\n\nconst buildDecorations = (state: EditorState, from: number, to: number) => {\n const decorations: Range<Decoration>[] = [];\n const cursor = state.selection.main.head;\n syntaxTree(state).iterate({\n enter: (node) => {\n if (node.name === 'Image') {\n const urlNode = node.node.getChild('URL');\n if (urlNode) {\n const hide = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);\n\n const url = state.sliceDoc(urlNode.from, urlNode.to);\n // Some plugins might be using custom URLs; avoid attempts to render those URLs.\n if (url.match(/^https?:\\/\\//) === null && url.match(/^file?:\\/\\//) === null) {\n return;\n }\n\n preloadImage(url);\n decorations.push(\n Decoration.replace({\n block: true, // Prevent cursor from entering.\n widget: new ImageWidget(url),\n }).range(hide ? node.from : node.to, node.to),\n );\n }\n }\n },\n from,\n to,\n });\n\n return decorations;\n};\n\nconst preloaded = new Set<string>();\n\nconst preloadImage = (url: string) => {\n if (!preloaded.has(url)) {\n const img = document.createElement('img');\n img.src = url;\n preloaded.add(url);\n }\n};\n\nclass ImageWidget extends WidgetType {\n constructor(readonly _url: string) {\n super();\n }\n\n override eq(other: this) {\n return this._url === other._url;\n }\n\n override toDOM(view: EditorView) {\n const img = document.createElement('img');\n img.setAttribute('src', this._url);\n img.setAttribute('class', 'cm-image');\n // If focused, hide image until successfully loaded to avoid flickering effects.\n if (view.state.field(focusField)) {\n img.onload = () => img.classList.add('cm-loaded-image');\n } else {\n img.classList.add('cm-loaded-image');\n }\n\n return img;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { EditorView } from '@codemirror/view';\n\nimport { fontMono } from '../../styles';\n\nexport const bulletListIndentationWidth = 24;\nexport const orderedListIndentationWidth = 36; // TODO(burdon): Make variable length based on number of digits.\n\nexport const formattingStyles = EditorView.theme({\n /**\n * Horizontal rule.\n */\n '& .cm-hr': {\n display: 'inline-block',\n width: '100%',\n height: '0',\n verticalAlign: 'middle',\n borderTop: '1px solid var(--color-cm-separator)',\n opacity: 0.5,\n },\n\n /**\n * Lists.\n */\n '& .cm-list-item': {},\n '& .cm-list-mark': {\n display: 'inline-block',\n textAlign: 'right',\n paddingRight: '0.5em',\n fontVariant: 'tabular-nums',\n },\n '& .cm-list-mark-bullet': {\n width: `${bulletListIndentationWidth}px`,\n },\n '& .cm-list-mark-ordered': {\n width: `${orderedListIndentationWidth}px`,\n },\n\n /**\n * Blockquote.\n */\n '& .cm-blockquote': {\n background: 'var(--color-cm-codeblock)',\n borderLeft: '2px solid var(--color-cm-separator)',\n paddingLeft: '1rem',\n margin: 0,\n },\n\n /**\n * Code and codeblocks.\n */\n '& code': {\n fontFamily: fontMono,\n color: 'var(--color-cm-code)',\n whiteSpace: 'nowrap',\n },\n '& .cm-code': {\n fontFamily: fontMono,\n color: 'var(--color-cm-code)',\n },\n // Inline code spans (triggered by backticks) use `cm-code-inline` + `font-mono`.\n // Different monospace font metrics can slightly overflow the fixed CodeMirror line box,\n // so constrain them to the target 24px height.\n '& .cm-code-inline': {\n fontFamily: fontMono,\n height: '24px',\n // display: 'inline-flex',\n alignItems: 'center',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n color: 'var(--color-cm-code-inline)',\n },\n '& .cm-code-mark': {\n fontFamily: fontMono,\n height: '24px',\n display: 'inline-flex',\n alignItems: 'center',\n overflow: 'hidden',\n },\n '& .cm-codeblock-line': {\n background: 'var(--color-cm-codeblock)',\n paddingInline: '1rem !important',\n },\n '& .cm-codeblock-start': {\n borderTopLeftRadius: '.25rem',\n borderTopRightRadius: '.25rem',\n },\n '& .cm-codeblock-end': {\n borderBottomLeftRadius: '.25rem',\n borderBottomRightRadius: '.25rem',\n },\n\n /**\n * Task list.\n */\n '& .cm-task': {\n display: 'inline-flex',\n width: `${bulletListIndentationWidth}px`,\n height: '20px',\n },\n '& .cm-task-checkbox': {\n display: 'grid',\n margin: '0',\n transform: 'translateY(2px)',\n },\n\n /**\n * Table.\n */\n '.cm-table *': {\n fontFamily: fontMono,\n lineHeight: 1.5,\n textDecoration: 'none !important',\n },\n '.cm-table-head': {\n padding: '2px 16px 2px 0px',\n overflowWrap: 'break-word',\n whiteSpace: 'pre-wrap',\n wordBreak: 'keep-all',\n textAlign: 'left',\n color: 'var(--color-subdued)',\n borderBottom: '1px solid var(--color-cm-separator)',\n },\n '.cm-table-cell': {\n padding: '2px 16px 2px 0px',\n overflowWrap: 'break-word',\n whiteSpace: 'pre-wrap',\n wordBreak: 'keep-all',\n verticalAlign: 'top',\n },\n\n /**\n * Image.\n */\n '.cm-image': {\n display: 'block',\n height: '0',\n },\n '.cm-image.cm-loaded-image': {\n height: 'auto',\n borderTop: '0.5rem solid transparent',\n borderBottom: '0.5rem solid transparent',\n },\n '.cm-image-with-loader': {\n display: 'block',\n opacity: 0,\n transitionDuration: '350ms',\n transitionProperty: 'opacity',\n },\n '.cm-image-with-loader.cm-loaded-image': {\n opacity: 1,\n },\n '.cm-image-wrapper': {\n 'grid-template-columns': '1fr',\n display: 'grid',\n margin: '0.5rem 0',\n overflow: 'hidden',\n transitionDuration: '350ms',\n transitionProperty: 'height',\n '& > *': {\n 'grid-row-start': 1,\n 'grid-column-start': 1,\n },\n },\n});\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport {\n type EditorState,\n type Extension,\n type RangeSet,\n RangeSetBuilder,\n StateField,\n type Transaction,\n} from '@codemirror/state';\nimport { Decoration, EditorView, WidgetType } from '@codemirror/view';\n\n// TODO(burdon): Snippet to create basic table.\n// https://codemirror.net/docs/ref/#autocomplete.snippet\n// TODO(burdon): Advanced formatting (left/right/center).\n// TODO(burdon): Editor to auto balance columns.\n\nexport type TableOptions = {};\n\n/**\n * GFM tables.\n * https://github.github.com/gfm/#tables-extension\n */\nexport const table = (options: TableOptions = {}): Extension => {\n return StateField.define<RangeSet<Decoration>>({\n create: (state) => update(state, options),\n update: (_: RangeSet<Decoration>, tr: Transaction) => update(tr.state, options),\n provide: (field) => EditorView.decorations.from(field),\n });\n};\n\ntype Table = {\n from: number;\n to: number;\n header?: string[];\n rows?: string[][];\n};\n\nconst update = (state: EditorState, _options: TableOptions) => {\n const builder = new RangeSetBuilder<Decoration>();\n const cursor = state.selection.main.head;\n\n const tables: Table[] = [];\n const getTable = () => tables[tables.length - 1];\n const getRow = () => {\n const table = getTable();\n return table.rows?.[table.rows.length - 1];\n };\n\n // Parse table.\n syntaxTree(state).iterate({\n enter: (node) => {\n // Check if cursor is inside text.\n switch (node.name) {\n case 'Table': {\n tables.push({ from: node.from, to: node.to });\n break;\n }\n case 'TableHeader': {\n getTable().header = [];\n break;\n }\n case 'TableRow': {\n (getTable().rows ??= []).push([]);\n break;\n }\n case 'TableCell': {\n const row = getRow();\n if (row) {\n row.push(state.sliceDoc(node.from, node.to));\n } else {\n getTable().header?.push(state.sliceDoc(node.from, node.to));\n }\n break;\n }\n }\n },\n });\n\n tables.forEach((table) => {\n const replace = state.readOnly || cursor < table.from || cursor > table.to;\n if (replace) {\n builder.add(\n table.from,\n table.to,\n Decoration.replace({\n block: true,\n widget: new TableWidget(table),\n }),\n );\n } else {\n // Add class for styling.\n // TODO(burdon): Apply to each line?\n builder.add(\n table.from,\n table.to,\n Decoration.mark({\n class: 'cm-table',\n }),\n );\n }\n });\n\n return builder.finish();\n};\n\n/** Renders cell text into el, processing inline markdown (bold, italic, code). */\nconst renderCellContent = (el: HTMLElement, text: string): void => {\n const parts = text.split(/(`[^`\\n]+`|\\*\\*[^*\\n]+\\*\\*|__[^_\\n]+__|\\*[^*\\n]+\\*|_[^_\\n]+_)/);\n for (const part of parts) {\n if (part.length > 2 && part.startsWith('`') && part.endsWith('`')) {\n const code = document.createElement('code');\n code.textContent = part.slice(1, -1);\n el.appendChild(code);\n } else if ((part.startsWith('**') && part.endsWith('**')) || (part.startsWith('__') && part.endsWith('__'))) {\n const strong = document.createElement('strong');\n strong.textContent = part.slice(2, -2);\n el.appendChild(strong);\n } else if ((part.startsWith('*') && part.endsWith('*')) || (part.startsWith('_') && part.endsWith('_'))) {\n const em = document.createElement('em');\n em.textContent = part.slice(1, -1);\n el.appendChild(em);\n } else {\n el.appendChild(document.createTextNode(part));\n }\n }\n};\n\nclass TableWidget extends WidgetType {\n constructor(readonly _table: Table) {\n super();\n }\n\n override eq(other: this) {\n return (\n this._table.header?.join() === other._table.header?.join() &&\n this._table.rows?.join() === other._table.rows?.join()\n );\n }\n\n override ignoreEvent(e: Event): boolean {\n return !/^mouse/.test(e.type);\n }\n\n override toDOM(_view: EditorView) {\n const div = document.createElement('div');\n const table = div.appendChild(document.createElement('table'));\n\n const header = table.appendChild(document.createElement('thead'));\n const tr = header.appendChild(document.createElement('tr'));\n this._table.header?.forEach((cell) => {\n const th = document.createElement('th');\n th.setAttribute('class', 'cm-table-head');\n renderCellContent(tr.appendChild(th), cell);\n });\n\n const body = table.appendChild(document.createElement('tbody'));\n this._table.rows?.forEach((row) => {\n const tr = body.appendChild(document.createElement('tr'));\n row.forEach((cell) => {\n const td = document.createElement('td');\n td.setAttribute('class', 'cm-table-cell');\n renderCellContent(tr.appendChild(td), cell);\n });\n });\n\n return div;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n// Copyright CodeMirror\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { hoverTooltip } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\n\nimport { tooltipContent } from '@dxos/ui-theme';\n\nimport { type RenderCallback } from '../../types';\n\nexport const linkTooltip = (renderTooltip: RenderCallback<{ url: string }>) => {\n return hoverTooltip((view, pos, side) => {\n const syntax = syntaxTree(view.state).resolveInner(pos, side);\n let link = null;\n for (let i = 0, node: SyntaxNode | null = syntax; !link && node && i < 5; node = node.parent, i++) {\n link = node.name === 'Link' ? node : null;\n }\n\n const url = link && link.getChild('URL');\n if (!url || !link) {\n return null;\n }\n\n const urlText = view.state.sliceDoc(url.from, url.to);\n if (urlText.startsWith('dxn')) {\n return null;\n }\n\n return {\n pos: link.from,\n end: link.to,\n above: true,\n create: () => {\n const el = document.createElement('div');\n el.className = tooltipContent({});\n renderTooltip(el, { url: urlText }, view);\n return { dom: el, offset: { x: 0, y: 4 } };\n },\n };\n });\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type CompletionContext, type CompletionResult, autocompletion } from '@codemirror/autocomplete';\nimport type { Extension } from '@codemirror/state';\n\nimport { log } from '@dxos/log';\n\nexport type MentionOptions = {\n debug?: boolean;\n onSearch: (text: string) => string[];\n};\n\n// TODO(burdon): Can only have a single autocompletion. Merge configuration with autocomplete.\nexport const mention = ({ debug, onSearch }: MentionOptions): Extension => {\n return autocompletion({\n // TODO(burdon): Not working.\n activateOnTyping: true,\n // activateOnTypingDelay: 100,\n // selectOnOpen: true,\n closeOnBlur: !debug,\n // defaultKeymap: false,\n icons: false,\n override: [\n (context: CompletionContext): CompletionResult | null => {\n log.info('completion context', { context });\n\n const match = context.matchBefore(/@(\\w+)?/);\n if (!match || (match.from === match.to && !context.explicit)) {\n return null;\n }\n\n return {\n from: match.from,\n options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({ label: `@${value}` })),\n };\n },\n ],\n });\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { StateEffect, StateField } from '@codemirror/state';\n\nexport const modalStateEffect = StateEffect.define<boolean>();\n\n/**\n * Determines if a modal dialog (e.g., popover) is active.\n */\nexport const modalStateField = StateField.define<boolean>({\n create: () => false,\n update: (value, tr) => {\n let newValue = value;\n for (const effect of tr.effects) {\n if (effect.is(modalStateEffect)) {\n newValue = effect.value;\n }\n }\n\n return newValue;\n },\n});\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\nimport { vim } from '@replit/codemirror-vim';\nimport { vscodeKeymap } from '@replit/codemirror-vscode-keymap';\n\nimport { singleValueFacet } from '../util';\n\nexport type EditorInputConfig = {\n type?: string;\n ignoreEscape?: boolean;\n};\n\nexport const editorInputMode = singleValueFacet<EditorInputConfig>({});\n\nexport const InputModeExtensions: { [mode: string]: Extension } = {\n default: [],\n vscode: [\n // https://github.com/replit/codemirror-vscode-keymap\n editorInputMode.of({ type: 'vscode' }),\n keymap.of(vscodeKeymap),\n ],\n vim: [\n // https://github.com/replit/codemirror-vim\n vim(),\n editorInputMode.of({ type: 'vim', ignoreEscape: true }),\n keymap.of([\n {\n key: 'Alt-Escape',\n run: (view) => {\n // Focus container for tab navigation.\n view.dom.parentElement?.focus();\n return true;\n },\n },\n ]),\n ],\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { indentMore } from '@codemirror/commands';\nimport { getIndentUnit } from '@codemirror/language';\nimport { type ChangeSpec, EditorSelection, type Extension } from '@codemirror/state';\nimport { type Command, type EditorView, keymap } from '@codemirror/view';\n\nimport { getSelection, selectAll, selectDown, selectNone, selectUp } from './selection';\nimport { getRange, treeFacet } from './tree';\n\n//\n// Indentation comnmands.\n//\n\nexport const indentItemMore: Command = (view: EditorView) => {\n const pos = getSelection(view.state).from;\n const tree = view.state.facet(treeFacet);\n const current = tree.find(pos);\n if (current) {\n const previous = tree.prev(current);\n if (previous && current.level <= previous.level) {\n // TODO(burdon): Indent descendants?\n indentMore(view);\n }\n }\n\n return true;\n};\n\nexport const indentItemLess: Command = (view: EditorView) => {\n const pos = getSelection(view.state).from;\n const tree = view.state.facet(treeFacet);\n const current = tree.find(pos);\n if (current) {\n if (current.level > 0) {\n // Unindent current line and all descendants.\n // NOTE: The markdown extension doesn't provide an indentation service.\n const indentUnit = getIndentUnit(view.state);\n const changes: ChangeSpec[] = [];\n tree.traverse(current, (item) => {\n const line = view.state.doc.lineAt(item.lineRange.from);\n changes.push({ from: line.from, to: line.from + indentUnit });\n });\n\n if (changes.length > 0) {\n view.dispatch({ changes });\n }\n }\n }\n\n return true;\n};\n\n//\n// Moving commands.\n//\n\nexport const moveItemDown: Command = (view: EditorView) => {\n const pos = getSelection(view.state)?.from;\n const tree = view.state.facet(treeFacet);\n const current = tree.find(pos);\n if (current && current.nextSibling) {\n const next = current.nextSibling;\n const currentContent = view.state.doc.sliceString(...getRange(tree, current));\n const nextContent = view.state.doc.sliceString(...getRange(tree, next));\n const changes: ChangeSpec[] = [\n {\n from: current.lineRange.from,\n to: current.lineRange.from + currentContent.length,\n insert: nextContent,\n },\n {\n from: next.lineRange.from,\n to: next.lineRange.from + nextContent.length,\n insert: currentContent,\n },\n ];\n\n view.dispatch({\n changes,\n selection: EditorSelection.cursor(pos + nextContent.length + 1),\n scrollIntoView: true,\n });\n }\n\n return true;\n};\n\nexport const moveItemUp: Command = (view: EditorView) => {\n const pos = getSelection(view.state)?.from;\n const tree = view.state.facet(treeFacet);\n const current = tree.find(pos);\n if (current && current.prevSibling) {\n const prev = current.prevSibling;\n const currentContent = view.state.doc.sliceString(...getRange(tree, current));\n const prevContent = view.state.doc.sliceString(...getRange(tree, prev));\n const changes: ChangeSpec[] = [\n {\n from: prev.lineRange.from,\n to: prev.lineRange.from + prevContent.length,\n insert: currentContent,\n },\n {\n from: current.lineRange.from,\n to: current.lineRange.from + currentContent.length,\n insert: prevContent,\n },\n ];\n\n view.dispatch({\n changes,\n selection: EditorSelection.cursor(pos - prevContent.length - 1),\n scrollIntoView: true,\n });\n }\n\n return true;\n};\n\n//\n// Misc commands.\n//\n\nexport const deleteItem: Command = (view: EditorView) => {\n const tree = view.state.facet(treeFacet);\n const pos = getSelection(view.state).from;\n const current = tree.find(pos);\n if (current) {\n view.dispatch({\n selection: EditorSelection.cursor(current.lineRange.from),\n changes: [\n {\n from: current.lineRange.from,\n to: Math.min(current.lineRange.to + 1, view.state.doc.length),\n },\n ],\n });\n }\n\n return true;\n};\n\nexport const toggleTask: Command = (view: EditorView) => {\n const tree = view.state.facet(treeFacet);\n const pos = getSelection(view.state)?.from;\n const current = tree.find(pos);\n if (current) {\n const type = current.type === 'task' ? 'bullet' : 'task';\n const indent = ' '.repeat(getIndentUnit(view.state) * current.level);\n view.dispatch({\n changes: [\n {\n from: current.lineRange.from,\n to: current.contentRange.from,\n insert: indent + (type === 'task' ? '- [ ] ' : '- '),\n },\n ],\n });\n }\n\n return true;\n};\n\nexport const commands = (): Extension =>\n keymap.of([\n //\n // Indentation.\n //\n {\n key: 'Tab',\n preventDefault: true,\n run: indentItemMore,\n shift: indentItemLess,\n },\n\n //\n // Continuation.\n //\n {\n key: 'Enter',\n shift: (view) => {\n const pos = getSelection(view.state).from;\n const insert = '\\n '; // TODO(burdon): Fix parsing.\n view.dispatch({\n changes: [{ from: pos, to: pos, insert }],\n selection: EditorSelection.cursor(pos + insert.length),\n });\n return true;\n },\n },\n\n //\n // Navigation.\n //\n {\n key: 'ArrowDown',\n // Jump to next item (default moves to end of currentline).\n run: (view) => {\n const tree = view.state.facet(treeFacet);\n const item = tree.find(getSelection(view.state).from);\n if (\n item &&\n view.state.doc.lineAt(item.lineRange.to).number - view.state.doc.lineAt(item.lineRange.from).number === 0\n ) {\n const next = tree.next(item);\n if (next) {\n view.dispatch({ selection: EditorSelection.cursor(next.contentRange.from) });\n return true;\n }\n }\n\n return false;\n },\n },\n\n //\n // Line selection.\n // TODO(burdon): Shortcut to select current item?\n //\n {\n key: 'Mod-a',\n preventDefault: true,\n run: selectAll,\n },\n {\n key: 'Escape',\n preventDefault: true,\n run: selectNone,\n },\n {\n key: 'ArrowUp',\n shift: selectUp,\n },\n {\n key: 'ArrowDown',\n shift: selectDown,\n },\n\n //\n // Move.\n //\n {\n key: 'Alt-ArrowDown',\n preventDefault: true,\n run: moveItemDown,\n },\n {\n key: 'Alt-ArrowUp',\n preventDefault: true,\n run: moveItemUp,\n },\n //\n // Delete.\n //\n {\n key: 'Mod-Backspace',\n preventDefault: true,\n run: deleteItem,\n },\n //\n // Misc.\n //\n {\n key: 'Alt-t',\n preventDefault: true,\n run: toggleTask,\n },\n ]);\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Compartment, type EditorState, Facet, type SelectionRange } from '@codemirror/state';\nimport { type Command, type EditorView } from '@codemirror/view';\n\nimport { treeFacet } from './tree';\n\nexport type Selection = number[];\n\nexport const getSelection = (state: EditorState): SelectionRange => state.selection.main;\n\nexport const selectionEquals = (a: number[], b: number[]) => a.length === b.length && a.every((i) => b.includes(i));\n\nexport const selectionFacet = Facet.define<Selection, Selection>({\n combine: (values) => values[0],\n});\n\nexport const selectionCompartment = new Compartment();\n\nexport const selectNone: Command = (view: EditorView) => {\n view.dispatch({\n effects: selectionCompartment.reconfigure(selectionFacet.of([])),\n });\n\n return true;\n};\n\nexport const selectAll: Command = (view: EditorView) => {\n const tree = view.state.facet(treeFacet);\n const selection = view.state.facet(selectionFacet);\n const items: Selection = [];\n tree.traverse((item) => items.push(item.index));\n view.dispatch({\n effects: selectionCompartment.reconfigure(selectionFacet.of(selectionEquals(selection, items) ? [] : items)),\n });\n\n return true;\n};\n\n// TODO(burdon): Implement.\nexport const selectUp: Command = (view: EditorView) => {\n return true;\n};\n\n// TODO(burdon): Implement.\nexport const selectDown: Command = (view: EditorView) => {\n return true;\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, StateField, type Transaction } from '@codemirror/state';\nimport { Facet } from '@codemirror/state';\nimport { type SyntaxNode } from '@lezer/common';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { type Range } from '../../types';\n\n/**\n * Represents a single item in the tree.\n */\nexport interface Item {\n type: 'root' | 'bullet' | 'task' | 'unknown';\n index: number;\n level: number;\n node: SyntaxNode;\n parent?: Item;\n nextSibling?: Item;\n prevSibling?: Item;\n children: Item[];\n /**\n * Actual range.\n * Starts at the start of the line containing the item and ends at the end of the line before the\n * first child or next sibling.\n */\n lineRange: Range;\n /**\n * Range of the editable content.\n * This doesn't include the list or task marker or indentation.\n */\n contentRange: Range;\n}\n\nexport const itemToJSON = ({ type, index, level, lineRange, contentRange, children }: Item): any => {\n return { type, index, level, lineRange, contentRange, children: children.map(itemToJSON) };\n};\n\n/**\n * Tree assumes the entire document is a single contiguous well-formed hierarchy of markdown LiteItem nodes.\n */\nexport class Tree implements Item {\n type: Item['type'] = 'root';\n index = -1;\n level = -1;\n node: Item['node'];\n lineRange: Item['lineRange'];\n contentRange: Item['contentRange'];\n children: Item['children'] = [];\n\n constructor(node: SyntaxNode) {\n this.node = node;\n this.lineRange = { from: node.from, to: node.to };\n this.contentRange = this.lineRange;\n }\n\n toJSON() {\n return itemToJSON(this);\n }\n\n get root(): Item {\n return this;\n }\n\n traverse<T = any>(cb: (item: Item, level: number) => T | void): T | undefined;\n traverse<T = any>(item: Item, cb: (item: Item, level: number) => T | void): T | undefined;\n traverse<T = any>(\n itemOrCb: Item | ((item: Item, level: number) => T | undefined | void),\n maybeCb?: (item: Item, level: number) => T | undefined | void,\n ): T | undefined {\n if (typeof itemOrCb === 'function') {\n return traverse<T>(this, itemOrCb);\n } else {\n return traverse<T>(itemOrCb, maybeCb!);\n }\n }\n\n /**\n * Return the closest item.\n */\n find(pos: number): Item | undefined {\n return this.traverse<Item>((item) => (item.lineRange.from <= pos && item.lineRange.to >= pos ? item : undefined));\n }\n\n /**\n * Return the first child, next sibling, or parent's next sibling.\n */\n next(item: Item, enter = true): Item | undefined {\n if (enter && item.children.length > 0) {\n return item.children[0];\n }\n\n if (item.nextSibling) {\n return item.nextSibling;\n }\n\n if (item.parent) {\n return this.next(item.parent, false);\n }\n\n return undefined;\n }\n\n /**\n * Return the previous sibling, or parent.\n */\n prev(item: Item): Item | undefined {\n if (item.prevSibling) {\n return this.lastDescendant(item.prevSibling);\n }\n\n return item.parent?.type === 'root' ? undefined : item.parent;\n }\n\n /**\n * Return the last descendant of the item, or the item itself if it has no children.\n */\n lastDescendant(item: Item): Item {\n return item.children.length > 0 ? this.lastDescendant(item.children.at(-1)!) : item;\n }\n}\n\nexport const getRange = (tree: Tree, item: Item): [number, number] => {\n const lastDescendant = tree.lastDescendant(item);\n return [item.lineRange.from, lastDescendant.lineRange.to];\n};\n\n/**\n * Traverse the tree, calling the callback for each item.\n * If the callback returns a value, the traversal is stopped and the value is returned.\n */\nexport const traverse = <T = any>(root: Item, cb: (item: Item, level: number) => T | void): T | undefined => {\n const t = (item: Item, level: number): T | undefined => {\n if (item.type !== 'root') {\n const value = cb(item, level);\n if (value != null) {\n return value;\n }\n }\n\n for (const child of item.children) {\n const value = t(child, level + 1);\n if (value != null) {\n return value;\n }\n }\n\n return undefined;\n };\n\n return t(root, root.type === 'root' ? -1 : 0);\n};\n\nexport const getListItemContent = (state: EditorState, item: Item): string => {\n return state.doc.sliceString(item.contentRange.from, item.contentRange.to);\n};\n\nexport const listItemToString = (item: Item, level = 0) => {\n const indent = ' '.repeat(level);\n const data = {\n i: item.index,\n n: item.nextSibling?.index ?? '∅',\n p: item.prevSibling?.index ?? '∅',\n level: item.level,\n node: format([item.node.from, item.node.to]),\n line: format([item.lineRange.from, item.lineRange.to]),\n content: format([item.contentRange.from, item.contentRange.to]),\n };\n\n return `${indent}${item.type[0].toUpperCase()}(${Object.entries(data)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ')})`;\n};\n\nconst format = (value: any) =>\n JSON.stringify(value, (key: string, value: any) => {\n if (typeof value === 'number') {\n return value.toString().padStart(3, ' ');\n }\n return value;\n }).replaceAll('\"', '');\n\nexport const treeFacet = Facet.define<Tree, Tree>({\n combine: (values) => values[0],\n});\n\nexport type TreeOptions = {};\n\n/**\n * Creates a shadow tree of `ListItem` nodes whenever the document changes.\n * This adds overhead relative to the markdown AST, but allows for efficient traversal of the list items.\n * NOTE: Requires markdown parser to be enabled.\n */\nexport const outlinerTree = (_options: TreeOptions = {}): Extension => {\n const buildTree = (state: EditorState): Tree => {\n let tree: Tree | undefined;\n let parent: Item | undefined;\n let current: Item | undefined;\n let prev: Item | undefined;\n let level = -1;\n let index = -1;\n\n // Array to track previous siblings at each level.\n const prevSiblings: (Item | undefined)[] = [];\n\n syntaxTree(state).iterate({\n enter: (node) => {\n switch (node.name) {\n case 'Document': {\n tree = new Tree(node.node);\n current = tree;\n break;\n }\n case 'BulletList': {\n invariant(current);\n parent = current;\n if (current) {\n current.lineRange.to = current.node.from;\n }\n prevSiblings[++level] = undefined;\n break;\n }\n case 'ListItem': {\n invariant(parent);\n\n // Include all content up to the next sibling or the end of the document.\n const nextSibling = node.node.nextSibling ?? node.node.parent?.nextSibling;\n const docRange: Range = {\n from: state.doc.lineAt(node.from).from,\n to: nextSibling ? nextSibling.from - 1 : state.doc.length,\n };\n\n current = {\n type: 'unknown',\n index: ++index,\n level,\n node: node.node,\n lineRange: docRange,\n contentRange: { ...docRange },\n parent,\n prevSibling: prevSiblings[level],\n children: [],\n };\n\n // Update sibling refs.\n if (current.prevSibling) {\n current.prevSibling.nextSibling = current;\n }\n\n // Update previous siblings array at current level.\n prevSiblings[level] = current;\n\n // Update previous item (not sibling).\n if (prev) {\n prev.lineRange.to = prev.contentRange.to = current.lineRange.from - 1;\n }\n prev = current;\n\n // Update parent.\n parent.children.push(current);\n if (parent.lineRange.to === parent.node.from) {\n parent.lineRange.to = parent.contentRange.to = current.lineRange.from - 1;\n }\n\n break;\n }\n case 'ListMark': {\n invariant(current);\n current.type = 'bullet';\n current.contentRange.from = node.from + '- '.length;\n break;\n }\n case 'Task': {\n invariant(current);\n current.type = 'task';\n break;\n }\n case 'TaskMarker': {\n invariant(current);\n current.contentRange.from = node.from + '[ ] '.length;\n break;\n }\n }\n },\n leave: (node) => {\n if (node.name === 'BulletList') {\n invariant(parent);\n prevSiblings[level--] = undefined;\n parent = parent.parent;\n }\n },\n });\n\n invariant(tree);\n return tree;\n };\n\n return [\n StateField.define<Tree | undefined>({\n create: (state) => {\n return buildTree(state);\n },\n update: (value: Tree | undefined, tr: Transaction) => {\n if (!tr.docChanged) {\n return value;\n }\n\n return buildTree(tr.state);\n },\n provide: (field) => treeFacet.from(field),\n }),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type EditorState, type Extension, Prec, type Range } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\nimport { mx } from '@dxos/ui-theme';\n\nimport { decorateMarkdown } from '../markdown';\nimport { commands } from './commands';\nimport { editor } from './editor';\nimport { menu } from './menu';\nimport { selectionCompartment, selectionEquals, selectionFacet } from './selection';\nimport { outlinerTree, treeFacet } from './tree';\n\n// ISSUES:\n// TODO(burdon): Remove requirement for continuous lines to be indented (so that user's can't accidentally delete them and break the layout).\n// TODO(burdon): Prevent unterminated fenced code from breaking subsequent items (\"firewall\" markdown parsing within each item?)\n// TODO(burdon): What if a different editor \"breaks\" the layout?\n// TODO(burdon): Check Automerge recognizes text that is moved/indented (e.g., concurrent editing item while being moved).\n\n// NEXT:\n// TODO(burdon): Update selection when adding/removing items.\n// TODO(burdon): When selecting across items, select entire items (don't show selection that spans the gaps).\n// TODO(burdon): Handle backspace at start of line (or empty line).\n// TODO(burdon): Convert to task object and insert link (menu button).\n// TODO(burdon): Smart Cut-and-paste.\n// TODO(burdon): DND.\n\nexport type OutlinerProps = {};\n\n/**\n * Outliner extension.\n * - Stores outline as a standard markdown document with task and list markers.\n * - Supports continuation lines and rich formatting (with Shift+Enter).\n * - Constrains editor to outline structure.\n * - Supports smart cut-and-paste.\n */\nexport const outliner = (_options: OutlinerProps = {}): Extension => [\n // Commands.\n Prec.highest(commands()),\n\n // Selection.\n selectionCompartment.of(selectionFacet.of([])),\n\n // State.\n outlinerTree(),\n\n // Filter and possibly modify changes.\n editor(),\n\n // Floating menu.\n menu(),\n\n // Line decorations.\n decorations(),\n\n // Default markdown decorations.\n decorateMarkdown({ listPaddingLeft: 8 }),\n\n // Researve space for menu.\n EditorView.contentAttributes.of({ class: 'w-full !mr-[3rem]' }),\n];\n\n/**\n * Line decorations (for border and selection).\n */\nconst decorations = () => [\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet = Decoration.none;\n constructor(view: EditorView) {\n this.updateDecorations(view.state, view);\n }\n\n update(update: ViewUpdate) {\n const selectionChanged = !selectionEquals(\n update.state.facet(selectionFacet),\n update.startState.facet(selectionFacet),\n );\n\n if (\n update.focusChanged ||\n update.docChanged ||\n update.viewportChanged ||\n update.selectionSet ||\n selectionChanged\n ) {\n this.updateDecorations(update.state, update.view);\n }\n }\n\n private updateDecorations(state: EditorState, { viewport: { from, to }, hasFocus }: EditorView) {\n const selection = state.facet(selectionFacet);\n const tree = state.facet(treeFacet);\n const current = tree.find(state.selection.ranges[state.selection.mainIndex]?.from);\n const doc = state.doc;\n\n const decorations: Range<Decoration>[] = [];\n for (let lineNum = doc.lineAt(from).number; lineNum <= doc.lineAt(to).number; lineNum++) {\n const line = doc.line(lineNum);\n const item = tree.find(line.from);\n if (item) {\n const lineFrom = doc.lineAt(item.contentRange.from);\n const lineTo = doc.lineAt(item.contentRange.to);\n const isSelected = selection.includes(item.index) || item === current;\n decorations.push(\n Decoration.line({\n class: mx(\n 'cm-list-item',\n lineFrom.number === line.number && 'cm-list-item-start',\n lineTo.number === line.number && 'cm-list-item-end',\n isSelected && (hasFocus ? 'cm-list-item-focused' : 'cm-list-item-selected'),\n ),\n }).range(line.from, line.from),\n );\n }\n }\n\n this.decorations = Decoration.set(decorations);\n }\n },\n {\n decorations: (v) => v.decorations,\n },\n ),\n\n // Theme.\n EditorView.theme(\n Object.assign({\n '.cm-list-item': {\n borderLeftWidth: '1px',\n borderRightWidth: '1px',\n paddingLeft: '32px',\n borderColor: 'transparent',\n },\n '.cm-list-item.cm-codeblock-start': {\n borderRadius: '0',\n },\n\n '.cm-list-item-start': {\n borderTopWidth: '1px',\n borderTopLeftRadius: '4px',\n borderTopRightRadius: '4px',\n paddingTop: '4px',\n marginTop: '2px',\n },\n\n '.cm-list-item-end': {\n borderBottomWidth: '1px',\n borderBottomLeftRadius: '4px',\n borderBottomRightRadius: '4px',\n paddingBottom: '4px',\n marginBottom: '2px',\n },\n\n '.cm-list-item-focused': {\n borderColor: 'var(--color-neutral-focus-indicator)',\n },\n '&:focus-within .cm-list-item-selected': {\n borderColor: 'var(--color-separator)',\n },\n }),\n ),\n];\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type ChangeSpec, EditorSelection, EditorState } from '@codemirror/state';\nimport { type EditorView, ViewPlugin } from '@codemirror/view';\n\nimport { log } from '@dxos/log';\n\nimport { getSelection } from './selection';\nimport { treeFacet } from './tree';\n\nconst LIST_ITEM_REGEX = /^\\s*- (\\[ \\]|\\[x\\])? /;\n\n/**\n * Initialize empty document.\n */\nconst initialize = () => {\n return ViewPlugin.fromClass(\n class {\n constructor(view: EditorView) {\n const first = view.state.doc.lineAt(0);\n const text = view.state.sliceDoc(first.from, first.to);\n const match = text.match(LIST_ITEM_REGEX);\n if (!match) {\n setTimeout(() => {\n const insert = '- [ ] ';\n view.dispatch({\n changes: [{ from: 0, to: 0, insert }],\n selection: EditorSelection.cursor(insert.length),\n });\n });\n }\n }\n },\n );\n};\n\n/**\n * Handle cursor movement, selection, and editing.\n */\nexport const editor = () => [\n initialize(),\n\n EditorState.transactionFilter.of((tr) => {\n const tree = tr.state.facet(treeFacet);\n\n //\n // Check cursor is in a valid position.\n //\n if (!tr.docChanged) {\n const current = getSelection(tr.state).from;\n if (current != null) {\n const currentItem = tree.find(current);\n if (!currentItem) {\n return [];\n }\n\n // Check if outside of editable range.\n if (current < currentItem.contentRange.from || current > currentItem.contentRange.to) {\n const prev = getSelection(tr.startState).from;\n const prevItem = prev != null ? tree.find(prev) : undefined;\n if (!prevItem) {\n return [{ selection: EditorSelection.cursor(currentItem.contentRange.from) }];\n } else {\n if (currentItem.index < prevItem.index) {\n // Moving line up.\n return [{ selection: EditorSelection.cursor(currentItem.contentRange.to) }];\n } else if (currentItem.index > prevItem.index) {\n // Moving line down.\n return [{ selection: EditorSelection.cursor(currentItem.contentRange.from) }];\n } else {\n // Moving left.\n if (current < prev) {\n if (currentItem.index === 0) {\n // At start of the list.\n return [];\n } else {\n // Go to previous line.\n return [{ selection: EditorSelection.cursor(currentItem.lineRange.from - 1) }];\n }\n } else {\n // Go to end of line.\n return [{ selection: EditorSelection.cursor(currentItem.contentRange.to) }];\n }\n }\n }\n }\n }\n\n return tr;\n }\n\n //\n // Validate changes that don't break the tree.\n //\n let cancel = false;\n const changes: ChangeSpec[] = [];\n tr.changes.iterChanges((fromA, toA, fromB, toB, insert) => {\n const line = tr.startState.doc.lineAt(fromA);\n const match = line.text.match(LIST_ITEM_REGEX);\n if (match) {\n // Check cursor was in a valid position.\n const startTree = tr.startState.facet(treeFacet);\n const startItem = startTree.find(tr.startState.selection.main.from);\n\n // Check if entire line was deleted (which is ok).\n const deleteLine = fromA === startItem?.lineRange.from && toA === startItem?.lineRange.to + 1;\n if (deleteLine) {\n return;\n }\n\n // if (!deleteLine && (!startItem || fromA < startItem.contentRange.from || toA > startItem.contentRange.to)) {\n // cancel = true;\n // return;\n // }\n\n // Check valid item.\n const currentItem = tree.find(tr.state.selection.main.from);\n if (!currentItem?.contentRange) {\n cancel = true;\n return;\n }\n\n // Detect and cancel replacement of task marker with continuation indent.\n // Task markers are atomic so will be deleted when backspace is pressed.\n // The markdown extension inserts 2 or 6 spaces when deleting a list or task marker in order to create a continuation.\n // - [ ] <- backspace here deletes the task marker.\n // - [ ] <- backspace here inserts 6 spaces (creates continuation).\n // - [ ] <- backspace here deletes the task marker.\n const start = line.from + (match?.[0]?.length ?? 0);\n const replace = start === toA && toA - fromA === insert.length;\n if (replace) {\n changes.push({ from: line.from - 1, to: toA });\n return;\n }\n\n // Detect deletion of marker.\n if (fromB === toB) {\n if (toA === line.to) {\n const line = tr.state.doc.lineAt(fromA);\n if (line.text.match(/^\\s*$/)) {\n if (line.from === 0) {\n // Don't delete first line.\n cancel = true;\n return;\n } else {\n // Delete indent and marker.\n changes.push({ from: line.from - 1, to: toA });\n return;\n }\n }\n }\n return;\n }\n\n // Prevent newline if line is empty.\n const item = tree.find(fromA);\n if (item?.contentRange.from === item?.contentRange.to && fromA === toA) {\n cancel = true;\n return;\n }\n\n log('change', {\n item,\n line: { from: line.from, to: line.to },\n a: [fromA, toA],\n b: [fromB, toB],\n insert: { text: insert.toString(), length: insert.length },\n });\n }\n });\n\n if (changes.length > 0) {\n log('modified,', { changes });\n return [{ changes }];\n } else if (cancel) {\n log('cancel');\n return [];\n }\n\n return tr;\n }),\n];\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\nimport { type CleanupFn, addEventListener } from '@dxos/async';\n\nexport type MenuOptions = {\n icon?: string;\n height?: number;\n padding?: number;\n};\n\n// TODO(burdon): Replace with popover.\nexport const menu = (options: MenuOptions = {}): Extension => [\n ViewPlugin.fromClass(\n class {\n view: EditorView;\n tag: HTMLElement;\n rafId?: number | null;\n cleanup?: CleanupFn;\n\n constructor(view: EditorView) {\n this.view = view;\n\n // Position context.\n const container = view.scrollDOM;\n if (getComputedStyle(container).position === 'static') {\n container.style.position = 'relative';\n }\n\n {\n const icon = document.createElement('dx-icon');\n icon.setAttribute('icon', options.icon ?? 'ph--dots-three-vertical--regular');\n\n this.tag = document.createElement('dx-anchor');\n this.tag.classList.add('cm-popover-trigger');\n this.tag.appendChild(icon);\n }\n\n container.appendChild(this.tag);\n\n // Listen for scroll events.\n const handler = () => this.scheduleUpdate();\n this.cleanup = addEventListener(container, 'scroll', handler);\n this.scheduleUpdate();\n }\n\n destroy() {\n this.cleanup?.();\n this.tag.remove();\n if (this.rafId != null) {\n cancelAnimationFrame(this.rafId);\n }\n }\n\n update(update: ViewUpdate) {\n this.tag.dataset.focused = update.view.hasFocus ? 'true' : 'false';\n if (!update.view.hasFocus) {\n return;\n }\n\n // TODO(burdon): Timer to fade in/out.\n /*if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(openEffect)))) {\n this.tag.style.display = 'none';\n this.tag.classList.add('opacity-10');\n } else if (update.transactions.some((tr) => tr.effects.some((effect) => effect.is(closeEffect)))) {\n this.tag.style.display = '';\n } else */ if (\n update.docChanged ||\n update.focusChanged ||\n update.geometryChanged ||\n update.selectionSet ||\n update.viewportChanged\n ) {\n this.scheduleUpdate();\n }\n }\n\n updateButtonPosition() {\n const { x, width } = this.view.contentDOM.getBoundingClientRect();\n\n const pos = this.view.state.selection.main.head;\n const line = this.view.lineBlockAt(pos);\n const coords = this.view.coordsAtPos(line.from);\n if (!coords) {\n return;\n }\n\n const lineHeight = coords.bottom - coords.top;\n const dy = (lineHeight - (options.height ?? 32)) / 2;\n\n const offsetTop = coords.top + dy;\n const offsetLeft = x + width + (options.padding ?? 8);\n\n this.tag.style.top = `${offsetTop}px`;\n this.tag.style.left = `${offsetLeft}px`;\n this.tag.style.display = '';\n }\n\n scheduleUpdate() {\n if (this.rafId != null) {\n cancelAnimationFrame(this.rafId);\n }\n\n this.rafId = requestAnimationFrame(this.updateButtonPosition.bind(this));\n }\n },\n ),\n\n EditorView.theme({\n '.cm-popover-trigger': {\n position: 'fixed',\n padding: '0',\n border: 'none',\n opacity: '0',\n display: 'grid',\n placeContent: 'center',\n width: '2rem',\n height: '2rem',\n },\n '&:focus-within .cm-popover-trigger': {\n opacity: '1',\n },\n }),\n];\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, RangeSetBuilder, StateEffect, StateField } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\n\nimport { type Database, DXN, Entity } from '@dxos/echo';\n\nexport type PreviewBlock = {\n link: PreviewLinkRef;\n el: HTMLElement;\n};\n\nexport type PreviewLinkRef = {\n suggest?: boolean;\n block?: boolean;\n label: string;\n dxn: string;\n};\n\nexport type PreviewLinkTarget = {\n label: string;\n text?: string;\n object?: any;\n};\n\nexport type PreviewOptions = {\n db?: Database.Database;\n addBlockContainer?: (block: PreviewBlock) => void;\n removeBlockContainer?: (block: PreviewBlock) => void;\n};\n\nconst labelResolvedEffect = StateEffect.define<void>();\n\n/**\n * Create preview decorations.\n */\nexport const preview = (options: PreviewOptions = {}): Extension => {\n // Mutable ref so the StateField's onLoad callback can dispatch into the view.\n const viewRef: { current: EditorView | undefined } = { current: undefined };\n\n return [\n // NOTE: Atomic block decorations must be created from a state field, now a widget, otherwise it results in the following error:\n // \"Block decorations may not be specified via plugins\".\n StateField.define<DecorationSet>({\n create: (state) => buildDecorations(state, options, viewRef),\n update: (decorations, tr) => {\n if (tr.docChanged || tr.effects.some((effect) => effect.is(labelResolvedEffect))) {\n return buildDecorations(tr.state, options, viewRef);\n }\n\n return decorations.map(tr.changes);\n },\n provide: (field) => [\n EditorView.decorations.from(field),\n EditorView.atomicRanges.of((view) => view.state.field(field)),\n ],\n }),\n ViewPlugin.define((view) => {\n viewRef.current = view;\n return {\n destroy() {\n viewRef.current = undefined;\n },\n };\n }),\n ];\n};\n\n/**\n * Resolve a DXN to a display label using the database.\n */\nconst resolveLabel = (\n db: Database.Database,\n dxnStr: string,\n viewRef: { current: EditorView | undefined },\n): string | undefined => {\n const dxn = DXN.tryParse(dxnStr);\n if (!dxn) {\n return;\n }\n\n const ref = db.makeRef(dxn);\n const target = ref.target;\n if (target) {\n return Entity.getLabel(target);\n }\n\n // Object not loaded yet — schedule a decoration rebuild when it resolves.\n void ref.tryLoad().then(() => {\n viewRef.current?.dispatch({ effects: labelResolvedEffect.of(undefined) });\n });\n};\n\n/**\n * Echo references are represented as markdown reference links.\n * https://www.markdownguide.org/basic-syntax/#reference-style-links\n */\nconst buildDecorations = (\n state: EditorState,\n options: PreviewOptions,\n viewRef: { current: EditorView | undefined },\n): DecorationSet => {\n const builder = new RangeSetBuilder<Decoration>();\n\n syntaxTree(state).iterate({\n enter: (node) => {\n switch (node.name) {\n //\n // Inline widget.\n // [Label](dxn:echo:123)\n //\n case 'Link': {\n const link = getLinkRef(state, node.node);\n if (link) {\n const resolved = options.db ? resolveLabel(options.db, link.dxn, viewRef) : undefined;\n const displayLink = resolved ? { ...link, label: resolved } : link;\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new PreviewInlineWidget(options, displayLink),\n side: 1,\n }),\n );\n }\n return false;\n }\n\n //\n // Block widget (transclusion).\n // \n //\n case 'Image': {\n if (options.addBlockContainer && options.removeBlockContainer) {\n const link = getLinkRef(state, node.node);\n if (link) {\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n block: true,\n widget: new PreviewBlockWidget(options, link),\n }),\n );\n }\n }\n return false;\n }\n }\n },\n });\n\n return builder.finish();\n};\n\n/**\n * Link references.\n * [Label](dxn:echo:123) Inline reference\n *  Block reference\n */\nexport const getLinkRef = (state: EditorState, node: SyntaxNode): PreviewLinkRef | undefined => {\n const mark = node.getChildren('LinkMark');\n const urlNode = node.getChild('URL');\n if (mark && urlNode) {\n const dxn = state.sliceDoc(urlNode.from, urlNode.to);\n if (dxn.startsWith('dxn:')) {\n const label = state.sliceDoc(mark[0].to, mark[1].from);\n return {\n block: state.sliceDoc(mark[0].from, mark[0].from + 1) === '!',\n label,\n dxn,\n };\n }\n }\n};\n\n/**\n * Inline widget.\n * [Label](dxn:echo:123)\n */\nclass PreviewInlineWidget extends WidgetType {\n constructor(\n readonly _options: PreviewOptions,\n readonly _link: PreviewLinkRef,\n ) {\n super();\n }\n\n // override ignoreEvent() {\n // return false;\n // }\n\n override eq(other: this) {\n return this._link.dxn === other._link.dxn && this._link.label === other._link.label;\n }\n\n override toDOM(_view: EditorView) {\n const root = document.createElement('dx-anchor');\n root.classList.add('dx-tag--anchor');\n root.textContent = this._link.label;\n root.setAttribute('dxn', this._link.dxn);\n return root;\n }\n}\n\n/**\n * Block widget (e.g., for surfaces).\n * ![Label][dxn:echo:123]\n */\nclass PreviewBlockWidget extends WidgetType {\n constructor(\n readonly _options: PreviewOptions,\n readonly _link: PreviewLinkRef,\n ) {\n super();\n }\n\n // override ignoreEvent() {\n // return true;\n // }\n\n override eq(other: this) {\n return this._link.dxn === other._link.dxn;\n }\n\n override toDOM(_view: EditorView) {\n const root = document.createElement('div');\n root.classList.add('cm-preview-block', 'dx-density-fine');\n this._options.addBlockContainer?.({ link: this._link, el: root });\n return root;\n }\n\n override destroy(root: HTMLDivElement) {\n this._options.removeBlockContainer?.({ link: this._link, el: root });\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { EditorView } from '@codemirror/view';\n\ntype Replacement = {\n input: string;\n output: string;\n};\n\n/**\n * Default character replacements for common typography.\n */\nexport const defaultReplacements: Replacement[] = [\n { input: '--', output: '—' },\n { input: '...', output: '…' },\n { input: '->', output: '→' },\n { input: '<-', output: '←' },\n { input: '=>', output: '⇒' },\n { input: '<=>', output: '⇔' },\n { input: '+-', output: '±' },\n { input: '!=', output: '≠' },\n { input: '<=', output: '≤' },\n { input: '>=', output: '≥' },\n { input: '(c)', output: '©' },\n { input: 'EUR', output: '€' },\n { input: 'GBP', output: '£' },\n { input: 'BTC', output: '₿' },\n];\n\n/**\n * Options for the replacer extension.\n */\nexport interface ReplacerOptions {\n replacements?: Replacement[];\n}\n\n/**\n * Creates a CodeMirror extension that automatically replaces typed character sequences.\n */\nexport const replacer = ({ replacements = defaultReplacements }: ReplacerOptions = {}): Extension => {\n // Sort replacements by input length (longest first) to handle overlapping patterns correctly.\n const sortedReplacements = [...replacements].sort((a, b) => b.input.length - a.input.length);\n\n return EditorView.inputHandler.of((view, from, to, insert) => {\n // Only process single character insertions for performance.\n if (insert.length !== 1) {\n return false;\n }\n\n const state = view.state;\n const doc = state.doc;\n\n // Get the text before the insertion point to check for patterns.\n const lineStart = doc.lineAt(from).from;\n const textBefore = doc.sliceString(lineStart, from);\n const textWithInsert = textBefore + insert;\n\n // Check each replacement pattern.\n for (const replacement of sortedReplacements) {\n if (textWithInsert.endsWith(replacement.input)) {\n const range = {\n from: from - replacement.input.length + 1,\n to: from,\n };\n\n // Ensure we don't go before the line start.\n if (range.from < lineStart) {\n continue;\n }\n\n // Create the replacement transaction.\n view.dispatch(\n state.update({\n changes: {\n ...range,\n insert: replacement.output,\n },\n selection: {\n anchor: range.from + replacement.output.length,\n },\n }),\n );\n\n return true;\n }\n }\n\n return false;\n });\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Extension } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\n\nconst defaultItems = ['hello world!', 'this is a test.', 'this is [DXOS](https://dxos.org)'];\n\nexport type SnippetsOptions = {\n delay?: number;\n items?: string[];\n};\n\n/**\n * Configurable plugin that lets users cycle through pre-configured input snippets.\n */\n// TODO(burdon): Review https://github.com/sergeche/codemirror-movie?tab=readme-ov-file\nexport const snippets = ({ delay = 75, items = defaultItems }: SnippetsOptions = {}): Extension => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let index = 0; // TODO(burdon): Make global.\n\n return [\n keymap.of([\n {\n // Reset.\n key: \"alt-meta-'\",\n run: () => {\n clearTimeout(timer);\n index = 0;\n return true;\n },\n },\n {\n // Next snippet.\n // TODO(burdon): Press 1-9 to select snippet?\n key: \"Shift-Meta-'\",\n run: (view) => {\n clearTimeout(timer);\n // TODO(burdon): Add space if needed.\n const text = items[index++];\n if (index === items?.length) {\n index = 0;\n }\n\n let offset = 0;\n const insert = (delayMs = 0) => {\n timer = setTimeout(() => {\n const pos = view.state.selection.main.head;\n view.dispatch({\n changes: { from: pos, insert: text[offset++] },\n selection: { anchor: pos + 1 },\n });\n\n if (offset < text.length) {\n insert(Math.random() * delay * (text[offset] === ' ' ? 2 : 1));\n }\n }, delayMs);\n };\n\n insert();\n return true;\n },\n },\n ]),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, Prec } from '@codemirror/state';\nimport { keymap } from '@codemirror/view';\n\nexport type SubmitOptions = {\n fireIfEmpty?: boolean;\n onSubmit?: (text: string) => boolean | void;\n};\n\n/**\n * Handles Enter and Shift-Enter.\n */\nexport const submit = ({ fireIfEmpty = false, onSubmit }: SubmitOptions = {}): Extension => {\n return [\n Prec.highest(\n keymap.of([\n {\n key: 'Enter',\n preventDefault: true,\n run: (view) => {\n const text = view.state.doc.toString().trim();\n if (onSubmit && (fireIfEmpty || text.length > 0)) {\n const reset = onSubmit(text);\n if (reset) {\n // Clear the document after calling onEnter.\n view.dispatch({\n changes: {\n from: 0,\n to: view.state.doc.length,\n insert: '',\n },\n });\n }\n }\n\n return true;\n },\n },\n {\n key: 'Shift-Enter',\n preventDefault: true,\n run: (view) => {\n view.dispatch({\n changes: {\n from: view.state.selection.main.head,\n insert: '\\n',\n },\n selection: {\n anchor: view.state.selection.main.head + 1,\n head: view.state.selection.main.head + 1,\n },\n });\n return true;\n },\n },\n ]),\n ),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { xmlLanguage } from '@codemirror/lang-xml';\nimport { type Extension } from '@codemirror/state';\nimport { type ParseWrapper, parseMixed } from '@lezer/common';\nimport { type BlockParser } from '@lezer/markdown';\n\nimport { createMarkdownExtensions } from '../markdown';\nimport { type XmlWidgetRegistry } from './xml-tags';\n\nexport type ExtendedMarkdownOptions = {\n registry?: XmlWidgetRegistry;\n};\n\n/** Escapes a string for safe embedding in RegExp source. */\nconst escapeRegExpSource = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * Extended markdown parser with mixed parser for custom rendering of XML tags.\n */\nexport const extendedMarkdown = ({ registry }: ExtendedMarkdownOptions = {}): Extension => {\n return [\n createMarkdownExtensions({\n extensions: [\n {\n wrap: mixedParser(registry),\n parseBlock: [\n // Disable SetextHeading since it causes flickering when parsing/rendering tasks in chunks.\n {\n name: 'SetextHeading',\n parse: () => false,\n },\n // Custom XML block parser that keeps registered tags as a single HTMLBlock\n // even when their content contains blank lines.\n ...xmlBlockParsers(registry),\n ],\n },\n ],\n }),\n ];\n};\n\n/**\n * Creates block parsers for registered XML tags that may contain blank lines.\n *\n * By default, the markdown parser treats custom HTML tags as type 6 HTML blocks,\n * which end at blank lines. This causes tags like `<reasoning>...\\n\\n...</reasoning>`\n * to be split into separate blocks, preventing the XML mixed parser from seeing the\n * full element. This custom parser consumes all lines (including blanks) until the\n * matching closing tag, emitting a single HTMLBlock.\n */\nconst xmlBlockParsers = (registry?: XmlWidgetRegistry): BlockParser[] => {\n const customTags = Object.keys(registry ?? {});\n if (customTags.length === 0) {\n return [];\n }\n\n const tagPattern = customTags.map(escapeRegExpSource).join('|');\n const selfClosePattern = new RegExp(`^\\\\s*<(${tagPattern})(\\\\s[^>]*)?\\\\/>\\\\s*$`);\n const openPattern = new RegExp(`^\\\\s*<(${tagPattern})(\\\\s[^>]*)?\\\\/?>`);\n\n return [\n {\n name: 'XMLBlock',\n before: 'HTMLBlock',\n parse: (cx, line) => {\n const match = openPattern.exec(line.text);\n if (!match) {\n return false;\n }\n\n // Self-closing tag (e.g., `<tag />` or `<tag id=\"x\" />`).\n if (selfClosePattern.test(line.text)) {\n const end = cx.lineStart + line.text.length;\n cx.addElement(cx.elt('HTMLBlock', cx.lineStart, end));\n cx.nextLine();\n return true;\n }\n\n // Self-closing tag with trailing text (e.g., `<tag /> text`).\n // Let markdown parse it as a normal paragraph.\n if (match[0].trimEnd().endsWith('/>')) {\n return false;\n }\n\n const tagName = match[1];\n const closeTag = `</${tagName}>`;\n const start = cx.lineStart;\n\n // Check if closing tag is on the same line.\n if (line.text.includes(closeTag)) {\n cx.addElement(cx.elt('HTMLBlock', start, start + line.text.length));\n cx.nextLine();\n return true;\n }\n\n // Consume lines (including blank lines) until the closing tag.\n let end = cx.lineStart + line.text.length;\n while (cx.nextLine()) {\n end = cx.lineStart + line.text.length;\n if (line.text.includes(closeTag)) {\n cx.addElement(cx.elt('HTMLBlock', start, end));\n cx.nextLine();\n return true;\n }\n }\n\n // Unclosed tag (e.g., still streaming) — emit what we have.\n cx.addElement(cx.elt('HTMLBlock', start, end));\n return true;\n },\n },\n ];\n};\n\n/**\n * Configure mixed parser to recognize custom tags.\n */\nconst mixedParser = (registry?: XmlWidgetRegistry): ParseWrapper => {\n const customTags = Object.keys(registry ?? {});\n const tagPattern = new RegExp(`<(${customTags.join('|')})`);\n\n return parseMixed((node, input) => {\n switch (node.name) {\n // Ignore XML inside of fenced and inline code.\n case 'FencedCode':\n case 'InlineCode': {\n return null;\n }\n\n // Parse multi-line HTML blocks.\n // case 'XMLBlock':\n case 'HTMLBlock': {\n return {\n parser: xmlLanguage.parser,\n };\n }\n\n // Parse paragraphs that contain custom XML tags.\n // TODO(burdon): Entire paragraph should be parsed as XML.\n case 'Paragraph': {\n const content = input.read(node.from, node.to);\n if (tagPattern.test(content)) {\n return {\n parser: xmlLanguage.parser,\n };\n }\n\n return null;\n }\n }\n\n return null;\n });\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Extension, StateEffect, StateField } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin } from '@codemirror/view';\n\nconst DEFAULT_REMOVAL_DELAY = 5_000; // ms.\nconst DEFAULT_COALESCE_WINDOW = 100; // ms.\nconst CLEANUP_INTERVAL = 1_000; // ms.\n\nexport type FaderOptions = {\n /** Time window in ms to coalesce adjacent appends into a single decoration. */\n coalesce?: number;\n};\n\n/**\n * Extension that decorates appended text with a fade-in effect.\n * Adjacent appends within the coalesce window are merged into a single decoration.\n * Decorations are queued with an expiry and removed by a timer.\n */\nexport const fader = (options: FaderOptions = {}): Extension => {\n const removalDelay = DEFAULT_REMOVAL_DELAY;\n const coalesceWindow = options.coalesce ?? DEFAULT_COALESCE_WINDOW;\n\n let lastCount = -1;\n const log = (expiries: number[]) => {\n if (expiries.length !== lastCount) {\n lastCount = expiries.length;\n // console.log('[fader] decorations:', lastCount);\n }\n };\n\n // Effect to remove all expired decorations.\n const dequeue = StateEffect.define<number>();\n\n // FIFO of expiry timestamps paired with a decoration set.\n // Tracks `batchStart` — the time the current coalesce batch began.\n type FaderState = {\n decorations: DecorationSet;\n expiries: number[];\n batchStart: number;\n };\n\n const fadeField = StateField.define<FaderState>({\n create: () => ({ decorations: Decoration.none, expiries: [], batchStart: 0 }),\n update: ({ decorations, expiries, batchStart }, tr) => {\n // Remove expired entries by count (FIFO order matches decoration insertion order).\n for (const effect of tr.effects) {\n if (effect.is(dequeue)) {\n const now = effect.value;\n let removeCount = 0;\n while (removeCount < expiries.length && expiries[removeCount] <= now) {\n removeCount++;\n }\n if (removeCount > 0) {\n expiries = expiries.slice(removeCount);\n let skipped = 0;\n decorations = decorations.update({\n filter: () => {\n if (skipped < removeCount) {\n skipped++;\n return false;\n }\n return true;\n },\n });\n }\n }\n }\n\n if (!tr.docChanged) {\n log(expiries);\n return { decorations, expiries, batchStart };\n }\n\n // Reset when document is cleared or fully replaced.\n let isReset = tr.state.doc.length === 0;\n if (!isReset && tr.startState.doc.length > 0) {\n tr.changes.iterChanges((fromA, toA) => {\n if (fromA === 0 && toA === tr.startState.doc.length) {\n isReset = true;\n }\n });\n }\n if (isReset) {\n log([]);\n return { decorations: Decoration.none, expiries: [], batchStart: 0 };\n }\n\n // Collect appended ranges.\n const now = Date.now();\n const add: { from: number; to: number }[] = [];\n tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {\n if (toA === tr.startState.doc.length && inserted.length > 0) {\n add.push({ from: fromB, to: toB });\n }\n });\n\n if (add.length > 0) {\n const canCoalesce = expiries.length > 0 && batchStart > 0 && now - batchStart < coalesceWindow;\n if (canCoalesce) {\n // Extend the last decoration: remove it, then add a merged one.\n let lastFrom = -1;\n let lastTo = -1;\n decorations.between(0, tr.state.doc.length, (from, to) => {\n lastFrom = from;\n lastTo = to;\n });\n\n if (lastFrom >= 0) {\n decorations = decorations.update({\n filter: (from, to) => !(from === lastFrom && to === lastTo),\n });\n\n const mergedFrom = Math.min(lastFrom, add[0].from);\n const mergedTo = add[add.length - 1].to;\n decorations = decorations.update({\n add: [Decoration.mark({ class: 'cm-fader' }).range(mergedFrom, mergedTo)],\n });\n\n // Update the last expiry rather than adding a new one.\n expiries = [...expiries.slice(0, -1), now + removalDelay];\n }\n } else {\n // New batch — record when it started.\n batchStart = now;\n expiries = [...expiries, now + removalDelay];\n decorations = decorations.update({\n add: add.map(({ from, to }) => Decoration.mark({ class: 'cm-fader' }).range(from, to)),\n });\n }\n }\n\n log(expiries);\n return { decorations, expiries, batchStart };\n },\n provide: (f) => EditorView.decorations.from(f, (value) => value.decorations),\n });\n\n // Timer that schedules removal based on the next pending expiry.\n const cleanup = ViewPlugin.fromClass(\n class {\n #timer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(private view: EditorView) {\n this.#schedule();\n }\n\n update() {\n this.#schedule();\n }\n\n #schedule() {\n const { expiries } = this.view.state.field(fadeField);\n if (expiries.length === 0) {\n clearTimeout(this.#timer);\n this.#timer = undefined;\n return;\n }\n\n if (this.#timer !== undefined) {\n return;\n }\n\n // Wait at least CLEANUP_INTERVAL after the oldest expiry to batch removals.\n const delay = Math.max(CLEANUP_INTERVAL, expiries[0] - Date.now());\n this.#timer = setTimeout(() => {\n this.#timer = undefined;\n this.view.dispatch({ effects: dequeue.of(Date.now()) });\n }, delay);\n }\n\n destroy() {\n clearTimeout(this.#timer);\n }\n },\n );\n\n return [\n fadeField,\n cleanup,\n EditorView.theme({\n '.cm-fader': {\n animation: 'fader 1s ease-out forwards',\n },\n '@keyframes fader': {\n '0%': {\n textShadow: '0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)',\n },\n '100%': {},\n },\n }),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport {\n Annotation,\n ChangeSet,\n EditorState,\n type Extension,\n StateEffect,\n StateField,\n type Transaction,\n} from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from '@codemirror/view';\n\nimport { Domino } from '@dxos/ui';\n\n/** Annotate a transaction to bypass the typewriter buffer (content appears immediately). */\nexport const typewriterBypass = Annotation.define<boolean>();\n\n/**\n * Public state effect signalling whether typewriter's drip queue is currently draining.\n * Other extensions can subscribe to coordinate behaviour with the typewriter (e.g. hide\n * a block-widget footer while text is being dripped to avoid scroll-measure conflicts).\n *\n * Dispatched at queue transitions:\n * - `true` — empty → non-empty (drain rAF/interval is starting).\n * - `false` — non-empty → empty (last char written, drain stopped).\n */\nexport const typewriterDrainingEffect = StateEffect.define<boolean>();\n\n/**\n * Buffer state. The pending text is `text.slice(head)` — but `head` is advanced\n * without slicing on every drip to avoid O(n²) string copying. The prefix is\n * compacted lazily once it exceeds half the string or `COMPACT_HEAD_THRESHOLD`.\n */\ntype BufferState = { text: string; head: number; insertAt: number };\n\n/** How long to show the cursor after motion has stopped. */\nconst CURSOR_LINGER = 3_000;\n\n/** Per-frame time budget for draining the buffer. Stays well under a 16 ms frame. */\nconst FRAME_BUDGET_MS = 4;\n\n/**\n * Visible characters of plain text emitted per animation frame. At 60 fps a value of 1\n * gives ~60 char/s — fast enough to keep up with most streams while still reading as a\n * smooth character-by-character drip. Atomic structures (XML elements, markdown links)\n * always flush whole regardless of this cap.\n */\nconst CHARS_PER_FRAME = 5;\n\n/**\n * When the pending buffer exceeds this many characters, abandon typewriter pacing\n * and flush the entire buffer in one transaction. The visual benefit of typewriter\n * has negative value past human-reading rates.\n */\nconst FLUSH_THRESHOLD = 2_000;\n\n/** Compaction trigger for the head-offset rope. */\nconst COMPACT_HEAD_THRESHOLD = 4_096;\n\nexport type TypewriterOptions = {\n /** Show a blinking cursor at the insertion point while streaming. */\n cursor?: boolean;\n /** Tag names whose inner content should be streamed (not buffered until close). */\n streamingTags?: Set<string>;\n /** Hard cap before falling back to single-flush mode. Defaults to 2 000 chars. */\n flushThreshold?: number;\n /** Per-frame time budget for draining (ms). Defaults to 20 ms. */\n frameBudgetMs?: number;\n /**\n * Maximum visible characters of plain text emitted per animation frame. Atomic\n * structures (XML elements, markdown links) always flush whole and are not subject\n * to this cap. Default 1 — ~60 char/s at 60 fps. Raise for faster typewriter speed.\n */\n charsPerFrame?: number;\n};\n\n/**\n * Intercepts appended text and inserts it as time-budgeted batches per animation frame,\n * while flushing XML tags, markdown links, and images atomically for smooth typewriter-style\n * streaming. Falls back to bulk-flush when the buffer grows past `flushThreshold` to keep\n * the editor responsive on long runs.\n */\nexport const typewriter = (options: TypewriterOptions = {}): Extension => {\n const streamingTags = options.streamingTags ?? new Set<string>();\n const flushThreshold = options.flushThreshold ?? FLUSH_THRESHOLD;\n const frameBudgetMs = options.frameBudgetMs ?? FRAME_BUDGET_MS;\n const charsPerFrame = options.charsPerFrame ?? CHARS_PER_FRAME;\n\n // Effect to suppress a transaction from being applied (replaced by buffered insert).\n const suppressAppend = StateEffect.define<{ from: number; text: string }>();\n // Effect to insert text from the buffer (single batch per frame).\n const insertChunk = StateEffect.define<{ from: number; text: string }>();\n\n // State field that holds the pending buffer of text to drip into the document.\n const bufferField = StateField.define<BufferState>({\n create: () => ({ text: '', head: 0, insertAt: 0 }),\n update: (value, tr) => {\n let { text, head, insertAt } = value;\n for (const effect of tr.effects) {\n if (effect.is(suppressAppend)) {\n // If pending was empty, anchor insertAt at the new append point.\n if (text.length === head) {\n insertAt = effect.value.from;\n }\n text += effect.value.text;\n }\n if (effect.is(insertChunk)) {\n head += effect.value.text.length;\n insertAt = effect.value.from + effect.value.text.length;\n // Compact lazily so the prefix doesn't grow without bound.\n if (head >= COMPACT_HEAD_THRESHOLD || (head > 0 && head * 2 >= text.length)) {\n text = text.slice(head);\n head = 0;\n }\n }\n }\n\n // Reset buffer when document is cleared or fully replaced.\n if (tr.docChanged) {\n let isReset = tr.state.doc.length === 0;\n if (!isReset && tr.startState.doc.length > 0) {\n tr.changes.iterChanges((fromA, toA) => {\n if (fromA === 0 && toA === tr.startState.doc.length) {\n isReset = true;\n }\n });\n }\n if (isReset) {\n return { text: '', head: 0, insertAt: 0 };\n }\n\n // Map insertion position through document changes not caused by us.\n if (!tr.effects.some((effect) => effect.is(insertChunk))) {\n insertAt = tr.changes.mapPos(Math.min(insertAt, tr.startState.doc.length));\n }\n }\n\n return { text, head, insertAt };\n },\n });\n\n // Transaction filter: intercept appends at end-of-document and buffer them.\n const filter = EditorState.transactionFilter.of((tr: Transaction) => {\n if (!tr.docChanged) {\n return tr;\n }\n\n // Allow bypassed and drip insertions through.\n if (tr.annotation(typewriterBypass) || tr.effects.some((effect) => effect.is(insertChunk))) {\n return tr;\n }\n\n // Collect appended text at the end of the document.\n let appendedText = '';\n let appendFrom = -1;\n let isAppendOnly = true;\n\n tr.changes.iterChanges((fromA, toA, _fromB, _toB, inserted) => {\n if (toA === tr.startState.doc.length && fromA === toA && inserted.length > 0) {\n appendedText += inserted.sliceString(0);\n if (appendFrom === -1) {\n appendFrom = fromA;\n }\n } else {\n isAppendOnly = false;\n }\n });\n\n if (!isAppendOnly || appendedText.length === 0) {\n return tr;\n }\n\n // Suppress the original insert; buffer the text instead.\n return {\n changes: ChangeSet.empty(tr.startState.doc.length),\n effects: suppressAppend.of({ from: appendFrom, text: appendedText }),\n };\n });\n\n // View plugin that drains the buffer once per animation frame, emitting as many atomic\n // chunks as fit within `frameBudgetMs`. Falls back to a single dispatch when the buffer\n // grows past `flushThreshold`.\n const drainPlugin = ViewPlugin.fromClass(\n class {\n _raf: number | undefined;\n _activeStreamTag: string | null = null;\n\n constructor(private view: EditorView) {\n // Note: do NOT eagerly start the drain here. The buffer is empty at construction,\n // and any synchronous `view.dispatch` inside the constructor is rejected by\n // CodeMirror because we're inside the initial update flow.\n }\n\n update(update: ViewUpdate) {\n const { text, head } = update.state.field(bufferField);\n const pending = text.length - head;\n if (pending === 0) {\n this._activeStreamTag = null;\n }\n if (pending > 0 && this._raf === undefined) {\n this._start();\n }\n }\n\n _start() {\n // Announce drain start. Deferred via microtask because `_start` runs from inside\n // `update()`, where synchronous `view.dispatch` is disallowed.\n queueMicrotask(() => {\n this.view.dispatch({\n effects: typewriterDrainingEffect.of(true),\n annotations: typewriterBypass.of(true),\n });\n });\n this._raf = requestAnimationFrame(this._tick);\n }\n\n _tick = () => {\n const { text, head, insertAt } = this.view.state.field(bufferField);\n const pending = text.length - head;\n\n if (pending === 0) {\n this.view.dispatch({\n effects: typewriterDrainingEffect.of(false),\n annotations: typewriterBypass.of(true),\n });\n this._raf = undefined;\n return;\n }\n\n // Backpressure: flush everything in one shot when the buffer is too large to\n // pace at typewriter rates. Streaming-tag context is dropped — anything still\n // buffered (including a closing tag, if present) lands as one chunk.\n if (pending > flushThreshold) {\n const chunk = text.slice(head);\n this._activeStreamTag = null;\n this.view.dispatch({\n changes: { from: insertAt, insert: chunk },\n effects: insertChunk.of({ from: insertAt, text: chunk }),\n });\n this._raf = requestAnimationFrame(this._tick);\n return;\n }\n\n // Time-budgeted batch: accumulate atomic chunks until we run out of budget,\n // hit an incomplete structure, exhaust the buffer, or hit the per-frame\n // visible-character cap. Atomic chunks (count > 1) are always emitted whole;\n // the cap only throttles plain-text drips so the typewriter cadence stays\n // visible at the per-frame level.\n const startTime = performance.now();\n let pos = head;\n let activeTag = this._activeStreamTag;\n let charsEmitted = 0;\n while (pos < text.length && performance.now() - startTime < frameBudgetMs) {\n const result = flushable(text, pos, streamingTags, activeTag);\n if (result.count === 0) {\n // Head is inside an incomplete structure — wait for more data.\n break;\n }\n // Stop after the per-frame cap, but only once we've already emitted at\n // least one chunk this frame — otherwise a multi-char atomic structure\n // (e.g. a markdown link) could starve forever on a small cap.\n if (charsEmitted > 0 && charsEmitted + result.count > charsPerFrame) {\n break;\n }\n if (result.enterTag) {\n activeTag = result.enterTag;\n }\n if (result.exitTag) {\n activeTag = null;\n }\n pos += result.count;\n charsEmitted += result.count;\n }\n\n const totalCount = pos - head;\n if (totalCount > 0) {\n const chunk = text.slice(head, head + totalCount);\n this._activeStreamTag = activeTag;\n this.view.dispatch({\n changes: { from: insertAt, insert: chunk },\n effects: insertChunk.of({ from: insertAt, text: chunk }),\n });\n }\n\n // Continue draining next frame; if pending is 0 after the dispatch, the next\n // tick will land on the early-out above and stop the loop.\n this._raf = requestAnimationFrame(this._tick);\n };\n\n destroy() {\n if (this._raf !== undefined) {\n cancelAnimationFrame(this._raf);\n }\n }\n },\n );\n\n return [bufferField, filter, drainPlugin, options.cursor && typewriterCursor(bufferField)].filter(\n Boolean,\n ) as Extension[];\n};\n\n//\n// Cursor\n//\n\n/**\n * Blinking cursor widget at the insertion point while the buffer is draining.\n * Lingers for 2s after the buffer empties before being removed.\n */\nconst typewriterCursor = (bufferField: StateField<BufferState>): Extension => {\n const hideCursor = StateEffect.define();\n\n const visibilityField = StateField.define<{\n visible: boolean;\n insertAt: number;\n /** Position after the last non-whitespace character was inserted. */\n lastNonWsAt: number;\n }>({\n create: () => ({ visible: false, insertAt: 0, lastNonWsAt: 0 }),\n update: (value, tr) => {\n const { text, head, insertAt } = tr.state.field(bufferField);\n const pending = text.length - head;\n if (pending > 0) {\n // Track the last position where a non-whitespace character was inserted.\n let lastNonWsAt = tr.changes.mapPos(Math.min(value.lastNonWsAt, tr.startState.doc.length));\n if (tr.docChanged) {\n tr.changes.iterChanges((_fromA, _toA, _fromB, _toB, inserted) => {\n const chunk = inserted.sliceString(0);\n if (chunk.trim().length > 0) {\n lastNonWsAt = _fromB + chunk.length;\n }\n });\n }\n return { visible: true, insertAt, lastNonWsAt };\n }\n for (const effect of tr.effects) {\n if (effect.is(hideCursor)) {\n return { ...value, visible: false };\n }\n }\n return value;\n },\n });\n\n const decorationField = StateField.define<DecorationSet>({\n create: () => Decoration.none,\n update: (_decorations, tr) => {\n const { visible, insertAt, lastNonWsAt } = tr.state.field(visibilityField);\n if (!visible) {\n return Decoration.none;\n }\n\n const { text, head } = tr.state.field(bufferField);\n // While draining, show cursor at the insertion point.\n // When lingering (buffer empty), show at last non-whitespace position.\n const cursorAt = text.length > head ? insertAt : lastNonWsAt;\n const pos = Math.min(cursorAt, tr.state.doc.length);\n return Decoration.set([\n Decoration.widget({\n widget: new CursorWidget(),\n side: 1,\n }).range(pos),\n ]);\n },\n provide: (field) => EditorView.decorations.from(field),\n });\n\n const timerPlugin = ViewPlugin.fromClass(\n class {\n _timer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(private view: EditorView) {}\n\n update(update: ViewUpdate) {\n const { text, head } = update.state.field(bufferField);\n const { visible } = update.state.field(visibilityField);\n const pending = text.length - head;\n\n if (pending > 0) {\n clearTimeout(this._timer);\n this._timer = undefined;\n } else if (visible && this._timer === undefined) {\n this._timer = setTimeout(() => {\n this.view.dispatch({ effects: hideCursor.of(null) });\n this._timer = undefined;\n }, CURSOR_LINGER);\n }\n }\n\n destroy() {\n clearTimeout(this._timer);\n }\n },\n );\n\n return [visibilityField, decorationField, timerPlugin];\n};\n\n/**\n * U+2217 Asterisk\n * U+25CF Ballot Box\n */\nclass CursorWidget extends WidgetType {\n // All instances are interchangeable — let CM reuse the existing DOM across drips so\n // the blink animation isn't restarted on every transaction.\n override eq(other: WidgetType): boolean {\n return other instanceof CursorWidget;\n }\n\n toDOM() {\n const inner = Domino.of('span').text('∗').style({ animation: 'blink 1s infinite', animationDelay: '250ms' });\n return Domino.of('span').style({ opacity: '0.8' }).append(inner).root;\n }\n}\n\n/**\n * Matches the local name of an opening tag after `<` (not `</`).\n * Custom elements use hyphens; `\\w+` alone incorrectly stops at `-` (e.g. `dom` from `dom-widget`).\n */\nconst OPENING_TAG_NAME = /^<([a-zA-Z][\\w-]*)/;\n\n/** Tag names are short — bound the slice we hand to the regex matcher. */\nconst TAG_NAME_PROBE = 64;\n\n/** Escapes a string for safe embedding in RegExp source (tag names from the document). */\nconst escapeRegExpSource = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\ntype FlushResult = {\n count: number;\n /** Tag name to enter streaming mode for. */\n enterTag?: string;\n /** Whether to exit streaming mode. */\n exitTag?: boolean;\n};\n\n/**\n * Scans the buffer starting at `start` and returns the number of characters that can be\n * flushed. Returns 0 if the head of the buffer is inside an incomplete structure (XML\n * element, markdown link, or image) that should be flushed atomically. Returns > 1 when\n * a complete structure is at the head and should be emitted in one batch.\n *\n * When `activeStreamTag` is set, we're inside a streaming tag: inner content drips one\n * character at a time, and the closing tag is flushed atomically.\n */\nconst flushable = (\n buffer: string,\n start: number,\n streamingTags: Set<string>,\n activeStreamTag: string | null,\n): FlushResult => {\n if (start >= buffer.length) {\n return { count: 0 };\n }\n\n // Inside a streaming tag: drip content, flush closing tag atomically.\n if (activeStreamTag) {\n const closeTag = `</${activeStreamTag}>`;\n if (buffer.startsWith(closeTag, start)) {\n return { count: closeTag.length, exitTag: true };\n }\n // Nested XML element — buffer atomically.\n if (buffer[start] === '<') {\n return { count: xmlElementLength(buffer, start) };\n }\n // Drip inner content one character at a time.\n return { count: 1 };\n }\n\n const ch = buffer[start];\n\n // XML element.\n if (ch === '<') {\n // Tag-name match against a bounded slice (tag names are short).\n const probe = buffer.slice(start, start + TAG_NAME_PROBE);\n const nameMatch = probe.match(OPENING_TAG_NAME);\n if (nameMatch && streamingTags.has(nameMatch[1])) {\n const close = buffer.indexOf('>', start);\n if (close === -1) {\n return { count: 0 }; // Opening tag incomplete.\n }\n // Self-closing streaming tag — flush atomically, no streaming mode.\n if (buffer[close - 1] === '/') {\n return { count: close + 1 - start };\n }\n // Flush opening tag and enter streaming mode.\n return { count: close + 1 - start, enterTag: nameMatch[1] };\n }\n // Non-streaming XML: buffer the entire element.\n return { count: xmlElementLength(buffer, start) };\n }\n\n // Image:  — starts with '!'.\n if (ch === '!' && buffer.length > start + 1 && buffer[start + 1] === '[') {\n return { count: linkLength(buffer, start, start + 1) };\n }\n\n // Link: [text](url).\n if (ch === '[') {\n return { count: linkLength(buffer, start, start) };\n }\n\n return { count: 1 };\n};\n\n/**\n * Returns the length of a complete XML element starting at `start`, or 0 if the element\n * is incomplete. Handles self-closing tags, closing tags, and opening tags with nested\n * content. E.g., `<foo>content<bar />more</foo>` returns the full length.\n */\nexport const xmlElementLength = (buffer: string, start = 0): number => {\n const close = buffer.indexOf('>', start);\n if (close === -1) {\n return 0; // Tag not closed yet.\n }\n\n // Self-closing tag: <foo />.\n if (buffer[close - 1] === '/') {\n return close + 1 - start;\n }\n\n // Closing tag: </foo>.\n if (buffer[start + 1] === '/') {\n return close + 1 - start;\n }\n\n // Opening tag: extract the tag name and find its matching closing tag.\n const probe = buffer.slice(start, start + TAG_NAME_PROBE);\n const nameMatch = probe.match(OPENING_TAG_NAME);\n if (!nameMatch) {\n // Not a valid tag (e.g., `< ` or `<123`); emit one character.\n return 1;\n }\n\n const tagName = nameMatch[1];\n let depth = 0;\n\n // Walk through all tags in the buffer tracking nesting depth, starting at `start`.\n const tagPattern = new RegExp(`<(/?)${escapeRegExpSource(tagName)}(\\\\s[^>]*)?>`, 'g');\n tagPattern.lastIndex = start;\n let match: RegExpExecArray | null;\n while ((match = tagPattern.exec(buffer)) !== null) {\n const isSelfClosing = match[0].endsWith('/>');\n const isClosing = match[1] === '/';\n\n if (isSelfClosing) {\n // Self-closing doesn't change depth, but if depth is 0 this is the root.\n if (depth === 0) {\n return match.index + match[0].length - start;\n }\n } else if (isClosing) {\n depth--;\n if (depth === 0) {\n return match.index + match[0].length - start;\n }\n } else {\n depth++;\n }\n }\n\n // Unbalanced — still waiting for closing tag.\n return 0;\n};\n\n/**\n * Returns the length (from `start`) of a complete markdown link/image whose `[` is at\n * `bracketAt`, or 0 if the structure is incomplete. Returns 1 if the bracket is not part\n * of a link (no following `(`).\n */\nconst linkLength = (buffer: string, start: number, bracketAt: number): number => {\n const bracketClose = buffer.indexOf(']', bracketAt + 1);\n if (bracketClose === -1) {\n return 0;\n }\n\n // Must be followed by '(' for a standard link.\n if (bracketClose + 1 >= buffer.length) {\n return 0;\n }\n if (buffer[bracketClose + 1] !== '(') {\n // Not a link — just a bracket; emit one character.\n return 1;\n }\n\n const parenClose = buffer.indexOf(')', bracketClose + 2);\n if (parenClose === -1) {\n return 0;\n }\n\n return parenClose + 1 - start;\n};\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { xmlLanguage } from '@codemirror/lang-xml';\nimport { type Extension, type Range } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\nexport type XmlBlockDecorationOptions = {\n /**\n * Tag name to match (e.g. `'prompt'`).\n */\n tag: string;\n\n /**\n * Class added via `Decoration.line` to each line that intersects the element's content\n * range. Use to style the bubble container (e.g. flex alignment, vertical margin).\n */\n lineClass?: string;\n\n /**\n * Class added via `Decoration.mark` covering the inner content (between the open and\n * close tags). Use to style the bubble surface (background, padding, rounding).\n */\n contentClass?: string;\n\n /**\n * When true, the open and close tag delimiters are hidden via `Decoration.replace`\n * with no widget, so the rendered text is the inner content only.\n */\n hideTags?: boolean;\n};\n\n/**\n * Walks the doc with the Lezer XML parser and decorates `<tag>…</tag>` elements without\n * replacing them with a widget — the source text remains in the document and can still\n * be matched by other extensions (e.g. `xmlFormatting`). Use this for \"bubble\"-style\n * styling of XML blocks (chat prompts, callouts, etc.) where the inner content should\n * stay editable/copyable rather than living inside a CodeMirror widget.\n */\nexport const xmlBlockDecoration = ({\n tag,\n lineClass,\n contentClass,\n hideTags,\n}: XmlBlockDecorationOptions): Extension => {\n const lineDecoration = lineClass ? Decoration.line({ class: lineClass }) : undefined;\n const contentDecoration = contentClass ? Decoration.mark({ class: contentClass }) : undefined;\n const hideDecoration = hideTags ? Decoration.replace({}) : undefined;\n\n const buildDecorations = (view: EditorView): DecorationSet => {\n const text = view.state.sliceDoc(0, view.state.doc.length);\n if (!text.includes(`<${tag}`)) {\n return Decoration.none;\n }\n\n const tree = xmlLanguage.parser.parse(text);\n const ranges: Range<Decoration>[] = [];\n tree.iterate({\n enter: (node) => {\n if (node.type.name !== 'Element') {\n return;\n }\n const openTag = node.node.getChild('OpenTag');\n const closeTag = node.node.getChild('CloseTag') ?? node.node.getChild('MismatchedCloseTag');\n const tagNameNode = openTag?.getChild('TagName');\n if (!openTag || !tagNameNode) {\n return;\n }\n if (text.slice(tagNameNode.from, tagNameNode.to) !== tag) {\n return;\n }\n\n const contentFrom = openTag.to;\n const contentTo = closeTag?.from ?? node.node.to;\n\n if (hideDecoration) {\n ranges.push(hideDecoration.range(openTag.from, openTag.to));\n if (closeTag) {\n ranges.push(hideDecoration.range(closeTag.from, closeTag.to));\n }\n }\n\n if (contentDecoration && contentFrom < contentTo) {\n ranges.push(contentDecoration.range(contentFrom, contentTo));\n }\n\n if (lineDecoration && contentFrom <= view.state.doc.length) {\n // Apply line decoration to every line that intersects the content range.\n let pos = contentFrom;\n while (pos <= contentTo && pos <= view.state.doc.length) {\n const line = view.state.doc.lineAt(pos);\n ranges.push(lineDecoration.range(line.from));\n if (line.to >= contentTo) {\n break;\n }\n pos = line.to + 1;\n }\n }\n },\n });\n return Decoration.set(ranges, true);\n };\n\n return ViewPlugin.fromClass(\n class {\n decorations: DecorationSet;\n\n constructor(view: EditorView) {\n this.decorations = buildDecorations(view);\n }\n\n update(update: ViewUpdate) {\n if (update.docChanged) {\n this.decorations = buildDecorations(update.view);\n }\n }\n },\n {\n decorations: (instance) => instance.decorations,\n },\n );\n};\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { xmlLanguage } from '@codemirror/lang-xml';\nimport { type Extension, type Range } from '@codemirror/state';\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';\n\n/**\n * Lezer XML node names that represent the angle-bracket delimited portions of an element.\n */\nconst XML_TAG_NODES = new Set(['OpenTag', 'CloseTag', 'SelfClosingTag', 'MismatchedCloseTag']);\n\nconst xmlElementMark = Decoration.mark({ class: 'cm-xml-element' });\nconst xmlTagMark = Decoration.mark({ class: 'cm-xml-tag' });\nconst xmlContentMark = Decoration.mark({ class: 'cm-xml-content' });\n\nexport type XmlFormattingOptions = {\n /**\n * Tag names whose elements should NOT receive xmlFormatting decorations. Use to\n * opt-out tags rendered by another extension (e.g. `xmlBlockDecoration` for `<prompt>`)\n * so the two don't double-wrap the same content with stacked styling.\n *\n * Skipping is recursive: descendants of a skipped element are also untouched, so a\n * `<foo>` inside a skipped `<prompt>` still appears literally without xmlFormatting\n * styling.\n */\n skip?: string[];\n};\n\n/**\n * Mark decoration extension that highlights XML tag delimiters\n * (e.g., `<tag>`, `</tag>`, `<tag attr=\"x\"/>`) with the `cm-xml-tag` class.\n *\n * Uses `@codemirror/lang-xml`'s Lezer parser standalone — only to compute\n * decoration ranges — without changing the editor's primary language. This\n * keeps the document plain text while still handling nesting and attributes\n * correctly.\n */\nexport const xmlFormatting = ({ skip }: XmlFormattingOptions = {}): Extension => {\n const skipSet = skip && skip.length > 0 ? new Set(skip) : undefined;\n\n const buildDecorations = (view: EditorView): DecorationSet => {\n const text = view.state.sliceDoc(0, view.state.doc.length);\n if (!text.includes('<')) {\n return Decoration.none;\n }\n\n const tagNameAt = (node: { from: number; to: number }) => text.slice(node.from, node.to);\n\n const tree = xmlLanguage.parser.parse(text);\n const ranges: Range<Decoration>[] = [];\n tree.iterate({\n enter: (node) => {\n const name = node.type.name;\n if (name === 'SelfClosingTag' && node.from < node.to) {\n if (skipSet) {\n const tagNameNode = node.node.getChild('TagName');\n if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {\n return false;\n }\n }\n // Self-closing tag is its own outer block and tag delimiter.\n ranges.push(xmlElementMark.range(node.from, node.to));\n ranges.push(xmlTagMark.range(node.from, node.to));\n return;\n }\n if (XML_TAG_NODES.has(name) && node.from < node.to) {\n ranges.push(xmlTagMark.range(node.from, node.to));\n return;\n }\n if (name === 'Element' && node.from < node.to) {\n const openTag = node.node.getChild('OpenTag');\n if (openTag && skipSet) {\n const tagNameNode = openTag.getChild('TagName');\n if (tagNameNode && skipSet.has(tagNameAt(tagNameNode))) {\n // Skip this element AND its descendants — another extension owns rendering.\n return false;\n }\n }\n const closeTag = node.node.getChild('CloseTag') ?? node.node.getChild('MismatchedCloseTag');\n ranges.push(xmlElementMark.range(node.from, node.to));\n if (openTag && closeTag && openTag.to < closeTag.from) {\n ranges.push(xmlContentMark.range(openTag.to, closeTag.from));\n }\n }\n },\n });\n return Decoration.set(ranges, true);\n };\n\n return [\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet;\n\n constructor(view: EditorView) {\n this.decorations = buildDecorations(view);\n }\n\n update(update: ViewUpdate) {\n if (update.docChanged) {\n this.decorations = buildDecorations(update.view);\n }\n }\n },\n {\n decorations: (instance) => instance.decorations,\n },\n ),\n\n EditorView.baseTheme({\n '.cm-xml-element': {\n backgroundColor: 'var(--color-active-surface)',\n borderRadius: '0.25rem',\n padding: '0.25rem',\n },\n '.cm-xml-tag': {\n color: 'var(--color-blue-500)',\n fontFamily: 'var(--font-mono)',\n },\n '.cm-xml-content': {},\n }),\n ];\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, Prec, RangeSetBuilder, StateEffect, StateField } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n WidgetType,\n keymap,\n} from '@codemirror/view';\nimport { type FunctionComponent } from 'react';\n\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { Domino } from '@dxos/ui';\n\nimport { type Range } from '../../types';\nimport { decorationSetToArray } from '../../util';\nimport { scrollerLineEffect } from '../scroller';\nimport { nodeToJson } from './xml-util';\n\n/**\n * StateEffect for navigating to previous bookmark.\n */\nexport const navigatePreviousEffect = StateEffect.define<void>();\n\n/**\n * StateEffect for navigating to next bookmark.\n */\nexport const navigateNextEffect = StateEffect.define<void>();\n\n/**\n * Dispatch function for updating state.\n */\nexport type StateDispatch<T> = T | ((state: T) => T);\n\n/**\n * Manages widget state.\n */\nexport interface XmlWidgetStateManager {\n updateWidget<T>(id: string, props: StateDispatch<T>): void;\n}\n\nexport type XmlEventHandler<TEvent = any> = (event: TEvent) => void;\n\n/**\n * Widget component.\n */\nexport type XmlWidgetProps<TProps = any, TContext = any> = TProps & {\n _tag: string;\n range: { from: number; to: number };\n children?: any[];\n context?: TContext;\n view?: EditorView;\n onEvent?: XmlEventHandler;\n};\n\n/**\n * Factory for creating widgets.\n */\nexport type XmlWidgetFactory = (props: XmlWidgetProps) => WidgetType | null;\n\n/**\n * Widget registry definition.\n * NOTE: Widgets should NOT use top/bottom margins (it causes unstable measurements while scrolling which leads to jumps).\n * If required, use encapsulated divs with padding instead.\n */\nexport type XmlWidgetDef = {\n /**\n * Block widget.\n */\n block?: boolean;\n\n /**\n * When true, the opening tag is flushed immediately and inner content streams character-by-character.\n */\n streaming?: boolean;\n\n /**\n * Debug only.\n */\n debug?: boolean;\n\n /**\n * Native widget (rendered inline).\n */\n factory?: XmlWidgetFactory;\n\n /**\n * React/Solid widget (rendered in portals outside of the editor).\n * Prefer an `id=\"...\"` attribute on the tag so `updateWidget` can target the instance; if omitted,\n * an id is derived from the tag’s document range (non-streaming) or opening position (streaming).\n * Streaming tags use `cm-xml-<from>` so the same portal id is kept when the closing tag arrives.\n */\n Component?: FunctionComponent<XmlWidgetProps>;\n};\n\nexport type XmlWidgetRegistry = Record<string, XmlWidgetDef>;\n\nexport const getXmlTextChild = (children: any[]): string | null => {\n const child = children?.[0];\n return typeof child === 'string' ? child : null;\n};\n\n/** Stable id for portaled React/Solid widgets; explicit `id` on the tag wins for `updateWidget`. */\nconst xmlWidgetId = (explicit: unknown, fallback: string): string =>\n typeof explicit === 'string' && explicit.length > 0 ? explicit : fallback;\n\n/** Escapes a string for safe embedding in RegExp source (tag names from the registry). */\nconst escapeRegExpSource = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * Update context.\n */\nexport const xmlTagContextEffect = StateEffect.define<any>();\n\n/**\n * Reset all state.\n */\nexport const xmlTagResetEffect = StateEffect.define();\n\n/**\n * Update widget.\n */\nexport const xmlTagUpdateEffect = StateEffect.define<{ id: string; value: any }>();\n\ntype WidgetDecorationSet = {\n from: number;\n /** Start position of an active unclosed streaming tag (for rebuild range). */\n streamingFrom?: number;\n decorations: DecorationSet;\n};\n\ntype XmlWidgetStateMap = Record<string, any>;\n\nexport type XmlWidgetState = {\n id: string;\n root: HTMLElement;\n props: any;\n Component: FunctionComponent<XmlWidgetProps>;\n};\n\nexport interface XmlWidgetNotifier {\n mounted(widget: XmlWidgetState): void;\n unmounted(id: string): void;\n}\n\n/**\n * Context state.\n */\nconst widgetContextStateField = StateField.define<any>({\n create: () => undefined,\n update: (value, tr) => {\n for (const effect of tr.effects) {\n if (effect.is(xmlTagContextEffect)) {\n return effect.value;\n }\n }\n\n return value;\n },\n});\n\n/**\n * Widget state management.\n */\nconst widgetStateMapStateField = StateField.define<XmlWidgetStateMap>({\n create: () => ({}),\n update: (map, tr) => {\n for (const effect of tr.effects) {\n if (effect.is(xmlTagResetEffect)) {\n return {};\n }\n\n if (effect.is(xmlTagUpdateEffect)) {\n // Update accumulated widget props by id.\n const { id, value } = effect.value;\n log('widget updated', { id, value });\n const state = typeof value === 'function' ? value(map[id]) : value;\n return { ...map, [id]: state };\n }\n }\n\n return map;\n },\n});\n\nexport type XmlTagsOptions = {\n /** Tag registry. */\n registry?: XmlWidgetRegistry;\n\n /** Tags to bookmark for navigation. */\n bookmarks?: string[];\n\n /** Called when widgets are mounted or unmounted. */\n setWidgets?: (widgets: XmlWidgetState[]) => void;\n};\n\n/**\n * Implements custom XML tags via CodeMirror-native Widgets and portaled React/Solid components.\n *\n * Basic mechanism:\n * - Decorations are created from XML tags that matched the provided Widget registry.\n * - Native widgets are rendered inline.\n * - React/Solid widgets are rendered in portals outside of the editor via the PlaceholderWidget.\n * - Widget state can be update via effects.\n * - NOTE: Widget state may be updated BEFORE the widget is mounted.\n */\nexport const xmlTags = ({ registry, setWidgets, bookmarks }: XmlTagsOptions = {}): Extension => {\n const notifier = createWidgetMap(setWidgets);\n const widgetDecorationsField = createWidgetDecorationsField(registry, notifier);\n\n return [\n widgetContextStateField,\n widgetStateMapStateField,\n widgetDecorationsField,\n createWidgetUpdatePlugin(widgetDecorationsField, notifier),\n createNavigationEffectPlugin(widgetDecorationsField, bookmarks),\n bookmarks?.length ? Prec.highest(keyHandlers) : [],\n ];\n};\n\n/**\n * Manages the collection of widgets.\n */\nconst createWidgetMap = (setWidgets?: (widgets: XmlWidgetState[]) => void): XmlWidgetNotifier => {\n const widgets = new Map<string, XmlWidgetState>();\n\n // TODO(burdon): Batch updates?\n const notifier = {\n mounted: (state: XmlWidgetState) => {\n log('widget mounted', { id: state.id, tag: state.props._tag });\n widgets.set(state.id, state);\n setWidgets?.([...widgets.values()]);\n },\n unmounted: (id: string) => {\n const state = widgets.get(id);\n log('widget unmounted', { id, tag: state?.props._tag });\n widgets.delete(id);\n setWidgets?.([...widgets.values()]);\n },\n } satisfies XmlWidgetNotifier;\n\n return notifier;\n};\n\n/**\n * Navigation keys.\n */\nconst keyHandlers = keymap.of([\n {\n key: 'Mod-ArrowUp',\n run: (view) => {\n view.dispatch({ effects: navigatePreviousEffect.of() });\n return true;\n },\n },\n {\n key: 'Mod-ArrowDown',\n run: (view) => {\n view.dispatch({ effects: navigateNextEffect.of() });\n return true;\n },\n },\n]);\n\n/**\n * Effect processing plugin for navigation.\n * Handles navigation up/down effects.\n */\nconst createNavigationEffectPlugin = (\n widgetDecorationsField: StateField<WidgetDecorationSet>,\n bookmarks?: string[],\n) => {\n return EditorView.updateListener.of((update) => {\n update.transactions.forEach((transaction) => {\n for (const effect of transaction.effects) {\n if (effect.is(navigatePreviousEffect)) {\n const view = update.view;\n const cursorPos = view.state.doc.lineAt(view.state.selection.main.head).from;\n let widget: { from: number; to: number; tag: string } | null = null;\n const { decorations } = view.state.field(widgetDecorationsField);\n for (const range of decorationSetToArray(decorations)) {\n if (range.from < cursorPos) {\n const tag = range.value.spec.tag;\n if (bookmarks?.includes(tag)) {\n if (!widget || range.from > widget.from) {\n widget = { from: range.from, to: range.to, tag };\n }\n }\n }\n }\n\n const line = view.state.doc.lineAt(widget?.from ?? 0);\n view.dispatch({\n selection: { anchor: line.from, head: line.from },\n effects: scrollerLineEffect.of({ line: line.number - 1, offset: -16 }),\n });\n\n continue;\n }\n\n if (effect.is(navigateNextEffect)) {\n const view = update.view;\n const cursorPos = view.state.doc.lineAt(view.state.selection.main.head).to;\n let widget: { from: number; to: number; tag: string } | null = null;\n const { decorations } = view.state.field(widgetDecorationsField);\n for (const range of decorationSetToArray(decorations)) {\n if (range.from > cursorPos) {\n const tag = range.value.spec.tag;\n if (bookmarks?.includes(tag)) {\n if (!widget || range.from < widget.from) {\n widget = { from: range.from, to: range.to, tag };\n }\n }\n }\n }\n\n if (widget) {\n const line = view.state.doc.lineAt(widget?.from);\n view.dispatch({\n selection: { anchor: line.to, head: line.to },\n effects: scrollerLineEffect.of({ line: line.number - 1, offset: -16 }),\n });\n } else {\n const line = view.state.doc.lineAt(view.state.doc.length);\n view.dispatch({\n selection: { anchor: line.to, head: line.to },\n effects: scrollerLineEffect.of({ line: line.number - 1, position: 'end' }),\n });\n }\n\n continue;\n }\n }\n });\n });\n};\n\n/**\n * Handles effect that updates widget state.\n */\nconst createWidgetUpdatePlugin = (\n widgetDecorationsField: StateField<WidgetDecorationSet>,\n notifier: XmlWidgetNotifier,\n) =>\n ViewPlugin.fromClass(\n class {\n update(update: ViewUpdate) {\n const widgetStateMap = update.state.field(widgetStateMapStateField);\n const { decorations } = update.state.field(widgetDecorationsField);\n\n // Check for widget update effects and re-render widgets.\n for (const effect of update.transactions.flatMap((tr) => tr.effects)) {\n if (effect.is(xmlTagUpdateEffect)) {\n const widgetState = widgetStateMap[effect.value.id];\n\n // Find and render widget.\n for (const range of decorationSetToArray(decorations)) {\n const deco = range.value;\n const widget = deco?.spec?.widget;\n\n // NOTE: If the widget has not yet been mounted, then the root will be null.\n if (widget && widget instanceof PlaceholderWidget && widget.id === effect.value.id && widget.root) {\n const props = { ...widget.props, ...widgetState };\n notifier.mounted({ id: widget.id, props, root: widget.root, Component: widget.Component });\n }\n }\n }\n }\n }\n },\n );\n\n/**\n * Builds and maintains decorations for XML widgets.\n * Must be a StateField because block decorations cannot be provided via ViewPlugin.\n */\nconst createWidgetDecorationsField = (registry: XmlWidgetRegistry = {}, notifier: XmlWidgetNotifier) =>\n StateField.define<WidgetDecorationSet>({\n create: (state) => {\n return buildDecorations(state, { from: 0, to: state.doc.length }, registry, notifier);\n },\n update: ({ from, streamingFrom, decorations }, tr) => {\n // Check for reset effect.\n for (const effect of tr.effects) {\n if (effect.is(xmlTagResetEffect)) {\n if (tr.docChanged) {\n return buildDecorations(tr.state, { from: 0, to: tr.state.doc.length }, registry, notifier);\n }\n return { from: 0, decorations: Decoration.none };\n }\n }\n\n if (tr.docChanged) {\n const { state } = tr;\n // Flag if the transaction has modified the head of the document.\n const reset = tr.changes.touchesRange(0, from);\n if (reset) {\n log('document reset', { from, to: state.doc.length });\n // Full rebuild from start.\n return buildDecorations(state, { from: 0, to: state.doc.length }, registry, notifier);\n } else {\n // Rebuild from the streaming tag start (if active) so the tree walk can detect completion.\n const rebuildFrom = streamingFrom ?? from;\n const result = buildDecorations(state, { from: rebuildFrom, to: state.doc.length }, registry, notifier);\n return {\n from: result.from,\n streamingFrom: result.streamingFrom,\n decorations: decorations.update({\n // Remove old streaming decorations — they are rebuilt each tick.\n filter: (_f, _t, deco) => !deco.spec.streaming,\n add: decorationSetToArray(result.decorations),\n }),\n };\n }\n }\n\n return { from, streamingFrom, decorations };\n },\n provide: (field) => [\n EditorView.decorations.from(field, (v) => v.decorations),\n EditorView.atomicRanges.of((view) => view.state.field(field).decorations || Decoration.none),\n ],\n });\n\n/**\n * Creates widget decorations for XML tags in the document using the syntax tree.\n * After the tree walk, scans for unclosed streaming tags and creates provisional decorations.\n */\nconst buildDecorations = (\n state: EditorState,\n range: Range,\n registry: XmlWidgetRegistry,\n notifier: XmlWidgetNotifier,\n): WidgetDecorationSet => {\n const context = state.field(widgetContextStateField, false);\n const widgetStateMap = state.field(widgetStateMapStateField, false) ?? {};\n const builder = new RangeSetBuilder<Decoration>();\n\n const tree = syntaxTree(state);\n if (!tree || (tree.type.name === 'Program' && tree.length === 0)) {\n return { from: range.from, decorations: Decoration.none };\n }\n\n let last = range.from;\n let streamingFrom: number | undefined;\n\n tree.iterate({\n from: range.from,\n to: range.to,\n enter: (node) => {\n switch (node.type.name) {\n // XML Element.\n case 'Element': {\n try {\n const args = nodeToJson(state, node.node);\n if (args) {\n const def = registry[args._tag];\n if (def) {\n // Skip unclosed streaming elements — the unclosed tag scan handles them.\n if (def.streaming && !node.node.getChild('CloseTag')) {\n return false;\n }\n\n // NOTE: The widget state may already have been updated before the widget is mounted.\n const { block, factory, Component } = def;\n const nodeRange = { from: node.node.from, to: node.node.to };\n const widgetId = xmlWidgetId(\n args.id,\n def.streaming ? `cm-xml-${nodeRange.from}` : `cm-xml-${nodeRange.from}-${nodeRange.to}`,\n );\n const widgetState = widgetStateMap[widgetId];\n const props = {\n id: widgetId,\n range: nodeRange,\n context,\n ...args,\n ...widgetState,\n } satisfies XmlWidgetProps;\n\n // Create widget.\n const widget: WidgetType | undefined = factory\n ? (factory(props) ?? undefined)\n : Component\n ? new PlaceholderWidget(widgetId, Component, props, notifier)\n : undefined;\n\n // Add decoration.\n if (widget) {\n builder.add(\n nodeRange.from,\n nodeRange.to,\n Decoration.replace({\n widget,\n block,\n atomic: true,\n inclusive: true,\n tag: args._tag,\n }),\n );\n\n // Track last widget (NOTE: range is inclusive).\n last = nodeRange.to - 1;\n }\n }\n }\n } catch (err) {\n log.catch(err);\n }\n\n // Don't descend into children.\n return false;\n }\n }\n },\n });\n\n // Scan for unclosed streaming tags at the document tail.\n const streamingTagNames = Object.entries(registry)\n .filter(([, def]) => def.streaming)\n .map(([name]) => name)\n // Longest names first so `react-widget` wins over `react` in alternation.\n .sort((a, b) => b.length - a.length);\n\n if (streamingTagNames.length > 0) {\n const tailText = state.sliceDoc(range.from, range.to);\n const streamingPattern = streamingTagNames.map(escapeRegExpSource).join('|');\n const tagPattern = new RegExp(`<(${streamingPattern})(\\\\s[^>]*)?>`, 'g');\n let match: RegExpExecArray | null;\n\n while ((match = tagPattern.exec(tailText)) !== null) {\n const tagName = match[1];\n const closeTag = `</${tagName}>`;\n const afterOpen = match.index + match[0].length;\n\n // Only process if there's no closing tag after this opening tag.\n if (tailText.indexOf(closeTag, afterOpen) === -1) {\n const absoluteFrom = range.from + match.index;\n const contentFrom = range.from + afterOpen;\n const innerText = state.sliceDoc(contentFrom, range.to).trim();\n\n const def = registry[tagName];\n const props: XmlWidgetProps = {\n _tag: tagName,\n context,\n range: { from: absoluteFrom, to: range.to },\n children: innerText ? [innerText] : undefined,\n };\n\n // Parse attributes from the opening tag.\n const attrPattern = /(\\w+)=\"([^\"]*)\"/g;\n let attrMatch: RegExpExecArray | null;\n while ((attrMatch = attrPattern.exec(match[0])) !== null) {\n props[attrMatch[1]] = attrMatch[2];\n }\n\n const widgetId = xmlWidgetId(props.id, `cm-xml-${absoluteFrom}`);\n const widgetState = widgetStateMap[widgetId];\n const mergedProps = { ...props, id: widgetId, ...widgetState };\n\n const widget: WidgetType | undefined = def.factory\n ? (def.factory(mergedProps) ?? undefined)\n : def.Component\n ? new PlaceholderWidget(widgetId, def.Component, mergedProps, notifier, true)\n : undefined;\n\n if (widget) {\n builder.add(\n absoluteFrom,\n range.to,\n Decoration.replace({\n widget,\n block: def.block,\n atomic: true,\n inclusive: true,\n tag: tagName,\n streaming: true,\n contentFrom,\n }),\n );\n\n // Set from to just before the streaming tag so next rebuild covers it.\n streamingFrom = absoluteFrom;\n last = absoluteFrom;\n }\n\n // Only one streaming tag at a time.\n break;\n }\n }\n }\n\n return { from: last, streamingFrom, decorations: builder.finish() };\n};\n\n/**\n * Placeholder for widgets.\n */\nclass PlaceholderWidget<TProps extends XmlWidgetProps> extends WidgetType {\n #root: HTMLElement | null = null;\n #view: EditorView | undefined;\n\n constructor(\n readonly id: string,\n readonly Component: FunctionComponent<TProps>,\n readonly props: TProps,\n readonly notifier: XmlWidgetNotifier,\n readonly streaming?: boolean,\n ) {\n super();\n invariant(id);\n }\n\n get root(): HTMLElement | null {\n return this.#root;\n }\n\n override eq(other: this) {\n // Streaming widgets always need updating (content changes on each tick).\n if (this.streaming) {\n return false;\n }\n\n return this.id === other.id;\n }\n\n override ignoreEvent() {\n return true;\n }\n\n override toDOM(view: EditorView) {\n this.#view = view;\n // NOTE: Set min-height to avoid jumps while scrolling.\n this.#root = Domino.of('div').classNames('min-h-[24px]').root;\n const props = Object.assign({}, this.props, { view }) as TProps;\n this.notifier.mounted({ id: this.id, root: this.#root, props, Component: this.Component });\n return this.#root;\n }\n\n override updateDOM(dom: HTMLElement) {\n this.#root = dom;\n const props = Object.assign({}, this.props, { view: this.#view }) as TProps;\n this.notifier.mounted({ id: this.id, root: this.#root, props, Component: this.Component });\n return true;\n }\n\n override destroy(_dom: HTMLElement) {\n this.notifier.unmounted(this.id);\n this.#root = null;\n this.#view = undefined;\n }\n}\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { type EditorState } from '@codemirror/state';\nimport { type SyntaxNode } from '@lezer/common';\n\nimport { invariant } from '@dxos/invariant';\n\nexport type Tag = Record<string, any> & {\n _tag: string;\n};\n\n/**\n * Parse XML Element.\n */\nexport const nodeToJson = (state: EditorState, node: SyntaxNode): Tag | undefined => {\n invariant(node.type.name === 'Element', 'Node is not an Element');\n\n // Find the opening tag.\n const openTag = node.node.getChild('OpenTag') || node.node.getChild('SelfClosingTag');\n if (openTag) {\n // Extract tag name.\n const tagName = openTag.getChild('TagName');\n if (!tagName) {\n return;\n }\n\n const tag: Tag = {\n _tag: state.doc.sliceString(tagName.from, tagName.to),\n };\n\n // Extract attributes.\n let attributeNode = openTag.getChild('Attribute');\n while (attributeNode) {\n const attrName = attributeNode.getChild('AttributeName');\n if (attrName) {\n const attr = state.doc.sliceString(attrName.from, attrName.to);\n\n // Default for attributes without values.\n let value: any = undefined;\n const attrValue = attributeNode.getChild('AttributeValue');\n if (attrValue) {\n const rawValue = state.doc.sliceString(attrValue.from, attrValue.to);\n if (\n (rawValue.startsWith('\"') && rawValue.endsWith('\"')) ||\n (rawValue.startsWith(\"'\") && rawValue.endsWith(\"'\"))\n ) {\n // Remove quotes if present.\n value = rawValue.slice(1, -1);\n } else {\n value = rawValue;\n }\n }\n\n tag[attr] = value;\n }\n\n // Get next sibling attribute.\n attributeNode = attributeNode.nextSibling;\n }\n\n // Extract children for non-self-closing tags.\n if (node.type.name === 'Element' && openTag.type.name !== 'SelfClosingTag') {\n const children: any[] = [];\n let child = node.node.firstChild;\n\n const appendText = (raw: string) => {\n if (raw.length === 0) {\n return;\n }\n const last = children[children.length - 1];\n if (typeof last === 'string') {\n children[children.length - 1] = last + raw;\n } else {\n children.push(raw);\n }\n };\n\n while (child) {\n // Skip the opening and closing tags.\n if (child.type.name !== 'OpenTag' && child.type.name !== 'CloseTag') {\n if (child.type.name === 'Text') {\n appendText(state.doc.sliceString(child.from, child.to));\n } else if (child.type.name === 'EntityReference' || child.type.name === 'CharacterReference') {\n appendText(decodeXmlEntity(state.doc.sliceString(child.from, child.to)));\n } else if (child.type.name === 'Element') {\n const data = nodeToJson(state, child);\n if (data) {\n children.push(data);\n }\n }\n }\n child = child.nextSibling;\n }\n\n // Trim only leading/trailing whitespace on the outer-boundary string segments —\n // interior strings are preserved verbatim so meaningful whitespace around inline\n // child elements (e.g. `<reasoning>foo <ref/> bar</reasoning>`) is not collapsed.\n if (children.length > 0 && typeof children[0] === 'string') {\n children[0] = children[0].trimStart();\n }\n if (children.length > 0) {\n const lastIndex = children.length - 1;\n const last = children[lastIndex];\n if (typeof last === 'string') {\n children[lastIndex] = last.trimEnd();\n }\n }\n const trimmed = children.filter((value) => typeof value !== 'string' || value.length > 0);\n\n if (trimmed.length > 0) {\n tag.children = trimmed;\n }\n }\n\n return tag;\n }\n};\n\n/**\n * Decode the common XML named entities and numeric character references that\n * Lezer XML produces as `EntityReference` / `CharacterReference` nodes.\n */\nconst XML_NAMED_ENTITIES: Record<string, string> = {\n '<': '<',\n '>': '>',\n '&': '&',\n '"': '\"',\n ''': \"'\",\n};\n\nconst decodeXmlEntity = (raw: string): string => {\n const named = XML_NAMED_ENTITIES[raw];\n if (named !== undefined) {\n return named;\n }\n const numeric = /^&#(x?)([0-9a-fA-F]+);$/.exec(raw);\n if (numeric) {\n const code = parseInt(numeric[2], numeric[1] ? 16 : 10);\n if (Number.isFinite(code)) {\n try {\n return String.fromCodePoint(code);\n } catch {\n // Fall through and return the raw text on out-of-range code points.\n }\n }\n }\n return raw;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["EditorState", "EditorView", "keymap", "tags", "TextKind", "mx", "editorClassNames", "role", "documentSlots", "content", "className", "compactSlots", "mobileSlots", "RangeSetBuilder", "Decoration", "EditorView", "ViewPlugin", "annotationMark", "mark", "class", "annotations", "match", "fromClass", "decorations", "none", "update", "builder", "from", "to", "view", "viewport", "text", "state", "doc", "sliceString", "matches", "matchAll", "m", "index", "undefined", "start", "end", "length", "add", "finish", "v", "theme", "textDecoration", "textDecorationStyle", "textDecorationColor", "Prec", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "keymap", "autocomplete", "onSuggest", "suggest", "fromClass", "_decorations", "_currentSuggestion", "view", "computeDecorations", "update", "docChanged", "selectionSet", "text", "state", "doc", "toString", "suggestions", "length", "none", "suffix", "slice", "set", "widget", "InlineSuggestionWidget", "side", "range", "completeSuggestion", "dispatch", "changes", "from", "insert", "selection", "anchor", "decorations", "v", "theme", "opacity", "highest", "of", "key", "preventDefault", "run", "plugin", "main", "head", "eq", "other", "toDOM", "span", "document", "createElement", "textContent", "className", "staticCompletion", "completions", "options", "line", "length", "default", "parts", "split", "filter", "Boolean", "str", "at", "minLength", "completion", "match", "matchCompletion", "startsWith", "slice", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "Facet", "singleValueFacet", "defaultValue", "define", "combine", "providers", "overlap", "a", "b", "from", "to", "defaultCursorConverter", "toCursor", "position", "toString", "fromCursor", "cursor", "parseInt", "Cursor", "converter", "singleValueFacet", "getCursorFromRange", "state", "range", "cursorConverter", "facet", "join", "getRangeFromCursor", "parts", "split", "undefined", "decorationSetToArray", "deco", "ranges", "iter", "value", "push", "from", "to", "next", "log", "join", "fn", "catch", "err", "label", "update", "trs", "changes", "undefined", "tr", "fromA", "toA", "fromB", "toB", "inserted", "filter", "Boolean", "flattenRect", "rect", "left", "x", "right", "top", "bottom", "scratchRange", "textRange", "node", "from", "to", "range", "document", "createRange", "setEnd", "setStart", "clientRectsFor", "dom", "nodeType", "nodeValue", "length", "getClientRects", "insertAtCursor", "view", "from", "insert", "dispatch", "changes", "to", "selection", "anchor", "length", "head", "insertAtLineStart", "line", "state", "doc", "lineAt", "placeholder", "content", "delay", "focusOnly", "plugin", "ViewPlugin", "fromClass", "_timeout", "_decorations", "Decoration", "none", "update", "docChanged", "selectionSet", "focusChanged", "window", "clearTimeout", "undefined", "view", "hasFocus", "activeLine", "state", "doc", "lineAt", "selection", "main", "head", "text", "trim", "lineStart", "from", "setTimeout", "set", "widget", "PlaceholderWidget", "side", "range", "destroy", "provide", "EditorView", "decorations", "of", "contentAttributes", "WidgetType", "toDOM", "wrap", "document", "createElement", "className", "style", "pointerEvents", "setAttribute", "appendChild", "createTextNode", "cloneNode", "coordsAt", "dom", "rects", "firstChild", "clientRectsFor", "length", "getComputedStyle", "parentNode", "rect", "flattenRect", "direction", "lineHeight", "parseInt", "bottom", "top", "left", "right", "ignoreEvent", "EditorSelection", "Prec", "RangeSetBuilder", "Decoration", "ViewPlugin", "keymap", "typeahead", "onComplete", "hint", "complete", "view", "selection", "state", "main", "dispatch", "changes", "from", "to", "insert", "EditorSelection", "cursor", "length", "ViewPlugin", "fromClass", "decorations", "Decoration", "none", "update", "builder", "RangeSetBuilder", "line", "doc", "lineAt", "str", "sliceDoc", "add", "widget", "PlaceholderWidget", "finish", "v", "Prec", "highest", "keymap", "of", "key", "preventDefault", "run", "StateEffect", "EditorView", "ViewPlugin", "addEventListener", "combine", "throttle", "Domino", "getSize", "StateEffect", "EditorView", "ViewPlugin", "log", "__dxlog_file", "effects", "scrollerLineEffect", "options", "scrollPlugin", "fromClass", "ScrollerPlugin", "crawler", "destroy", "cancel", "crawl", "start", "scroll", "scrollerRect", "scrollDOM", "getBoundingClientRect", "doc", "view", "targetScrollTop", "scrollHeight", "clientHeight", "offset", "line", "coords", "coordsAtPos", "currentScrollTop", "position", "requestAnimationFrame", "update", "plugin", "effect", "transaction", "value", "overflowY", "height", "right", "currentTop", "velocity", "rafId", "lastTime", "frame", "targetTop", "el", "delta", "Math", "snapThreshold", "scrollTop", "dt", "cancelAnimationFrame", "autoScrollEffect", "StateEffect", "define", "autoScroll", "scrollOnResize", "buttonContainer", "isPinned", "jumpPending", "enabled", "firstUpdate", "setPinned", "pinned", "classList", "toggle", "EditorView", "updateListener", "of", "update", "view", "heightChanged", "state", "startState", "tr", "transactions", "effect", "effects", "is", "value", "dispatch", "scrollerCrawlEffect", "doc", "length", "requestAnimationFrame", "scrollDOM", "scrollTop", "scrollHeight", "clientHeight", "delta", "ViewPlugin", "fromClass", "observer", "firstObservation", "destroyed", "onResize", "throttle", "scrollTo", "top", "behavior", "ResizeObserver", "observe", "destroy", "disconnect", "cleanup", "createUserScrollDetector", "icon", "Domino", "classNames", "getSize", "attributes", "button", "append", "on", "scrollerLineEffect", "line", "position", "root", "parentElement", "appendChild", "element", "onUserScroll", "combine", "addEventListener", "passive", "event", "clientX", "getBoundingClientRect", "right", "offsetWidth", "clientWidth", "next", "A", "StateField", "Transaction", "EditorView", "ViewPlugin", "DocAccessor", "Transaction", "initialSync", "userEvent", "of", "fromCursor", "toCursor", "log", "__dxlog_file", "cursorConverter", "accessor", "catch", "err", "Annotation", "StateEffect", "getPath", "state", "field", "path", "getLastHeads", "lastHeads", "updateHeadsEffect", "define", "updateHeads", "newHeads", "of", "reconcileAnnotation", "isReconcile", "tr", "annotation", "next", "A", "log", "next", "A", "updateAutomerge", "field", "handle", "transactions", "state", "lastHeads", "path", "hasChanges", "tr", "changes", "iterChanges", "undefined", "newHeads", "changeAt", "doc", "invertedTransactions", "fromA", "toA", "_fromB", "_toB", "insert", "push", "from", "del", "reverse", "forEach", "splice", "slice", "toString", "ChangeSet", "updateCodeMirror", "view", "selection", "target", "patches", "patch", "changeSpec", "handlePatch", "state", "changeSet", "ChangeSet", "of", "doc", "length", "map", "dispatch", "changes", "annotations", "reconcileAnnotation", "action", "handleInsert", "handleSplice", "handleDel", "handlePut", "index", "charPath", "path", "text", "values", "value", "toString", "join", "from", "to", "insert", "textPath", "candidatePath", "i", "__dxlog_file", "_pending", "_state", "reconcile", "editor", "onEditorChange", "onAutomergeChange", "view", "log", "state", "unreconciledTransactions", "filter", "newHeads", "effects", "annotations", "getLastHeads", "diff", "equals", "oldHeads", "selection", "path", "getPath", "A", "updateCodeMirror", "automerge", "accessor", "syncState", "StateField", "define", "create", "path", "slice", "lastHeads", "A", "getHeads", "handle", "doc", "unreconciledTransactions", "update", "value", "tr", "result", "clearUnreconciled", "effect", "effects", "is", "updateHeadsEffect", "newHeads", "isReconcile", "push", "syncer", "Syncer", "Cursor", "converter", "of", "cursorConverter", "ViewPlugin", "fromClass", "_view", "addListener", "_handleChange", "requestAnimationFrame", "DocAccessor", "getValue", "current", "state", "toString", "dispatch", "changes", "from", "to", "length", "insert", "annotations", "initialSync", "reconcileAnnotation", "destroy", "removeListener", "reconcile", "EditorView", "updateListener", "view", "transactions", "empty", "isInitialSync", "some", "annotation", "Transaction", "userEvent", "Annotation", "RangeSet", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "Event", "Context", "__dxlog_file", "dummyProvider", "open", "close", "getRemoteStates", "update", "awarenessProvider", "RemoteSelectionChangedAnnotation", "Annotation", "provider", "ViewPlugin", "value", "styles", "_cursorConverter", "_provider", "_lastAnchor", "_lastHead", "decorations", "view", "remoteStateChange", "on", "dispatch", "annotations", "destroy", "_updateRemoteSelections", "_updateLocalSelection", "undefined", "anchor", "head", "toCursor", "awarenessStates", "state", "position", "startLine", "start", "endLine", "end", "darkColor", "lightColor", "info", "number", "attributes", "class", "Decoration", "from", "linePos", "side", "block", "widget", "RemoteCaretWidget", "toDOM", "span", "style", "backgroundColor", "_color", "borderColor", "dot", "createElement", "className", "document", "innerText", "_name", "appendChild", "createTextNode", "updateDOM", "estimatedHeight", "ignoreEvent", "EditorView", "borderRight", "marginLeft", "marginRight", "boxSizing", "display", "cursor", "width", "height", "top", "left", "transition", "fontSize", "fontFamily", "fontStyle", "fontWeight", "lineHeight", "userSelect", "color", "padding", "zIndex", "borderRadius", "opacity", "transitionDelay", "whiteSpace", "DeferredTask", "Event", "sleep", "Context", "invariant", "log", "__dxlog_file", "DEBOUNCE_INTERVAL", "_messenger", "_channel", "_peerId", "_info", "_ctx", "_postTask", "_localState", "remoteStateChange", "messenger", "channel", "peerId", "info", "open", "postMessage", "kind", "state", "catch", "err", "debug", "close", "undefined", "getRemoteStates", "update", "position", "schedule", "_handleQueryMessage", "_handlePostMessage", "message", "_remoteStates", "EditorView", "keymap", "defaultsDeep", "throttle", "invariant", "__dxlog_file", "defaultOptions", "maxParticles", "particleGravity", "particleAlphaFadeout", "particleSize", "particleNumRange", "particleVelocityRange", "particleShrinkRate", "shakeIntensity", "blast", "last", "element", "document", "elementFromPoint", "offsetLeft", "left", "offsetTop", "top", "view", "scrollDOM", "point", "x", "y", "blaster", "update", "destroy", "Blaster", "color", "random", "initialize", "start", "resize", "current", "any", "event", "time", "_effect", "_canvas", "_ctx", "_running", "_lastTime", "_shakeTime", "_shakeTimeMax", "_particles", "_particlePointer", "_lastPoint", "_options", "node", "style", "position", "pointerEvents", "parent", "appendChild", "undefined", "width", "height", "stop", "loop", "now", "Date", "getTime", "dt", "shakeY", "magnitude", "_node", "transform", "shakeX", "drawParticles", "requestAnimationFrame", "shake", "spawn", "numParticles", "dir", "i", "particle", "vx", "vy", "size", "alpha", "ctx", "fillStyle", "fillRect", "round", "theta", "drag", "wander", "Math", "beginPath", "arc", "fill", "bgColor", "getComputedStyle", "min", "RangeSetBuilder", "Decoration", "EditorView", "ViewPlugin", "mx", "paragraphBlockPlugin", "fromClass", "decorations", "view", "build", "update", "docChanged", "viewportChanged", "state", "builder", "pushBlock", "fromLine", "toLine", "lineNum", "line", "doc", "add", "from", "class", "blockStart", "consecutiveBlankLines", "totalLines", "lines", "i", "isBlank", "test", "text", "lastNonBlankLine", "finish", "v", "blocks", "baseTheme", "paddingLeft", "paddingRight", "borderLeft", "borderRight", "border", "borderRadius", "paddingTop", "paddingBottom", "marginTop", "marginBottom", "borderTop", "borderTopLeftRadius", "borderTopRightRadius", "borderBottom", "borderBottomLeftRadius", "borderBottomRightRadius", "Prec", "StateEffect", "StateField", "keymap", "log", "__dxlog_file", "addBookmark", "clearBookmarks", "define", "bookmarks", "bookmarksField", "tr", "value", "changes", "bookmark", "effect", "is", "invertedEffects", "StateEffect", "StateField", "Decoration", "EditorView", "ViewPlugin", "hoverTooltip", "keymap", "sortBy", "debounce", "log", "isNonNullable", "Transaction", "EditorView", "keymap", "debounce", "invariant", "isTruthy", "__dxlog_file", "createEditorStateTransaction", "scrollTo", "selection", "scrollIntoView", "effects", "undefined", "annotations", "Transaction", "invariant", "id", "state", "parse", "setState", "localStorage", "setItem", "transactions", "some", "tr", "isUserEvent", "stateRestoreAnnotation", "pos", "x", "y", "scrollTop", "setStateDebounced", "anchor", "head", "getState", "key", "view", "dispatch", "__dxlog_file", "setComments", "setCommentState", "StateEffect", "define", "state", "documentId", "comments", "selection", "tr", "effect", "setSelection", "value", "commentStates", "cursor", "range", "comment", "filter", "padding", "EditorView", "backgroundColor", "color", "Decoration", "decorations", "log", "undefined", "mark", "isNonNullable", "commentClickedEffect", "click", "event", "view", "target", "editorRoot", "commentId", "effects", "handleTrack", "selectedRanges", "length", "tracked", "id", "from", "main", "to", "invertedEffects", "changes", "iterChangedRanges", "fromA", "toA", "restoreCommentEffect", "update", "transactions", "j", "restore", "mapTrackedComment", "paste", "found", "text", "indexOf", "fromB", "push", "exists", "some", "Cursor", "getCursorFromRange", "onUpdate", "mapPos", "insert", "options", "onCreate", "location", "optionsFacet", "handleSelect", "debounce", "commentsState", "commentsDecorations", "handleCommentClick", "styles", "key", "shortcut", "pos", "end", "above", "create", "renderTooltip", "dom", "offset", "x", "field", "iterChanges", "forEach", "from2", "to2", "newRange", "onDelete", "Object", "assign", "mod", "current", "closest", "head", "min", "d", "currentSelection", "currentScrollPosition", "targetScrollPosition", "coordsAtPos", "needsScroll", "needsSelectionUpdate", "anchor", "y", "subscribe", "getComments", "facet", "queueMicrotask", "dispatch", "destroy", "ExternalCommentSync", "syntaxTree", "StateField", "debugNodeLogger", "log", "console", "logTokens", "state", "iterate", "enter", "node", "type", "define", "create", "update", "_", "tr", "EditorView", "dropCursor", "dropFile", "options", "styles", "domEventHandlers", "drop", "event", "view", "preventDefault", "files", "dataTransfer", "pos", "posAtCoords", "length", "dispatch", "selection", "anchor", "onDrop", "theme", "borderLeft", "color", "padding", "content", "closeBrackets", "closeBracketsKeymap", "defaultKeymap", "history", "historyKeymap", "indentWithTab", "standardKeymap", "HighlightStyle", "bracketMatching", "syntaxHighlighting", "searchKeymap", "EditorState", "EditorView", "ViewPlugin", "drawSelection", "dropCursor", "highlightActiveLine", "keymap", "lineNumbers", "placeholder", "vscodeDarkStyle", "vscodeLightStyle", "defaultsDeep", "generateName", "log", "hexToHue", "isTruthy", "EditorView", "mx", "headings", "className", "fontSize", "lineHeight", "fontBody", "fontMono", "markdownTheme", "code", "codeMark", "mark", "heading", "level", "color", "fontWeight", "baseTheme", "outline", "overflowAnchor", "width", "height", "background", "transition", "padding", "borderRight", "paddingRight", "minWidth", "paddingInline", "borderLeft", "margin", "borderRadius", "textDecoration", "textDecorationLine", "textDecorationThickness", "textDecorationColor", "textUnderlineOffset", "border", "overflow", "marginTop", "marginLeft", "maxHeight", "paddingLeft", "borderColor", "display", "backgroundColor", "all", "alignItems", "cursor", "marginRight", "borderTop", "editorGutter", "theme", "createFontTheme", "monospace", "fontFamily", "StateEffect", "StateField", "EditorView", "focusEffect", "define", "focusField", "create", "update", "value", "tr", "effect", "effects", "is", "focus", "domEventHandlers", "_event", "view", "requestAnimationFrame", "dispatch", "of", "blur", "EditorView", "ViewPlugin", "scrollPastEndPlugin", "fromClass", "height", "attrs", "style", "update", "view", "lastLineBlock", "lineBlockAt", "state", "doc", "length", "dom", "clientHeight", "documentPadding", "top", "scrollPastEnd", "contentAttributes", "of", "plugin", "__dxlog_file", "EditorView", "filterChars", "transaction", "docChanged", "changes", "inserted", "filtered", "replace", "chars", "fromB", "toB", "insert", "bracketMatching", "closeBrackets", "drawSelection", "focus", "history", "keymap", "lineWrapping", "search", "keymaps", "standard", "standardKeymap", "default", "defaultKeymap", "createBasicExtensions", "defaultsDeep", "props", "allowMultipleSelections", "EditorState", "of", "dropCursor", "cursorBlinkRate", "undefined", "highlightActiveLine", "lineNumbers", "editorGutter", "readOnly", "placeholder", "tabbable", "tabSize", "historyKeymap", "searchKeymap", "run", "isTruthy", "grow", "className", "dark", "vscodeDarkStyle", "light", "vscodeLightStyle", "baseTheme", "createFontTheme", "monospace", "syntaxHighlightingProp", "slots", "content", "scroller", "ViewPlugin", "view", "scrollDOM", "scrollbarThin", "createDataExtensions", "text", "extensions", "automerge", "messenger", "identity", "profile", "awareness", "SpaceAwarenessProvider", "channel", "id", "peerId", "info", "darkColor", "lightColor", "displayName", "codeFolding", "foldGutter", "EditorView", "Domino", "mx", "folding", "placeholderDOM", "of", "root", "markerDOM", "open", "classNames", "append", "SVG", "attributes", "href", "icon", "theme", "opacity", "transition", "width", "Decoration", "EditorView", "MatchDecorator", "ViewPlugin", "WidgetType", "getHashStyles", "mx", "TagWidget", "_text", "toDOM", "span", "document", "createElement", "className", "surface", "textContent", "tagMatcher", "regexp", "decoration", "match", "replace", "widget", "hashtag", "fromClass", "tags", "view", "createDeco", "update", "updateDeco", "decorations", "instance", "provide", "plugin", "atomicRanges", "of", "none", "theme", "borderRadius", "marginRight", "padding", "json", "jsonParseLinter", "linter", "Ajv", "createJsonExtensions", "schema", "lintSource", "ajv", "allErrors", "strict", "validate", "compile", "schemaLinter", "view", "jsonText", "state", "doc", "toString", "jsonData", "JSON", "parse", "valid", "errors", "map", "err", "from", "to", "length", "severity", "message", "instancePath", "EditorView", "isNonNullable", "listener", "onFocus", "onChange", "EditorView", "focusChangeEffect", "of", "state", "focusing", "id", "facet", "documentId", "updateListener", "docChanged", "text", "doc", "toString", "filter", "isNonNullable", "snippet", "syntaxTree", "EditorSelection", "EditorView", "keymap", "debounceAndThrottle", "formattingEquals", "a", "b", "blockType", "strong", "emphasis", "strikethrough", "code", "link", "listStyle", "blockQuote", "Inline", "List", "setHeading", "level", "state", "dispatch", "selection", "ranges", "doc", "changes", "prevBlock", "range", "sawBlock", "iterate", "from", "to", "enter", "node", "Object", "hasOwn", "Textblocks", "name", "isHeading", "exec", "curLevel", "push", "insert", "repeat", "nextLine", "lineAt", "Math", "min", "line", "empty", "test", "text", "length", "changeSet", "update", "map", "userEvent", "scrollIntoView", "setStyle", "type", "enable", "marker", "inlineMarkerText", "changeByRange", "after", "sliceString", "head", "found", "indexOf", "slice", "before", "reverse", "join", "cursor", "changesAtEnd", "blockStart", "blockEnd", "startCovered", "endCovered", "blockContentStart", "blockContentEnd", "IgnoreInline", "has", "InlineMarker", "markType", "size", "openEnd", "closeStart", "skipMarkers", "skipSpaces", "max", "leave", "rangeStart", "rangeEnd", "concat", "mapPos", "addStyle", "style", "removeStyle", "toggleStyle", "arg", "form", "getFormatting", "toggleStrong", "toggleEmphasis", "toggleStrikethrough", "toggleInlineCode", "atx", "setext", "lastLine", "pos", "dir", "limit", "tree", "next", "resolve", "moveTo", "snippets", "codeblock", "table", "insertTable", "view", "main", "number", "anchor", "removeLinkInner", "removeLink", "addLink", "url", "image", "cutStyles", "okay", "sNode", "firstChild", "lastChild", "changesAfter", "cursorOffset", "mark", "addList", "lastBlock", "counter", "first", "parentColumn", "blocks", "prevSibling", "item", "itemLine", "itemText", "i", "nodeFrom", "padding", "String", "column", "j", "num", "open", "last", "nextSibling", "renumberListItems", "removeList", "stack", "targetNodeType", "pop", "toggleList", "target", "formatting", "active", "newNum", "setBlockquote", "lines", "prevLine", "quote", "addBlockquote", "removeBlockquote", "toggleBlockquote", "addCodeblock", "blockFrom", "blockTo", "removeCodeblock", "firstLine", "toggleCodeblock", "formattingKeymap", "_options", "of", "key", "run", "Emphasis", "StrongEmphasis", "InlineCode", "Strikethrough", "Set", "ATXHeading1", "ATXHeading2", "ATXHeading3", "ATXHeading4", "ATXHeading5", "ATXHeading6", "CodeBlock", "FencedCode", "Paragraph", "SetextHeading1", "SetextHeading2", "TableCell", "Task", "inline", "currentBlock", "advanceInline", "upto", "end", "skipInline", "some", "v", "contextSize", "contextBefore", "contextAfter", "ch", "blockCode", "index", "hasList", "hasQuote", "blankLine", "formattingListener", "onStateChange", "delay", "updateListener", "docChanged", "selectionSet", "processEditorPayload", "view", "type", "data", "inlineType", "listType", "setHeading", "parseInt", "Inline", "Strong", "Emphasis", "Strikethrough", "Code", "setStyle", "toggleStyle", "List", "Ordered", "Bullet", "Task", "removeList", "addList", "toggleList", "removeBlockquote", "addBlockquote", "toggleBlockquote", "removeCodeblock", "addCodeblock", "insertTable", "removeLink", "addLink", "url", "image", "createComment", "requestAnimationFrame", "hasFocus", "focus", "completionKeymap", "defaultKeymap", "indentWithTab", "jsonLanguage", "markdown", "markdownLanguage", "foldNodeProp", "syntaxHighlighting", "languages", "keymap", "isTruthy", "markdownLanguage", "HighlightStyle", "Tag", "styleTags", "tags", "Table", "markdownTags", "Blockquote", "Tag", "define", "CodeMark", "CodeText", "EmphasisMark", "HeaderMark", "InlineCode", "LinkLabel", "LinkReference", "ListMark", "QuoteMark", "URL", "TableCell", "Table", "defineNodes", "forEach", "node", "name", "style", "markdownTagsExtensions", "props", "styleTags", "markdownHighlightStyle", "_options", "HighlightStyle", "tag", "tags", "keyword", "deleted", "character", "propertyName", "macroName", "color", "constant", "standard", "definition", "separator", "typeName", "className", "number", "changed", "annotation", "modifier", "self", "namespace", "operator", "operatorKeyword", "escape", "regexp", "special", "string", "meta", "comment", "atom", "bool", "variableName", "processingInstruction", "inserted", "invalid", "class", "markdownTheme", "mark", "function", "labelName", "codeMark", "monospace", "heading", "fontWeight", "heading1", "heading2", "heading3", "heading4", "heading5", "heading6", "emphasis", "strong", "strikethrough", "code", "scope", "markdownLanguage", "all", "fontFamily", "fontBody", "createMarkdownExtensions", "options", "markdown", "base", "markdownLanguage", "defaultCodeLanguage", "jsonLanguage", "codeLanguages", "languages", "completeHTMLTags", "extensions", "markdownTagsExtensions", "defaultExtensions", "noFencedCodeFolding", "syntaxHighlighting", "markdownHighlightStyle", "keymap", "of", "indentWithTab", "defaultKeymap", "completionKeymap", "filter", "isTruthy", "props", "foldNodeProp", "add", "FencedCode", "noSetExtHeading", "noHtml", "remove", "syntaxTree", "StateField", "debugTree", "cb", "define", "create", "state", "convertTreeToJson", "update", "value", "tr", "treeToJson", "cursor", "node", "type", "name", "from", "to", "text", "doc", "slice", "toString", "children", "firstChild", "push", "nextSibling", "parent", "syntaxTree", "Prec", "RangeSetBuilder", "StateEffect", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "invariant", "syntaxTree", "Transaction", "ViewPlugin", "adjustChanges", "fromClass", "update", "tree", "state", "adjustments", "tr", "transactions", "event", "annotation", "userEvent", "changes", "empty", "iterChanges", "fromA", "node", "resolveInner", "name", "text", "doc", "lineAt", "endsWith", "push", "from", "to", "insert", "toA", "fromB", "toB", "url", "getValidUrl", "view", "sliceDoc", "invalidPositions", "Set", "has", "replacedText", "startState", "createLink", "str", "toString", "match", "replacement", "length", "setTimeout", "dispatch", "label", "host", "pathname", "extension", "split", "imageExtensions", "includes", "createLinkLabel", "protocol", "replace", "filter", "Boolean", "join", "validProtocols", "URL", "undefined", "_err", "syntaxTree", "StateField", "Decoration", "EditorView", "WidgetType", "image", "_options", "StateField", "define", "create", "state", "Decoration", "set", "buildDecorations", "doc", "length", "update", "value", "tr", "docChanged", "selection", "cursor", "main", "head", "oldCursor", "changes", "mapPos", "startState", "from", "Math", "min", "to", "max", "iterChangedRanges", "fromA", "toA", "fromB", "toB", "lineAt", "map", "filterFrom", "filterTo", "filter", "add", "provide", "field", "EditorView", "decorations", "syntaxTree", "iterate", "enter", "node", "name", "urlNode", "getChild", "hide", "readOnly", "focusField", "url", "sliceDoc", "match", "preloadImage", "push", "replace", "block", "widget", "ImageWidget", "range", "preloaded", "Set", "has", "img", "document", "createElement", "src", "WidgetType", "_url", "eq", "other", "toDOM", "view", "setAttribute", "onload", "classList", "EditorView", "bulletListIndentationWidth", "orderedListIndentationWidth", "formattingStyles", "EditorView", "theme", "display", "width", "height", "verticalAlign", "borderTop", "opacity", "textAlign", "paddingRight", "fontVariant", "background", "borderLeft", "paddingLeft", "margin", "fontFamily", "fontMono", "color", "whiteSpace", "alignItems", "overflow", "paddingInline", "borderTopLeftRadius", "borderTopRightRadius", "borderBottomLeftRadius", "borderBottomRightRadius", "transform", "lineHeight", "textDecoration", "padding", "overflowWrap", "wordBreak", "borderBottom", "transitionDuration", "transitionProperty", "syntaxTree", "RangeSetBuilder", "StateField", "Decoration", "EditorView", "WidgetType", "table", "options", "define", "create", "state", "update", "_", "tr", "provide", "field", "decorations", "from", "_options", "builder", "cursor", "selection", "main", "head", "tables", "getTable", "length", "getRow", "rows", "iterate", "enter", "node", "name", "push", "to", "header", "row", "sliceDoc", "forEach", "replace", "readOnly", "add", "block", "widget", "TableWidget", "mark", "class", "finish", "renderCellContent", "el", "text", "parts", "split", "part", "startsWith", "endsWith", "code", "document", "createElement", "textContent", "slice", "appendChild", "strong", "em", "createTextNode", "_table", "eq", "other", "join", "ignoreEvent", "e", "test", "type", "toDOM", "_view", "div", "cell", "th", "setAttribute", "body", "td", "__dxlog_file", "bullet", "bulletSmall", "bulletSquare", "createElement", "className", "el", "other", "toDOM", "render", "url", "view", "WidgetType", "ignoreEvent", "input", "type", "tabIndex", "checked", "readOnly", "setAttribute", "onmousedown", "event", "doc", "match", "text", "pos", "_checked", "dispatch", "changes", "insert", "span", "appendChild", "innerText", "class", "Decoration", "fencedCodeLine", "fencedCodeLineFirst", "fencedCodeLineLast", "commentBlockLine", "commentBlockLineLast", "horizontalRule", "widget", "HorizontalRuleWidget", "checkedTask", "replace", "uncheckedTask", "head", "from", "autoHideTags", "buildDecorations", "atomicDecoRanges", "focus", "invariant", "level", "headerLevels", "length", "len", "node", "name", "to", "number", "slice", "listLevels", "getCurrentListLevel", "options", "numberedHeadings", "undefined", "header", "state", "push", "deco", "hide", "mark", "TextWidget", "list", "offset", "listPaddingLeft", "line", "attributes", "style", "sliceString", "lineAt", "paragraph", "getChild", "editing", "quoteMark", "block", "decoRanges", "blockQuote", "isFirst", "first", "editingRange", "urlNode", "marks", "sliceDoc", "tagName", "rel", "target", "renderLinkButton", "syntaxTree", "tree", "enter", "leave", "wrapWithCatch", "sort", "sortRanges", "RangeSetBuilder", "d", "atomicDeco", "StateEffect", "ViewPlugin", "pendingUpdate", "update", "clearUpdate", "selectionSet", "scheduleUpdate", "forceUpdate", "selectionChangeDelay", "clearTimeout", "destroy", "provide", "EditorView", "decorations", "atomicRanges", "plugin", "none", "image", "table", "adjustChanges", "formattingStyles", "syntaxTree", "hoverTooltip", "tooltipContent", "linkTooltip", "renderTooltip", "view", "pos", "side", "syntax", "state", "resolveInner", "link", "i", "node", "parent", "name", "url", "getChild", "urlText", "sliceDoc", "from", "to", "startsWith", "end", "above", "create", "el", "document", "createElement", "className", "dom", "offset", "x", "y", "autocompletion", "log", "__dxlog_file", "activateOnTyping", "icons", "context", "match", "explicit", "options", "label", "StateEffect", "StateField", "modalStateEffect", "define", "modalStateField", "create", "update", "value", "tr", "newValue", "effect", "effects", "is", "keymap", "vim", "vscodeKeymap", "editorInputMode", "singleValueFacet", "InputModeExtensions", "default", "vscode", "of", "type", "keymap", "vscodeKeymap", "vim", "ignoreEscape", "key", "run", "view", "dom", "parentElement", "focus", "indentMore", "getIndentUnit", "EditorSelection", "keymap", "Compartment", "Facet", "syntaxTree", "StateField", "Facet", "invariant", "__dxlog_file", "itemToJSON", "type", "index", "level", "lineRange", "contentRange", "children", "node", "from", "to", "toJSON", "root", "traverse", "itemOrCb", "maybeCb", "item", "nextSibling", "parent", "undefined", "lastDescendant", "value", "getListItemContent", "listItemToString", "data", "i", "n", "p", "prevSibling", "format", "line", "content", "JSON", "stringify", "key", "toString", "padStart", "replaceAll", "treeFacet", "combine", "values", "tree", "current", "prev", "prevSiblings", "enter", "lineAt", "docRange", "length", "leave", "buildTree", "update", "tr", "provide", "field", "getSelection", "state", "selection", "main", "selectionEquals", "a", "b", "length", "every", "i", "includes", "selectionFacet", "Facet", "define", "combine", "values", "selectionCompartment", "Compartment", "selectNone", "view", "dispatch", "effects", "reconfigure", "of", "selectAll", "tree", "facet", "treeFacet", "items", "traverse", "item", "push", "index", "selectUp", "selectDown", "indentItemMore", "view", "pos", "getSelection", "state", "from", "tree", "facet", "treeFacet", "current", "find", "previous", "prev", "level", "indentMore", "indentItemLess", "indentUnit", "getIndentUnit", "changes", "traverse", "item", "line", "doc", "lineAt", "lineRange", "push", "to", "length", "dispatch", "moveItemDown", "nextSibling", "next", "currentContent", "sliceString", "getRange", "nextContent", "insert", "selection", "EditorSelection", "cursor", "scrollIntoView", "moveItemUp", "prevSibling", "prevContent", "deleteItem", "Math", "min", "toggleTask", "type", "indent", "repeat", "contentRange", "commands", "keymap", "of", "key", "preventDefault", "run", "shift", "number", "selectAll", "selectNone", "selectUp", "selectDown", "Prec", "Decoration", "EditorView", "ViewPlugin", "mx", "EditorSelection", "EditorState", "ViewPlugin", "log", "__dxlog_file", "LIST_ITEM_REGEX", "view", "first", "state", "doc", "text", "match", "setTimeout", "dispatch", "changes", "from", "insert", "selection", "EditorSelection", "EditorState", "transactionFilter", "tree", "current", "currentItem", "find", "prevItem", "prev", "undefined", "tr", "iterChanges", "line", "startTree", "deleteLine", "fromA", "startItem", "lineRange", "toA", "cancel", "replace", "to", "length", "log", "EditorView", "ViewPlugin", "addEventListener", "menu", "options", "fromClass", "view", "tag", "rafId", "cleanup", "container", "scrollDOM", "getComputedStyle", "position", "style", "icon", "document", "createElement", "setAttribute", "classList", "add", "appendChild", "handler", "scheduleUpdate", "destroy", "remove", "cancelAnimationFrame", "update", "dataset", "focused", "hasFocus", "docChanged", "focusChanged", "geometryChanged", "selectionSet", "viewportChanged", "updateButtonPosition", "x", "width", "contentDOM", "getBoundingClientRect", "pos", "state", "selection", "main", "head", "line", "lineBlockAt", "coords", "coordsAtPos", "from", "lineHeight", "bottom", "top", "dy", "height", "offsetTop", "offsetLeft", "padding", "left", "display", "requestAnimationFrame", "bind", "theme", "border", "opacity", "placeContent", "outliner", "_options", "Prec", "highest", "commands", "selectionCompartment", "of", "selectionFacet", "outlinerTree", "editor", "menu", "decorations", "decorateMarkdown", "listPaddingLeft", "EditorView", "contentAttributes", "class", "ViewPlugin", "fromClass", "Decoration", "none", "view", "updateDecorations", "state", "update", "selectionChanged", "selectionEquals", "facet", "startState", "focusChanged", "docChanged", "viewportChanged", "selectionSet", "viewport", "from", "to", "hasFocus", "selection", "tree", "treeFacet", "current", "find", "ranges", "mainIndex", "doc", "lineNum", "lineAt", "number", "line", "item", "lineFrom", "contentRange", "lineTo", "isSelected", "includes", "index", "push", "mx", "range", "set", "v", "theme", "Object", "assign", "borderLeftWidth", "borderRightWidth", "paddingLeft", "borderColor", "borderRadius", "borderTopWidth", "borderTopLeftRadius", "borderTopRightRadius", "paddingTop", "marginTop", "borderBottomWidth", "borderBottomLeftRadius", "borderBottomRightRadius", "paddingBottom", "marginBottom", "syntaxTree", "RangeSetBuilder", "StateEffect", "StateField", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "DXN", "Entity", "labelResolvedEffect", "define", "preview", "options", "viewRef", "current", "undefined", "create", "state", "buildDecorations", "update", "decorations", "tr", "docChanged", "effects", "some", "effect", "is", "map", "changes", "provide", "field", "from", "atomicRanges", "of", "view", "destroy", "resolveLabel", "db", "dxnStr", "dxn", "tryParse", "ref", "makeRef", "target", "getLabel", "tryLoad", "then", "dispatch", "builder", "iterate", "enter", "node", "name", "link", "getLinkRef", "resolved", "displayLink", "label", "add", "to", "replace", "widget", "PreviewInlineWidget", "side", "addBlockContainer", "removeBlockContainer", "block", "PreviewBlockWidget", "finish", "mark", "getChildren", "urlNode", "getChild", "sliceDoc", "startsWith", "_options", "_link", "eq", "other", "toDOM", "_view", "root", "document", "createElement", "classList", "textContent", "setAttribute", "el", "EditorView", "defaultReplacements", "input", "output", "replacer", "replacements", "sortedReplacements", "sort", "a", "b", "length", "inputHandler", "of", "view", "from", "to", "insert", "state", "doc", "lineStart", "lineAt", "textBefore", "sliceString", "textWithInsert", "replacement", "endsWith", "range", "dispatch", "update", "changes", "selection", "anchor", "keymap", "defaultItems", "snippets", "delay", "items", "timer", "index", "of", "key", "run", "clearTimeout", "view", "text", "length", "offset", "insert", "delayMs", "setTimeout", "pos", "state", "selection", "main", "head", "dispatch", "changes", "from", "anchor", "Math", "random", "Prec", "keymap", "submit", "fireIfEmpty", "onSubmit", "highest", "of", "key", "preventDefault", "run", "view", "text", "state", "doc", "toString", "trim", "length", "reset", "dispatch", "changes", "from", "to", "insert", "selection", "main", "head", "anchor", "xmlLanguage", "parseMixed", "escapeRegExpSource", "value", "replace", "extendedMarkdown", "registry", "createMarkdownExtensions", "extensions", "wrap", "mixedParser", "parseBlock", "name", "parse", "xmlBlockParsers", "customTags", "Object", "keys", "length", "tagPattern", "map", "join", "selfClosePattern", "RegExp", "openPattern", "before", "cx", "line", "match", "exec", "text", "test", "end", "lineStart", "addElement", "elt", "nextLine", "trimEnd", "endsWith", "tagName", "closeTag", "start", "includes", "parseMixed", "node", "input", "parser", "xmlLanguage", "content", "read", "from", "to", "StateEffect", "StateField", "Decoration", "EditorView", "ViewPlugin", "DEFAULT_REMOVAL_DELAY", "DEFAULT_COALESCE_WINDOW", "CLEANUP_INTERVAL", "fader", "options", "removalDelay", "coalesceWindow", "coalesce", "lastCount", "log", "expiries", "length", "dequeue", "define", "fadeField", "create", "decorations", "none", "batchStart", "update", "tr", "effect", "effects", "is", "now", "value", "removeCount", "slice", "skipped", "filter", "docChanged", "isReset", "state", "doc", "startState", "changes", "iterChanges", "fromA", "toA", "Date", "add", "fromB", "toB", "inserted", "push", "from", "to", "canCoalesce", "lastFrom", "lastTo", "between", "mergedFrom", "Math", "min", "mergedTo", "mark", "class", "range", "map", "provide", "f", "cleanup", "fromClass", "view", "field", "clearTimeout", "undefined", "delay", "max", "setTimeout", "dispatch", "of", "destroy", "theme", "animation", "textShadow", "Annotation", "ChangeSet", "EditorState", "StateEffect", "StateField", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "Domino", "typewriterBypass", "define", "typewriterDrainingEffect", "CURSOR_LINGER", "FRAME_BUDGET_MS", "CHARS_PER_FRAME", "FLUSH_THRESHOLD", "COMPACT_HEAD_THRESHOLD", "typewriter", "options", "streamingTags", "Set", "flushThreshold", "frameBudgetMs", "charsPerFrame", "suppressAppend", "insertChunk", "bufferField", "create", "text", "head", "insertAt", "update", "value", "tr", "effect", "effects", "is", "length", "from", "slice", "docChanged", "isReset", "state", "doc", "startState", "changes", "iterChanges", "fromA", "toA", "some", "mapPos", "Math", "min", "filter", "transactionFilter", "of", "annotation", "appendedText", "appendFrom", "isAppendOnly", "_fromB", "_toB", "inserted", "sliceString", "empty", "drainPlugin", "fromClass", "_raf", "_activeStreamTag", "view", "field", "pending", "undefined", "_start", "queueMicrotask", "dispatch", "annotations", "requestAnimationFrame", "_tick", "chunk", "insert", "startTime", "performance", "now", "pos", "activeTag", "charsEmitted", "result", "flushable", "count", "enterTag", "exitTag", "totalCount", "destroy", "cancelAnimationFrame", "cursor", "typewriterCursor", "Boolean", "hideCursor", "visibilityField", "visible", "lastNonWsAt", "_fromA", "_toA", "trim", "decorationField", "none", "_decorations", "cursorAt", "set", "widget", "CursorWidget", "side", "range", "provide", "decorations", "timerPlugin", "_timer", "clearTimeout", "setTimeout", "eq", "other", "toDOM", "inner", "style", "animation", "animationDelay", "opacity", "append", "root", "OPENING_TAG_NAME", "TAG_NAME_PROBE", "escapeRegExpSource", "replace", "buffer", "start", "activeStreamTag", "closeTag", "startsWith", "xmlElementLength", "ch", "probe", "nameMatch", "match", "has", "close", "indexOf", "linkLength", "tagName", "depth", "tagPattern", "RegExp", "lastIndex", "exec", "isSelfClosing", "endsWith", "isClosing", "index", "bracketAt", "bracketClose", "parenClose", "xmlLanguage", "Decoration", "ViewPlugin", "xmlBlockDecoration", "tag", "lineClass", "contentClass", "hideTags", "lineDecoration", "line", "class", "undefined", "contentDecoration", "mark", "hideDecoration", "replace", "buildDecorations", "view", "text", "state", "sliceDoc", "doc", "length", "includes", "none", "tree", "parser", "parse", "ranges", "iterate", "enter", "node", "type", "name", "openTag", "getChild", "closeTag", "tagNameNode", "slice", "from", "to", "contentFrom", "contentTo", "push", "range", "pos", "lineAt", "set", "fromClass", "decorations", "update", "docChanged", "instance", "xmlLanguage", "Decoration", "EditorView", "ViewPlugin", "XML_TAG_NODES", "Set", "xmlElementMark", "mark", "class", "xmlTagMark", "xmlContentMark", "xmlFormatting", "skip", "skipSet", "length", "undefined", "buildDecorations", "view", "text", "state", "sliceDoc", "doc", "includes", "none", "tagNameAt", "node", "slice", "from", "to", "tree", "parser", "parse", "ranges", "iterate", "enter", "name", "type", "tagNameNode", "getChild", "has", "push", "range", "openTag", "closeTag", "set", "fromClass", "decorations", "update", "docChanged", "instance", "baseTheme", "backgroundColor", "borderRadius", "padding", "color", "fontFamily", "syntaxTree", "Prec", "RangeSetBuilder", "StateEffect", "StateField", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "keymap", "invariant", "log", "Domino", "invariant", "__dxlog_file", "openTag", "node", "getChild", "tagName", "attrName", "attributeNode", "state", "sliceString", "value", "undefined", "attrValue", "rawValue", "slice", "attr", "child", "appendText", "length", "children", "last", "push", "raw", "from", "name", "decodeXmlEntity", "doc", "type", "data", "lastIndex", "trimEnd", "tag", "trimmed", "named", "numeric", "code", "Number", "String", "fromCodePoint", "__dxlog_file", "child", "StateEffect", "update", "tr", "effect", "value", "is", "id", "widgetDecorationsField", "createWidgetDecorationsField", "registry", "widgetContextStateField", "widgetStateMapStateField", "createWidgetUpdatePlugin", "createNavigationEffectPlugin", "bookmarks", "highest", "Prec", "notifier", "tag", "_tag", "widgets", "set", "state", "setWidgets", "values", "unmounted", "delete", "key", "keymap", "view", "effects", "transaction", "navigatePreviousEffect", "cursorPos", "lineAt", "widget", "decorations", "range", "from", "selection", "anchor", "line", "scrollerLineEffect", "offset", "doc", "dispatch", "position", "transactions", "flatMap", "widgetState", "widgetStateMap", "decorationSetToArray", "deco", "PlaceholderWidget", "props", "root", "Component", "StateField", "to", "streamingFrom", "docChanged", "buildDecorations", "length", "Decoration", "reset", "changes", "log", "rebuildFrom", "result", "_f", "provide", "EditorView", "field", "builder", "RangeSetBuilder", "tree", "syntaxTree", "type", "last", "iterate", "enter", "node", "def", "widgetId", "xmlWidgetId", "nodeRange", "context", "block", "atomic", "inclusive", "args", "streamingTagNames", "tailText", "sliceDoc", "streamingPattern", "tagPattern", "RegExp", "match", "closeTag", "tagName", "afterOpen", "indexOf", "contentFrom", "innerText", "children", "undefined", "attrMatch", "attrPattern", "mergedProps", "absoluteFrom", "replace", "streaming", "invariant", "other", "ignoreEvent", "toDOM", "Domino", "updateDOM", "dom", "mounted", "destroy", "_dom"]
|
|
7
|
+
}
|