@lapismd/mira 0.0.4 → 0.1.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 (305) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/extensions/index.d.ts +13 -1
  3. package/dist/extensions/index.d.ts.map +1 -1
  4. package/dist/extensions/index.js +13 -3
  5. package/dist/extensions/inline-links.d.ts +8 -0
  6. package/dist/extensions/inline-links.d.ts.map +1 -0
  7. package/dist/extensions/inline-links.js +120 -0
  8. package/dist/extensions/markdown-editing.d.ts +32 -0
  9. package/dist/extensions/markdown-editing.d.ts.map +1 -0
  10. package/dist/extensions/markdown-editing.js +1 -0
  11. package/dist/internal/codemirror/base/index.d.ts.map +1 -1
  12. package/dist/internal/codemirror/base/index.js +3 -0
  13. package/dist/internal/codemirror/markdown/index.d.ts.map +1 -1
  14. package/dist/internal/codemirror/markdown/index.js +2 -1
  15. package/dist/internal/codemirror/rich/block-controls.d.ts.map +1 -1
  16. package/dist/internal/codemirror/rich/block-controls.js +2 -0
  17. package/dist/internal/codemirror/rich/block-gutter-accessibility.d.ts +15 -0
  18. package/dist/internal/codemirror/rich/block-gutter-accessibility.d.ts.map +1 -0
  19. package/dist/internal/codemirror/rich/block-gutter-accessibility.js +67 -0
  20. package/dist/internal/codemirror/rich/index.d.ts.map +1 -1
  21. package/dist/internal/codemirror/rich/index.js +43 -9
  22. package/dist/internal/codemirror/rich/utils/images.d.ts +6 -3
  23. package/dist/internal/codemirror/rich/utils/images.d.ts.map +1 -1
  24. package/dist/internal/codemirror/rich/utils/images.js +16 -29
  25. package/dist/internal/codemirror/rich/utils/references.d.ts +15 -0
  26. package/dist/internal/codemirror/rich/utils/references.d.ts.map +1 -0
  27. package/dist/internal/codemirror/rich/utils/references.js +86 -0
  28. package/dist/internal/codemirror/rich/widgets/preview-widgets.d.ts +3 -0
  29. package/dist/internal/codemirror/rich/widgets/preview-widgets.d.ts.map +1 -1
  30. package/dist/internal/codemirror/rich/widgets/preview-widgets.js +31 -3
  31. package/dist/internal/inline-links/icons.d.ts +115 -0
  32. package/dist/internal/inline-links/icons.d.ts.map +1 -0
  33. package/dist/internal/inline-links/icons.js +148 -0
  34. package/dist/internal/inline-links/live-preview.d.ts +5 -0
  35. package/dist/internal/inline-links/live-preview.d.ts.map +1 -0
  36. package/dist/internal/inline-links/live-preview.js +135 -0
  37. package/dist/internal/inline-links/registry.d.ts +44 -0
  38. package/dist/internal/inline-links/registry.d.ts.map +1 -0
  39. package/dist/internal/inline-links/registry.js +153 -0
  40. package/dist/mira.svelte.d.ts +1 -1
  41. package/dist/preview/asset-url-lease.d.ts +6 -0
  42. package/dist/preview/asset-url-lease.d.ts.map +1 -0
  43. package/dist/preview/asset-url-lease.js +28 -0
  44. package/dist/preview/components/embed.svelte +10 -5
  45. package/dist/preview/components/embed.svelte.d.ts.map +1 -1
  46. package/dist/preview/components/image.svelte +7 -2
  47. package/dist/preview/components/image.svelte.d.ts.map +1 -1
  48. package/dist/preview/components/inline-link.svelte +94 -0
  49. package/dist/preview/components/inline-link.svelte.d.ts +16 -0
  50. package/dist/preview/components/inline-link.svelte.d.ts.map +1 -0
  51. package/dist/preview/components/link-destination-tooltip.svelte +63 -0
  52. package/dist/preview/components/link-destination-tooltip.svelte.d.ts +7 -0
  53. package/dist/preview/components/link-destination-tooltip.svelte.d.ts.map +1 -0
  54. package/dist/preview/components/link-site-icon.svelte +39 -0
  55. package/dist/preview/components/link-site-icon.svelte.d.ts +10 -0
  56. package/dist/preview/components/link-site-icon.svelte.d.ts.map +1 -0
  57. package/dist/preview/components/link.svelte +19 -9
  58. package/dist/preview/components/link.svelte.d.ts.map +1 -1
  59. package/dist/preview/editable-markdown-preview/editable-markdown-surface.svelte +26 -10
  60. package/dist/preview/editable-markdown-preview/editable-markdown-surface.svelte.d.ts.map +1 -1
  61. package/dist/preview/editable-markdown-preview/editing-session.d.ts +15 -0
  62. package/dist/preview/editable-markdown-preview/editing-session.d.ts.map +1 -0
  63. package/dist/preview/editable-markdown-preview/editing-session.js +103 -0
  64. package/dist/preview/editable-markdown-preview/editor-surface.svelte +13 -4
  65. package/dist/preview/editable-markdown-preview/editor-surface.svelte.d.ts +1 -0
  66. package/dist/preview/editable-markdown-preview/editor-surface.svelte.d.ts.map +1 -1
  67. package/dist/preview/editable-markdown-preview/serialized-writer.d.ts +10 -8
  68. package/dist/preview/editable-markdown-preview/serialized-writer.d.ts.map +1 -1
  69. package/dist/preview/editable-markdown-preview/serialized-writer.js +105 -6
  70. package/dist/preview/editable-markdown-preview.svelte +8 -6
  71. package/dist/preview/editable-markdown-preview.svelte.d.ts.map +1 -1
  72. package/dist/preview/index.d.ts +2 -0
  73. package/dist/preview/index.d.ts.map +1 -1
  74. package/dist/preview/index.js +2 -0
  75. package/dist/preview/markdown-preview.svelte +11 -0
  76. package/dist/preview/markdown-preview.svelte.d.ts.map +1 -1
  77. package/dist/preview/renderer/utils.js +0 -2
  78. package/dist/preview/styles/inline-links.css +38 -0
  79. package/dist/preview/styles/links-embeds-tags.css +2 -2
  80. package/dist/preview/styles/mermaid-highlight.css +4 -3
  81. package/dist/preview/styles/references.css +72 -0
  82. package/dist/preview/styles.css +2 -0
  83. package/dist/tables/editor-column.svelte +20 -7
  84. package/dist/tables/editor-column.svelte.d.ts +2 -0
  85. package/dist/tables/editor-column.svelte.d.ts.map +1 -1
  86. package/dist/tables/editor-table.svelte +4 -0
  87. package/dist/tables/editor-table.svelte.d.ts +2 -0
  88. package/dist/tables/editor-table.svelte.d.ts.map +1 -1
  89. package/dist/tables/grid-editor-column.svelte +6 -2
  90. package/dist/tables/grid-editor-column.svelte.d.ts +2 -0
  91. package/dist/tables/grid-editor-column.svelte.d.ts.map +1 -1
  92. package/dist/tables/grid-editor-table.svelte +4 -0
  93. package/dist/tables/grid-editor-table.svelte.d.ts +2 -0
  94. package/dist/tables/grid-editor-table.svelte.d.ts.map +1 -1
  95. package/dist/tables/index.d.ts +1 -0
  96. package/dist/tables/index.d.ts.map +1 -1
  97. package/dist/tables/index.js +1 -0
  98. package/dist/tables/markdown-table-data-cell.svelte +4 -0
  99. package/dist/tables/markdown-table-data-cell.svelte.d.ts +2 -0
  100. package/dist/tables/markdown-table-data-cell.svelte.d.ts.map +1 -1
  101. package/dist/tables/table-reader.svelte +101 -0
  102. package/dist/tables/table-reader.svelte.d.ts +21 -0
  103. package/dist/tables/table-reader.svelte.d.ts.map +1 -0
  104. package/dist/tables/types.d.ts +2 -0
  105. package/dist/tables/types.d.ts.map +1 -1
  106. package/dist/tables/widgets/grid-table-widget.d.ts +1 -1
  107. package/dist/tables/widgets/grid-table-widget.d.ts.map +1 -1
  108. package/dist/tables/widgets/grid-table-widget.js +5 -2
  109. package/dist/tables/widgets/lifecycle.d.ts +4 -0
  110. package/dist/tables/widgets/lifecycle.d.ts.map +1 -0
  111. package/dist/tables/widgets/lifecycle.js +13 -0
  112. package/dist/tables/widgets/pipe-table-widget.d.ts +1 -1
  113. package/dist/tables/widgets/pipe-table-widget.d.ts.map +1 -1
  114. package/dist/tables/widgets/pipe-table-widget.js +5 -2
  115. package/dist/ui/context-menu/context-menu-radio-group.svelte.d.ts +1 -1
  116. package/dist/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +1 -1
  117. package/dist/ui/toolbar/toolbar-group.svelte.d.ts +1 -1
  118. package/inline-links-NOTICE.md +31 -0
  119. package/package.json +6 -2
  120. package/dist/core/code-mirror.test.d.ts +0 -2
  121. package/dist/core/code-mirror.test.d.ts.map +0 -1
  122. package/dist/core/code-mirror.test.js +0 -68
  123. package/dist/core/images.test.d.ts +0 -2
  124. package/dist/core/images.test.d.ts.map +0 -1
  125. package/dist/core/images.test.js +0 -109
  126. package/dist/core/index.test.d.ts +0 -2
  127. package/dist/core/index.test.d.ts.map +0 -1
  128. package/dist/core/index.test.js +0 -11
  129. package/dist/core/markdown-actions.test.d.ts +0 -2
  130. package/dist/core/markdown-actions.test.d.ts.map +0 -1
  131. package/dist/core/markdown-actions.test.js +0 -182
  132. package/dist/extensions/doodle-dividers.test.d.ts +0 -2
  133. package/dist/extensions/doodle-dividers.test.d.ts.map +0 -1
  134. package/dist/extensions/doodle-dividers.test.js +0 -296
  135. package/dist/extensions/index.test.d.ts +0 -2
  136. package/dist/extensions/index.test.d.ts.map +0 -1
  137. package/dist/extensions/index.test.js +0 -283
  138. package/dist/index.test.d.ts +0 -2
  139. package/dist/index.test.d.ts.map +0 -1
  140. package/dist/index.test.js +0 -64
  141. package/dist/internal/appearance-context.test.d.ts +0 -2
  142. package/dist/internal/appearance-context.test.d.ts.map +0 -1
  143. package/dist/internal/appearance-context.test.js +0 -31
  144. package/dist/internal/codemirror/base/index.test.d.ts +0 -2
  145. package/dist/internal/codemirror/base/index.test.d.ts.map +0 -1
  146. package/dist/internal/codemirror/base/index.test.js +0 -303
  147. package/dist/internal/codemirror/base/search.test.d.ts +0 -2
  148. package/dist/internal/codemirror/base/search.test.d.ts.map +0 -1
  149. package/dist/internal/codemirror/base/search.test.js +0 -155
  150. package/dist/internal/codemirror/base/selection-toolbar.test.d.ts +0 -2
  151. package/dist/internal/codemirror/base/selection-toolbar.test.d.ts.map +0 -1
  152. package/dist/internal/codemirror/base/selection-toolbar.test.js +0 -149
  153. package/dist/internal/codemirror/markdown/authoring.test.d.ts +0 -2
  154. package/dist/internal/codemirror/markdown/authoring.test.d.ts.map +0 -1
  155. package/dist/internal/codemirror/markdown/authoring.test.js +0 -222
  156. package/dist/internal/codemirror/markdown/index.test.d.ts +0 -2
  157. package/dist/internal/codemirror/markdown/index.test.d.ts.map +0 -1
  158. package/dist/internal/codemirror/markdown/index.test.js +0 -158
  159. package/dist/internal/codemirror/markdown/showcase-fixture.test.d.ts +0 -2
  160. package/dist/internal/codemirror/markdown/showcase-fixture.test.d.ts.map +0 -1
  161. package/dist/internal/codemirror/markdown/showcase-fixture.test.js +0 -50
  162. package/dist/internal/codemirror/rich/block-controls.test.d.ts +0 -2
  163. package/dist/internal/codemirror/rich/block-controls.test.d.ts.map +0 -1
  164. package/dist/internal/codemirror/rich/block-controls.test.js +0 -401
  165. package/dist/internal/codemirror/rich/block-ranges.test.d.ts +0 -2
  166. package/dist/internal/codemirror/rich/block-ranges.test.d.ts.map +0 -1
  167. package/dist/internal/codemirror/rich/block-ranges.test.js +0 -310
  168. package/dist/internal/codemirror/rich/block-toolbar.test.d.ts +0 -2
  169. package/dist/internal/codemirror/rich/block-toolbar.test.d.ts.map +0 -1
  170. package/dist/internal/codemirror/rich/block-toolbar.test.js +0 -178
  171. package/dist/internal/codemirror/rich/decorations/fold-indicators.test.d.ts +0 -2
  172. package/dist/internal/codemirror/rich/decorations/fold-indicators.test.d.ts.map +0 -1
  173. package/dist/internal/codemirror/rich/decorations/fold-indicators.test.js +0 -8
  174. package/dist/internal/codemirror/rich/index.test.d.ts +0 -2
  175. package/dist/internal/codemirror/rich/index.test.d.ts.map +0 -1
  176. package/dist/internal/codemirror/rich/index.test.js +0 -607
  177. package/dist/internal/codemirror/rich/utils/code-block-lines.test.d.ts +0 -2
  178. package/dist/internal/codemirror/rich/utils/code-block-lines.test.d.ts.map +0 -1
  179. package/dist/internal/codemirror/rich/utils/code-block-lines.test.js +0 -82
  180. package/dist/internal/codemirror/rich/utils/fenced-code.test.d.ts +0 -2
  181. package/dist/internal/codemirror/rich/utils/fenced-code.test.d.ts.map +0 -1
  182. package/dist/internal/codemirror/rich/utils/fenced-code.test.js +0 -12
  183. package/dist/internal/codemirror/rich/utils/headings.test.d.ts +0 -2
  184. package/dist/internal/codemirror/rich/utils/headings.test.d.ts.map +0 -1
  185. package/dist/internal/codemirror/rich/utils/headings.test.js +0 -27
  186. package/dist/internal/codemirror/rich/utils/height-estimates.test.d.ts +0 -2
  187. package/dist/internal/codemirror/rich/utils/height-estimates.test.d.ts.map +0 -1
  188. package/dist/internal/codemirror/rich/utils/height-estimates.test.js +0 -10
  189. package/dist/internal/codemirror/rich/utils/images.test.d.ts +0 -2
  190. package/dist/internal/codemirror/rich/utils/images.test.d.ts.map +0 -1
  191. package/dist/internal/codemirror/rich/utils/images.test.js +0 -37
  192. package/dist/internal/codemirror/rich/utils/indent.test.d.ts +0 -2
  193. package/dist/internal/codemirror/rich/utils/indent.test.d.ts.map +0 -1
  194. package/dist/internal/codemirror/rich/utils/indent.test.js +0 -169
  195. package/dist/internal/codemirror/rich/utils/inline-math.test.d.ts +0 -2
  196. package/dist/internal/codemirror/rich/utils/inline-math.test.d.ts.map +0 -1
  197. package/dist/internal/codemirror/rich/utils/inline-math.test.js +0 -15
  198. package/dist/internal/codemirror/rich/utils/links.test.d.ts +0 -2
  199. package/dist/internal/codemirror/rich/utils/links.test.d.ts.map +0 -1
  200. package/dist/internal/codemirror/rich/utils/links.test.js +0 -28
  201. package/dist/internal/codemirror/rich/utils/list-callouts.test.d.ts +0 -2
  202. package/dist/internal/codemirror/rich/utils/list-callouts.test.d.ts.map +0 -1
  203. package/dist/internal/codemirror/rich/utils/list-callouts.test.js +0 -47
  204. package/dist/internal/codemirror/rich/utils/measured-indent.test.d.ts +0 -2
  205. package/dist/internal/codemirror/rich/utils/measured-indent.test.d.ts.map +0 -1
  206. package/dist/internal/codemirror/rich/utils/measured-indent.test.js +0 -102
  207. package/dist/internal/codemirror/rich/utils/ranges.test.d.ts +0 -2
  208. package/dist/internal/codemirror/rich/utils/ranges.test.d.ts.map +0 -1
  209. package/dist/internal/codemirror/rich/utils/ranges.test.js +0 -22
  210. package/dist/internal/codemirror/rich/utils/tasks.test.d.ts +0 -2
  211. package/dist/internal/codemirror/rich/utils/tasks.test.d.ts.map +0 -1
  212. package/dist/internal/codemirror/rich/utils/tasks.test.js +0 -57
  213. package/dist/internal/task-states.test.d.ts +0 -2
  214. package/dist/internal/task-states.test.d.ts.map +0 -1
  215. package/dist/internal/task-states.test.js +0 -36
  216. package/dist/mira-code-editor.test.d.ts +0 -2
  217. package/dist/mira-code-editor.test.d.ts.map +0 -1
  218. package/dist/mira-code-editor.test.js +0 -93
  219. package/dist/mode-position.test.d.ts +0 -2
  220. package/dist/mode-position.test.d.ts.map +0 -1
  221. package/dist/mode-position.test.js +0 -60
  222. package/dist/preview/code-language.test.d.ts +0 -2
  223. package/dist/preview/code-language.test.d.ts.map +0 -1
  224. package/dist/preview/code-language.test.js +0 -12
  225. package/dist/preview/components/icon.test.d.ts +0 -2
  226. package/dist/preview/components/icon.test.d.ts.map +0 -1
  227. package/dist/preview/components/icon.test.js +0 -20
  228. package/dist/preview/editable-markdown-preview/behavior.test.d.ts +0 -2
  229. package/dist/preview/editable-markdown-preview/behavior.test.d.ts.map +0 -1
  230. package/dist/preview/editable-markdown-preview/behavior.test.js +0 -36
  231. package/dist/preview/editable-markdown-preview/serialized-writer.test.d.ts +0 -2
  232. package/dist/preview/editable-markdown-preview/serialized-writer.test.d.ts.map +0 -1
  233. package/dist/preview/editable-markdown-preview/serialized-writer.test.js +0 -59
  234. package/dist/preview/embed-target.test.d.ts +0 -2
  235. package/dist/preview/embed-target.test.d.ts.map +0 -1
  236. package/dist/preview/embed-target.test.js +0 -78
  237. package/dist/preview/frontmatter/frontmatter.test.d.ts +0 -2
  238. package/dist/preview/frontmatter/frontmatter.test.d.ts.map +0 -1
  239. package/dist/preview/frontmatter/frontmatter.test.js +0 -190
  240. package/dist/preview/frontmatter/suggestions.test.d.ts +0 -2
  241. package/dist/preview/frontmatter/suggestions.test.d.ts.map +0 -1
  242. package/dist/preview/frontmatter/suggestions.test.js +0 -45
  243. package/dist/preview/outline.test.d.ts +0 -2
  244. package/dist/preview/outline.test.d.ts.map +0 -1
  245. package/dist/preview/outline.test.js +0 -98
  246. package/dist/preview/portable-surfaces.test.d.ts +0 -2
  247. package/dist/preview/portable-surfaces.test.d.ts.map +0 -1
  248. package/dist/preview/portable-surfaces.test.js +0 -513
  249. package/dist/preview/preview.test.d.ts +0 -2
  250. package/dist/preview/preview.test.d.ts.map +0 -1
  251. package/dist/preview/preview.test.js +0 -154
  252. package/dist/preview/remark/callouts.test.d.ts +0 -2
  253. package/dist/preview/remark/callouts.test.d.ts.map +0 -1
  254. package/dist/preview/remark/callouts.test.js +0 -23
  255. package/dist/preview/remark/custom-checklists.test.d.ts +0 -2
  256. package/dist/preview/remark/custom-checklists.test.d.ts.map +0 -1
  257. package/dist/preview/remark/custom-checklists.test.js +0 -51
  258. package/dist/preview/remark/links.test.d.ts +0 -2
  259. package/dist/preview/remark/links.test.d.ts.map +0 -1
  260. package/dist/preview/remark/links.test.js +0 -62
  261. package/dist/preview/remark/parity.test.d.ts +0 -2
  262. package/dist/preview/remark/parity.test.d.ts.map +0 -1
  263. package/dist/preview/remark/parity.test.js +0 -105
  264. package/dist/preview/styles/frontmatter-properties.test.d.ts +0 -2
  265. package/dist/preview/styles/frontmatter-properties.test.d.ts.map +0 -1
  266. package/dist/preview/styles/frontmatter-properties.test.js +0 -57
  267. package/dist/preview/styles/source-mode.test.d.ts +0 -2
  268. package/dist/preview/styles/source-mode.test.d.ts.map +0 -1
  269. package/dist/preview/styles/source-mode.test.js +0 -28
  270. package/dist/tables/extension.test.d.ts +0 -2
  271. package/dist/tables/extension.test.d.ts.map +0 -1
  272. package/dist/tables/extension.test.js +0 -100
  273. package/dist/tables/grid-editor-column.test.d.ts +0 -2
  274. package/dist/tables/grid-editor-column.test.d.ts.map +0 -1
  275. package/dist/tables/grid-editor-column.test.js +0 -27
  276. package/dist/tables/grid-table.test.d.ts +0 -2
  277. package/dist/tables/grid-table.test.d.ts.map +0 -1
  278. package/dist/tables/grid-table.test.js +0 -140
  279. package/dist/tables/index.test.d.ts +0 -2
  280. package/dist/tables/index.test.d.ts.map +0 -1
  281. package/dist/tables/index.test.js +0 -7
  282. package/dist/tables/inline-editor-extensions.test.d.ts +0 -2
  283. package/dist/tables/inline-editor-extensions.test.d.ts.map +0 -1
  284. package/dist/tables/inline-editor-extensions.test.js +0 -23
  285. package/dist/tables/pipe-table.test.d.ts +0 -2
  286. package/dist/tables/pipe-table.test.d.ts.map +0 -1
  287. package/dist/tables/pipe-table.test.js +0 -13
  288. package/dist/tables/table-node.test.d.ts +0 -2
  289. package/dist/tables/table-node.test.d.ts.map +0 -1
  290. package/dist/tables/table-node.test.js +0 -167
  291. package/dist/tables/widgets/source-button.test.d.ts +0 -2
  292. package/dist/tables/widgets/source-button.test.d.ts.map +0 -1
  293. package/dist/tables/widgets/source-button.test.js +0 -11
  294. package/dist/themes/theme-contract.test.d.ts +0 -2
  295. package/dist/themes/theme-contract.test.d.ts.map +0 -1
  296. package/dist/themes/theme-contract.test.js +0 -88
  297. package/dist/ui/index.test.d.ts +0 -2
  298. package/dist/ui/index.test.d.ts.map +0 -1
  299. package/dist/ui/index.test.js +0 -7
  300. package/dist/ui/styles.test.d.ts +0 -2
  301. package/dist/ui/styles.test.d.ts.map +0 -1
  302. package/dist/ui/styles.test.js +0 -26
  303. package/dist/ui/table-dnd/table-dnd-utils.test.d.ts +0 -2
  304. package/dist/ui/table-dnd/table-dnd-utils.test.d.ts.map +0 -1
  305. package/dist/ui/table-dnd/table-dnd-utils.test.js +0 -46
