@k2b/ui 0.33.0 → 0.35.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 (310) hide show
  1. package/dist/base.css +14 -1
  2. package/dist/browser/actions/ContextMenu.js +13 -0
  3. package/dist/browser/actions/ContextMenu.js.map +1 -1
  4. package/dist/browser/actions/Dropdown.js +16 -4
  5. package/dist/browser/actions/Dropdown.js.map +1 -1
  6. package/dist/browser/actions/SelectionToolbar.js +129 -0
  7. package/dist/browser/actions/SelectionToolbar.js.map +1 -0
  8. package/dist/browser/actions/index.js +1 -0
  9. package/dist/browser/actions/index.js.map +1 -1
  10. package/dist/browser/charts.js +6 -0
  11. package/dist/browser/charts.js.map +1 -0
  12. package/dist/browser/chat/ChatComposer.js +525 -407
  13. package/dist/browser/chat/ChatComposer.js.map +1 -1
  14. package/dist/browser/chat/chat-messages.js +4 -0
  15. package/dist/browser/chat/chat-messages.js.map +1 -1
  16. package/dist/browser/chat/composer-document.js +19 -0
  17. package/dist/browser/chat/composer-document.js.map +1 -1
  18. package/dist/browser/chat/index.js.map +1 -1
  19. package/dist/browser/content/Chart.js +8 -0
  20. package/dist/browser/content/Chart.js.map +1 -1
  21. package/dist/browser/content/FileGrid.js +231 -9
  22. package/dist/browser/content/FileGrid.js.map +1 -1
  23. package/dist/browser/content/FileTypeIcon.js +15 -0
  24. package/dist/browser/content/FileTypeIcon.js.map +1 -1
  25. package/dist/browser/content/FileView.js +11 -4
  26. package/dist/browser/content/FileView.js.map +1 -1
  27. package/dist/browser/content/MatchText.js +61 -0
  28. package/dist/browser/content/MatchText.js.map +1 -0
  29. package/dist/browser/content/MessageRow.js +73 -53
  30. package/dist/browser/content/MessageRow.js.map +1 -1
  31. package/dist/browser/content/ReactionBar.js +3 -1
  32. package/dist/browser/content/ReactionBar.js.map +1 -1
  33. package/dist/browser/content/calendar-day-scroll.js +4 -3
  34. package/dist/browser/content/calendar-day-scroll.js.map +1 -1
  35. package/dist/browser/content/chart-bar.js +476 -0
  36. package/dist/browser/content/chart-bar.js.map +1 -0
  37. package/dist/browser/content/file-list-messages.js +52 -0
  38. package/dist/browser/content/file-list-messages.js.map +1 -0
  39. package/dist/browser/content/index.js +2 -1
  40. package/dist/browser/content/index.js.map +1 -1
  41. package/dist/browser/feedback/Tooltip.js +31 -14
  42. package/dist/browser/feedback/Tooltip.js.map +1 -1
  43. package/dist/browser/inputs/ChoiceList.js +178 -0
  44. package/dist/browser/inputs/ChoiceList.js.map +1 -0
  45. package/dist/browser/inputs/ChoiceSlider.js +314 -0
  46. package/dist/browser/inputs/ChoiceSlider.js.map +1 -0
  47. package/dist/browser/inputs/ChoiceTiles.js +135 -0
  48. package/dist/browser/inputs/ChoiceTiles.js.map +1 -0
  49. package/dist/browser/inputs/ColorChoices.js +120 -0
  50. package/dist/browser/inputs/ColorChoices.js.map +1 -0
  51. package/dist/browser/inputs/QrScanner.js +95 -13
  52. package/dist/browser/inputs/QrScanner.js.map +1 -1
  53. package/dist/browser/inputs/TextInput.js +15 -13
  54. package/dist/browser/inputs/TextInput.js.map +1 -1
  55. package/dist/browser/inputs/index.js +4 -0
  56. package/dist/browser/inputs/index.js.map +1 -1
  57. package/dist/browser/inputs/qr-messages.js +2 -0
  58. package/dist/browser/inputs/qr-messages.js.map +1 -1
  59. package/dist/browser/internal/radio-keys.js +13 -0
  60. package/dist/browser/internal/radio-keys.js.map +1 -0
  61. package/dist/browser/layout/AnchoredPopover.js +180 -0
  62. package/dist/browser/layout/AnchoredPopover.js.map +1 -0
  63. package/dist/browser/layout/AppWorkspace.js +155 -20
  64. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  65. package/dist/browser/layout/DetailPanel.js +443 -333
  66. package/dist/browser/layout/DetailPanel.js.map +1 -1
  67. package/dist/browser/layout/MobileShell.js +21 -7
  68. package/dist/browser/layout/MobileShell.js.map +1 -1
  69. package/dist/browser/layout/Settings.js +283 -175
  70. package/dist/browser/layout/Settings.js.map +1 -1
  71. package/dist/browser/layout/SidebarRailHint.js +79 -0
  72. package/dist/browser/layout/SidebarRailHint.js.map +1 -0
  73. package/dist/browser/layout/SidebarSwitcher.js +79 -66
  74. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  75. package/dist/browser/layout/TabBar.js +18 -4
  76. package/dist/browser/layout/TabBar.js.map +1 -1
  77. package/dist/browser/layout/app-workspace-controller.js +11 -4
  78. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  79. package/dist/browser/layout/detail-panel-messages.js +4 -2
  80. package/dist/browser/layout/detail-panel-messages.js.map +1 -1
  81. package/dist/browser/layout/index.js +2 -1
  82. package/dist/browser/layout/index.js.map +1 -1
  83. package/dist/browser/layout/settings-messages.js +26 -2
  84. package/dist/browser/layout/settings-messages.js.map +1 -1
  85. package/dist/browser/surfaces/Avatar.js +2 -14
  86. package/dist/browser/surfaces/Avatar.js.map +1 -1
  87. package/dist/browser/surfaces/DotStrip.js +70 -0
  88. package/dist/browser/surfaces/DotStrip.js.map +1 -0
  89. package/dist/browser/surfaces/ProgressRing.js +3 -0
  90. package/dist/browser/surfaces/ProgressRing.js.map +1 -1
  91. package/dist/browser/surfaces/ResourceCard.js +125 -68
  92. package/dist/browser/surfaces/ResourceCard.js.map +1 -1
  93. package/dist/browser/surfaces/index.js +2 -0
  94. package/dist/browser/surfaces/index.js.map +1 -1
  95. package/dist/browser/surfaces/person-color.js +18 -0
  96. package/dist/browser/surfaces/person-color.js.map +1 -0
  97. package/dist/browser/surfaces/resource-messages.js +6 -2
  98. package/dist/browser/surfaces/resource-messages.js.map +1 -1
  99. package/dist/browser/text-editor/TextEditor.js +1358 -0
  100. package/dist/browser/text-editor/TextEditor.js.map +1 -0
  101. package/dist/browser/text-editor/clipboard-html.js +152 -0
  102. package/dist/browser/text-editor/clipboard-html.js.map +1 -0
  103. package/dist/browser/text-editor/clipboard-loading.js +68 -0
  104. package/dist/browser/text-editor/clipboard-loading.js.map +1 -0
  105. package/dist/browser/text-editor/clipboard.js +51 -0
  106. package/dist/browser/text-editor/clipboard.js.map +1 -0
  107. package/dist/browser/text-editor/engine.js +125 -0
  108. package/dist/browser/text-editor/engine.js.map +1 -0
  109. package/dist/browser/text-editor/format.js +218 -0
  110. package/dist/browser/text-editor/format.js.map +1 -0
  111. package/dist/browser/text-editor/formatted.js +164 -0
  112. package/dist/browser/text-editor/formatted.js.map +1 -0
  113. package/dist/browser/text-editor/language.js +19 -0
  114. package/dist/browser/text-editor/language.js.map +1 -0
  115. package/dist/browser/text-editor/markdown-table.js +563 -0
  116. package/dist/browser/text-editor/markdown-table.js.map +1 -0
  117. package/dist/browser/text-editor/messages.js +233 -0
  118. package/dist/browser/text-editor/messages.js.map +1 -0
  119. package/dist/browser/text-editor/paste.js +115 -0
  120. package/dist/browser/text-editor/paste.js.map +1 -0
  121. package/dist/browser/text-editor/table.js +1760 -0
  122. package/dist/browser/text-editor/table.js.map +1 -0
  123. package/dist/browser/text-editor.js +5 -0
  124. package/dist/browser/text-editor.js.map +1 -0
  125. package/dist/browser/widgets/Widget.js +3 -2
  126. package/dist/browser/widgets/Widget.js.map +1 -1
  127. package/dist/ssr/actions/ContextMenu.js +9 -0
  128. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  129. package/dist/ssr/actions/Dropdown.js +15 -4
  130. package/dist/ssr/actions/Dropdown.js.map +1 -1
  131. package/dist/ssr/actions/SelectionToolbar.js +104 -0
  132. package/dist/ssr/actions/SelectionToolbar.js.map +1 -0
  133. package/dist/ssr/actions/index.js +1 -0
  134. package/dist/ssr/actions/index.js.map +1 -1
  135. package/dist/ssr/charts.js +6 -0
  136. package/dist/ssr/charts.js.map +1 -0
  137. package/dist/ssr/chat/ChatComposer.js +132 -53
  138. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  139. package/dist/ssr/chat/chat-messages.js +4 -0
  140. package/dist/ssr/chat/chat-messages.js.map +1 -1
  141. package/dist/ssr/chat/composer-document.js +19 -0
  142. package/dist/ssr/chat/composer-document.js.map +1 -1
  143. package/dist/ssr/chat/index.js.map +1 -1
  144. package/dist/ssr/content/Chart.js +8 -0
  145. package/dist/ssr/content/Chart.js.map +1 -1
  146. package/dist/ssr/content/FileGrid.js +132 -5
  147. package/dist/ssr/content/FileGrid.js.map +1 -1
  148. package/dist/ssr/content/FileTypeIcon.js +15 -0
  149. package/dist/ssr/content/FileTypeIcon.js.map +1 -1
  150. package/dist/ssr/content/FileView.js +11 -4
  151. package/dist/ssr/content/FileView.js.map +1 -1
  152. package/dist/ssr/content/MatchText.js +56 -0
  153. package/dist/ssr/content/MatchText.js.map +1 -0
  154. package/dist/ssr/content/MessageRow.js +16 -6
  155. package/dist/ssr/content/MessageRow.js.map +1 -1
  156. package/dist/ssr/content/ReactionBar.js +3 -1
  157. package/dist/ssr/content/ReactionBar.js.map +1 -1
  158. package/dist/ssr/content/calendar-day-scroll.js +4 -3
  159. package/dist/ssr/content/calendar-day-scroll.js.map +1 -1
  160. package/dist/ssr/content/chart-bar.js +476 -0
  161. package/dist/ssr/content/chart-bar.js.map +1 -0
  162. package/dist/ssr/content/file-list-messages.js +52 -0
  163. package/dist/ssr/content/file-list-messages.js.map +1 -0
  164. package/dist/ssr/content/index.js +2 -1
  165. package/dist/ssr/content/index.js.map +1 -1
  166. package/dist/ssr/feedback/Tooltip.js +31 -14
  167. package/dist/ssr/feedback/Tooltip.js.map +1 -1
  168. package/dist/ssr/inputs/ChoiceList.js +95 -0
  169. package/dist/ssr/inputs/ChoiceList.js.map +1 -0
  170. package/dist/ssr/inputs/ChoiceSlider.js +191 -0
  171. package/dist/ssr/inputs/ChoiceSlider.js.map +1 -0
  172. package/dist/ssr/inputs/ChoiceTiles.js +61 -0
  173. package/dist/ssr/inputs/ChoiceTiles.js.map +1 -0
  174. package/dist/ssr/inputs/ColorChoices.js +60 -0
  175. package/dist/ssr/inputs/ColorChoices.js.map +1 -0
  176. package/dist/ssr/inputs/QrScanner.js +89 -10
  177. package/dist/ssr/inputs/QrScanner.js.map +1 -1
  178. package/dist/ssr/inputs/TextInput.js +13 -1
  179. package/dist/ssr/inputs/TextInput.js.map +1 -1
  180. package/dist/ssr/inputs/index.js +4 -0
  181. package/dist/ssr/inputs/index.js.map +1 -1
  182. package/dist/ssr/inputs/qr-messages.js +2 -0
  183. package/dist/ssr/inputs/qr-messages.js.map +1 -1
  184. package/dist/ssr/internal/radio-keys.js +13 -0
  185. package/dist/ssr/internal/radio-keys.js.map +1 -0
  186. package/dist/ssr/layout/AnchoredPopover.js +142 -0
  187. package/dist/ssr/layout/AnchoredPopover.js.map +1 -0
  188. package/dist/ssr/layout/AppWorkspace.js +154 -20
  189. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  190. package/dist/ssr/layout/DetailPanel.js +181 -108
  191. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  192. package/dist/ssr/layout/MobileShell.js +20 -6
  193. package/dist/ssr/layout/MobileShell.js.map +1 -1
  194. package/dist/ssr/layout/Settings.js +122 -45
  195. package/dist/ssr/layout/Settings.js.map +1 -1
  196. package/dist/ssr/layout/SidebarRailHint.js +79 -0
  197. package/dist/ssr/layout/SidebarRailHint.js.map +1 -0
  198. package/dist/ssr/layout/SidebarSwitcher.js +13 -3
  199. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  200. package/dist/ssr/layout/TabBar.js +11 -3
  201. package/dist/ssr/layout/TabBar.js.map +1 -1
  202. package/dist/ssr/layout/app-workspace-controller.js +11 -4
  203. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  204. package/dist/ssr/layout/detail-panel-messages.js +4 -2
  205. package/dist/ssr/layout/detail-panel-messages.js.map +1 -1
  206. package/dist/ssr/layout/index.js +2 -1
  207. package/dist/ssr/layout/index.js.map +1 -1
  208. package/dist/ssr/layout/settings-messages.js +26 -2
  209. package/dist/ssr/layout/settings-messages.js.map +1 -1
  210. package/dist/ssr/surfaces/Avatar.js +2 -14
  211. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  212. package/dist/ssr/surfaces/DotStrip.js +31 -0
  213. package/dist/ssr/surfaces/DotStrip.js.map +1 -0
  214. package/dist/ssr/surfaces/ProgressRing.js +3 -0
  215. package/dist/ssr/surfaces/ProgressRing.js.map +1 -1
  216. package/dist/ssr/surfaces/ResourceCard.js +40 -15
  217. package/dist/ssr/surfaces/ResourceCard.js.map +1 -1
  218. package/dist/ssr/surfaces/index.js +2 -0
  219. package/dist/ssr/surfaces/index.js.map +1 -1
  220. package/dist/ssr/surfaces/person-color.js +18 -0
  221. package/dist/ssr/surfaces/person-color.js.map +1 -0
  222. package/dist/ssr/surfaces/resource-messages.js +6 -2
  223. package/dist/ssr/surfaces/resource-messages.js.map +1 -1
  224. package/dist/ssr/text-editor/TextEditor.js +1155 -0
  225. package/dist/ssr/text-editor/TextEditor.js.map +1 -0
  226. package/dist/ssr/text-editor/clipboard-html.js +152 -0
  227. package/dist/ssr/text-editor/clipboard-html.js.map +1 -0
  228. package/dist/ssr/text-editor/clipboard-loading.js +68 -0
  229. package/dist/ssr/text-editor/clipboard-loading.js.map +1 -0
  230. package/dist/ssr/text-editor/clipboard.js +51 -0
  231. package/dist/ssr/text-editor/clipboard.js.map +1 -0
  232. package/dist/ssr/text-editor/engine.js +125 -0
  233. package/dist/ssr/text-editor/engine.js.map +1 -0
  234. package/dist/ssr/text-editor/format.js +218 -0
  235. package/dist/ssr/text-editor/format.js.map +1 -0
  236. package/dist/ssr/text-editor/formatted.js +164 -0
  237. package/dist/ssr/text-editor/formatted.js.map +1 -0
  238. package/dist/ssr/text-editor/language.js +19 -0
  239. package/dist/ssr/text-editor/language.js.map +1 -0
  240. package/dist/ssr/text-editor/markdown-table.js +563 -0
  241. package/dist/ssr/text-editor/markdown-table.js.map +1 -0
  242. package/dist/ssr/text-editor/messages.js +233 -0
  243. package/dist/ssr/text-editor/messages.js.map +1 -0
  244. package/dist/ssr/text-editor/paste.js +115 -0
  245. package/dist/ssr/text-editor/paste.js.map +1 -0
  246. package/dist/ssr/text-editor/table.js +1760 -0
  247. package/dist/ssr/text-editor/table.js.map +1 -0
  248. package/dist/ssr/text-editor.js +5 -0
  249. package/dist/ssr/text-editor.js.map +1 -0
  250. package/dist/ssr/widgets/Widget.js +3 -2
  251. package/dist/ssr/widgets/Widget.js.map +1 -1
  252. package/dist/styles.css +1 -1
  253. package/dist/types/actions/ContextMenu.d.ts +5 -0
  254. package/dist/types/actions/Dropdown.d.ts +7 -0
  255. package/dist/types/actions/SelectionToolbar.d.ts +38 -0
  256. package/dist/types/actions/index.d.ts +2 -0
  257. package/dist/types/charts.d.ts +5 -0
  258. package/dist/types/chat/ChatComposer.d.ts +15 -0
  259. package/dist/types/chat/chat-messages.d.ts +2 -0
  260. package/dist/types/chat/composer-document.d.ts +5 -0
  261. package/dist/types/chat/index.d.ts +1 -1
  262. package/dist/types/content/Chart.d.ts +2 -1
  263. package/dist/types/content/FileGrid.d.ts +43 -3
  264. package/dist/types/content/FileTypeIcon.d.ts +10 -0
  265. package/dist/types/content/FileView.d.ts +5 -1
  266. package/dist/types/content/MatchText.d.ts +21 -0
  267. package/dist/types/content/MessageRow.d.ts +2 -0
  268. package/dist/types/content/calendar-day-scroll.d.ts +2 -1
  269. package/dist/types/content/chart-bar.d.ts +60 -0
  270. package/dist/types/content/file-list-messages.d.ts +24 -0
  271. package/dist/types/content/index.d.ts +3 -2
  272. package/dist/types/feedback/Tooltip.d.ts +8 -2
  273. package/dist/types/inputs/ChoiceList.d.ts +28 -0
  274. package/dist/types/inputs/ChoiceSlider.d.ts +36 -0
  275. package/dist/types/inputs/ChoiceTiles.d.ts +25 -0
  276. package/dist/types/inputs/ColorChoices.d.ts +19 -0
  277. package/dist/types/inputs/index.d.ts +8 -0
  278. package/dist/types/inputs/qr-messages.d.ts +1 -0
  279. package/dist/types/internal/radio-keys.d.ts +5 -0
  280. package/dist/types/layout/AnchoredPopover.d.ts +31 -0
  281. package/dist/types/layout/AppWorkspace.d.ts +10 -0
  282. package/dist/types/layout/DetailPanel.d.ts +17 -0
  283. package/dist/types/layout/MobileShell.d.ts +5 -2
  284. package/dist/types/layout/Settings.d.ts +22 -0
  285. package/dist/types/layout/SidebarRailHint.d.ts +26 -0
  286. package/dist/types/layout/TabBar.d.ts +5 -0
  287. package/dist/types/layout/detail-panel-messages.d.ts +1 -0
  288. package/dist/types/layout/index.d.ts +3 -2
  289. package/dist/types/layout/settings-messages.d.ts +12 -0
  290. package/dist/types/surfaces/DotStrip.d.ts +22 -0
  291. package/dist/types/surfaces/ProgressRing.d.ts +2 -1
  292. package/dist/types/surfaces/ResourceCard.d.ts +9 -0
  293. package/dist/types/surfaces/index.d.ts +4 -1
  294. package/dist/types/surfaces/person-color.d.ts +10 -0
  295. package/dist/types/surfaces/resource-messages.d.ts +2 -0
  296. package/dist/types/text-editor/TextEditor.d.ts +69 -0
  297. package/dist/types/text-editor/clipboard-html.d.ts +9 -0
  298. package/dist/types/text-editor/clipboard-loading.d.ts +8 -0
  299. package/dist/types/text-editor/clipboard.d.ts +20 -0
  300. package/dist/types/text-editor/engine.d.ts +34 -0
  301. package/dist/types/text-editor/format.d.ts +34 -0
  302. package/dist/types/text-editor/formatted.d.ts +1 -0
  303. package/dist/types/text-editor/language.d.ts +8 -0
  304. package/dist/types/text-editor/markdown-table.d.ts +105 -0
  305. package/dist/types/text-editor/messages.d.ts +113 -0
  306. package/dist/types/text-editor/paste.d.ts +6 -0
  307. package/dist/types/text-editor/table.d.ts +81 -0
  308. package/dist/types/text-editor.d.ts +4 -0
  309. package/dist/types/widgets/Widget.d.ts +3 -2
  310. package/package.json +28 -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":"AAAA,SAAS,cAAc,QAAQ,sBAAsB;AACrD,SAAS,qBAAqB,EAAE,kBAAkB,QAAQ,sBAAsB;AAChF,SAAS,WAAW,EAAE,WAAW,EAAkB,IAAI,EAAE,IAAI,QAAQ,mBAAmB;AACxF,SAAS,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,QAAQ,kBAAkB;AACnG,SAAS,gBAAgB,QAAQ,qBAAqB;AACtD,SAAS,QAAQ,QAAQ,UAAU;AACnC,SAAS,aAAa,QAAQ,aAAa;AAC3C,SAAS,QAAQ,QAAQ,YAAY;AACrC,SAAS,UAAU,QAAQ,SAAS;AACpC,SAAyB,SAAS,EAAE,SAAS,QAAQ,SAAS;AAwB9D,MAAM,mBAAmB,GAAI,IAAsC,IAAgB,CACjF,QAAQ,CAAC,CAAC,EACV,kBAAkB,CAAC,qBAAqB,EAAE;EAAE,QAAQ,EAAE;AAAK,CAAC,CAAC,EAC7D,IAAI,KAAK,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;EAAE,KAAK,EAAE;AAAiB,CAAC,CAAC,EACnG,MAAM,CAAC,EAAE,CAAC,CACR;EAAE,GAAG,EAAE,OAAO;EAAE,GAAG,EAAE,QAAQ,CAAC;AAAK,CAAC,EACpC;EAAE,GAAG,EAAE,OAAO;EAAE,GAAG,EAAE,QAAQ,CAAC;AAAO,CAAC,EACtC;EAAE,GAAG,EAAE,OAAO;EAAE,GAAG,EAAE,QAAQ,CAAC;AAAK,CAAC,EACpC;EAAE,GAAG,EAAE,aAAa;EAAE,GAAG,EAAE,QAAQ,CAAC;AAAO,CAAC,CAC7C,CAAC,CACH;;AAED;AACA,OAAO,SAAS,gBAAgB,CAAC,OAA0B,EAAE;EAC3D,MAAM,QAAQ,GAAG,IAAI,WAAW,CAAC,CAAC;EAClC,MAAM,YAAY,GAAG,IAAI,WAAW,CAAC,CAAC;EACtC,MAAM,SAAS,GAAG,IAAI,WAAW,CAAC,CAAC;EACnC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,mBAAmB;EAChE,MAAM,UAAU,GAAG,CAAC,IAAgB,EAAE,SAA0B,KAAK;IACnE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAC1C;IACA,OAAO,IAAI;EACb,CAAC;EACD,MAAM,cAAc,GAAI,IAAoB,IAC1C,IAAI,KAAK,OAAO,GACZ,CAAC,gBAAgB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,GACjF,CACE,YAAY,CAAC,IAAI,CAAC,EAClB,IAAI,KAAK,WAAW,GAAG,SAAS,CAAC,CAAC,GAAG,gBAAgB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EACzE,UAAU,CAAC,OAAO,CAAC,eAAe,CAAC,CACpC;EACP,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;IACtB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;MACxB,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;MAC7C,UAAU,EAAE,CACV,aAAa,CAAC,CAAC,EACf,UAAU,CAAC,YAAY,EACvB,WAAW,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,EACtC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAAE,YAAY,EAAE,OAAO,CAAC;MAAM,CAAC,CAAC,CAAC,EAC9E,IAAI,CAAC,OAAO,CAAC,CACX,MAAM,CAAC,EAAE,CAAC,CACR;QAAE,GAAG,EAAE,OAAO;QAAE,GAAG,EAAG,IAAI,IAAK,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,KAAK,EAAG,IAAI,IAAK,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,cAAc,EAAE;MAAK,CAAC,EAC1H;QAAE,GAAG,EAAE,OAAO;QAAE,GAAG,EAAG,IAAI,IAAK,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;QAAE,cAAc,EAAE;MAAK,CAAC,CAChF,CAAC,EACF,UAAU,CAAC,gBAAgB,CAAC;QAC1B,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE;UACvB,IAAI,KAAK,CAAC,SAAS,KAAK,aAAa,EAAE,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;UACtE,IAAI,KAAK,CAAC,SAAS,KAAK,aAAa,EAAE,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC;UACtE,OAAO,KAAK;QACd;MACF,CAAC,CAAC,CACH,CAAC,EACF,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,EACzB,SAAS,CAAC,EAAE,CAAC;QACX,GAAG,OAAO,CAAC,IAAI;QACf,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,IAAI,EAAE,MAAM;UACV,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,EAAE,MAAM;UACV,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C;MACF,CAAC,CAAC,EACF,WAAW,CAAC,iBAAiB,CAAC,EAAE,CAAE,EAAE,IAAK;QACvC;QACA,IACE,EAAE,CAAC,UAAU,IACb,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,IACvB,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,IACzC,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAC3C;UACA,MAAM,QAAkB,GAAG,EAAE;UAC7B,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,KAAK;YAC7D,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;UACjD,CAAC,CAAC;UACF,cAAc,CAAC,MAAM;YACnB,IAAI,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;UACtC,CAAC,CAAC;UACF,OAAO,EAAE;QACX;QACA,OAAO,EAAE;MACX,CAAC,CAAC,EACF,UAAU,CAAC,cAAc,CAAC,EAAE,CAAE,MAAM,IAAK;QACvC,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;MACxE,CAAC,CAAC,EACF,QAAQ,CAAC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,CAAC,EACxD,YAAY,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAChH,OAAO,CAAC,UAAU,IAAI,EAAE;IAE5B,CAAC;EACH,CAAC,CAAC;EACF;EACA;EACA;EACA,MAAM,KAAK,GAAI,KAAoB,IAAK;IACtC,IACE,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,IAChC,KAAK,CAAC,GAAG,KAAK,OAAO,IACrB,KAAK,CAAC,OAAO,KAAK,EAAE,IACpB,KAAK,CAAC,WAAW,IACjB,IAAI,CAAC,SAAS,IACd,KAAK,CAAC,gBAAgB,IACtB,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,WAAW,EAAE,SAAS,CAAC,SAAS,IAAI,EAAE,CAAC,IAC9E,EAAE,aAAa,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAElE;IACF,IAAI,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE;MAC3C,KAAK,CAAC,cAAc,CAAC,CAAC;MACtB,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAClC;EACF,CAAC;EACD,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC;EACxD,OAAO;IACL,IAAI;IACJ;IACA,OAAO,EAAG,IAAoB,IAAK,IAAI,CAAC,QAAQ,CAAC;MAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC;IAAE,CAAC,CAAC;IACzG,QAAQ,EAAG,KAAa,IACtB,IAAI,CAAC,QAAQ,CAAC;MAAE,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAAE,YAAY,EAAE;MAAM,CAAC,CAAC;IAAE,CAAC,CAAC;IAC7G;IACA,WAAW,EAAG,QAAiB,IAAK;MAClC,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;MAC7F,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;MAAE,CAAC,CAAC;IAC9H,CAAC;IACD,OAAO,EAAE,MAAM;MACb,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC;MAC3D,IAAI,CAAC,OAAO,CAAC,CAAC;IAChB;EACF,CAAC;AACH","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":[]}