@k2b/ui 0.34.0 → 0.36.0

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.
Files changed (126) hide show
  1. package/dist/browser/actions/Dropdown.js +1 -0
  2. package/dist/browser/actions/Dropdown.js.map +1 -1
  3. package/dist/browser/content/MapView.js +128 -13
  4. package/dist/browser/content/MapView.js.map +1 -1
  5. package/dist/browser/content/MapViewFrame.js +1 -1
  6. package/dist/browser/content/MapViewFrame.js.map +1 -1
  7. package/dist/browser/content/MatchText.js +61 -0
  8. package/dist/browser/content/MatchText.js.map +1 -0
  9. package/dist/browser/content/index.js +2 -0
  10. package/dist/browser/content/index.js.map +1 -1
  11. package/dist/browser/content/map-view-glyphs.js +23 -0
  12. package/dist/browser/content/map-view-glyphs.js.map +1 -0
  13. package/dist/browser/content/map-view-live.js +45 -22
  14. package/dist/browser/content/map-view-live.js.map +1 -1
  15. package/dist/browser/content/map-view-snapshot.js +191 -0
  16. package/dist/browser/content/map-view-snapshot.js.map +1 -0
  17. package/dist/browser/content/map-view-types.js.map +1 -1
  18. package/dist/browser/inputs/Combobox.js +139 -62
  19. package/dist/browser/inputs/Combobox.js.map +1 -1
  20. package/dist/browser/inputs/TextInput.js +1 -1
  21. package/dist/browser/inputs/TextInput.js.map +1 -1
  22. package/dist/browser/layout/AppWorkspace.js +73 -70
  23. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  24. package/dist/browser/layout/ScrollArea.js +4 -1
  25. package/dist/browser/layout/ScrollArea.js.map +1 -1
  26. package/dist/browser/text-editor/TextEditor.js +1358 -0
  27. package/dist/browser/text-editor/TextEditor.js.map +1 -0
  28. package/dist/browser/text-editor/clipboard-html.js +152 -0
  29. package/dist/browser/text-editor/clipboard-html.js.map +1 -0
  30. package/dist/browser/text-editor/clipboard-loading.js +68 -0
  31. package/dist/browser/text-editor/clipboard-loading.js.map +1 -0
  32. package/dist/browser/text-editor/clipboard.js +51 -0
  33. package/dist/browser/text-editor/clipboard.js.map +1 -0
  34. package/dist/browser/text-editor/engine.js +125 -0
  35. package/dist/browser/text-editor/engine.js.map +1 -0
  36. package/dist/browser/text-editor/format.js +218 -0
  37. package/dist/browser/text-editor/format.js.map +1 -0
  38. package/dist/browser/text-editor/formatted.js +164 -0
  39. package/dist/browser/text-editor/formatted.js.map +1 -0
  40. package/dist/browser/text-editor/language.js +19 -0
  41. package/dist/browser/text-editor/language.js.map +1 -0
  42. package/dist/browser/text-editor/markdown-table.js +563 -0
  43. package/dist/browser/text-editor/markdown-table.js.map +1 -0
  44. package/dist/browser/text-editor/messages.js +233 -0
  45. package/dist/browser/text-editor/messages.js.map +1 -0
  46. package/dist/browser/text-editor/paste.js +115 -0
  47. package/dist/browser/text-editor/paste.js.map +1 -0
  48. package/dist/browser/text-editor/table.js +1760 -0
  49. package/dist/browser/text-editor/table.js.map +1 -0
  50. package/dist/browser/text-editor.js +5 -0
  51. package/dist/browser/text-editor.js.map +1 -0
  52. package/dist/ssr/actions/Dropdown.js +1 -0
  53. package/dist/ssr/actions/Dropdown.js.map +1 -1
  54. package/dist/ssr/content/MapView.js +128 -13
  55. package/dist/ssr/content/MapView.js.map +1 -1
  56. package/dist/ssr/content/MapViewFrame.js +1 -1
  57. package/dist/ssr/content/MapViewFrame.js.map +1 -1
  58. package/dist/ssr/content/MatchText.js +56 -0
  59. package/dist/ssr/content/MatchText.js.map +1 -0
  60. package/dist/ssr/content/index.js +2 -0
  61. package/dist/ssr/content/index.js.map +1 -1
  62. package/dist/ssr/content/map-view-glyphs.js +23 -0
  63. package/dist/ssr/content/map-view-glyphs.js.map +1 -0
  64. package/dist/ssr/content/map-view-snapshot.js +191 -0
  65. package/dist/ssr/content/map-view-snapshot.js.map +1 -0
  66. package/dist/ssr/content/map-view-types.js.map +1 -1
  67. package/dist/ssr/inputs/Combobox.js +66 -20
  68. package/dist/ssr/inputs/Combobox.js.map +1 -1
  69. package/dist/ssr/inputs/TextInput.js.map +1 -1
  70. package/dist/ssr/layout/AppWorkspace.js +1 -1
  71. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  72. package/dist/ssr/layout/ScrollArea.js +4 -1
  73. package/dist/ssr/layout/ScrollArea.js.map +1 -1
  74. package/dist/ssr/text-editor/TextEditor.js +1155 -0
  75. package/dist/ssr/text-editor/TextEditor.js.map +1 -0
  76. package/dist/ssr/text-editor/clipboard-html.js +152 -0
  77. package/dist/ssr/text-editor/clipboard-html.js.map +1 -0
  78. package/dist/ssr/text-editor/clipboard-loading.js +68 -0
  79. package/dist/ssr/text-editor/clipboard-loading.js.map +1 -0
  80. package/dist/ssr/text-editor/clipboard.js +51 -0
  81. package/dist/ssr/text-editor/clipboard.js.map +1 -0
  82. package/dist/ssr/text-editor/engine.js +125 -0
  83. package/dist/ssr/text-editor/engine.js.map +1 -0
  84. package/dist/ssr/text-editor/format.js +218 -0
  85. package/dist/ssr/text-editor/format.js.map +1 -0
  86. package/dist/ssr/text-editor/formatted.js +164 -0
  87. package/dist/ssr/text-editor/formatted.js.map +1 -0
  88. package/dist/ssr/text-editor/language.js +19 -0
  89. package/dist/ssr/text-editor/language.js.map +1 -0
  90. package/dist/ssr/text-editor/markdown-table.js +563 -0
  91. package/dist/ssr/text-editor/markdown-table.js.map +1 -0
  92. package/dist/ssr/text-editor/messages.js +233 -0
  93. package/dist/ssr/text-editor/messages.js.map +1 -0
  94. package/dist/ssr/text-editor/paste.js +115 -0
  95. package/dist/ssr/text-editor/paste.js.map +1 -0
  96. package/dist/ssr/text-editor/table.js +1760 -0
  97. package/dist/ssr/text-editor/table.js.map +1 -0
  98. package/dist/ssr/text-editor.js +5 -0
  99. package/dist/ssr/text-editor.js.map +1 -0
  100. package/dist/styles.css +1 -1
  101. package/dist/types/actions/Dropdown.d.ts +2 -0
  102. package/dist/types/content/MapViewFrame.d.ts +1 -1
  103. package/dist/types/content/MatchText.d.ts +21 -0
  104. package/dist/types/content/index.d.ts +3 -1
  105. package/dist/types/content/map-view-glyphs.d.ts +5 -0
  106. package/dist/types/content/map-view-live.d.ts +1 -1
  107. package/dist/types/content/map-view-snapshot.d.ts +13 -0
  108. package/dist/types/content/map-view-types.d.ts +15 -0
  109. package/dist/types/inputs/Combobox.d.ts +12 -0
  110. package/dist/types/inputs/TextInput.d.ts +2 -1
  111. package/dist/types/layout/AppWorkspace.d.ts +4 -1
  112. package/dist/types/layout/ScrollArea.d.ts +2 -0
  113. package/dist/types/text-editor/TextEditor.d.ts +69 -0
  114. package/dist/types/text-editor/clipboard-html.d.ts +9 -0
  115. package/dist/types/text-editor/clipboard-loading.d.ts +8 -0
  116. package/dist/types/text-editor/clipboard.d.ts +20 -0
  117. package/dist/types/text-editor/engine.d.ts +34 -0
  118. package/dist/types/text-editor/format.d.ts +34 -0
  119. package/dist/types/text-editor/formatted.d.ts +1 -0
  120. package/dist/types/text-editor/language.d.ts +8 -0
  121. package/dist/types/text-editor/markdown-table.d.ts +105 -0
  122. package/dist/types/text-editor/messages.d.ts +113 -0
  123. package/dist/types/text-editor/paste.d.ts +6 -0
  124. package/dist/types/text-editor/table.d.ts +81 -0
  125. package/dist/types/text-editor.d.ts +4 -0
  126. package/package.json +24 -3
