@dxos/ui-editor 0.10.0 → 0.11.1
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/chunk-diff.mjs +935 -0
- package/dist/lib/chunk-diff.mjs.map +1 -0
- package/dist/lib/headless.mjs +2 -0
- package/dist/lib/index.mjs +9937 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/types.mjs +18 -0
- package/dist/lib/types.mjs.map +1 -0
- package/dist/types/src/extensions/{bookmarks.d.ts → behavior/bookmarks.d.ts} +3 -0
- package/dist/types/src/extensions/behavior/bookmarks.d.ts.map +1 -0
- package/dist/types/src/extensions/behavior/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/behavior/index.d.ts +6 -0
- package/dist/types/src/extensions/behavior/index.d.ts.map +1 -0
- package/dist/types/src/extensions/{listener.d.ts → behavior/listener.d.ts} +3 -0
- package/dist/types/src/extensions/behavior/listener.d.ts.map +1 -0
- package/dist/types/src/extensions/{spacing.d.ts → behavior/spacing.d.ts} +3 -0
- package/dist/types/src/extensions/behavior/spacing.d.ts.map +1 -0
- package/dist/types/src/extensions/behavior/submit.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/automerge/automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/automerge/automerge.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/cursor.d.ts +1 -1
- package/dist/types/src/extensions/collab/automerge/cursor.d.ts.map +1 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/defs.d.ts +3 -1
- package/dist/types/src/extensions/collab/automerge/defs.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/automerge/index.d.ts +3 -0
- package/dist/types/src/extensions/collab/automerge/index.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/automerge/sync.d.ts.map +1 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/update-automerge.d.ts +4 -0
- package/dist/types/src/extensions/collab/automerge/update-automerge.d.ts.map +1 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/update-codemirror.d.ts +4 -0
- package/dist/types/src/extensions/collab/automerge/update-codemirror.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/awareness/awareness-provider.d.ts.map +1 -0
- package/dist/types/src/extensions/{awareness → collab/awareness}/awareness.d.ts +4 -1
- package/dist/types/src/extensions/collab/awareness/awareness.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/awareness/index.d.ts.map +1 -0
- package/dist/types/src/extensions/collab/index.d.ts +3 -0
- package/dist/types/src/extensions/collab/index.d.ts.map +1 -0
- package/dist/types/src/extensions/completion/autocomplete.d.ts.map +1 -0
- package/dist/types/src/extensions/{autocomplete → completion}/index.d.ts +1 -0
- package/dist/types/src/extensions/completion/index.d.ts.map +1 -0
- package/dist/types/src/extensions/{autocomplete → completion}/match.d.ts +2 -2
- package/dist/types/src/extensions/completion/match.d.ts.map +1 -0
- package/dist/types/src/extensions/{mention.d.ts → completion/mention.d.ts} +3 -0
- package/dist/types/src/extensions/completion/mention.d.ts.map +1 -0
- package/dist/types/src/extensions/completion/placeholder.d.ts.map +1 -0
- package/dist/types/src/extensions/{autocomplete → completion}/typeahead.d.ts +2 -2
- package/dist/types/src/extensions/completion/typeahead.d.ts.map +1 -0
- package/dist/types/src/extensions/{factories.d.ts → core/factories.d.ts} +23 -2
- package/dist/types/src/extensions/core/factories.d.ts.map +1 -0
- package/dist/types/src/extensions/core/factories.test.d.ts.map +1 -0
- package/dist/types/src/extensions/core/index.d.ts +3 -0
- package/dist/types/src/extensions/core/index.d.ts.map +1 -0
- package/dist/types/src/extensions/{modes.d.ts → core/modes.d.ts} +3 -0
- package/dist/types/src/extensions/core/modes.d.ts.map +1 -0
- package/dist/types/src/extensions/{debug.d.ts → debug/debug.d.ts} +3 -0
- package/dist/types/src/extensions/debug/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/debug/index.d.ts +2 -0
- package/dist/types/src/extensions/debug/index.d.ts.map +1 -0
- package/dist/types/src/extensions/{annotations.d.ts → decoration/annotations.d.ts} +1 -1
- package/dist/types/src/extensions/decoration/annotations.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/assistant.d.ts +27 -0
- package/dist/types/src/extensions/decoration/assistant.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/fader.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/hashtag.d.ts +6 -0
- package/dist/types/src/extensions/decoration/hashtag.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/index.d.ts +8 -0
- package/dist/types/src/extensions/decoration/index.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/marker.d.ts.map +1 -0
- package/dist/types/src/extensions/{pos.d.ts → decoration/pos.d.ts} +40 -14
- package/dist/types/src/extensions/decoration/pos.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/pos.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{replacer.d.ts → decoration/replacer.d.ts} +8 -8
- package/dist/types/src/extensions/decoration/replacer.d.ts.map +1 -0
- package/dist/types/src/extensions/decoration/replacer.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{blast.d.ts → demo/blast.d.ts} +3 -0
- package/dist/types/src/extensions/demo/blast.d.ts.map +1 -0
- package/dist/types/src/extensions/demo/index.d.ts +3 -0
- package/dist/types/src/extensions/demo/index.d.ts.map +1 -0
- package/dist/types/src/extensions/demo/snippets.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +10 -33
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- package/dist/types/src/extensions/language/index.d.ts +5 -0
- package/dist/types/src/extensions/language/index.d.ts.map +1 -0
- package/dist/types/src/extensions/language/json/index.d.ts +2 -0
- package/dist/types/src/extensions/language/json/index.d.ts.map +1 -0
- package/dist/types/src/extensions/language/json/json.d.ts +12 -0
- package/dist/types/src/extensions/language/json/json.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/action.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/bundle.d.ts.map +1 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/changes.d.ts +1 -1
- package/dist/types/src/extensions/language/markdown/changes.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/debug.d.ts +3 -0
- package/dist/types/src/extensions/language/markdown/debug.d.ts.map +1 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/decorate.d.ts +5 -1
- package/dist/types/src/extensions/language/markdown/decorate.d.ts.map +1 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/formatting.d.ts +11 -2
- package/dist/types/src/extensions/language/markdown/formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/formatting.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/highlight.d.ts +16 -12
- package/dist/types/src/extensions/language/markdown/highlight.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/image.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/image.test.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/index.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/link.d.ts +25 -0
- package/dist/types/src/extensions/language/markdown/link.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/link.test.d.ts +2 -0
- package/dist/types/src/extensions/language/markdown/link.test.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/parser.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/styles.d.ts +3 -0
- package/dist/types/src/extensions/language/markdown/styles.d.ts.map +1 -0
- package/dist/types/src/extensions/language/markdown/table.d.ts.map +1 -0
- package/dist/types/src/extensions/language/mermaid/index.d.ts +2 -0
- package/dist/types/src/extensions/language/mermaid/index.d.ts.map +1 -0
- package/dist/types/src/extensions/language/mermaid/mermaid.d.ts +18 -0
- package/dist/types/src/extensions/language/mermaid/mermaid.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/extended-markdown.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/extended-markdown.test.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/index.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/stub.d.ts +76 -0
- package/dist/types/src/extensions/language/xml/stub.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/widgets/anchor.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/widgets/index.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/xml-block-decoration.d.ts +48 -0
- package/dist/types/src/extensions/language/xml/xml-block-decoration.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/xml-formatting.d.ts.map +1 -0
- package/dist/types/src/extensions/{tags → language/xml}/xml-tags.d.ts +12 -1
- package/dist/types/src/extensions/language/xml/xml-tags.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/xml-tags.test.d.ts +2 -0
- package/dist/types/src/extensions/language/xml/xml-tags.test.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/xml-util.d.ts.map +1 -0
- package/dist/types/src/extensions/language/xml/xml-util.test.d.ts.map +1 -0
- package/dist/types/src/extensions/review/change-bar.d.ts +29 -0
- package/dist/types/src/extensions/review/change-bar.d.ts.map +1 -0
- package/dist/types/src/extensions/{comments.d.ts → review/comments.d.ts} +56 -38
- package/dist/types/src/extensions/review/comments.d.ts.map +1 -0
- package/dist/types/src/extensions/review/comments.test.d.ts +2 -0
- package/dist/types/src/extensions/review/comments.test.d.ts.map +1 -0
- package/dist/types/src/extensions/review/diff.d.ts +131 -0
- package/dist/types/src/extensions/review/diff.d.ts.map +1 -0
- package/dist/types/src/extensions/review/diff.test.d.ts +2 -0
- package/dist/types/src/extensions/review/diff.test.d.ts.map +1 -0
- package/dist/types/src/extensions/review/index.d.ts +7 -0
- package/dist/types/src/extensions/review/index.d.ts.map +1 -0
- package/dist/types/src/extensions/review/suggest.d.ts +89 -0
- package/dist/types/src/extensions/review/suggest.d.ts.map +1 -0
- package/dist/types/src/extensions/review/suggest.test.d.ts +2 -0
- package/dist/types/src/extensions/review/suggest.test.d.ts.map +1 -0
- package/dist/types/src/extensions/review/suggestions-overlay.d.ts +25 -0
- package/dist/types/src/extensions/review/suggestions-overlay.d.ts.map +1 -0
- package/dist/types/src/extensions/review/suggestions-overlay.test.d.ts +2 -0
- package/dist/types/src/extensions/review/suggestions-overlay.test.d.ts.map +1 -0
- package/dist/types/src/extensions/review/track-changes.d.ts +27 -0
- package/dist/types/src/extensions/review/track-changes.d.ts.map +1 -0
- package/dist/types/src/extensions/review/track-changes.test.d.ts +2 -0
- package/dist/types/src/extensions/review/track-changes.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{busy.d.ts → state/busy.d.ts} +1 -0
- package/dist/types/src/extensions/state/busy.d.ts.map +1 -0
- package/dist/types/src/extensions/{focus.d.ts → state/focus.d.ts} +4 -0
- package/dist/types/src/extensions/state/focus.d.ts.map +1 -0
- package/dist/types/src/extensions/state/index.d.ts +5 -0
- package/dist/types/src/extensions/state/index.d.ts.map +1 -0
- package/dist/types/src/extensions/state/modal.d.ts.map +1 -0
- package/dist/types/src/extensions/{selection.d.ts → state/selection.d.ts} +1 -1
- package/dist/types/src/extensions/state/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/state/selection.test.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/index.d.ts +4 -0
- package/dist/types/src/extensions/streaming/index.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/pending/index.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/pending/pending-text-stream.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/pending/pending-text-stream.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{pending → streaming/pending}/pending-text.d.ts +1 -0
- package/dist/types/src/extensions/streaming/pending/pending-text.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/pending/pending-text.test.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/scrolling/auto-scroll.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/scrolling/crawler.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/scrolling/index.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/scrolling/scroll-past-end.d.ts +4 -0
- package/dist/types/src/extensions/streaming/scrolling/scroll-past-end.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/scrolling/scrollbar-autohide.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/scrolling/scroller.d.ts.map +1 -0
- package/dist/types/src/extensions/{typewriter.d.ts → streaming/typewriter.d.ts} +12 -12
- package/dist/types/src/extensions/streaming/typewriter.d.ts.map +1 -0
- package/dist/types/src/extensions/streaming/typewriter.test.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/blocks.d.ts +52 -0
- package/dist/types/src/extensions/structure/blocks/blocks.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/blocks.test.d.ts +2 -0
- package/dist/types/src/extensions/structure/blocks/blocks.test.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/drag.d.ts +57 -0
- package/dist/types/src/extensions/structure/blocks/drag.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/index.d.ts +5 -0
- package/dist/types/src/extensions/structure/blocks/index.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/selection.d.ts +47 -0
- package/dist/types/src/extensions/structure/blocks/selection.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/selection.test.d.ts +2 -0
- package/dist/types/src/extensions/structure/blocks/selection.test.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/blocks/types.d.ts +17 -0
- package/dist/types/src/extensions/structure/blocks/types.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/folding/folding.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/folding/index.d.ts +3 -0
- package/dist/types/src/extensions/structure/folding/index.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/folding/turns.d.ts +55 -0
- package/dist/types/src/extensions/structure/folding/turns.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/folding/turns.test.d.ts +2 -0
- package/dist/types/src/extensions/structure/folding/turns.test.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/index.d.ts +4 -0
- package/dist/types/src/extensions/structure/index.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/commands.d.ts +31 -0
- package/dist/types/src/extensions/structure/outliner/commands.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/dnd.d.ts +43 -0
- package/dist/types/src/extensions/structure/outliner/dnd.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/dnd.test.d.ts +2 -0
- package/dist/types/src/extensions/structure/outliner/dnd.test.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/editor.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/editor.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/index.d.ts +1 -0
- package/dist/types/src/extensions/structure/outliner/index.d.ts.map +1 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/menu.d.ts +1 -0
- package/dist/types/src/extensions/structure/outliner/menu.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/outliner.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/outliner.test.d.ts.map +1 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/tree.d.ts +1 -1
- package/dist/types/src/extensions/structure/outliner/tree.d.ts.map +1 -0
- package/dist/types/src/extensions/structure/outliner/tree.test.d.ts.map +1 -0
- package/dist/types/src/headless.d.ts +4 -0
- package/dist/types/src/headless.d.ts.map +1 -0
- package/dist/types/src/styles/theme.d.ts +1 -1
- package/dist/types/src/styles/theme.d.ts.map +1 -1
- package/dist/types/src/util/util.d.ts +2 -0
- package/dist/types/src/util/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +48 -42
- package/src/defaults.ts +1 -1
- package/src/extensions/{bookmarks.ts → behavior/bookmarks.ts} +24 -14
- package/src/extensions/behavior/index.ts +9 -0
- package/src/extensions/{listener.ts → behavior/listener.ts} +4 -1
- package/src/extensions/{spacing.ts → behavior/spacing.ts} +8 -2
- package/src/extensions/{submit.ts → behavior/submit.ts} +2 -10
- package/src/extensions/{automerge → collab/automerge}/automerge.test.tsx +4 -4
- package/src/extensions/{automerge → collab/automerge}/automerge.ts +7 -4
- package/src/extensions/{automerge → collab/automerge}/cursor.ts +1 -1
- package/src/extensions/{automerge → collab/automerge}/defs.ts +4 -1
- package/src/extensions/{automerge → collab/automerge}/index.ts +1 -0
- package/src/extensions/{automerge → collab/automerge}/sync.ts +1 -2
- package/src/extensions/{automerge → collab/automerge}/update-automerge.ts +4 -0
- package/src/extensions/{automerge → collab/automerge}/update-codemirror.ts +5 -1
- package/src/extensions/{awareness → collab/awareness}/awareness-provider.ts +3 -4
- package/src/extensions/{awareness → collab/awareness}/awareness.ts +19 -16
- package/src/extensions/collab/index.ts +6 -0
- package/src/extensions/{autocomplete → completion}/autocomplete.ts +7 -5
- package/src/extensions/{autocomplete → completion}/index.ts +2 -1
- package/src/extensions/{autocomplete → completion}/match.ts +2 -2
- package/src/extensions/{mention.ts → completion/mention.ts} +3 -0
- package/src/extensions/{autocomplete → completion}/placeholder.ts +1 -1
- package/src/extensions/completion/typeahead.ts +97 -0
- package/src/extensions/{factories.ts → core/factories.ts} +35 -13
- package/src/extensions/core/index.ts +6 -0
- package/src/extensions/{modes.ts → core/modes.ts} +4 -1
- package/src/extensions/{debug.ts → debug/debug.ts} +3 -0
- package/src/extensions/debug/index.ts +5 -0
- package/src/extensions/{annotations.ts → decoration/annotations.ts} +12 -10
- package/src/extensions/decoration/assistant.ts +225 -0
- package/src/extensions/{fader.ts → decoration/fader.ts} +17 -19
- package/src/extensions/{hashtag.ts → decoration/hashtag.ts} +35 -28
- package/src/extensions/decoration/index.ts +11 -0
- package/src/extensions/{marker.ts → decoration/marker.ts} +18 -18
- package/src/extensions/{pos.test.ts → decoration/pos.test.ts} +57 -1
- package/src/extensions/{pos.ts → decoration/pos.ts} +165 -31
- package/src/extensions/{blast.ts → demo/blast.ts} +3 -0
- package/src/extensions/demo/index.ts +6 -0
- package/src/extensions/{snippets.ts → demo/snippets.ts} +5 -1
- package/src/extensions/index.ts +10 -33
- package/src/extensions/language/index.ts +8 -0
- package/src/extensions/language/json/index.ts +5 -0
- package/src/extensions/{json.ts → language/json/json.ts} +11 -6
- package/src/extensions/{markdown → language/markdown}/action.ts +1 -1
- package/src/extensions/{markdown → language/markdown}/bundle.ts +7 -1
- package/src/extensions/{markdown → language/markdown}/changes.test.ts +2 -2
- package/src/extensions/{markdown → language/markdown}/changes.ts +2 -2
- package/src/extensions/{markdown → language/markdown}/debug.ts +3 -0
- package/src/extensions/{markdown → language/markdown}/decorate.ts +96 -85
- package/src/extensions/{markdown → language/markdown}/formatting.test.ts +88 -1
- package/src/extensions/{markdown → language/markdown}/formatting.ts +193 -74
- package/src/extensions/{markdown → language/markdown}/highlight.ts +42 -41
- package/src/extensions/{markdown → language/markdown}/image.test.ts +1 -1
- package/src/extensions/{markdown → language/markdown}/image.ts +6 -6
- package/src/extensions/language/markdown/link.test.ts +58 -0
- package/src/extensions/language/markdown/link.ts +109 -0
- package/src/extensions/{markdown → language/markdown}/parser.test.ts +0 -28
- package/src/extensions/{markdown → language/markdown}/styles.ts +38 -7
- package/src/extensions/{markdown → language/markdown}/table.ts +5 -5
- package/src/extensions/language/mermaid/index.ts +5 -0
- package/src/extensions/language/mermaid/mermaid.ts +44 -0
- package/src/extensions/{tags → language/xml}/DESIGN.md +3 -3
- package/src/extensions/{tags → language/xml}/extended-markdown.test.ts +2 -1
- package/src/extensions/{tags → language/xml}/extended-markdown.ts +2 -4
- package/src/extensions/language/xml/stub.ts +233 -0
- package/src/extensions/language/xml/xml-block-decoration.ts +165 -0
- package/src/extensions/{tags → language/xml}/xml-formatting.ts +54 -38
- package/src/extensions/language/xml/xml-tags.test.ts +588 -0
- package/src/extensions/{tags → language/xml}/xml-tags.ts +165 -66
- package/src/extensions/{tags → language/xml}/xml-util.test.ts +2 -2
- package/src/extensions/review/change-bar.ts +94 -0
- package/src/extensions/review/comments.test.ts +72 -0
- package/src/extensions/{comments.ts → review/comments.ts} +395 -267
- package/src/extensions/review/diff.test.ts +405 -0
- package/src/extensions/review/diff.ts +502 -0
- package/src/extensions/review/index.ts +10 -0
- package/src/extensions/review/suggest.test.ts +170 -0
- package/src/extensions/review/suggest.ts +512 -0
- package/src/extensions/review/suggestions-overlay.test.ts +58 -0
- package/src/extensions/review/suggestions-overlay.ts +50 -0
- package/src/extensions/review/track-changes.test.ts +101 -0
- package/src/extensions/review/track-changes.ts +215 -0
- package/src/extensions/{busy.ts → state/busy.ts} +1 -0
- package/src/extensions/{focus.ts → state/focus.ts} +4 -0
- package/src/extensions/state/index.ts +8 -0
- package/src/extensions/{selection.ts → state/selection.ts} +3 -3
- package/src/extensions/streaming/index.ts +7 -0
- package/src/extensions/{pending → streaming/pending}/pending-text-stream.ts +10 -3
- package/src/extensions/{pending → streaming/pending}/pending-text.test.ts +1 -1
- package/src/extensions/{pending → streaming/pending}/pending-text.ts +20 -19
- package/src/extensions/{scrolling → streaming/scrolling}/auto-scroll.ts +9 -6
- package/src/extensions/{scrolling → streaming/scrolling}/scroll-past-end.ts +1 -0
- package/src/extensions/{scrolling → streaming/scrolling}/scrollbar-autohide.ts +13 -11
- package/src/extensions/{typewriter.ts → streaming/typewriter.ts} +46 -47
- package/src/extensions/structure/blocks/DESIGN.md +134 -0
- package/src/extensions/structure/blocks/blocks.test.ts +147 -0
- package/src/extensions/structure/blocks/blocks.ts +219 -0
- package/src/extensions/structure/blocks/drag.ts +996 -0
- package/src/extensions/structure/blocks/index.ts +8 -0
- package/src/extensions/structure/blocks/selection.test.ts +56 -0
- package/src/extensions/structure/blocks/selection.ts +279 -0
- package/src/extensions/structure/blocks/types.ts +22 -0
- package/src/extensions/{folding.ts → structure/folding/folding.ts} +12 -10
- package/src/extensions/structure/folding/index.ts +6 -0
- package/src/extensions/structure/folding/turns.test.ts +72 -0
- package/src/extensions/structure/folding/turns.ts +209 -0
- package/src/extensions/structure/index.ts +7 -0
- package/src/extensions/structure/outliner/DESIGN.md +183 -0
- package/src/extensions/structure/outliner/SPEC.mdl +305 -0
- package/src/extensions/{outliner → structure/outliner}/commands.ts +125 -42
- package/src/extensions/structure/outliner/dnd.test.ts +142 -0
- package/src/extensions/structure/outliner/dnd.ts +375 -0
- package/src/extensions/structure/outliner/editor.test.ts +85 -0
- package/src/extensions/{outliner → structure/outliner}/editor.ts +14 -9
- package/src/extensions/{outliner → structure/outliner}/index.ts +1 -0
- package/src/extensions/{outliner → structure/outliner}/menu.ts +48 -25
- package/src/extensions/structure/outliner/outliner.test.ts +193 -0
- package/src/extensions/structure/outliner/outliner.ts +183 -0
- package/src/extensions/{outliner → structure/outliner}/tree.test.ts +2 -2
- package/src/extensions/{outliner → structure/outliner}/tree.ts +1 -1
- package/src/headless.ts +13 -0
- package/src/styles/theme.ts +3 -1
- package/src/util/util.ts +3 -0
- package/dist/lib/browser/index.mjs +0 -9594
- package/dist/lib/browser/index.mjs.map +0 -7
- package/dist/lib/browser/meta.json +0 -1
- package/dist/lib/browser/types/index.mjs +0 -33
- package/dist/lib/browser/types/index.mjs.map +0 -7
- package/dist/lib/node-esm/index.mjs +0 -9596
- package/dist/lib/node-esm/index.mjs.map +0 -7
- package/dist/lib/node-esm/meta.json +0 -1
- package/dist/lib/node-esm/types/index.mjs +0 -35
- package/dist/lib/node-esm/types/index.mjs.map +0 -7
- package/dist/types/src/extensions/annotations.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete/autocomplete.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete/index.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete/match.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete/placeholder.d.ts.map +0 -1
- package/dist/types/src/extensions/autocomplete/typeahead.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/automerge.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/automerge.test.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/cursor.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/defs.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/index.d.ts +0 -2
- package/dist/types/src/extensions/automerge/index.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/sync.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +0 -1
- package/dist/types/src/extensions/automerge/update-codemirror.d.ts.map +0 -1
- package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +0 -1
- package/dist/types/src/extensions/awareness/awareness.d.ts.map +0 -1
- package/dist/types/src/extensions/awareness/index.d.ts.map +0 -1
- package/dist/types/src/extensions/blast.d.ts.map +0 -1
- package/dist/types/src/extensions/blocks.d.ts +0 -2
- package/dist/types/src/extensions/blocks.d.ts.map +0 -1
- package/dist/types/src/extensions/bookmarks.d.ts.map +0 -1
- package/dist/types/src/extensions/busy.d.ts.map +0 -1
- package/dist/types/src/extensions/comments.d.ts.map +0 -1
- package/dist/types/src/extensions/debug.d.ts.map +0 -1
- package/dist/types/src/extensions/dnd.d.ts.map +0 -1
- package/dist/types/src/extensions/factories.d.ts.map +0 -1
- package/dist/types/src/extensions/factories.test.d.ts.map +0 -1
- package/dist/types/src/extensions/fader.d.ts.map +0 -1
- package/dist/types/src/extensions/focus.d.ts.map +0 -1
- package/dist/types/src/extensions/folding.d.ts.map +0 -1
- package/dist/types/src/extensions/hashtag.d.ts +0 -3
- package/dist/types/src/extensions/hashtag.d.ts.map +0 -1
- package/dist/types/src/extensions/json.d.ts +0 -7
- package/dist/types/src/extensions/json.d.ts.map +0 -1
- package/dist/types/src/extensions/listener.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/bundle.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/changes.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/changes.test.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/debug.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/formatting.test.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/image.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/image.test.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/index.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/link.d.ts +0 -7
- package/dist/types/src/extensions/markdown/link.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/parser.test.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/styles.d.ts.map +0 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +0 -1
- package/dist/types/src/extensions/marker.d.ts.map +0 -1
- package/dist/types/src/extensions/mention.d.ts.map +0 -1
- package/dist/types/src/extensions/modal.d.ts.map +0 -1
- package/dist/types/src/extensions/modes.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/commands.d.ts +0 -10
- package/dist/types/src/extensions/outliner/commands.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/editor.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/editor.test.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/index.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/menu.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/outliner.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/outliner.test.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/selection.d.ts +0 -12
- package/dist/types/src/extensions/outliner/selection.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/tree.d.ts.map +0 -1
- package/dist/types/src/extensions/outliner/tree.test.d.ts.map +0 -1
- package/dist/types/src/extensions/pending/index.d.ts.map +0 -1
- package/dist/types/src/extensions/pending/pending-text-stream.d.ts.map +0 -1
- package/dist/types/src/extensions/pending/pending-text-stream.test.d.ts.map +0 -1
- package/dist/types/src/extensions/pending/pending-text.d.ts.map +0 -1
- package/dist/types/src/extensions/pending/pending-text.test.d.ts.map +0 -1
- package/dist/types/src/extensions/pos.d.ts.map +0 -1
- package/dist/types/src/extensions/pos.test.d.ts.map +0 -1
- package/dist/types/src/extensions/replacer.d.ts.map +0 -1
- package/dist/types/src/extensions/replacer.test.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling/auto-scroll.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling/crawler.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling/index.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts +0 -3
- package/dist/types/src/extensions/scrolling/scroll-past-end.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling/scrollbar-autohide.d.ts.map +0 -1
- package/dist/types/src/extensions/scrolling/scroller.d.ts.map +0 -1
- package/dist/types/src/extensions/selection.d.ts.map +0 -1
- package/dist/types/src/extensions/selection.test.d.ts.map +0 -1
- package/dist/types/src/extensions/snippets.d.ts.map +0 -1
- package/dist/types/src/extensions/spacing.d.ts.map +0 -1
- package/dist/types/src/extensions/state.d.ts +0 -2
- package/dist/types/src/extensions/state.d.ts.map +0 -1
- package/dist/types/src/extensions/submit.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/extended-markdown.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/extended-markdown.test.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/index.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/stub.d.ts +0 -35
- package/dist/types/src/extensions/tags/stub.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/widgets/anchor.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/widgets/index.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts +0 -31
- package/dist/types/src/extensions/tags/xml-block-decoration.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/xml-formatting.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/xml-tags.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/xml-util.d.ts.map +0 -1
- package/dist/types/src/extensions/tags/xml-util.test.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.d.ts.map +0 -1
- package/dist/types/src/extensions/typewriter.test.d.ts.map +0 -1
- package/src/extensions/autocomplete/typeahead.ts +0 -87
- package/src/extensions/blocks.ts +0 -131
- package/src/extensions/markdown/link.ts +0 -49
- package/src/extensions/outliner/editor.test.ts +0 -33
- package/src/extensions/outliner/outliner.test.ts +0 -99
- package/src/extensions/outliner/outliner.ts +0 -166
- package/src/extensions/outliner/selection.ts +0 -50
- package/src/extensions/state.ts +0 -7
- package/src/extensions/tags/stub.ts +0 -80
- package/src/extensions/tags/xml-block-decoration.ts +0 -123
- package/dist/types/src/extensions/{dnd.d.ts → behavior/dnd.d.ts} +0 -0
- package/dist/types/src/extensions/{submit.d.ts → behavior/submit.d.ts} +0 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/automerge.d.ts +0 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/automerge.test.d.ts +0 -0
- package/dist/types/src/extensions/{automerge → collab/automerge}/sync.d.ts +0 -0
- package/dist/types/src/extensions/{awareness → collab/awareness}/awareness-provider.d.ts +0 -0
- package/dist/types/src/extensions/{awareness → collab/awareness}/index.d.ts +0 -0
- package/dist/types/src/extensions/{autocomplete → completion}/autocomplete.d.ts +0 -0
- package/dist/types/src/extensions/{autocomplete → completion}/placeholder.d.ts +0 -0
- package/dist/types/src/extensions/{factories.test.d.ts → core/factories.test.d.ts} +0 -0
- package/dist/types/src/extensions/{fader.d.ts → decoration/fader.d.ts} +0 -0
- package/dist/types/src/extensions/{marker.d.ts → decoration/marker.d.ts} +0 -0
- package/dist/types/src/extensions/{pos.test.d.ts → decoration/pos.test.d.ts} +0 -0
- package/dist/types/src/extensions/{replacer.test.d.ts → decoration/replacer.test.d.ts} +0 -0
- package/dist/types/src/extensions/{snippets.d.ts → demo/snippets.d.ts} +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/action.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/bundle.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/changes.test.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/formatting.test.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/image.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/image.test.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/index.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/parser.test.d.ts +0 -0
- package/dist/types/src/extensions/{markdown → language/markdown}/table.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/extended-markdown.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/extended-markdown.test.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/index.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/widgets/anchor.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/widgets/index.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/xml-formatting.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/xml-util.d.ts +0 -0
- package/dist/types/src/extensions/{tags → language/xml}/xml-util.test.d.ts +0 -0
- package/dist/types/src/extensions/{modal.d.ts → state/modal.d.ts} +0 -0
- package/dist/types/src/extensions/{selection.test.d.ts → state/selection.test.d.ts} +0 -0
- package/dist/types/src/extensions/{pending → streaming/pending}/index.d.ts +0 -0
- package/dist/types/src/extensions/{pending → streaming/pending}/pending-text-stream.d.ts +0 -0
- package/dist/types/src/extensions/{pending → streaming/pending}/pending-text-stream.test.d.ts +0 -0
- package/dist/types/src/extensions/{pending → streaming/pending}/pending-text.test.d.ts +0 -0
- package/dist/types/src/extensions/{scrolling → streaming/scrolling}/auto-scroll.d.ts +0 -0
- package/dist/types/src/extensions/{scrolling → streaming/scrolling}/crawler.d.ts +0 -0
- package/dist/types/src/extensions/{scrolling → streaming/scrolling}/index.d.ts +0 -0
- package/dist/types/src/extensions/{scrolling → streaming/scrolling}/scrollbar-autohide.d.ts +0 -0
- package/dist/types/src/extensions/{scrolling → streaming/scrolling}/scroller.d.ts +0 -0
- package/dist/types/src/extensions/{typewriter.test.d.ts → streaming/typewriter.test.d.ts} +0 -0
- package/dist/types/src/extensions/{folding.d.ts → structure/folding/folding.d.ts} +0 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/editor.d.ts +0 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/editor.test.d.ts +0 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/outliner.d.ts +0 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/outliner.test.d.ts +0 -0
- package/dist/types/src/extensions/{outliner → structure/outliner}/tree.test.d.ts +0 -0
- package/src/extensions/{dnd.ts → behavior/dnd.ts} +29 -29
- package/src/extensions/{awareness → collab/awareness}/index.ts +0 -0
- package/src/extensions/{factories.test.ts → core/factories.test.ts} +0 -0
- package/src/extensions/{replacer.test.ts → decoration/replacer.test.ts} +0 -0
- package/src/extensions/{replacer.ts → decoration/replacer.ts} +25 -25
- /package/src/extensions/{markdown → language/markdown}/index.ts +0 -0
- /package/src/extensions/{tags → language/xml}/index.ts +0 -0
- /package/src/extensions/{tags → language/xml}/testing/text.md +0 -0
- /package/src/extensions/{tags → language/xml}/testing/text.txt +0 -0
- /package/src/extensions/{tags → language/xml}/widgets/anchor.ts +0 -0
- /package/src/extensions/{tags → language/xml}/widgets/index.ts +0 -0
- /package/src/extensions/{tags → language/xml}/xml-util.ts +0 -0
- /package/src/extensions/{modal.ts → state/modal.ts} +0 -0
- /package/src/extensions/{selection.test.ts → state/selection.test.ts} +0 -0
- /package/src/extensions/{pending → streaming/pending}/index.ts +0 -0
- /package/src/extensions/{pending → streaming/pending}/pending-text-stream.test.ts +0 -0
- /package/src/extensions/{scrolling → streaming/scrolling}/crawler.ts +0 -0
- /package/src/extensions/{scrolling → streaming/scrolling}/index.ts +0 -0
- /package/src/extensions/{scrolling → streaming/scrolling}/scroller.ts +0 -0
- /package/src/extensions/{typewriter.test.ts → streaming/typewriter.test.ts} +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { EditorSelection, type Extension, Prec, RangeSetBuilder } from '@codemirror/state';
|
|
6
|
+
import {
|
|
7
|
+
type Command,
|
|
8
|
+
Decoration,
|
|
9
|
+
type DecorationSet,
|
|
10
|
+
type EditorView,
|
|
11
|
+
ViewPlugin,
|
|
12
|
+
type ViewUpdate,
|
|
13
|
+
keymap,
|
|
14
|
+
} from '@codemirror/view';
|
|
15
|
+
|
|
16
|
+
import { type CompletionContext } from './match';
|
|
17
|
+
import { PlaceholderWidget } from './placeholder';
|
|
18
|
+
|
|
19
|
+
// TODO(burdon): Option to complete only at end of line.
|
|
20
|
+
export type TypeaheadOptions = {
|
|
21
|
+
onComplete?: (context: CompletionContext) => string | undefined;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Shows a completion placeholder.
|
|
26
|
+
*/
|
|
27
|
+
export const typeahead = ({ onComplete }: TypeaheadOptions = {}): Extension => {
|
|
28
|
+
// Kept per-view (not in the factory closure) so a single extension instance shared across
|
|
29
|
+
// multiple editors does not leak completion state between them.
|
|
30
|
+
const typeaheadPlugin = ViewPlugin.fromClass(
|
|
31
|
+
class {
|
|
32
|
+
decorations: DecorationSet = Decoration.none;
|
|
33
|
+
hint: string | undefined;
|
|
34
|
+
update(update: ViewUpdate) {
|
|
35
|
+
// Only recompute on doc/selection changes; skip unrelated updates on this per-keystroke path.
|
|
36
|
+
if (!update.docChanged && !update.selectionSet) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const builder = new RangeSetBuilder<Decoration>();
|
|
41
|
+
const selection = update.view.state.selection.main;
|
|
42
|
+
const line = update.view.state.doc.lineAt(selection.from);
|
|
43
|
+
|
|
44
|
+
// TODO(burdon): Check at end of line and matches start of previous word.
|
|
45
|
+
// TODO(burdon): Context grammar.
|
|
46
|
+
this.hint = undefined;
|
|
47
|
+
if (selection.from === selection.to && selection.from === line.to) {
|
|
48
|
+
const str = update.state.sliceDoc(line.from, selection.from);
|
|
49
|
+
this.hint = onComplete?.({ line: str });
|
|
50
|
+
if (this.hint) {
|
|
51
|
+
builder.add(selection.from, selection.to, Decoration.widget({ widget: new PlaceholderWidget(this.hint) }));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.decorations = builder.finish();
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
decorations: (value) => value.decorations,
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const complete: Command = (view: EditorView) => {
|
|
64
|
+
const hint = view.plugin(typeaheadPlugin)?.hint;
|
|
65
|
+
if (!hint) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const selection = view.state.selection.main;
|
|
70
|
+
view.dispatch({
|
|
71
|
+
changes: [{ from: selection.from, to: selection.to, insert: hint }],
|
|
72
|
+
selection: EditorSelection.cursor(selection.from + hint.length),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return true;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return [
|
|
79
|
+
typeaheadPlugin,
|
|
80
|
+
|
|
81
|
+
// Keys.
|
|
82
|
+
Prec.highest(
|
|
83
|
+
keymap.of([
|
|
84
|
+
{
|
|
85
|
+
key: 'Tab',
|
|
86
|
+
preventDefault: true,
|
|
87
|
+
run: complete,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
key: 'ArrowRight',
|
|
91
|
+
preventDefault: true,
|
|
92
|
+
run: complete,
|
|
93
|
+
},
|
|
94
|
+
]),
|
|
95
|
+
),
|
|
96
|
+
];
|
|
97
|
+
};
|
|
@@ -25,15 +25,14 @@ import { generateName } from '@dxos/display-name';
|
|
|
25
25
|
import { Doc } from '@dxos/echo-doc';
|
|
26
26
|
import { log } from '@dxos/log';
|
|
27
27
|
import { type Messenger } from '@dxos/protocols';
|
|
28
|
-
import { type Identity } from '@dxos/protocols/proto/dxos/client/services';
|
|
29
28
|
import { type ChromaticPalette, type ThemeMode } from '@dxos/ui-types';
|
|
30
29
|
import { hexToHue, isTruthy } from '@dxos/util';
|
|
31
30
|
|
|
32
|
-
import { baseTheme, createFontTheme, editorGutter } from '
|
|
33
|
-
import { automerge } from '
|
|
34
|
-
import { SpaceAwarenessProvider, awareness } from '
|
|
35
|
-
import { focus } from '
|
|
36
|
-
import { scrollPastEnd } from '
|
|
31
|
+
import { baseTheme, createFontTheme, editorGutter } from '../../styles';
|
|
32
|
+
import { automerge } from '../collab/automerge';
|
|
33
|
+
import { SpaceAwarenessProvider, awareness } from '../collab/awareness';
|
|
34
|
+
import { focus } from '../state/focus';
|
|
35
|
+
import { scrollPastEnd } from '../streaming/scrolling';
|
|
37
36
|
|
|
38
37
|
//
|
|
39
38
|
// Basic
|
|
@@ -44,6 +43,9 @@ import { scrollPastEnd } from './scrolling';
|
|
|
44
43
|
*/
|
|
45
44
|
export const tabbable = EditorView.contentAttributes.of({ tabindex: '0' });
|
|
46
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Transaction filter that strips characters matching the given pattern from inserted text.
|
|
48
|
+
*/
|
|
47
49
|
export const filterChars = (chars: RegExp) => {
|
|
48
50
|
return EditorState.transactionFilter.of((transaction) => {
|
|
49
51
|
if (!transaction.docChanged) {
|
|
@@ -122,6 +124,10 @@ const keymaps: { [key: string]: readonly KeyBinding[] } = {
|
|
|
122
124
|
default: defaultKeymap,
|
|
123
125
|
};
|
|
124
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Assembles the base editor setup: keymaps, history, bracket matching/closing, drop cursor,
|
|
129
|
+
* read-only handling, line wrapping, and tab handling.
|
|
130
|
+
*/
|
|
125
131
|
export const createBasicExtensions = (propsProp?: BasicExtensionsOptions): Extension => {
|
|
126
132
|
const props = defaultsDeep({}, propsProp, defaultBasicOptions);
|
|
127
133
|
return [
|
|
@@ -209,7 +215,7 @@ export type ThemeExtensionsOptions = {
|
|
|
209
215
|
|
|
210
216
|
export const grow: ThemeExtensionsOptions['slots'] = {
|
|
211
217
|
editor: {
|
|
212
|
-
className: '
|
|
218
|
+
className: 'w-full h-full',
|
|
213
219
|
},
|
|
214
220
|
} as const;
|
|
215
221
|
|
|
@@ -265,32 +271,48 @@ export const createThemeExtensions = ({
|
|
|
265
271
|
// Data
|
|
266
272
|
//
|
|
267
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Minimal identity shape consumed by awareness. Kept structural so both the
|
|
276
|
+
* client identity and the `@dxos/halo` `Identity.Info` can be passed without
|
|
277
|
+
* this foundational editor package depending on either.
|
|
278
|
+
*/
|
|
279
|
+
export type DataExtensionsIdentity = {
|
|
280
|
+
/** Hex-encoded identity key, used as the awareness peer id. */
|
|
281
|
+
identityKey?: string;
|
|
282
|
+
displayName?: string;
|
|
283
|
+
/** Free-form profile metadata (e.g. `hue`). */
|
|
284
|
+
data?: Record<string, unknown>;
|
|
285
|
+
};
|
|
286
|
+
|
|
268
287
|
export type DataExtensionsProps<T> = {
|
|
269
288
|
id: string;
|
|
270
289
|
text?: Doc.Accessor<T>;
|
|
271
290
|
messenger?: Messenger;
|
|
272
|
-
identity?:
|
|
291
|
+
identity?: DataExtensionsIdentity | null;
|
|
273
292
|
};
|
|
274
293
|
|
|
294
|
+
/**
|
|
295
|
+
* Wires document sync (automerge) and presence (awareness) for a text accessor.
|
|
296
|
+
*/
|
|
275
297
|
export const createDataExtensions = <T>({ id, text, messenger, identity }: DataExtensionsProps<T>): Extension[] => {
|
|
276
298
|
const extensions: Extension[] = [];
|
|
277
299
|
if (text) {
|
|
278
300
|
extensions.push(automerge(text));
|
|
279
301
|
}
|
|
280
302
|
|
|
281
|
-
if (messenger && identity) {
|
|
282
|
-
const peerId = identity
|
|
283
|
-
const hue = (identity
|
|
303
|
+
if (messenger && identity?.identityKey) {
|
|
304
|
+
const peerId = identity.identityKey;
|
|
305
|
+
const hue = (identity.data?.hue as ChromaticPalette | undefined) ?? hexToHue(peerId);
|
|
284
306
|
extensions.push(
|
|
285
307
|
awareness(
|
|
286
308
|
new SpaceAwarenessProvider({
|
|
287
309
|
messenger,
|
|
288
310
|
channel: `awareness.${id}`,
|
|
289
|
-
peerId
|
|
311
|
+
peerId,
|
|
290
312
|
info: {
|
|
291
313
|
darkColor: `var(--color-${hue}-border)`,
|
|
292
314
|
lightColor: `var(--color-${hue}-border)`,
|
|
293
|
-
displayName: identity.
|
|
315
|
+
displayName: identity.displayName ?? generateName(peerId),
|
|
294
316
|
},
|
|
295
317
|
}),
|
|
296
318
|
),
|
|
@@ -7,7 +7,7 @@ import { keymap } from '@codemirror/view';
|
|
|
7
7
|
import { vim } from '@replit/codemirror-vim';
|
|
8
8
|
import { vscodeKeymap } from '@replit/codemirror-vscode-keymap';
|
|
9
9
|
|
|
10
|
-
import { singleValueFacet } from '
|
|
10
|
+
import { singleValueFacet } from '../../util';
|
|
11
11
|
|
|
12
12
|
export type EditorInputConfig = {
|
|
13
13
|
type?: string;
|
|
@@ -16,6 +16,9 @@ export type EditorInputConfig = {
|
|
|
16
16
|
|
|
17
17
|
export const editorInputMode = singleValueFacet<EditorInputConfig>({});
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Map of input-mode keymap bundles (default, vscode, vim).
|
|
21
|
+
*/
|
|
19
22
|
export const InputModeExtensions: { [mode: string]: Extension } = {
|
|
20
23
|
default: [],
|
|
21
24
|
vscode: [
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
import { syntaxTree } from '@codemirror/language';
|
|
6
6
|
import { type EditorState, type Extension, type RangeSet, StateField, type Transaction } from '@codemirror/state';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Logs every syntax-tree node type on each editor update (debug only).
|
|
10
|
+
*/
|
|
8
11
|
// eslint-disable-next-line no-console
|
|
9
12
|
export const debugNodeLogger = (log: (...args: any[]) => void = console.log): Extension => {
|
|
10
13
|
const logTokens = (state: EditorState) => syntaxTree(state).iterate({ enter: (node) => log(node.type) });
|
|
@@ -5,14 +5,12 @@
|
|
|
5
5
|
import { type Extension, RangeSetBuilder } from '@codemirror/state';
|
|
6
6
|
import { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate } from '@codemirror/view';
|
|
7
7
|
|
|
8
|
-
const annotationMark = Decoration.mark({ class: 'cm-annotation' });
|
|
9
|
-
|
|
10
8
|
export type AnnotationOptions = {
|
|
11
9
|
match?: RegExp; // TODO(burdon): Update via hook (e.g., for search).
|
|
12
10
|
};
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
|
-
*
|
|
13
|
+
* Wavy-underline decoration over regex matches in the viewport.
|
|
16
14
|
*/
|
|
17
15
|
export const annotations = ({ match }: AnnotationOptions = {}): Extension => {
|
|
18
16
|
return [
|
|
@@ -44,12 +42,16 @@ export const annotations = ({ match }: AnnotationOptions = {}): Extension => {
|
|
|
44
42
|
},
|
|
45
43
|
),
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
'.cm-annotation': {
|
|
49
|
-
textDecoration: 'underline',
|
|
50
|
-
textDecorationStyle: 'wavy',
|
|
51
|
-
textDecorationColor: 'var(--color-error-text)',
|
|
52
|
-
},
|
|
53
|
-
}),
|
|
45
|
+
styles,
|
|
54
46
|
];
|
|
55
47
|
};
|
|
48
|
+
|
|
49
|
+
const annotationMark = Decoration.mark({ class: 'cm-annotation' });
|
|
50
|
+
|
|
51
|
+
const styles = EditorView.theme({
|
|
52
|
+
'.cm-annotation': {
|
|
53
|
+
textDecoration: 'underline',
|
|
54
|
+
textDecorationStyle: 'wavy',
|
|
55
|
+
textDecorationColor: 'var(--color-error-text)',
|
|
56
|
+
},
|
|
57
|
+
});
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Diagnostic, forEachDiagnostic, linter, setDiagnostics } from '@codemirror/lint';
|
|
6
|
+
import { ChangeSet, type Extension } from '@codemirror/state';
|
|
7
|
+
import { EditorView } from '@codemirror/view';
|
|
8
|
+
|
|
9
|
+
import { log } from '@dxos/log';
|
|
10
|
+
import { safeParseJson, trim } from '@dxos/util';
|
|
11
|
+
|
|
12
|
+
export type AssistantOptions = {
|
|
13
|
+
/**
|
|
14
|
+
* Instructions to use for the language model.
|
|
15
|
+
*/
|
|
16
|
+
instructions?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Show panel automatically.
|
|
19
|
+
*/
|
|
20
|
+
autoPanel?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Debounce delay.
|
|
23
|
+
*/
|
|
24
|
+
delay?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Invoke the language model with the given prompt and return the raw text response.
|
|
27
|
+
*/
|
|
28
|
+
generate: (request: { instructions: string; content: string }) => Promise<string>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* LLM-backed proofreading linter that draws colored underlines and populates a lint panel.
|
|
33
|
+
*/
|
|
34
|
+
export const assistant = (options: AssistantOptions): Extension[] => {
|
|
35
|
+
const styles = getComputedStyle(document.documentElement);
|
|
36
|
+
const style = {
|
|
37
|
+
info: styles.getPropertyValue('--color-green-500').trim(),
|
|
38
|
+
warning: styles.getPropertyValue('--color-orange-500').trim(),
|
|
39
|
+
error: styles.getPropertyValue('--color-rose-500').trim(),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return [
|
|
43
|
+
assistantLinter(options),
|
|
44
|
+
EditorView.baseTheme({
|
|
45
|
+
'.cm-lintRange-info': {
|
|
46
|
+
backgroundImage: underline(style.info),
|
|
47
|
+
},
|
|
48
|
+
'.cm-lintRange-warning': {
|
|
49
|
+
backgroundImage: underline(style.warning),
|
|
50
|
+
},
|
|
51
|
+
'.cm-lintRange-error': {
|
|
52
|
+
backgroundImage: underline(style.error),
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
'.cm-panels-bottom': {
|
|
56
|
+
borderTop: '1px solid var(--color-separator) !important',
|
|
57
|
+
},
|
|
58
|
+
'.cm-panel-lint .cm-panel': {
|
|
59
|
+
outline: 'none !important',
|
|
60
|
+
},
|
|
61
|
+
'.cm-panel button': {
|
|
62
|
+
color: 'var(--color-base-fg) !important',
|
|
63
|
+
},
|
|
64
|
+
'.cm-panel.cm-panel-lint ul': {
|
|
65
|
+
color: 'var(--color-base-fg) !important',
|
|
66
|
+
backgroundColor: 'var(--color-base-surface) !important',
|
|
67
|
+
marginRight: '2rem !important',
|
|
68
|
+
},
|
|
69
|
+
'.cm-panel.cm-panel-lint ul [aria-selected]': {
|
|
70
|
+
color: 'var(--color-base-fg) !important',
|
|
71
|
+
backgroundColor: 'var(--color-base-surface) !important',
|
|
72
|
+
},
|
|
73
|
+
'.cm-panel.cm-panel-lint ul li': {
|
|
74
|
+
display: 'grid',
|
|
75
|
+
gridTemplateColumns: '1fr auto',
|
|
76
|
+
alignItems: 'center',
|
|
77
|
+
},
|
|
78
|
+
'.cm-panel.cm-panel-lint ul li .cm-diagnosticText': {
|
|
79
|
+
paddingRight: '8px !important',
|
|
80
|
+
},
|
|
81
|
+
'.cm-panel.cm-panel-lint ul li button.cm-diagnosticAction': {
|
|
82
|
+
margin: 'none !important',
|
|
83
|
+
},
|
|
84
|
+
'.cm-diagnostic': {
|
|
85
|
+
padding: '0px 8px !important',
|
|
86
|
+
whiteSpace: 'pre-wrap !important',
|
|
87
|
+
},
|
|
88
|
+
'.cm-diagnostic-info': {
|
|
89
|
+
border: 'none !important',
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const underline = (color: string) => {
|
|
96
|
+
const svg = trim`
|
|
97
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="3">
|
|
98
|
+
<path d="m0 3 l2 -2 l1 0 l2 2 l1 0" stroke="${color}" fill="none" stroke-width="1"/>
|
|
99
|
+
</svg>
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
return `url('data:image/svg+xml;base64,${btoa(svg)}') !important`;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//
|
|
106
|
+
// Linter
|
|
107
|
+
//
|
|
108
|
+
|
|
109
|
+
type Suggestion = {
|
|
110
|
+
original: string;
|
|
111
|
+
replacement: string;
|
|
112
|
+
context: string;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const isSuggestion = (value: unknown): value is Suggestion =>
|
|
116
|
+
typeof value === 'object' &&
|
|
117
|
+
value !== null &&
|
|
118
|
+
typeof (value as Suggestion).original === 'string' &&
|
|
119
|
+
typeof (value as Suggestion).replacement === 'string' &&
|
|
120
|
+
typeof (value as Suggestion).context === 'string';
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Find the index of `original` within `content`, using `context` to disambiguate when there are multiple occurrences.
|
|
124
|
+
*/
|
|
125
|
+
const findSuggestionIndex = (content: string, suggestion: Suggestion): number => {
|
|
126
|
+
const firstIdx = content.indexOf(suggestion.original);
|
|
127
|
+
if (firstIdx === -1) {
|
|
128
|
+
return -1;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Check for duplicate occurrences; use context to disambiguate.
|
|
132
|
+
const secondIdx = content.indexOf(suggestion.original, firstIdx + 1);
|
|
133
|
+
if (secondIdx === -1) {
|
|
134
|
+
return firstIdx;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Find the occurrence whose surrounding text best matches the context.
|
|
138
|
+
const contextIdx = content.indexOf(suggestion.context);
|
|
139
|
+
if (contextIdx !== -1) {
|
|
140
|
+
const contextEnd = contextIdx + suggestion.context.length;
|
|
141
|
+
if (secondIdx >= contextIdx && secondIdx <= contextEnd) {
|
|
142
|
+
return secondIdx;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return firstIdx;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const replaceTextAndDropLintAtRange = (view: EditorView, from: number, to: number, insert: string) => {
|
|
150
|
+
const kept: Diagnostic[] = [];
|
|
151
|
+
forEachDiagnostic(view.state, (diagnostic, diagnosticFrom, diagnosticTo) => {
|
|
152
|
+
if (diagnosticFrom < to && diagnosticTo > from) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
kept.push({ ...diagnostic, from: diagnosticFrom, to: diagnosticTo });
|
|
156
|
+
});
|
|
157
|
+
const changeSet = ChangeSet.of({ from, to, insert }, view.state.doc.length);
|
|
158
|
+
const next = kept.map((d) => ({
|
|
159
|
+
...d,
|
|
160
|
+
from: changeSet.mapPos(d.from, 1),
|
|
161
|
+
to: changeSet.mapPos(d.to, -1),
|
|
162
|
+
}));
|
|
163
|
+
view.dispatch({
|
|
164
|
+
changes: { from, to, insert },
|
|
165
|
+
...setDiagnostics(view.state, next),
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const DEFAULT_INSTRUCTIONS = trim`
|
|
170
|
+
Proofread the input text below.
|
|
171
|
+
Identify typos and grammatical errors.
|
|
172
|
+
Return ONLY a valid JSON array of objects with fields: "original" (string), "replacement" (string), "context" (string, 3-5 words around match).
|
|
173
|
+
--
|
|
174
|
+
`;
|
|
175
|
+
|
|
176
|
+
const assistantLinter = ({
|
|
177
|
+
generate,
|
|
178
|
+
instructions = DEFAULT_INSTRUCTIONS,
|
|
179
|
+
autoPanel = true,
|
|
180
|
+
delay = 2_000,
|
|
181
|
+
}: AssistantOptions) =>
|
|
182
|
+
linter(
|
|
183
|
+
async (view) => {
|
|
184
|
+
try {
|
|
185
|
+
const content = view.state.doc.toString();
|
|
186
|
+
const result = await generate({ instructions, content });
|
|
187
|
+
|
|
188
|
+
const [match] = result.match(/\[.*\]/s) ?? [];
|
|
189
|
+
const parsed = match ? safeParseJson<unknown[]>(match, []) : [];
|
|
190
|
+
const suggestions = Array.isArray(parsed) ? parsed.filter(isSuggestion) : [];
|
|
191
|
+
if (suggestions && suggestions.length > 0) {
|
|
192
|
+
const diagnostics: Diagnostic[] = [];
|
|
193
|
+
for (const suggestion of suggestions) {
|
|
194
|
+
const idx = findSuggestionIndex(content, suggestion);
|
|
195
|
+
if (idx !== -1) {
|
|
196
|
+
diagnostics.push({
|
|
197
|
+
from: idx,
|
|
198
|
+
to: idx + suggestion.original.length,
|
|
199
|
+
severity: 'info',
|
|
200
|
+
message: `Suggestion: ${suggestion.replacement}`,
|
|
201
|
+
actions: [
|
|
202
|
+
{
|
|
203
|
+
name: 'Apply',
|
|
204
|
+
apply: (view, from, to) => {
|
|
205
|
+
replaceTextAndDropLintAtRange(view, from, to, suggestion.replacement);
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
],
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return diagnostics;
|
|
214
|
+
}
|
|
215
|
+
} catch (err) {
|
|
216
|
+
log.catch(err);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return [];
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
delay,
|
|
223
|
+
autoPanel,
|
|
224
|
+
},
|
|
225
|
+
);
|
|
@@ -5,10 +5,6 @@
|
|
|
5
5
|
import { type Extension, StateEffect, StateField } from '@codemirror/state';
|
|
6
6
|
import { Decoration, type DecorationSet, EditorView, ViewPlugin } from '@codemirror/view';
|
|
7
7
|
|
|
8
|
-
const DEFAULT_REMOVAL_DELAY = 5_000; // ms.
|
|
9
|
-
const DEFAULT_COALESCE_WINDOW = 100; // ms.
|
|
10
|
-
const CLEANUP_INTERVAL = 1_000; // ms.
|
|
11
|
-
|
|
12
8
|
export type FaderOptions = {
|
|
13
9
|
/** Time window in ms to coalesce adjacent appends into a single decoration. */
|
|
14
10
|
coalesce?: number;
|
|
@@ -177,19 +173,21 @@ export const fader = (options: FaderOptions = {}): Extension => {
|
|
|
177
173
|
},
|
|
178
174
|
);
|
|
179
175
|
|
|
180
|
-
return [
|
|
181
|
-
fadeField,
|
|
182
|
-
cleanup,
|
|
183
|
-
EditorView.theme({
|
|
184
|
-
'.cm-fader': {
|
|
185
|
-
animation: 'fader 1s ease-out forwards',
|
|
186
|
-
},
|
|
187
|
-
'@keyframes fader': {
|
|
188
|
-
'0%': {
|
|
189
|
-
textShadow: '0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)',
|
|
190
|
-
},
|
|
191
|
-
'100%': {},
|
|
192
|
-
},
|
|
193
|
-
}),
|
|
194
|
-
];
|
|
176
|
+
return [fadeField, cleanup, styles];
|
|
195
177
|
};
|
|
178
|
+
|
|
179
|
+
const DEFAULT_REMOVAL_DELAY = 5_000; // ms.
|
|
180
|
+
const DEFAULT_COALESCE_WINDOW = 100; // ms.
|
|
181
|
+
const CLEANUP_INTERVAL = 1_000; // ms.
|
|
182
|
+
|
|
183
|
+
const styles = EditorView.theme({
|
|
184
|
+
'.cm-fader': {
|
|
185
|
+
animation: 'fader 1s ease-out forwards',
|
|
186
|
+
},
|
|
187
|
+
'@keyframes fader': {
|
|
188
|
+
'0%': {
|
|
189
|
+
textShadow: '0 0 16px rgba(100, 200, 255, 1), 0 0 32px rgba(100, 200, 255, 0.6)',
|
|
190
|
+
},
|
|
191
|
+
'100%': {},
|
|
192
|
+
},
|
|
193
|
+
});
|
|
@@ -15,28 +15,10 @@ import {
|
|
|
15
15
|
|
|
16
16
|
import { getHashStyles, mx } from '@dxos/ui-theme';
|
|
17
17
|
|
|
18
|
-
class TagWidget extends WidgetType {
|
|
19
|
-
constructor(private _text: string) {
|
|
20
|
-
super();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
toDOM(): HTMLSpanElement {
|
|
24
|
-
const span = document.createElement('span');
|
|
25
|
-
span.className = mx('cm-tag', getHashStyles(this._text).surface);
|
|
26
|
-
span.textContent = this._text;
|
|
27
|
-
return span;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const tagMatcher = new MatchDecorator({
|
|
32
|
-
regexp: /#(\w+)\W/g,
|
|
33
|
-
decoration: (match) =>
|
|
34
|
-
Decoration.replace({
|
|
35
|
-
widget: new TagWidget(match[1]),
|
|
36
|
-
}),
|
|
37
|
-
});
|
|
38
|
-
|
|
39
18
|
// TODO(burdon): Autocomplete from existing tags?
|
|
19
|
+
/**
|
|
20
|
+
* Replaces `#tag` occurrences with a styled atomic widget.
|
|
21
|
+
*/
|
|
40
22
|
export const hashtag = (): Extension => [
|
|
41
23
|
ViewPlugin.fromClass(
|
|
42
24
|
class {
|
|
@@ -58,11 +40,36 @@ export const hashtag = (): Extension => [
|
|
|
58
40
|
},
|
|
59
41
|
),
|
|
60
42
|
|
|
61
|
-
|
|
62
|
-
'.cm-tag': {
|
|
63
|
-
borderRadius: '4px',
|
|
64
|
-
marginRight: '6px',
|
|
65
|
-
padding: '2px 6px',
|
|
66
|
-
},
|
|
67
|
-
}),
|
|
43
|
+
styles,
|
|
68
44
|
];
|
|
45
|
+
|
|
46
|
+
class TagWidget extends WidgetType {
|
|
47
|
+
constructor(private _text: string) {
|
|
48
|
+
super();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
toDOM(): HTMLSpanElement {
|
|
52
|
+
const span = document.createElement('span');
|
|
53
|
+
span.className = mx('cm-tag', getHashStyles(this._text).surface);
|
|
54
|
+
span.textContent = this._text;
|
|
55
|
+
return span;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const tagMatcher = new MatchDecorator({
|
|
60
|
+
// `\w+` stops at the first non-word char, so no trailing boundary is needed; requiring one
|
|
61
|
+
// (e.g. `\W`) would consume that char and fail to match a tag at the end of the document.
|
|
62
|
+
regexp: /#(\w+)/g,
|
|
63
|
+
decoration: (match) =>
|
|
64
|
+
Decoration.replace({
|
|
65
|
+
widget: new TagWidget(match[1]),
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const styles = EditorView.theme({
|
|
70
|
+
'.cm-tag': {
|
|
71
|
+
borderRadius: '4px',
|
|
72
|
+
marginRight: '6px',
|
|
73
|
+
padding: '2px 6px',
|
|
74
|
+
},
|
|
75
|
+
});
|