@@ -1,303 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { describe, expect, it } from "vitest";
3
- import { CompletionContext } from "@codemirror/autocomplete";
4
- import { EditorState } from "@codemirror/state";
5
- import { EditorView } from "@codemirror/view";
6
- import { createBaseCodeMirrorExtensions, createMarkdownTemplate, createSlashCommandCompletionSource, createSlashCommandExtensions, createSlashSnippet, } from ".";
7
- const slashCommands = [
8
- createSlashSnippet({
9
- id: "heading",
10
- label: "Heading 1",
11
- description: "Large section heading",
12
- group: "Basic",
13
- keywords: ["h1"],
14
- markdown: "# <|>",
15
- }),
16
- createSlashSnippet({
17
- id: "quote",
18
- label: "Quote",
19
- description: "Create a quote",
20
- group: "Basic",
21
- keywords: ["blockquote"],
22
- markdown: "> <|>",
23
- }),
24
- createSlashSnippet({
25
- id: "table",
26
- label: "Table",
27
- description: "Insert a pipe table",
28
- group: "Blocks",
29
- keywords: ["tabular"],
30
- markdown: "| Column | Value |\n| --- | --- |\n| Item | Detail |\n",
31
- }),
32
- ];
33
- function createSlashEditor(doc = "") {
34
- const parent = document.createElement("div");
35
- document.body.append(parent);
36
- const view = new EditorView({
37
- doc,
38
- selection: { anchor: doc.length },
39
- extensions: [
40
- createSlashCommandExtensions({
41
- commands: slashCommands,
42
- }),
43
- ],
44
- parent,
45
- });
46
- return {
47
- parent,
48
- view,
49
- destroy() {
50
- view.destroy();
51
- parent.remove();
52
- },
53
- };
54
- }
55
- function createAfterWhitespaceSlashEditor(doc = "") {
56
- const parent = document.createElement("div");
57
- document.body.append(parent);
58
- const view = new EditorView({
59
- doc,
60
- selection: { anchor: doc.length },
61
- extensions: [
62
- createSlashCommandExtensions({
63
- commands: slashCommands,
64
- triggerScope: "after-whitespace",
65
- }),
66
- ],
67
- parent,
68
- });
69
- return {
70
- parent,
71
- view,
72
- destroy() {
73
- view.destroy();
74
- parent.remove();
75
- },
76
- };
77
- }
78
- function insertText(view, text) {
79
- const selection = view.state.selection.main;
80
- view.dispatch({
81
- changes: {
82
- from: selection.from,
83
- to: selection.to,
84
- insert: text,
85
- },
86
- selection: {
87
- anchor: selection.from + text.length,
88
- },
89
- });
90
- }
91
- function pressKey(view, key) {
92
- view.contentDOM.dispatchEvent(new KeyboardEvent("keydown", {
93
- bubbles: true,
94
- cancelable: true,
95
- key,
96
- }));
97
- }
98
- function slashMenu(parent) {
99
- return parent.querySelector(".mira-slash-menu");
100
- }
101
- function slashMenuTitles(parent) {
102
- return Array.from(parent.querySelectorAll(".mira-slash-menu__item-title"), (title) => title.textContent ?? "");
103
- }
104
- describe("createBaseCodeMirrorExtensions", () => {
105
- it("returns a non-empty extension set", () => {
106
- expect(createBaseCodeMirrorExtensions()).not.toHaveLength(0);
107
- });
108
- it("uses muted monospaced tabular line numbers", () => {
109
- const parent = document.createElement("div");
110
- document.body.append(parent);
111
- const view = new EditorView({
112
- doc: Array.from({ length: 12 }, (_, index) => `Line ${index + 1}`).join("\n"),
113
- extensions: createBaseCodeMirrorExtensions(),
114
- parent,
115
- });
116
- const gutter = parent.querySelector(".cm-gutter.cm-lineNumbers");
117
- const number = gutter?.querySelector(".cm-gutterElement");
118
- expect(gutter).not.toBeNull();
119
- expect(number).not.toBeNull();
120
- expect(getComputedStyle(gutter).fontFamily).toBe("var(--font-monospace, var(--mira-font-mono))");
121
- expect(getComputedStyle(gutter).fontVariantNumeric).toBe("tabular-nums");
122
- expect(getComputedStyle(gutter).color).toBe("var(--text-faint, var(--mira-muted-foreground))");
123
- expect(getComputedStyle(number).justifyContent).toBe("end");
124
- view.destroy();
125
- parent.remove();
126
- });
127
- });
128
- describe("createSlashCommandExtensions", () => {
129
- it("is empty without commands", () => {
130
- expect(createSlashCommandExtensions()).toEqual([]);
131
- });
132
- it("completes slash commands after a slash trigger", () => {
133
- const source = createSlashCommandCompletionSource([
134
- {
135
- id: "heading",
136
- label: "Heading 1",
137
- group: "Basic",
138
- keywords: ["h1"],
139
- insert: "# ",
140
- },
141
- {
142
- id: "table",
143
- label: "Table",
144
- group: "Blocks",
145
- insert: "| Column |",
146
- },
147
- ]);
148
- const state = EditorState.create({ doc: "/h" });
149
- const result = source(new CompletionContext(state, 2, false));
150
- if (result instanceof Promise) {
151
- throw new Error("Expected synchronous slash completions.");
152
- }
153
- expect(result?.from).toBe(1);
154
- expect(result?.to).toBe(2);
155
- expect(result?.filter).toBe(false);
156
- expect(result?.options.map((option) => option.label)).toEqual([
157
- "Heading 1",
158
- ]);
159
- });
160
- it("does not complete slash commands in the middle of a word", () => {
161
- const source = createSlashCommandCompletionSource([
162
- {
163
- id: "heading",
164
- label: "Heading 1",
165
- insert: "# ",
166
- },
167
- ]);
168
- const state = EditorState.create({ doc: "word/h" });
169
- const result = source(new CompletionContext(state, 6, false));
170
- expect(result).toBeNull();
171
- });
172
- it("keeps the autocomplete UI path available", () => {
173
- expect(createSlashCommandExtensions({
174
- commands: slashCommands,
175
- ui: "autocomplete",
176
- })).not.toHaveLength(0);
177
- });
178
- });
179
- describe("slash command popover", () => {
180
- it("opens on slash at line start and after indentation", () => {
181
- const editor = createSlashEditor();
182
- insertText(editor.view, "/");
183
- expect(slashMenu(editor.parent)).not.toBeNull();
184
- editor.destroy();
185
- const indentedEditor = createSlashEditor(" ");
186
- insertText(indentedEditor.view, "/");
187
- expect(slashMenu(indentedEditor.parent)).not.toBeNull();
188
- indentedEditor.destroy();
189
- });
190
- it("does not open after prose, URLs, or paths", () => {
191
- for (const doc of ["word ", "https:/", "notes"]) {
192
- const editor = createSlashEditor(doc);
193
- insertText(editor.view, "/");
194
- expect(slashMenu(editor.parent)).toBeNull();
195
- editor.destroy();
196
- }
197
- });
198
- it("can opt into opening after whitespace", () => {
199
- const editor = createAfterWhitespaceSlashEditor("word ");
200
- insertText(editor.view, "/");
201
- expect(slashMenu(editor.parent)).not.toBeNull();
202
- editor.destroy();
203
- });
204
- it("filters commands by label, description, and keywords", () => {
205
- const editor = createSlashEditor();
206
- insertText(editor.view, "/tab");
207
- expect(slashMenuTitles(editor.parent)).toEqual(["Table"]);
208
- editor.view.dispatch({
209
- changes: { from: 0, to: editor.view.state.doc.length, insert: "/large" },
210
- selection: { anchor: 6 },
211
- });
212
- expect(slashMenuTitles(editor.parent)).toEqual(["Heading 1"]);
213
- editor.view.dispatch({
214
- changes: { from: 0, to: editor.view.state.doc.length, insert: "/block" },
215
- selection: { anchor: 6 },
216
- });
217
- expect(slashMenuTitles(editor.parent)).toEqual(["Quote"]);
218
- editor.destroy();
219
- });
220
- it("renders no menu when no commands match", () => {
221
- const editor = createSlashEditor();
222
- insertText(editor.view, "/missing");
223
- expect(slashMenu(editor.parent)).toBeNull();
224
- editor.destroy();
225
- });
226
- it("groups commands while preserving command order within groups", () => {
227
- const editor = createSlashEditor();
228
- insertText(editor.view, "/");
229
- expect(Array.from(editor.parent.querySelectorAll(".mira-slash-menu__group"), (group) => group.textContent)).toEqual(["Basic", "Blocks"]);
230
- expect(slashMenuTitles(editor.parent)).toEqual([
231
- "Heading 1",
232
- "Quote",
233
- "Table",
234
- ]);
235
- editor.destroy();
236
- });
237
- it("navigates with wrapping arrow keys and applies the active command", () => {
238
- const editor = createSlashEditor();
239
- insertText(editor.view, "/");
240
- pressKey(editor.view, "ArrowUp");
241
- pressKey(editor.view, "Enter");
242
- expect(editor.view.state.doc.toString()).toBe("| Column | Value |\n| --- | --- |\n| Item | Detail |\n");
243
- expect(slashMenu(editor.parent)).toBeNull();
244
- editor.destroy();
245
- });
246
- it("applies a command selected by mouse", () => {
247
- const editor = createSlashEditor();
248
- insertText(editor.view, "/tab");
249
- editor.parent
250
- .querySelector(".mira-slash-menu__item")
251
- ?.click();
252
- expect(editor.view.state.doc.toString()).toBe("| Column | Value |\n| --- | --- |\n| Item | Detail |\n");
253
- editor.destroy();
254
- });
255
- it("closes on escape, space, and backspace from an empty query", () => {
256
- const escapeEditor = createSlashEditor();
257
- insertText(escapeEditor.view, "/");
258
- pressKey(escapeEditor.view, "Escape");
259
- expect(slashMenu(escapeEditor.parent)).toBeNull();
260
- escapeEditor.destroy();
261
- const spaceEditor = createSlashEditor();
262
- insertText(spaceEditor.view, "/");
263
- insertText(spaceEditor.view, " ");
264
- expect(slashMenu(spaceEditor.parent)).toBeNull();
265
- spaceEditor.destroy();
266
- const backspaceEditor = createSlashEditor();
267
- insertText(backspaceEditor.view, "/");
268
- backspaceEditor.view.dispatch({
269
- changes: { from: 0, to: 1 },
270
- selection: { anchor: 0 },
271
- });
272
- expect(slashMenu(backspaceEditor.parent)).toBeNull();
273
- backspaceEditor.destroy();
274
- });
275
- it("places the cursor at the markdown template marker", () => {
276
- const editor = createSlashEditor();
277
- insertText(editor.view, "/h");
278
- pressKey(editor.view, "Enter");
279
- expect(editor.view.state.doc.toString()).toBe("# ");
280
- expect(editor.view.state.selection.main.head).toBe(2);
281
- editor.destroy();
282
- });
283
- });
284
- describe("slash snippet helpers", () => {
285
- it("creates templates and slash commands with cursor markers", () => {
286
- expect(createMarkdownTemplate("## <|>")).toEqual({
287
- markdown: "## ",
288
- selection: 3,
289
- });
290
- expect(createSlashSnippet({
291
- id: "math",
292
- label: "Math block",
293
- markdown: "$$\n<|>\n$$",
294
- })).toEqual({
295
- id: "math",
296
- label: "Math block",
297
- insert: {
298
- markdown: "$$\n\n$$",
299
- selection: 3,
300
- },
301
- });
302
- });
303
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=search.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"search.test.d.ts","sourceRoot":"","sources":["../../../../src/internal/codemirror/base/search.test.ts"],"names":[],"mappings":""}
@@ -1,155 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { getSearchQuery, openSearchPanel, searchPanelOpen, } from "@codemirror/search";
3
- import { EditorState } from "@codemirror/state";
4
- import { EditorView } from "@codemirror/view";
5
- import { tick } from "svelte";
6
- import { describe, expect, it } from "vitest";
7
- import { createBaseCodeMirrorExtensions } from ".";
8
- import { createMiraSearchExtension, createSearchPanelHost, focusSearchPanelInput, } from "./search";
9
- function createSearchEditor(doc = "Alpha beta Alpha", selection = { anchor: 0, head: 5 }) {
10
- const parent = document.createElement("div");
11
- document.body.append(parent);
12
- const view = new EditorView({
13
- state: EditorState.create({
14
- doc,
15
- selection,
16
- extensions: [createBaseCodeMirrorExtensions()],
17
- }),
18
- parent,
19
- });
20
- return {
21
- parent,
22
- view,
23
- destroy() {
24
- view.destroy();
25
- parent.remove();
26
- },
27
- };
28
- }
29
- function inputValue(input, value) {
30
- input.value = value;
31
- input.dispatchEvent(new Event("input", { bubbles: true }));
32
- }
33
- describe("Mira search extension", () => {
34
- it("opens the Lapis-compatible search interface with the selection", () => {
35
- const editor = createSearchEditor();
36
- openSearchPanel(editor.view);
37
- const panel = editor.parent.querySelector(".mira-search-panel");
38
- const searchInput = editor.parent.querySelector(".mira-search-panel__search-input");
39
- expect(panel).not.toBeNull();
40
- expect(editor.parent.querySelector(".cm-panels-top .mira-search-panel-host")).not.toBeNull();
41
- expect(searchInput?.value).toBe("Alpha");
42
- expect(document.activeElement).toBe(searchInput);
43
- expect(editor.parent.querySelector('[aria-label="Case sensitive"]')).not.toBeNull();
44
- expect(editor.parent.querySelector('[aria-label="Match whole word"]')).not.toBeNull();
45
- expect(editor.parent.querySelector('[aria-label="Use regular expression"]')).not.toBeNull();
46
- const searchField = editor.parent.querySelector(".mira-search-panel__search-field");
47
- const searchOptions = editor.parent.querySelector('[role="group"][aria-label="Search options"]');
48
- expect(searchField?.contains(searchInput)).toBe(true);
49
- expect(searchField?.contains(searchOptions)).toBe(true);
50
- expect(searchOptions?.parentElement).toBe(searchField);
51
- expect(searchField?.querySelector(".mira-search-panel__find-icon svg")).not.toBeNull();
52
- expect(editor.parent.querySelector('[aria-label="Select all matches"]')).not.toBeNull();
53
- editor.destroy();
54
- });
55
- it("updates search flags and reports missing matches", async () => {
56
- const editor = createSearchEditor();
57
- openSearchPanel(editor.view);
58
- editor.parent
59
- .querySelector('[aria-label="Case sensitive"]')
60
- ?.click();
61
- editor.parent
62
- .querySelector('[aria-label="Match whole word"]')
63
- ?.click();
64
- editor.parent
65
- .querySelector('[aria-label="Use regular expression"]')
66
- ?.click();
67
- expect(getSearchQuery(editor.view.state)).toMatchObject({
68
- caseSensitive: true,
69
- wholeWord: true,
70
- regexp: true,
71
- });
72
- const searchInput = editor.parent.querySelector(".mira-search-panel__search-input");
73
- if (!searchInput) {
74
- throw new Error("Expected the search input.");
75
- }
76
- inputValue(searchInput, "Missing");
77
- await tick();
78
- expect(getSearchQuery(editor.view.state).search).toBe("Missing");
79
- expect(searchInput.getAttribute("aria-invalid")).toBe("true");
80
- expect(editor.parent.querySelector('[role="status"]')?.textContent).toContain("No matches found");
81
- editor.destroy();
82
- });
83
- it("expands replace controls and replaces all matches", async () => {
84
- const editor = createSearchEditor("one two one", { anchor: 0, head: 3 });
85
- openSearchPanel(editor.view);
86
- editor.parent
87
- .querySelector('[aria-label="Toggle replace"]')
88
- ?.click();
89
- await tick();
90
- const replaceInput = editor.parent.querySelector('input[aria-label="Replace"]');
91
- if (!replaceInput) {
92
- throw new Error("Expected the replace input.");
93
- }
94
- inputValue(replaceInput, "three");
95
- editor.parent
96
- .querySelector('[aria-label="Replace all matches"]')
97
- ?.click();
98
- expect(editor.view.state.doc.toString()).toBe("three two three");
99
- editor.destroy();
100
- });
101
- it("respects initial search configuration and panel placement", () => {
102
- const parent = document.createElement("div");
103
- document.body.append(parent);
104
- const view = new EditorView({
105
- state: EditorState.create({
106
- doc: "Alpha alpha",
107
- extensions: [
108
- createMiraSearchExtension({
109
- top: false,
110
- caseSensitive: true,
111
- wholeWord: true,
112
- }),
113
- ],
114
- }),
115
- parent,
116
- });
117
- openSearchPanel(view);
118
- expect(getSearchQuery(view.state)).toMatchObject({
119
- caseSensitive: true,
120
- wholeWord: true,
121
- });
122
- expect(parent.querySelector(".cm-panels-bottom .mira-search-panel-host")).not.toBeNull();
123
- view.destroy();
124
- parent.remove();
125
- });
126
- it("closes with Escape from the search panel", () => {
127
- const editor = createSearchEditor();
128
- openSearchPanel(editor.view);
129
- const searchInput = editor.parent.querySelector(".mira-search-panel__search-input");
130
- searchInput?.dispatchEvent(new KeyboardEvent("keydown", {
131
- bubbles: true,
132
- cancelable: true,
133
- key: "Escape",
134
- }));
135
- expect(searchPanelOpen(editor.view.state)).toBe(false);
136
- editor.destroy();
137
- });
138
- it("creates and focuses the panel host in the editor document", () => {
139
- const iframe = document.createElement("iframe");
140
- document.body.append(iframe);
141
- const popupDocument = iframe.contentDocument;
142
- if (!popupDocument) {
143
- throw new Error("Expected an iframe document.");
144
- }
145
- const host = createSearchPanelHost(popupDocument);
146
- const input = popupDocument.createElement("input");
147
- input.className = "mira-search-panel__search-input";
148
- host.append(input);
149
- popupDocument.body.append(host);
150
- focusSearchPanelInput(host);
151
- expect(host.ownerDocument).toBe(popupDocument);
152
- expect(popupDocument.activeElement).toBe(input);
153
- iframe.remove();
154
- });
155
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=selection-toolbar.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"selection-toolbar.test.d.ts","sourceRoot":"","sources":["../../../../src/internal/codemirror/base/selection-toolbar.test.ts"],"names":[],"mappings":""}
@@ -1,149 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { EditorSelection, EditorState } from "@codemirror/state";
3
- import { EditorView } from "@codemirror/view";
4
- import { describe, expect, it } from "vitest";
5
- import { createMarkdownCodeMirrorExtensions } from "../markdown";
6
- import { createSelectionToolbarExtension, defaultMiraSelectionToolbarActions, } from "./selection-toolbar";
7
- function createEditor({ actions, ariaLabel, labels, placement, readonly = false, doc = "Format this text", selection = EditorSelection.single(7, 11), } = {}) {
8
- const parent = document.createElement("div");
9
- document.body.append(parent);
10
- const view = new EditorView({
11
- state: EditorState.create({
12
- doc,
13
- selection,
14
- extensions: [
15
- createMarkdownCodeMirrorExtensions({ sourceMode: true }),
16
- EditorState.readOnly.of(readonly),
17
- createSelectionToolbarExtension({
18
- actions,
19
- ariaLabel,
20
- labels,
21
- placement,
22
- }),
23
- ],
24
- }),
25
- parent,
26
- });
27
- return {
28
- parent,
29
- view,
30
- destroy() {
31
- view.destroy();
32
- parent.remove();
33
- },
34
- };
35
- }
36
- function toolbar(parent) {
37
- return parent.querySelector('[role="toolbar"]');
38
- }
39
- describe("createSelectionToolbarExtension", () => {
40
- it("shows the default accessible actions in screenshot order", () => {
41
- const editor = createEditor();
42
- const selectionToolbar = toolbar(editor.parent);
43
- expect(defaultMiraSelectionToolbarActions).toEqual([
44
- "link",
45
- "bold",
46
- "italic",
47
- "strikethrough",
48
- ]);
49
- expect(selectionToolbar?.getAttribute("aria-label")).toBe("Text formatting");
50
- expect(selectionToolbar?.dataset.placement).toBe("below");
51
- expect(Array.from(selectionToolbar?.querySelectorAll("button") ?? [], (button) => ({
52
- action: button.dataset.miraSelectionAction,
53
- label: button.getAttribute("aria-label"),
54
- title: button.title,
55
- icon: button.querySelector("svg")?.getAttribute("aria-hidden"),
56
- }))).toEqual([
57
- { action: "link", label: "Link", title: "Link", icon: "true" },
58
- { action: "bold", label: "Bold", title: "Bold", icon: "true" },
59
- { action: "italic", label: "Italic", title: "Italic", icon: "true" },
60
- {
61
- action: "strikethrough",
62
- label: "Strikethrough",
63
- title: "Strikethrough",
64
- icon: "true",
65
- },
66
- ]);
67
- expect(Array.from(selectionToolbar?.querySelectorAll("button") ?? [], (button) => button.getAttribute("aria-pressed"))).toEqual(["false", "false", "false", "false"]);
68
- expect(editor.view.state.doc.toString()).toBe("Format this text");
69
- editor.destroy();
70
- });
71
- it("delegates button activation to the shared Markdown action engine", () => {
72
- const editor = createEditor();
73
- const bold = editor.parent.querySelector('[data-mira-selection-action="bold"]');
74
- bold?.click();
75
- expect(editor.view.state.doc.toString()).toBe("Format **this** text");
76
- expect(editor.view.state.selection.main.from).toBe(9);
77
- expect(editor.view.state.selection.main.to).toBe(13);
78
- expect(toolbar(editor.parent)).not.toBeNull();
79
- expect(editor.parent
80
- .querySelector('[data-mira-selection-action="bold"]')
81
- ?.getAttribute("aria-pressed")).toBe("true");
82
- editor.parent
83
- .querySelector('[data-mira-selection-action="bold"]')
84
- ?.click();
85
- expect(editor.view.state.doc.toString()).toBe("Format this text");
86
- expect(editor.parent
87
- .querySelector('[data-mira-selection-action="bold"]')
88
- ?.getAttribute("aria-pressed")).toBe("false");
89
- editor.destroy();
90
- });
91
- it("marks an existing exact formatting span as selected", () => {
92
- const editor = createEditor({
93
- doc: "Format __this__ text",
94
- selection: EditorSelection.single(9, 13),
95
- });
96
- expect(editor.parent
97
- .querySelector('[data-mira-selection-action="bold"]')
98
- ?.getAttribute("aria-pressed")).toBe("true");
99
- expect(editor.parent
100
- .querySelector('[data-mira-selection-action="italic"]')
101
- ?.getAttribute("aria-pressed")).toBe("false");
102
- editor.destroy();
103
- });
104
- it("supports configured action order, labels, placement, and toolbar name", () => {
105
- const editor = createEditor({
106
- actions: ["inlineCode", "italic", "inlineCode"],
107
- ariaLabel: "Quick formatting",
108
- labels: { inlineCode: "Code selection" },
109
- placement: "above",
110
- });
111
- const selectionToolbar = toolbar(editor.parent);
112
- expect(selectionToolbar?.getAttribute("aria-label")).toBe("Quick formatting");
113
- expect(selectionToolbar?.dataset.placement).toBe("above");
114
- expect(Array.from(selectionToolbar?.querySelectorAll("button") ?? [], (button) => button.getAttribute("aria-label"))).toEqual(["Code selection", "Italic"]);
115
- editor.destroy();
116
- });
117
- it("moves keyboard focus into and through the toolbar", () => {
118
- const editor = createEditor();
119
- editor.view.focus();
120
- editor.view.contentDOM.dispatchEvent(new KeyboardEvent("keydown", {
121
- bubbles: true,
122
- cancelable: true,
123
- key: "Tab",
124
- }));
125
- expect(document.activeElement?.getAttribute("aria-label")).toBe("Link");
126
- document.activeElement?.dispatchEvent(new KeyboardEvent("keydown", {
127
- bubbles: true,
128
- cancelable: true,
129
- key: "ArrowRight",
130
- }));
131
- expect(document.activeElement?.getAttribute("aria-label")).toBe("Bold");
132
- document.activeElement?.dispatchEvent(new KeyboardEvent("keydown", {
133
- bubbles: true,
134
- cancelable: true,
135
- key: "Escape",
136
- }));
137
- expect(document.activeElement).toBe(editor.view.contentDOM);
138
- editor.destroy();
139
- });
140
- it("hides for collapsed selections and readonly editors", () => {
141
- const editor = createEditor();
142
- editor.view.dispatch({ selection: EditorSelection.cursor(7) });
143
- expect(toolbar(editor.parent)).toBeNull();
144
- editor.destroy();
145
- const readonlyEditor = createEditor({ readonly: true });
146
- expect(toolbar(readonlyEditor.parent)).toBeNull();
147
- readonlyEditor.destroy();
148
- });
149
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=authoring.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"authoring.test.d.ts","sourceRoot":"","sources":["../../../../src/internal/codemirror/markdown/authoring.test.ts"],"names":[],"mappings":""}