@@ -0,0 +1,125 @@
1
+ import { standardKeymap } from "@codemirror/commands";
2
+ import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
3
+ import { Compartment, EditorState, Prec, Text } from "@codemirror/state";
4
+ import { drawSelection, EditorView, keymap, placeholder, runScopeHandlers } from "@codemirror/view";
5
+ import { clipboardLoading } from "./clipboard-loading";
6
+ import { commands } from "./format";
7
+ import { formattedView } from "./formatted";
8
+ import { markdown } from "./language";
9
+ import { cleanPaste } from "./paste";
10
+ import { tableGrid, tableHost } from "./table";
11
+ const builtInPresentation = mode => [markdown(), syntaxHighlighting(defaultHighlightStyle, {
12
+ fallback: true
13
+ }), mode === "formatted" ? formattedView : EditorView.contentAttributes.of({
14
+ class: "k2b-ste-source"
15
+ }), keymap.of([{
16
+ key: "Mod-b",
17
+ run: commands.bold
18
+ }, {
19
+ key: "Mod-i",
20
+ run: commands.italic
21
+ }, {
22
+ key: "Mod-k",
23
+ run: commands.link
24
+ }, {
25
+ key: "Mod-Shift-x",
26
+ run: commands.strike
27
+ }])];
28
+
29
+ /** Shared engine; application extensions own transport, awareness and domain features. */
30
+ export function createTextEditor(options) {
31
+ const modeSlot = new Compartment();
32
+ const readOnlySlot = new Compartment();
33
+ const labelSlot = new Compartment();
34
+ const presentation = options.presentation ?? builtInPresentation;
35
+ const runHistory = (view, direction) => {
36
+ view.state.facet(tableHost)?.[direction]();
37
+ // Consume even an empty or read-only history, so another binding cannot handle it again.
38
+ return true;
39
+ };
40
+ const modeExtensions = mode => mode === "plain" ? [clipboardLoading(() => options.host), cleanPaste(options.onDroppedImages, true)] : [presentation(mode), mode === "formatted" ? tableGrid() : clipboardLoading(() => options.host), cleanPaste(options.onDroppedImages)];
41
+ const view = new EditorView({
42
+ parent: options.parent,
43
+ state: EditorState.create({
44
+ doc: Text.of((options.doc ?? "").split("\n")),
45
+ extensions: [drawSelection(), EditorView.lineWrapping, placeholder(options.placeholder ?? ""), labelSlot.of(EditorView.contentAttributes.of({
46
+ "aria-label": options.label
47
+ })), Prec.highest([keymap.of([{
48
+ key: "Mod-z",
49
+ run: view => runHistory(view, "undo"),
50
+ shift: view => runHistory(view, "redo"),
51
+ preventDefault: true
52
+ }, {
53
+ key: "Mod-y",
54
+ run: view => runHistory(view, "redo"),
55
+ preventDefault: true
56
+ }]), EditorView.domEventHandlers({
57
+ beforeinput(event, view) {
58
+ if (event.inputType === "historyUndo") return runHistory(view, "undo");
59
+ if (event.inputType === "historyRedo") return runHistory(view, "redo");
60
+ return false;
61
+ }
62
+ })]), keymap.of(standardKeymap), tableHost.of({
63
+ ...options.host,
64
+ onDroppedImages: options.onDroppedImages,
65
+ undo: () => {
66
+ if (!view.state.readOnly) options.host.undo();
67
+ },
68
+ redo: () => {
69
+ if (!view.state.readOnly) options.host.redo();
70
+ }
71
+ }), EditorState.transactionFilter.of(tr => {
72
+ // Only growth is refused: an over-limit text stays editable so it can be shortened.
73
+ if (tr.docChanged && tr.isUserEvent("input") && tr.newDoc.length > options.host.maxLength && tr.newDoc.length > tr.startState.doc.length) {
74
+ const inserted = [];
75
+ tr.changes.iterChanges((_from, _to, _newFrom, _newTo, text) => {
76
+ if (text.length) inserted.push(text.toString());
77
+ });
78
+ queueMicrotask(() => {
79
+ if (inserted.length) options.host.onRecovery(inserted.join("\n"));
80
+ options.host.onError("textTooLarge");
81
+ });
82
+ return [];
83
+ }
84
+ return tr;
85
+ }), EditorView.updateListener.of(update => {
86
+ if (update.docChanged) options.onChange?.(update.state.doc.toString());
87
+ }), modeSlot.of(modeExtensions(options.mode ?? "formatted")), readOnlySlot.of([EditorState.readOnly.of(options.readOnly ?? false), EditorView.editable.of(!options.readOnly)]), options.extensions ?? []]
88
+ })
89
+ });
90
+ // CM's Android DOM-input deferral can lose a physical Enter when the next
91
+ // EditContext update arrives before its animation frame. Run the public
92
+ // keymap synchronously only for that reliable, non-composing key event.
93
+ const enter = event => {
94
+ if (event.target !== view.contentDOM || event.key !== "Enter" || event.keyCode !== 13 || event.isComposing || view.composing || event.defaultPrevented || !/Android/.test(view.dom.ownerDocument.defaultView?.navigator.userAgent ?? "") || !("editContext" in view.contentDOM && view.contentDOM.editContext)) return;
95
+ if (runScopeHandlers(view, event, "editor")) {
96
+ event.preventDefault();
97
+ event.stopImmediatePropagation();
98
+ }
99
+ };
100
+ view.contentDOM.addEventListener("keydown", enter, true);
101
+ return {
102
+ view,
103
+ /** Also re-reads `presentation`, so a host can refresh it, e.g. after a theme change. */
104
+ setMode: mode => view.dispatch({
105
+ effects: modeSlot.reconfigure(modeExtensions(mode))
106
+ }),
107
+ setLabel: label => view.dispatch({
108
+ effects: labelSlot.reconfigure(EditorView.contentAttributes.of({
109
+ "aria-label": label
110
+ }))
111
+ }),
112
+ // Hosts re-run this from reactive state that may change inside an editor update; an unchanged value must not dispatch.
113
+ setReadOnly: readOnly => {
114
+ if (view.state.readOnly === readOnly && view.state.facet(EditorView.editable) === !readOnly) return;
115
+ view.dispatch({
116
+ effects: readOnlySlot.reconfigure([EditorState.readOnly.of(readOnly), EditorView.editable.of(!readOnly)])
117
+ });
118
+ },
119
+ destroy: () => {
120
+ view.contentDOM.removeEventListener("keydown", enter, true);
121
+ view.destroy();
122
+ }
123
+ };
124
+ }
125
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/engine.ts"],"sourcesContent":["import { standardKeymap } from \"@codemirror/commands\";\nimport { defaultHighlightStyle, syntaxHighlighting } from \"@codemirror/language\";\nimport { Compartment, EditorState, type Extension, Prec, Text } from \"@codemirror/state\";\nimport { drawSelection, EditorView, keymap, placeholder, runScopeHandlers } from \"@codemirror/view\";\nimport { clipboardLoading } from \"./clipboard-loading\";\nimport { commands } from \"./format\";\nimport { formattedView } from \"./formatted\";\nimport { markdown } from \"./language\";\nimport { cleanPaste } from \"./paste\";\nimport { type TableHost, tableGrid, tableHost } from \"./table\";\n\nexport type TextEditorMode = \"formatted\" | \"source\" | \"plain\";\nexport type TextEditorOptions = {\n parent: HTMLElement;\n /** Initial Markdown. Subsequent collaborative changes arrive through extensions. */\n doc?: string;\n mode?: TextEditorMode;\n readOnly?: boolean;\n placeholder?: string;\n label: string;\n extensions?: Extension;\n /**\n * Replaces the built-in Markdown language, highlighting, formatted markers and\n * formatting keys of the formatted and source modes. The engine keeps the\n * table grid, clean paste, limits and history routing in every mode.\n */\n presentation?: (mode: Exclude<TextEditorMode, \"plain\">) => Extension;\n /** The host owns history; collaboration bindings supply theirs. */\n host: TableHost;\n onChange?: (text: string) => void;\n onDroppedImages?: (count: number, files: File[]) => void;\n};\n\nconst builtInPresentation = (mode: Exclude<TextEditorMode, \"plain\">): Extension => [\n markdown(),\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n mode === \"formatted\" ? formattedView : EditorView.contentAttributes.of({ class: \"k2b-ste-source\" }),\n keymap.of([\n { key: \"Mod-b\", run: commands.bold },\n { key: \"Mod-i\", run: commands.italic },\n { key: \"Mod-k\", run: commands.link },\n { key: \"Mod-Shift-x\", run: commands.strike },\n ]),\n];\n\n/** Shared engine; application extensions own transport, awareness and domain features. */\nexport function createTextEditor(options: TextEditorOptions) {\n const modeSlot = new Compartment();\n const readOnlySlot = new Compartment();\n const labelSlot = new Compartment();\n const presentation = options.presentation ?? builtInPresentation;\n const runHistory = (view: EditorView, direction: \"undo\" | \"redo\") => {\n view.state.facet(tableHost)?.[direction]();\n // Consume even an empty or read-only history, so another binding cannot handle it again.\n return true;\n };\n const modeExtensions = (mode: TextEditorMode): Extension =>\n mode === \"plain\"\n ? [clipboardLoading(() => options.host), cleanPaste(options.onDroppedImages, true)]\n : [\n presentation(mode),\n mode === \"formatted\" ? tableGrid() : clipboardLoading(() => options.host),\n cleanPaste(options.onDroppedImages),\n ];\n const view = new EditorView({\n parent: options.parent,\n state: EditorState.create({\n doc: Text.of((options.doc ?? \"\").split(\"\\n\")),\n extensions: [\n drawSelection(),\n EditorView.lineWrapping,\n placeholder(options.placeholder ?? \"\"),\n labelSlot.of(EditorView.contentAttributes.of({ \"aria-label\": options.label })),\n Prec.highest([\n keymap.of([\n { key: \"Mod-z\", run: (view) => runHistory(view, \"undo\"), shift: (view) => runHistory(view, \"redo\"), preventDefault: true },\n { key: \"Mod-y\", run: (view) => runHistory(view, \"redo\"), preventDefault: true },\n ]),\n EditorView.domEventHandlers({\n beforeinput(event, view) {\n if (event.inputType === \"historyUndo\") return runHistory(view, \"undo\");\n if (event.inputType === \"historyRedo\") return runHistory(view, \"redo\");\n return false;\n },\n }),\n ]),\n keymap.of(standardKeymap),\n tableHost.of({\n ...options.host,\n onDroppedImages: options.onDroppedImages,\n undo: () => {\n if (!view.state.readOnly) options.host.undo();\n },\n redo: () => {\n if (!view.state.readOnly) options.host.redo();\n },\n }),\n EditorState.transactionFilter.of((tr) => {\n // Only growth is refused: an over-limit text stays editable so it can be shortened.\n if (\n tr.docChanged &&\n tr.isUserEvent(\"input\") &&\n tr.newDoc.length > options.host.maxLength &&\n tr.newDoc.length > tr.startState.doc.length\n ) {\n const inserted: string[] = [];\n tr.changes.iterChanges((_from, _to, _newFrom, _newTo, text) => {\n if (text.length) inserted.push(text.toString());\n });\n queueMicrotask(() => {\n if (inserted.length) options.host.onRecovery(inserted.join(\"\\n\"));\n options.host.onError(\"textTooLarge\");\n });\n return [];\n }\n return tr;\n }),\n EditorView.updateListener.of((update) => {\n if (update.docChanged) options.onChange?.(update.state.doc.toString());\n }),\n modeSlot.of(modeExtensions(options.mode ?? \"formatted\")),\n readOnlySlot.of([EditorState.readOnly.of(options.readOnly ?? false), EditorView.editable.of(!options.readOnly)]),\n options.extensions ?? [],\n ],\n }),\n });\n // CM's Android DOM-input deferral can lose a physical Enter when the next\n // EditContext update arrives before its animation frame. Run the public\n // keymap synchronously only for that reliable, non-composing key event.\n const enter = (event: KeyboardEvent) => {\n if (\n event.target !== view.contentDOM ||\n event.key !== \"Enter\" ||\n event.keyCode !== 13 ||\n event.isComposing ||\n view.composing ||\n event.defaultPrevented ||\n !/Android/.test(view.dom.ownerDocument.defaultView?.navigator.userAgent ?? \"\") ||\n !(\"editContext\" in view.contentDOM && view.contentDOM.editContext)\n )\n return;\n if (runScopeHandlers(view, event, \"editor\")) {\n event.preventDefault();\n event.stopImmediatePropagation();\n }\n };\n view.contentDOM.addEventListener(\"keydown\", enter, true);\n return {\n view,\n /** Also re-reads `presentation`, so a host can refresh it, e.g. after a theme change. */\n setMode: (mode: TextEditorMode) => view.dispatch({ effects: modeSlot.reconfigure(modeExtensions(mode)) }),\n setLabel: (label: string) =>\n view.dispatch({ effects: labelSlot.reconfigure(EditorView.contentAttributes.of({ \"aria-label\": label })) }),\n // Hosts re-run this from reactive state that may change inside an editor update; an unchanged value must not dispatch.\n setReadOnly: (readOnly: boolean) => {\n if (view.state.readOnly === readOnly && view.state.facet(EditorView.editable) === !readOnly) return;\n view.dispatch({ effects: readOnlySlot.reconfigure([EditorState.readOnly.of(readOnly), EditorView.editable.of(!readOnly)]) });\n },\n destroy: () => {\n view.contentDOM.removeEventListener(\"keydown\", enter, true);\n view.destroy();\n },\n };\n}\nexport type TextEditorController = ReturnType<typeof createTextEditor>;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,218 @@
1
+ /** Toolbar and keyboard commands. Each one is a plain Markdown edit of the selection. */
2
+ import { EditorSelection, Facet } from "@codemirror/state";
3
+ /** Insertion text follows the editor's inherited locale, including keyboard commands. */
4
+ export const formatLabels = Facet.define({
5
+ combine: values => values[0] ?? {
6
+ link: "Link",
7
+ column: column => `Column ${column}`
8
+ }
9
+ });
10
+
11
+ /** Named Markdown marks or an app's single-line paired delimiter (for example Notebook's `==`). */
12
+
13
+ /** Pure transaction spec, also used when a missing table cell must be materialized atomically. */
14
+ export const inlineFormat = (state, name) => {
15
+ if (name === "link") {
16
+ const {
17
+ from,
18
+ to
19
+ } = state.selection.main;
20
+ const label = state.sliceDoc(from, to) || state.facet(formatLabels).link;
21
+ return {
22
+ changes: {
23
+ from,
24
+ to,
25
+ insert: `[${label}](https://)`
26
+ },
27
+ selection: {
28
+ anchor: from + label.length + 3,
29
+ head: from + label.length + 11
30
+ },
31
+ userEvent: "input.format"
32
+ };
33
+ }
34
+ const marker = typeof name === "string" ? {
35
+ bold: "**",
36
+ italic: "*",
37
+ code: "`",
38
+ strike: "~~"
39
+ }[name] : name.marker;
40
+ // A host inline delimiter must not split a cell or introduce another row.
41
+ if (!marker || /[|\r\n]/.test(marker)) return {};
42
+ return {
43
+ ...state.changeByRange(range => {
44
+ const text = state.sliceDoc(range.from, range.to);
45
+ const before = state.sliceDoc(Math.max(0, range.from - marker.length), range.from);
46
+ const after = state.sliceDoc(range.to, Math.min(state.doc.length, range.to + marker.length));
47
+ const italicBoundary = name !== "italic" || (/\*+$/.exec(state.sliceDoc(state.doc.lineAt(range.from).from, range.from))?.[0].length ?? 0) % 2 === 1 && (/^\*+/.exec(state.sliceDoc(range.to, state.doc.lineAt(range.to).to))?.[0].length ?? 0) % 2 === 1;
48
+ if (before === marker && after === marker && italicBoundary) return {
49
+ changes: [{
50
+ from: range.from - marker.length,
51
+ to: range.from
52
+ }, {
53
+ from: range.to,
54
+ to: range.to + marker.length
55
+ }],
56
+ range: EditorSelection.range(range.from - marker.length, range.to - marker.length)
57
+ };
58
+ return {
59
+ changes: {
60
+ from: range.from,
61
+ to: range.to,
62
+ insert: `${marker}${text}${marker}`
63
+ },
64
+ range: EditorSelection.range(range.from + marker.length, range.to + marker.length)
65
+ };
66
+ }),
67
+ userEvent: "input.format"
68
+ };
69
+ };
70
+ const inlineCommand = name => view => {
71
+ if (view.state.readOnly) return false;
72
+ view.dispatch(inlineFormat(view.state, name));
73
+ view.focus();
74
+ return true;
75
+ };
76
+ const linePrefix = (pattern, prefix) => view => {
77
+ if (view.state.readOnly) return false;
78
+ const {
79
+ state
80
+ } = view;
81
+ const lines = new Set();
82
+ for (const r of state.selection.ranges) for (let n = state.doc.lineAt(r.from).number; n <= state.doc.lineAt(r.to).number; n++) lines.add(n);
83
+ const all = [...lines].every(n => pattern.test(state.doc.line(n).text));
84
+ const changes = [...lines].map(n => {
85
+ const line = state.doc.line(n);
86
+ const m = pattern.exec(line.text);
87
+ return all && m ? {
88
+ from: line.from,
89
+ to: line.from + m[0].length
90
+ } : {
91
+ from: line.from,
92
+ insert: prefix(state, n)
93
+ };
94
+ });
95
+ view.dispatch({
96
+ changes,
97
+ userEvent: "input.format"
98
+ });
99
+ view.focus();
100
+ return true;
101
+ };
102
+ const heading = level => view => {
103
+ if (view.state.readOnly) return false;
104
+ const {
105
+ state
106
+ } = view;
107
+ const numbers = new Set();
108
+ for (const range of state.selection.ranges) for (let n = state.doc.lineAt(range.from).number; n <= state.doc.lineAt(range.to).number; n++) numbers.add(n);
109
+ const prefix = `${"#".repeat(level)} `;
110
+ const lines = [...numbers].sort((a, b) => a - b).map(number => state.doc.line(number));
111
+ const remove = lines.every(line => line.text.startsWith(prefix));
112
+ view.dispatch({
113
+ changes: lines.map(line => ({
114
+ from: line.from,
115
+ to: line.from + (/^#{1,6} /.exec(line.text)?.[0].length ?? 0),
116
+ insert: remove ? "" : prefix
117
+ })),
118
+ userEvent: "input.format"
119
+ });
120
+ view.focus();
121
+ return true;
122
+ };
123
+ export const commands = {
124
+ bold: inlineCommand("bold"),
125
+ italic: inlineCommand("italic"),
126
+ code: inlineCommand("code"),
127
+ strike: inlineCommand("strike"),
128
+ heading: heading(2),
129
+ heading1: heading(1),
130
+ heading2: heading(2),
131
+ heading3: heading(3),
132
+ codeBlock: view => {
133
+ if (view.state.readOnly) return false;
134
+ const {
135
+ state
136
+ } = view;
137
+ const from = state.doc.lineAt(state.selection.main.from).from;
138
+ const to = state.doc.lineAt(state.selection.main.to).to;
139
+ const text = state.sliceDoc(from, to);
140
+ let fenceLength = 3;
141
+ for (const match of text.matchAll(/`+/g)) fenceLength = Math.max(fenceLength, match[0].length + 1);
142
+ const fence = "`".repeat(fenceLength);
143
+ const lead = from > 0 && state.doc.lineAt(from - 1).length ? "\n" : "";
144
+ const tail = to < state.doc.length && state.doc.lineAt(to + 1).length ? "\n" : "";
145
+ const start = from + lead.length + fence.length + 1;
146
+ view.dispatch({
147
+ changes: {
148
+ from,
149
+ to,
150
+ insert: `${lead}${fence}\n${text}\n${fence}${tail}`
151
+ },
152
+ selection: {
153
+ anchor: start,
154
+ head: start + text.length
155
+ },
156
+ userEvent: "input.format"
157
+ });
158
+ view.focus();
159
+ return true;
160
+ },
161
+ bulletList: linePrefix(/^\s*[-*] /, () => "- "),
162
+ orderedList: linePrefix(/^\s*\d+\. /, () => "1. "),
163
+ quote: linePrefix(/^> ?/, () => "> "),
164
+ link: inlineCommand("link"),
165
+ table: view => {
166
+ if (view.state.readOnly) return false;
167
+ const {
168
+ from
169
+ } = view.state.selection.main;
170
+ const line = view.state.doc.lineAt(from);
171
+ const lead = line.length ? "\n\n" : "";
172
+ const labels = view.state.facet(formatLabels);
173
+ const first = labels.column(1);
174
+ const insert = `${lead}| ${first} | ${labels.column(2)} |\n| --- | --- |\n| | |\n`;
175
+ const anchor = line.to + lead.length + 2;
176
+ view.dispatch({
177
+ changes: {
178
+ from: line.to,
179
+ insert
180
+ },
181
+ selection: {
182
+ anchor,
183
+ head: anchor + first.length
184
+ },
185
+ userEvent: "input.format"
186
+ });
187
+ view.focus();
188
+ queueMicrotask(() => {
189
+ if (!view.dom.isConnected) return;
190
+ const table = [...view.contentDOM.querySelectorAll(".k2b-ste-table")].find(element => view.posAtDOM(element) === line.to + lead.length);
191
+ const cell = table?.querySelector('.k2b-ste-cell[data-r="0"][data-c="0"]');
192
+ if (!cell) return;
193
+ cell.focus();
194
+ const selection = cell.ownerDocument.getSelection();
195
+ const range = cell.ownerDocument.createRange();
196
+ range.selectNodeContents(cell);
197
+ selection?.removeAllRanges();
198
+ selection?.addRange(range);
199
+ });
200
+ return true;
201
+ },
202
+ rule: view => {
203
+ if (view.state.readOnly) return false;
204
+ const line = view.state.doc.lineAt(view.state.selection.main.from);
205
+ const previousHasText = line.number > 1 && view.state.doc.line(line.number - 1).text.trim().length > 0;
206
+ const lead = line.length ? "\n\n" : previousHasText ? "\n" : "";
207
+ view.dispatch({
208
+ changes: {
209
+ from: line.to,
210
+ insert: `${lead}---\n`
211
+ },
212
+ userEvent: "input.format"
213
+ });
214
+ view.focus();
215
+ return true;
216
+ }
217
+ };
218
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/format.ts"],"sourcesContent":["/** Toolbar and keyboard commands. Each one is a plain Markdown edit of the selection. */\nimport { EditorSelection, type EditorState, Facet, type TransactionSpec } from \"@codemirror/state\";\nimport type { EditorView } from \"@codemirror/view\";\n\n/** Insertion text follows the editor's inherited locale, including keyboard commands. */\nexport const formatLabels = Facet.define<\n { link: string; column: (column: number) => string },\n { link: string; column: (column: number) => string }\n>({\n combine: (values) => values[0] ?? { link: \"Link\", column: (column) => `Column ${column}` },\n});\n\n/** Named Markdown marks or an app's single-line paired delimiter (for example Notebook's `==`). */\nexport type InlineFormat = \"bold\" | \"italic\" | \"code\" | \"strike\" | \"link\" | { marker: string };\n/** Pure transaction spec, also used when a missing table cell must be materialized atomically. */\nexport const inlineFormat = (state: EditorState, name: InlineFormat): TransactionSpec => {\n if (name === \"link\") {\n const { from, to } = state.selection.main;\n const label = state.sliceDoc(from, to) || state.facet(formatLabels).link;\n return {\n changes: { from, to, insert: `[${label}](https://)` },\n selection: { anchor: from + label.length + 3, head: from + label.length + 11 },\n userEvent: \"input.format\",\n };\n }\n const marker = typeof name === \"string\" ? { bold: \"**\", italic: \"*\", code: \"`\", strike: \"~~\" }[name] : name.marker;\n // A host inline delimiter must not split a cell or introduce another row.\n if (!marker || /[|\\r\\n]/.test(marker)) return {};\n return {\n ...state.changeByRange((range) => {\n const text = state.sliceDoc(range.from, range.to);\n const before = state.sliceDoc(Math.max(0, range.from - marker.length), range.from);\n const after = state.sliceDoc(range.to, Math.min(state.doc.length, range.to + marker.length));\n const italicBoundary =\n name !== \"italic\" ||\n ((/\\*+$/.exec(state.sliceDoc(state.doc.lineAt(range.from).from, range.from))?.[0].length ?? 0) % 2 === 1 &&\n (/^\\*+/.exec(state.sliceDoc(range.to, state.doc.lineAt(range.to).to))?.[0].length ?? 0) % 2 === 1);\n if (before === marker && after === marker && italicBoundary)\n return {\n changes: [\n { from: range.from - marker.length, to: range.from },\n { from: range.to, to: range.to + marker.length },\n ],\n range: EditorSelection.range(range.from - marker.length, range.to - marker.length),\n };\n return {\n changes: { from: range.from, to: range.to, insert: `${marker}${text}${marker}` },\n range: EditorSelection.range(range.from + marker.length, range.to + marker.length),\n };\n }),\n userEvent: \"input.format\",\n };\n};\nconst inlineCommand = (name: InlineFormat) => (view: EditorView) => {\n if (view.state.readOnly) return false;\n view.dispatch(inlineFormat(view.state, name));\n view.focus();\n return true;\n};\n\nconst linePrefix = (pattern: RegExp, prefix: (state: EditorState, n: number) => string) => (view: EditorView) => {\n if (view.state.readOnly) return false;\n const { state } = view;\n const lines = new Set<number>();\n for (const r of state.selection.ranges)\n for (let n = state.doc.lineAt(r.from).number; n <= state.doc.lineAt(r.to).number; n++) lines.add(n);\n const all = [...lines].every((n) => pattern.test(state.doc.line(n).text));\n const changes = [...lines].map((n) => {\n const line = state.doc.line(n);\n const m = pattern.exec(line.text);\n return all && m ? { from: line.from, to: line.from + m[0].length } : { from: line.from, insert: prefix(state, n) };\n });\n view.dispatch({ changes, userEvent: \"input.format\" });\n view.focus();\n return true;\n};\n\nconst heading = (level: number) => (view: EditorView) => {\n if (view.state.readOnly) return false;\n const { state } = view;\n const numbers = new Set<number>();\n for (const range of state.selection.ranges)\n for (let n = state.doc.lineAt(range.from).number; n <= state.doc.lineAt(range.to).number; n++) numbers.add(n);\n const prefix = `${\"#\".repeat(level)} `;\n const lines = [...numbers].sort((a, b) => a - b).map((number) => state.doc.line(number));\n const remove = lines.every((line) => line.text.startsWith(prefix));\n view.dispatch({\n changes: lines.map((line) => ({\n from: line.from,\n to: line.from + (/^#{1,6} /.exec(line.text)?.[0].length ?? 0),\n insert: remove ? \"\" : prefix,\n })),\n userEvent: \"input.format\",\n });\n view.focus();\n return true;\n};\n\nexport const commands = {\n bold: inlineCommand(\"bold\"),\n italic: inlineCommand(\"italic\"),\n code: inlineCommand(\"code\"),\n strike: inlineCommand(\"strike\"),\n heading: heading(2),\n heading1: heading(1),\n heading2: heading(2),\n heading3: heading(3),\n codeBlock: (view: EditorView) => {\n if (view.state.readOnly) return false;\n const { state } = view;\n const from = state.doc.lineAt(state.selection.main.from).from;\n const to = state.doc.lineAt(state.selection.main.to).to;\n const text = state.sliceDoc(from, to);\n let fenceLength = 3;\n for (const match of text.matchAll(/`+/g)) fenceLength = Math.max(fenceLength, match[0].length + 1);\n const fence = \"`\".repeat(fenceLength);\n const lead = from > 0 && state.doc.lineAt(from - 1).length ? \"\\n\" : \"\";\n const tail = to < state.doc.length && state.doc.lineAt(to + 1).length ? \"\\n\" : \"\";\n const start = from + lead.length + fence.length + 1;\n view.dispatch({\n changes: { from, to, insert: `${lead}${fence}\\n${text}\\n${fence}${tail}` },\n selection: { anchor: start, head: start + text.length },\n userEvent: \"input.format\",\n });\n view.focus();\n return true;\n },\n bulletList: linePrefix(/^\\s*[-*] /, () => \"- \"),\n orderedList: linePrefix(/^\\s*\\d+\\. /, () => \"1. \"),\n quote: linePrefix(/^> ?/, () => \"> \"),\n link: inlineCommand(\"link\"),\n table: (view: EditorView) => {\n if (view.state.readOnly) return false;\n const { from } = view.state.selection.main;\n const line = view.state.doc.lineAt(from);\n const lead = line.length ? \"\\n\\n\" : \"\";\n const labels = view.state.facet(formatLabels);\n const first = labels.column(1);\n const insert = `${lead}| ${first} | ${labels.column(2)} |\\n| --- | --- |\\n| | |\\n`;\n const anchor = line.to + lead.length + 2;\n view.dispatch({ changes: { from: line.to, insert }, selection: { anchor, head: anchor + first.length }, userEvent: \"input.format\" });\n view.focus();\n queueMicrotask(() => {\n if (!view.dom.isConnected) return;\n const table = [...view.contentDOM.querySelectorAll<HTMLElement>(\".k2b-ste-table\")].find(\n (element) => view.posAtDOM(element) === line.to + lead.length,\n );\n const cell = table?.querySelector<HTMLElement>('.k2b-ste-cell[data-r=\"0\"][data-c=\"0\"]');\n if (!cell) return;\n cell.focus();\n const selection = cell.ownerDocument.getSelection();\n const range = cell.ownerDocument.createRange();\n range.selectNodeContents(cell);\n selection?.removeAllRanges();\n selection?.addRange(range);\n });\n return true;\n },\n rule: (view: EditorView) => {\n if (view.state.readOnly) return false;\n const line = view.state.doc.lineAt(view.state.selection.main.from);\n const previousHasText = line.number > 1 && view.state.doc.line(line.number - 1).text.trim().length > 0;\n const lead = line.length ? \"\\n\\n\" : previousHasText ? \"\\n\" : \"\";\n view.dispatch({ changes: { from: line.to, insert: `${lead}---\\n` }, userEvent: \"input.format\" });\n view.focus();\n return true;\n },\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Formatted view: Markdown markers hide outside the element you are editing.
3
+ * The document never changes; only decorations do. Headings, bold, italic,
4
+ * strikethrough, inline code, links, quotes, lists, code blocks and `---`.
5
+ */
6
+ import { syntaxTree } from "@codemirror/language";
7
+ import { Decoration, EditorView, ViewPlugin, WidgetType } from "@codemirror/view";
8
+ class BulletWidget extends WidgetType {
9
+ toDOM() {
10
+ const el = document.createElement("span");
11
+ el.className = "k2b-ste-bullet";
12
+ el.textContent = "•";
13
+ return el;
14
+ }
15
+ eq() {
16
+ return true;
17
+ }
18
+ }
19
+ class RuleWidget extends WidgetType {
20
+ toDOM() {
21
+ const el = document.createElement("span");
22
+ el.className = "k2b-ste-hr";
23
+ return el;
24
+ }
25
+ eq() {
26
+ return true;
27
+ }
28
+ }
29
+ const hide = Decoration.replace({});
30
+ const lineClass = cls => Decoration.line({
31
+ class: cls
32
+ });
33
+ const mark = cls => Decoration.mark({
34
+ class: cls
35
+ });
36
+
37
+ // Without focus nothing is "being edited": the whole text shows formatted.
38
+
39
+ const touches = (state, from, to, focused) => focused && state.selection.ranges.some(r => r.from <= to && r.to >= from);
40
+ const onLine = (state, from, to, focused) => {
41
+ if (!focused) return false;
42
+ const a = state.doc.lineAt(from).number;
43
+ const b = state.doc.lineAt(to).number;
44
+ return state.selection.ranges.some(r => state.doc.lineAt(r.from).number <= b && state.doc.lineAt(r.to).number >= a);
45
+ };
46
+ const build = view => {
47
+ const {
48
+ state
49
+ } = view;
50
+ const focused = view.hasFocus;
51
+ const out = [];
52
+ for (const {
53
+ from,
54
+ to
55
+ } of view.visibleRanges) {
56
+ syntaxTree(state).iterate({
57
+ from,
58
+ to,
59
+ enter: node => {
60
+ const name = node.name;
61
+ if (name === "Table") return false; // owned by the table grid
62
+ if (name === "FencedCode" || name === "CodeBlock") {
63
+ for (let pos = node.from; pos <= node.to;) {
64
+ const line = state.doc.lineAt(pos);
65
+ out.push(lineClass("k2b-ste-codeblock").range(line.from));
66
+ pos = line.to + 1;
67
+ }
68
+ if (name === "FencedCode" && !touches(state, node.from, node.to, focused)) {
69
+ for (const marker of node.node.getChildren("CodeMark")) out.push(hide.range(marker.from, marker.to));
70
+ const info = node.node.getChild("CodeInfo");
71
+ if (info) out.push(hide.range(info.from, info.to));
72
+ }
73
+ return false;
74
+ }
75
+ const heading = /^ATXHeading(\d)$/.exec(name);
76
+ if (heading) {
77
+ const line = state.doc.lineAt(node.from);
78
+ out.push(lineClass(`k2b-ste-h k2b-ste-h${heading[1]}`).range(line.from));
79
+ if (!onLine(state, node.from, node.to, focused)) {
80
+ const markNode = node.node.getChild("HeaderMark");
81
+ if (markNode) {
82
+ const end = state.doc.sliceString(markNode.to, markNode.to + 1) === " " ? markNode.to + 1 : markNode.to;
83
+ out.push(hide.range(markNode.from, end));
84
+ }
85
+ }
86
+ return;
87
+ }
88
+ if (name === "Blockquote") {
89
+ for (let pos = node.from; pos <= node.to;) {
90
+ const line = state.doc.lineAt(pos);
91
+ out.push(lineClass("k2b-ste-quote").range(line.from));
92
+ pos = line.to + 1;
93
+ }
94
+ return;
95
+ }
96
+ if (name === "QuoteMark") {
97
+ if (!onLine(state, node.from, node.to, focused)) {
98
+ const end = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
99
+ out.push(hide.range(node.from, end));
100
+ }
101
+ return;
102
+ }
103
+ if (name === "HorizontalRule") {
104
+ if (!onLine(state, node.from, node.to, focused)) out.push(Decoration.replace({
105
+ widget: new RuleWidget()
106
+ }).range(node.from, node.to));
107
+ return;
108
+ }
109
+ if (name === "ListMark") {
110
+ const bullet = /^[-*+]$/.test(state.sliceDoc(node.from, node.to));
111
+ if (bullet && !onLine(state, node.from, node.to, focused)) out.push(Decoration.replace({
112
+ widget: new BulletWidget()
113
+ }).range(node.from, node.to));else out.push(mark("k2b-ste-listmark").range(node.from, node.to));
114
+ return;
115
+ }
116
+ const inline = {
117
+ StrongEmphasis: ["k2b-ste-strong", "EmphasisMark"],
118
+ Emphasis: ["k2b-ste-em", "EmphasisMark"],
119
+ Strikethrough: ["k2b-ste-strike", "StrikethroughMark"],
120
+ InlineCode: ["k2b-ste-code", "CodeMark"]
121
+ };
122
+ const spec = inline[name];
123
+ if (spec) {
124
+ if (node.to > node.from) out.push(mark(spec[0]).range(node.from, node.to));
125
+ if (!touches(state, node.from, node.to, focused)) {
126
+ const cursor = node.node.cursor();
127
+ if (cursor.firstChild()) do {
128
+ if (cursor.name === spec[1] && cursor.to > cursor.from) out.push(hide.range(cursor.from, cursor.to));
129
+ } while (cursor.nextSibling());
130
+ }
131
+ return name === "InlineCode" ? false : undefined;
132
+ }
133
+ if (name === "Link") {
134
+ const marks = node.node.getChildren("LinkMark");
135
+ const url = node.node.getChild("URL");
136
+ if (marks.length >= 2) {
137
+ out.push(mark("k2b-ste-link").range(marks[0].to, marks[1].from));
138
+ if (!touches(state, node.from, node.to, focused)) {
139
+ out.push(hide.range(marks[0].from, marks[0].to));
140
+ out.push(hide.range(marks[1].from, node.to));
141
+ } else if (url) out.push(mark("k2b-ste-url").range(url.from, url.to));
142
+ }
143
+ return false;
144
+ }
145
+ return;
146
+ }
147
+ });
148
+ }
149
+ return Decoration.set(out, true);
150
+ };
151
+ export const formattedView = [ViewPlugin.fromClass(class {
152
+ decorations;
153
+ constructor(view) {
154
+ this.decorations = build(view);
155
+ }
156
+ update(update) {
157
+ if (update.docChanged || update.selectionSet || update.focusChanged || update.viewportChanged || syntaxTree(update.startState) !== syntaxTree(update.state)) this.decorations = build(update.view);
158
+ }
159
+ }, {
160
+ decorations: v => v.decorations
161
+ }), EditorView.contentAttributes.of({
162
+ class: "k2b-ste-formatted"
163
+ })];
164
+ //# sourceMappingURL=formatted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/formatted.ts"],"sourcesContent":["/**\n * Formatted view: Markdown markers hide outside the element you are editing.\n * The document never changes; only decorations do. Headings, bold, italic,\n * strikethrough, inline code, links, quotes, lists, code blocks and `---`.\n */\nimport { syntaxTree } from \"@codemirror/language\";\nimport type { EditorState, Range } from \"@codemirror/state\";\nimport { Decoration, type DecorationSet, EditorView, ViewPlugin, type ViewUpdate, WidgetType } from \"@codemirror/view\";\n\nclass BulletWidget extends WidgetType {\n override toDOM() {\n const el = document.createElement(\"span\");\n el.className = \"k2b-ste-bullet\";\n el.textContent = \"•\";\n return el;\n }\n override eq() {\n return true;\n }\n}\n\nclass RuleWidget extends WidgetType {\n override toDOM() {\n const el = document.createElement(\"span\");\n el.className = \"k2b-ste-hr\";\n return el;\n }\n override eq() {\n return true;\n }\n}\n\nconst hide = Decoration.replace({});\nconst lineClass = (cls: string) => Decoration.line({ class: cls });\nconst mark = (cls: string) => Decoration.mark({ class: cls });\n\n// Without focus nothing is \"being edited\": the whole text shows formatted.\n\nconst touches = (state: EditorState, from: number, to: number, focused: boolean) =>\n focused && state.selection.ranges.some((r) => r.from <= to && r.to >= from);\nconst onLine = (state: EditorState, from: number, to: number, focused: boolean) => {\n if (!focused) return false;\n const a = state.doc.lineAt(from).number;\n const b = state.doc.lineAt(to).number;\n return state.selection.ranges.some((r) => state.doc.lineAt(r.from).number <= b && state.doc.lineAt(r.to).number >= a);\n};\n\nconst build = (view: EditorView): DecorationSet => {\n const { state } = view;\n const focused = view.hasFocus;\n const out: Range<Decoration>[] = [];\n for (const { from, to } of view.visibleRanges) {\n syntaxTree(state).iterate({\n from,\n to,\n enter: (node) => {\n const name = node.name;\n if (name === \"Table\") return false; // owned by the table grid\n if (name === \"FencedCode\" || name === \"CodeBlock\") {\n for (let pos = node.from; pos <= node.to; ) {\n const line = state.doc.lineAt(pos);\n out.push(lineClass(\"k2b-ste-codeblock\").range(line.from));\n pos = line.to + 1;\n }\n if (name === \"FencedCode\" && !touches(state, node.from, node.to, focused)) {\n for (const marker of node.node.getChildren(\"CodeMark\")) out.push(hide.range(marker.from, marker.to));\n const info = node.node.getChild(\"CodeInfo\");\n if (info) out.push(hide.range(info.from, info.to));\n }\n return false;\n }\n const heading = /^ATXHeading(\\d)$/.exec(name);\n if (heading) {\n const line = state.doc.lineAt(node.from);\n out.push(lineClass(`k2b-ste-h k2b-ste-h${heading[1]}`).range(line.from));\n if (!onLine(state, node.from, node.to, focused)) {\n const markNode = node.node.getChild(\"HeaderMark\");\n if (markNode) {\n const end = state.doc.sliceString(markNode.to, markNode.to + 1) === \" \" ? markNode.to + 1 : markNode.to;\n out.push(hide.range(markNode.from, end));\n }\n }\n return;\n }\n if (name === \"Blockquote\") {\n for (let pos = node.from; pos <= node.to; ) {\n const line = state.doc.lineAt(pos);\n out.push(lineClass(\"k2b-ste-quote\").range(line.from));\n pos = line.to + 1;\n }\n return;\n }\n if (name === \"QuoteMark\") {\n if (!onLine(state, node.from, node.to, focused)) {\n const end = state.doc.sliceString(node.to, node.to + 1) === \" \" ? node.to + 1 : node.to;\n out.push(hide.range(node.from, end));\n }\n return;\n }\n if (name === \"HorizontalRule\") {\n if (!onLine(state, node.from, node.to, focused))\n out.push(Decoration.replace({ widget: new RuleWidget() }).range(node.from, node.to));\n return;\n }\n if (name === \"ListMark\") {\n const bullet = /^[-*+]$/.test(state.sliceDoc(node.from, node.to));\n if (bullet && !onLine(state, node.from, node.to, focused))\n out.push(Decoration.replace({ widget: new BulletWidget() }).range(node.from, node.to));\n else out.push(mark(\"k2b-ste-listmark\").range(node.from, node.to));\n return;\n }\n const inline: Record<string, [string, string]> = {\n StrongEmphasis: [\"k2b-ste-strong\", \"EmphasisMark\"],\n Emphasis: [\"k2b-ste-em\", \"EmphasisMark\"],\n Strikethrough: [\"k2b-ste-strike\", \"StrikethroughMark\"],\n InlineCode: [\"k2b-ste-code\", \"CodeMark\"],\n };\n const spec = inline[name];\n if (spec) {\n if (node.to > node.from) out.push(mark(spec[0]).range(node.from, node.to));\n if (!touches(state, node.from, node.to, focused)) {\n const cursor = node.node.cursor();\n if (cursor.firstChild())\n do {\n if (cursor.name === spec[1] && cursor.to > cursor.from) out.push(hide.range(cursor.from, cursor.to));\n } while (cursor.nextSibling());\n }\n return name === \"InlineCode\" ? false : undefined;\n }\n if (name === \"Link\") {\n const marks = node.node.getChildren(\"LinkMark\");\n const url = node.node.getChild(\"URL\");\n if (marks.length >= 2) {\n out.push(mark(\"k2b-ste-link\").range(marks[0]!.to, marks[1]!.from));\n if (!touches(state, node.from, node.to, focused)) {\n out.push(hide.range(marks[0]!.from, marks[0]!.to));\n out.push(hide.range(marks[1]!.from, node.to));\n } else if (url) out.push(mark(\"k2b-ste-url\").range(url.from, url.to));\n }\n return false;\n }\n return;\n },\n });\n }\n return Decoration.set(out, true);\n};\n\nexport const formattedView = [\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet;\n constructor(view: EditorView) {\n this.decorations = build(view);\n }\n update(update: ViewUpdate) {\n if (\n update.docChanged ||\n update.selectionSet ||\n update.focusChanged ||\n update.viewportChanged ||\n syntaxTree(update.startState) !== syntaxTree(update.state)\n )\n this.decorations = build(update.view);\n }\n },\n { decorations: (v) => v.decorations },\n ),\n EditorView.contentAttributes.of({ class: \"k2b-ste-formatted\" }),\n];\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Markdown language without `@codemirror/lang-markdown`: that package pulls in
3
+ * `@codemirror/lang-html` (and with it CSS and JavaScript) for HTML blocks.
4
+ * The shared editor needs only the GFM tree, so it wraps `@lezer/markdown`.
5
+ */
6
+ import { defineLanguageFacet, Language, LanguageSupport } from "@codemirror/language";
7
+ import { GFM, parser } from "@lezer/markdown";
8
+ const facet = defineLanguageFacet({
9
+ commentTokens: {
10
+ block: {
11
+ open: "<!--",
12
+ close: "-->"
13
+ }
14
+ }
15
+ });
16
+ const gfmParser = parser.configure([GFM]);
17
+ export const markdownLanguage = new Language(facet, gfmParser, [], "markdown");
18
+ export const markdown = () => new LanguageSupport(markdownLanguage);
19
+ //# sourceMappingURL=language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["text-editor/language.ts"],"sourcesContent":["/**\n * Markdown language without `@codemirror/lang-markdown`: that package pulls in\n * `@codemirror/lang-html` (and with it CSS and JavaScript) for HTML blocks.\n * The shared editor needs only the GFM tree, so it wraps `@lezer/markdown`.\n */\nimport { defineLanguageFacet, Language, LanguageSupport } from \"@codemirror/language\";\nimport { GFM, parser } from \"@lezer/markdown\";\n\nconst facet = defineLanguageFacet({ commentTokens: { block: { open: \"<!--\", close: \"-->\" } } });\nconst gfmParser = parser.configure([GFM]);\n\nexport const markdownLanguage = new Language(facet, gfmParser, [], \"markdown\");\nexport const markdown = () => new LanguageSupport(markdownLanguage);\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA,SAAS,mBAAmB,EAAE,QAAQ,EAAE,eAAe,QAAQ,sBAAsB;AACrF,SAAS,GAAG,EAAE,MAAM,QAAQ,iBAAiB;AAE7C,MAAM,KAAK,GAAG,mBAAmB,CAAC;EAAE,aAAa,EAAE;IAAE,KAAK,EAAE;MAAE,IAAI,EAAE,MAAM;MAAE,KAAK,EAAE;IAAM;EAAE;AAAE,CAAC,CAAC;AAC/F,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC;AAEzC,OAAO,MAAM,gBAAgB,GAAG,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC;AAC9E,OAAO,MAAM,QAAQ,GAAG,MAAM,IAAI,eAAe,CAAC,gBAAgB,CAAC","ignoreList":[]}