@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
@@ -0,0 +1,94 @@
1
+ <script lang="ts">
2
+ import { getContext, type Snippet } from "svelte";
3
+ import {
4
+ miraAppearanceContextKey,
5
+ resolveMiraThemeAttribute,
6
+ resolveMiraColorModeAttribute,
7
+ type MiraAppearanceContext,
8
+ } from "../../internal/appearance-context";
9
+ import type { HTMLAnchorAttributes } from "svelte/elements";
10
+ import * as Tooltip from "../../ui/tooltip";
11
+ import LinkSiteIcon from "./link-site-icon.svelte";
12
+ import {
13
+ defaultMiraLinkIconRegistry,
14
+ parseInlineLinkUrl,
15
+ type MiraLinkIconRegistry,
16
+ } from "../../internal/inline-links/registry";
17
+ let {
18
+ href = "",
19
+ label,
20
+ registry = defaultMiraLinkIconRegistry,
21
+ children,
22
+ title,
23
+ class: className = "",
24
+ target = "_blank",
25
+ rel,
26
+ ref = $bindable(null),
27
+ tagName: _tagName,
28
+ sourcePath: _sourcePath,
29
+ dialog: _dialog,
30
+ ...rest
31
+ }: Omit<HTMLAnchorAttributes, "children"> & {
32
+ registry?: MiraLinkIconRegistry;
33
+ label?: string;
34
+ children?: Snippet;
35
+ ref?: HTMLAnchorElement | null;
36
+ tagName?: string;
37
+ sourcePath?: string;
38
+ dialog?: boolean;
39
+ } = $props();
40
+ const safeHref = $derived(parseInlineLinkUrl(href ?? "")?.href);
41
+ const appearance = getContext<MiraAppearanceContext | undefined>(
42
+ miraAppearanceContextKey,
43
+ );
44
+ const appearanceTheme = $derived(
45
+ resolveMiraThemeAttribute(appearance?.theme, ref),
46
+ );
47
+ const appearanceMode = $derived(
48
+ resolveMiraColorModeAttribute(appearance?.colorMode, ref),
49
+ );
50
+ const showDestination = $derived(
51
+ Boolean(safeHref && (title || children || (label && label !== href))),
52
+ );
53
+ const safeRel = $derived(
54
+ target === "_blank"
55
+ ? [
56
+ ...new Set(`${rel ?? ""} noopener noreferrer`.trim().split(/\s+/u)),
57
+ ].join(" ")
58
+ : rel,
59
+ );
60
+ </script>
61
+
62
+ <Tooltip.Provider delayDuration={200}>
63
+ <Tooltip.Root disabled={!showDestination}>
64
+ <Tooltip.Trigger>
65
+ {#snippet child({ props })}
66
+ <a
67
+ {...props}
68
+ {...rest}
69
+ bind:this={ref}
70
+ class={`mira-inline-link ${className}`.trim()}
71
+ href={safeHref}
72
+ {title}
73
+ {target}
74
+ rel={safeRel}
75
+ >
76
+ {#if safeHref}<LinkSiteIcon href={safeHref} {registry} />{/if}<span
77
+ >{#if children}{@render children()}{:else}{label || href}{/if}</span
78
+ >
79
+ </a>
80
+ {/snippet}
81
+ </Tooltip.Trigger>
82
+ <Tooltip.Content
83
+ role="tooltip"
84
+ side="top"
85
+ sideOffset={6}
86
+ data-mira-theme={appearanceTheme}
87
+ data-mira-color-mode={appearanceMode}
88
+ >
89
+ {#if title}<span>{title}</span><br />{/if}<span
90
+ class="mira-inline-link__destination">{safeHref}</span
91
+ >
92
+ </Tooltip.Content>
93
+ </Tooltip.Root>
94
+ </Tooltip.Provider>
@@ -0,0 +1,16 @@
1
+ import { type Snippet } from "svelte";
2
+ import type { HTMLAnchorAttributes } from "svelte/elements";
3
+ import { type MiraLinkIconRegistry } from "../../internal/inline-links/registry";
4
+ type $$ComponentProps = Omit<HTMLAnchorAttributes, "children"> & {
5
+ registry?: MiraLinkIconRegistry;
6
+ label?: string;
7
+ children?: Snippet;
8
+ ref?: HTMLAnchorElement | null;
9
+ tagName?: string;
10
+ sourcePath?: string;
11
+ dialog?: boolean;
12
+ };
13
+ declare const InlineLink: import("svelte").Component<$$ComponentProps, {}, "ref">;
14
+ type InlineLink = ReturnType<typeof InlineLink>;
15
+ export default InlineLink;
16
+ //# sourceMappingURL=inline-link.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-link.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/components/inline-link.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOlD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG5D,OAAO,EAGH,KAAK,oBAAoB,EAC1B,MAAM,sCAAsC,CAAC;AAE/C,KAAK,gBAAgB,GAAI,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC,GAAG;IAC/D,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AA8DJ,QAAA,MAAM,UAAU,yDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import * as Tooltip from "../../ui/tooltip";
3
+ let { anchor }: { anchor: HTMLAnchorElement } = $props();
4
+ const id = $props.id();
5
+ let open = $state(false);
6
+ const theme = $derived(
7
+ anchor.closest<HTMLElement>("[data-mira-theme]")?.dataset.miraTheme,
8
+ );
9
+ const colorMode = $derived(
10
+ anchor.closest<HTMLElement>("[data-mira-color-mode]")?.dataset
11
+ .miraColorMode,
12
+ );
13
+ $effect(() => {
14
+ const show = () => (open = true);
15
+ const hide = () => (open = false);
16
+ const escape = (event: KeyboardEvent) => {
17
+ if (event.key === "Escape") hide();
18
+ };
19
+ anchor.addEventListener("pointerenter", show);
20
+ anchor.addEventListener("pointerleave", hide);
21
+ anchor.addEventListener("focus", show);
22
+ anchor.addEventListener("blur", hide);
23
+ anchor.addEventListener("keydown", escape);
24
+ if (anchor.matches(":focus, :hover")) show();
25
+ return () => {
26
+ anchor.removeEventListener("pointerenter", show);
27
+ anchor.removeEventListener("pointerleave", hide);
28
+ anchor.removeEventListener("focus", show);
29
+ anchor.removeEventListener("blur", hide);
30
+ anchor.removeEventListener("keydown", escape);
31
+ };
32
+ });
33
+ $effect(() => {
34
+ if (!open) return;
35
+ const previous = anchor.getAttribute("aria-describedby");
36
+ anchor.setAttribute(
37
+ "aria-describedby",
38
+ [previous, id].filter(Boolean).join(" "),
39
+ );
40
+ return () => {
41
+ if (previous) anchor.setAttribute("aria-describedby", previous);
42
+ else anchor.removeAttribute("aria-describedby");
43
+ };
44
+ });
45
+ </script>
46
+
47
+ <Tooltip.Provider>
48
+ <Tooltip.Root bind:open>
49
+ <Tooltip.Content
50
+ {id}
51
+ role="tooltip"
52
+ customAnchor={anchor}
53
+ side="top"
54
+ sideOffset={6}
55
+ data-mira-theme={theme}
56
+ data-mira-color-mode={colorMode}
57
+ >
58
+ {#if anchor.title}<span>{anchor.title}</span><br />{/if}<span
59
+ class="mira-inline-link__destination">{anchor.href}</span
60
+ >
61
+ </Tooltip.Content>
62
+ </Tooltip.Root>
63
+ </Tooltip.Provider>
@@ -0,0 +1,7 @@
1
+ type $$ComponentProps = {
2
+ anchor: HTMLAnchorElement;
3
+ };
4
+ declare const LinkDestinationTooltip: import("svelte").Component<$$ComponentProps, {}, "">;
5
+ type LinkDestinationTooltip = ReturnType<typeof LinkDestinationTooltip>;
6
+ export default LinkDestinationTooltip;
7
+ //# sourceMappingURL=link-destination-tooltip.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-destination-tooltip.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/components/link-destination-tooltip.svelte.ts"],"names":[],"mappings":"AAKC,KAAK,gBAAgB,GAAI;IAAE,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAyDxD,QAAA,MAAM,sBAAsB,sDAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,39 @@
1
+ <script lang="ts">
2
+ import {
3
+ defaultMiraLinkIconRegistry,
4
+ type MiraLinkIconRegistry,
5
+ } from "../../internal/inline-links/registry";
6
+ let {
7
+ href,
8
+ registry = defaultMiraLinkIconRegistry,
9
+ class: className = "",
10
+ }: {
11
+ href: string;
12
+ registry?: MiraLinkIconRegistry;
13
+ class?: string;
14
+ } = $props();
15
+ const resolved = $derived(registry.resolve(href));
16
+ </script>
17
+
18
+ {#if resolved?.icon}
19
+ <svg
20
+ class={`mira-link-site-icon ${className}`.trim()}
21
+ data-link-site={resolved.id}
22
+ viewBox={resolved.icon.viewBox ?? "0 0 24 24"}
23
+ fill="currentColor"
24
+ aria-hidden="true"
25
+ focusable="false"
26
+ >
27
+ {#each resolved.icon.paths as path}
28
+ <path
29
+ d={path.d}
30
+ fill={path.fill}
31
+ stroke={path.stroke}
32
+ stroke-width={path.strokeWidth}
33
+ stroke-linecap={path.strokeLinecap}
34
+ stroke-linejoin={path.strokeLinejoin}
35
+ fill-rule={path.fillRule}
36
+ />
37
+ {/each}
38
+ </svg>
39
+ {/if}
@@ -0,0 +1,10 @@
1
+ import { type MiraLinkIconRegistry } from "../../internal/inline-links/registry";
2
+ type $$ComponentProps = {
3
+ href: string;
4
+ registry?: MiraLinkIconRegistry;
5
+ class?: string;
6
+ };
7
+ declare const LinkSiteIcon: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type LinkSiteIcon = ReturnType<typeof LinkSiteIcon>;
9
+ export default LinkSiteIcon;
10
+ //# sourceMappingURL=link-site-icon.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-site-icon.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/components/link-site-icon.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAEH,KAAK,oBAAoB,EAC1B,MAAM,sCAAsC,CAAC;AAE/C,KAAK,gBAAgB,GAAI;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAqBJ,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -19,6 +19,7 @@
19
19
  import { useMarkdownContext } from "../renderer/context.svelte";
20
20
  import EditableMarkdownSurface from "../editable-markdown-preview/editable-markdown-surface.svelte";
21
21
  import EmbeddedMarkdownPreview from "./embedded-markdown-preview.svelte";
22
+ import { createAssetUrlLease } from "../asset-url-lease";
22
23
 
23
24
  type Props = {
24
25
  href?: string;
@@ -69,7 +70,9 @@
69
70
  const target = $derived(id || href);
70
71
  const displayText = $derived(text || label || target);
71
72
  const activeSourcePath = $derived(sourcePath || markdown.sourcePath);
72
- const parsedTarget = $derived(parseMiraFileTarget(target, activeSourcePath));
73
+ const parsedTarget = $derived(
74
+ parseMiraFileTarget(target, activeSourcePath, { decodeUri: !id }),
75
+ );
73
76
  const hasFileAdapter = $derived(Boolean(markdown.fileAdapter));
74
77
  const isExternal = $derived(isExternalHref(target));
75
78
  const resolvedHref = $derived(
@@ -126,6 +129,14 @@
126
129
  ).then(
127
130
  (file) => {
128
131
  if (!cancelled) {
132
+ if (
133
+ resolvedFile?.path === file?.path &&
134
+ resolvedFile?.name === file?.name &&
135
+ resolvedFile?.extension === file?.extension &&
136
+ resolvedFile?.kind === file?.kind
137
+ ) {
138
+ return;
139
+ }
129
140
  if (resolvedFile?.path !== file?.path) {
130
141
  previewMarkdown = null;
131
142
  previewAssetUrl = null;
@@ -174,14 +185,12 @@
174
185
  }
175
186
 
176
187
  let cancelled = false;
177
- const markdownPromise = adapter.readMarkdown
178
- ? Promise.resolve(adapter.readMarkdown(file))
179
- : Promise.resolve(null);
180
- const assetPromise = adapter.readAssetUrl
181
- ? Promise.resolve(adapter.readAssetUrl(file))
182
- : Promise.resolve(null);
188
+ const markdownPromise = Promise.resolve().then(
189
+ () => adapter.readMarkdown?.(file) ?? null,
190
+ );
191
+ const asset = createAssetUrlLease(adapter, file);
183
192
 
184
- Promise.all([markdownPromise, assetPromise]).then(
193
+ Promise.all([markdownPromise, asset.result]).then(
185
194
  ([nextMarkdown, nextAssetUrl]) => {
186
195
  if (cancelled) {
187
196
  return;
@@ -205,6 +214,7 @@
205
214
 
206
215
  return () => {
207
216
  cancelled = true;
217
+ asset.release();
208
218
  stopWatching?.();
209
219
  };
210
220
  });
@@ -324,7 +334,7 @@
324
334
  src={previewAssetUrl}
325
335
  alt={resolvedFile.name || displayText}
326
336
  />
327
- {:else if previewMarkdown}
337
+ {:else if previewMarkdown !== null}
328
338
  {#snippet renderedPreview(value: string)}
329
339
  <EmbeddedMarkdownPreview
330
340
  class="mira-link-preview__markdown"
@@ -1 +1 @@
1
- {"version":3,"file":"link.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/components/link.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAqBhD,KAAK,KAAK,GAAG;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAC1B,CAAC;AAySJ,QAAA,MAAM,IAAI,8CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"link.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/components/link.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAsBhD,KAAK,KAAK,GAAG;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAC1B,CAAC;AAmTJ,QAAA,MAAM,IAAI,8CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { onDestroy, tick, untrack, type Snippet } from "svelte";
2
+ import { tick, untrack, type Snippet } from "svelte";
3
3
  import type {
4
4
  MiraAssetResolver,
5
5
  MiraExtension,
@@ -14,6 +14,7 @@
14
14
  shouldReturnEditableMarkdownPreviewOnBlur,
15
15
  } from "./behavior";
16
16
  import EditorSurface from "./editor-surface.svelte";
17
+ import { attachMarkdownEditingSession } from "./editing-session";
17
18
  import {
18
19
  SerializedMarkdownWriter,
19
20
  type SerializedMarkdownWriterState,
@@ -83,6 +84,7 @@
83
84
  let buffer = $state("");
84
85
  let pendingOffset = $state<number | null>(null);
85
86
  let writerState = $state<SerializedMarkdownWriterState>({
87
+ readonly: false,
86
88
  dirty: false,
87
89
  saving: false,
88
90
  error: null,
@@ -94,7 +96,7 @@
94
96
  let previewScrollRatio = 0;
95
97
  let editorScrollRatio = 0;
96
98
 
97
- const writable = $derived(Boolean(writeMarkdown));
99
+ const writable = $derived(Boolean(writeMarkdown) && !writerState.readonly);
98
100
 
99
101
  $effect(() => {
100
102
  previewOnChange = writable ? updatePreviewRange : undefined;
@@ -106,15 +108,16 @@
106
108
  $effect(() => {
107
109
  const write = writeMarkdown;
108
110
  const key = sourcePath;
111
+ const adapter = fileAdapter;
109
112
  const initialValue = untrack(() => value);
110
113
  key;
111
114
 
112
- writer?.destroy();
113
115
  writer = null;
114
116
  buffer = initialValue;
115
117
  lastExternalValue = initialValue;
116
118
  lastPersistedNotification = initialValue;
117
119
  writerState = {
120
+ readonly: false,
118
121
  dirty: false,
119
122
  saving: false,
120
123
  error: null,
@@ -127,10 +130,13 @@
127
130
  return;
128
131
  }
129
132
 
133
+ let current = true;
134
+ let persist = write;
130
135
  const activeWriter = new SerializedMarkdownWriter({
131
136
  value: initialValue,
132
- write,
137
+ write: (contents) => persist(contents),
133
138
  onStateChange(state) {
139
+ if (!current) return;
134
140
  writerState = state;
135
141
  buffer = state.value;
136
142
  if (state.persistedValue !== lastPersistedNotification) {
@@ -140,9 +146,22 @@
140
146
  },
141
147
  });
142
148
  writer = activeWriter;
149
+ const attached = attachMarkdownEditingSession({
150
+ writer: activeWriter,
151
+ sourcePath: key,
152
+ register: adapter?.registerEditingSession
153
+ ? (path, session) => adapter.registerEditingSession?.(path, session)
154
+ : undefined,
155
+ bind: adapter?.bindMarkdownEditingSession
156
+ ? (path, session) => adapter.bindMarkdownEditingSession!(path, session)
157
+ : undefined,
158
+ synchronizeProtection: tick,
159
+ });
160
+ persist = attached.write ?? write;
143
161
 
144
162
  return () => {
145
- activeWriter.destroy();
163
+ current = false;
164
+ attached.detach();
146
165
  if (writer === activeWriter) {
147
166
  writer = null;
148
167
  }
@@ -251,8 +270,8 @@
251
270
  }
252
271
 
253
272
  function updateBuffer(nextValue: string): void {
273
+ if (!writer?.update(nextValue)) return;
254
274
  buffer = nextValue;
255
- writer?.update(nextValue);
256
275
  }
257
276
 
258
277
  function updatePreviewRange(
@@ -316,10 +335,6 @@
316
335
  await leaveEditing("blur");
317
336
  return !editing;
318
337
  }
319
-
320
- onDestroy(() => {
321
- writer?.destroy();
322
- });
323
338
  </script>
324
339
 
325
340
  <div
@@ -342,6 +357,7 @@
342
357
  >
343
358
  <EditorSurface
344
359
  value={buffer}
360
+ readonly={writerState.readonly}
345
361
  {extensions}
346
362
  {sourcePath}
347
363
  {linkResolver}
@@ -1 +1 @@
1
- {"version":3,"file":"editable-markdown-surface.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/editable-markdown-surface.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,KAAK,EACR,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAalC,KAAK,mBAAmB,GAAG,CACzB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,KACP,IAAI,CAAC;AAEV,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3B,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACrE,CAAC;AAsTJ,QAAA,MAAM,uBAAuB;iBA9CF,OAAO,CAAC,OAAO,CAAC;gBAIjB,OAAO,CAAC,OAAO,CAAC;iCA0C2B,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"editable-markdown-surface.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/editable-markdown-surface.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,EACR,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAclC,KAAK,mBAAmB,GAAG,CACzB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,KACP,IAAI,CAAC;AAEV,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3B,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACrE,CAAC;AAqUJ,QAAA,MAAM,uBAAuB;iBA1CF,OAAO,CAAC,OAAO,CAAC;gBAIjB,OAAO,CAAC,OAAO,CAAC;iCAsC2B,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { MiraFileAdapter, MiraMarkdownEditingSession } from "../../extensions";
2
+ import type { SerializedMarkdownWriter } from "./serialized-writer";
3
+ /** Retain detached writers until persistence succeeds so external operations can join them. */
4
+ export declare function attachMarkdownEditingSession(options: {
5
+ writer: SerializedMarkdownWriter;
6
+ sourcePath?: string;
7
+ register?: MiraFileAdapter["registerEditingSession"];
8
+ bind?: MiraFileAdapter["bindMarkdownEditingSession"];
9
+ synchronizeProtection?: () => Promise<void>;
10
+ }): {
11
+ session: MiraMarkdownEditingSession;
12
+ write?: (value: string) => void | Promise<void>;
13
+ detach(): void;
14
+ };
15
+ //# sourceMappingURL=editing-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editing-session.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/editing-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAC3B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEpE,+FAA+F;AAC/F,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,MAAM,EAAE,wBAAwB,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,eAAe,CAAC,wBAAwB,CAAC,CAAC;IACrD,IAAI,CAAC,EAAE,eAAe,CAAC,4BAA4B,CAAC,CAAC;IACrD,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C,GAAG;IACF,OAAO,EAAE,0BAA0B,CAAC;IACpC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,IAAI,IAAI,CAAC;CAChB,CAiGA"}
@@ -0,0 +1,103 @@
1
+ /** Retain detached writers until persistence succeeds so external operations can join them. */
2
+ export function attachMarkdownEditingSession(options) {
3
+ const { writer } = options;
4
+ let detached = false;
5
+ let remove;
6
+ let stop;
7
+ let releaseError;
8
+ let write;
9
+ function releaseIfClean() {
10
+ const state = writer.state;
11
+ if (!detached || state.dirty || state.saving || state.error !== null)
12
+ return;
13
+ try {
14
+ remove?.();
15
+ remove = undefined;
16
+ releaseError = undefined;
17
+ stop?.();
18
+ stop = undefined;
19
+ }
20
+ catch (error) {
21
+ releaseError = error ?? new Error("Markdown binding release failed");
22
+ }
23
+ }
24
+ const session = {
25
+ get dirty() {
26
+ const state = writer.state;
27
+ return (state.dirty ||
28
+ state.saving ||
29
+ state.error !== null ||
30
+ releaseError !== undefined);
31
+ },
32
+ async flush() {
33
+ if (!(await writer.flush()))
34
+ throw writer.state.error ?? new Error("Unable to save Markdown");
35
+ releaseIfClean();
36
+ if (releaseError !== undefined)
37
+ throw releaseError;
38
+ },
39
+ async protect() {
40
+ const release = await writer.protect();
41
+ try {
42
+ await options.synchronizeProtection?.();
43
+ return release;
44
+ }
45
+ catch (error) {
46
+ release();
47
+ throw error;
48
+ }
49
+ },
50
+ text: {
51
+ get state() {
52
+ return writer.state;
53
+ },
54
+ subscribe: (listener) => writer.subscribe(listener),
55
+ async protectRecovery() {
56
+ const lease = await writer.protectRecovery();
57
+ try {
58
+ await options.synchronizeProtection?.();
59
+ return lease;
60
+ }
61
+ catch (error) {
62
+ lease.release();
63
+ throw error;
64
+ }
65
+ },
66
+ },
67
+ };
68
+ try {
69
+ if (options.bind) {
70
+ if (!options.sourcePath)
71
+ throw new Error("A Markdown binding requires a stable source path");
72
+ const binding = options.bind(options.sourcePath, session);
73
+ if (!binding ||
74
+ typeof binding.write !== "function" ||
75
+ typeof binding.release !== "function") {
76
+ if (typeof binding?.release === "function")
77
+ binding.release();
78
+ throw new Error("Invalid Markdown editing binding");
79
+ }
80
+ remove = () => binding.release();
81
+ write = (value) => binding.write(value);
82
+ }
83
+ else if (options.sourcePath)
84
+ remove = options.register?.(options.sourcePath, session);
85
+ stop = writer.subscribe(releaseIfClean);
86
+ }
87
+ catch (error) {
88
+ writer.destroy();
89
+ throw error;
90
+ }
91
+ return {
92
+ session,
93
+ write,
94
+ detach() {
95
+ if (detached)
96
+ return;
97
+ detached = true;
98
+ writer.destroy();
99
+ // A failed detached save remains discoverable, with the writer's error retained.
100
+ void session.flush().catch(() => undefined);
101
+ },
102
+ };
103
+ }
@@ -22,6 +22,7 @@
22
22
 
23
23
  type Props = {
24
24
  value: string;
25
+ readonly?: boolean;
25
26
  extensions?: MiraExtension[];
26
27
  sourcePath?: string;
27
28
  linkResolver?: MiraLinkResolver;
@@ -40,6 +41,7 @@
40
41
 
41
42
  let {
42
43
  value,
44
+ readonly = false,
43
45
  extensions = [],
44
46
  sourcePath,
45
47
  linkResolver,
@@ -63,13 +65,14 @@
63
65
  const resolvedExtensions = $derived(
64
66
  resolveMiraExtensions(extensions, {
65
67
  mode: "live-preview",
66
- readonly: false,
68
+ readonly,
67
69
  sourcePath,
68
70
  }),
69
71
  );
70
72
  const extensionSignature = $derived(
71
73
  [
72
74
  sourcePath,
75
+ readonly,
73
76
  frontmatterOpen,
74
77
  JSON.stringify({ authoring, frontmatterConfig, imageConfig }),
75
78
  extensions.map((extension) => extension.name).join(","),
@@ -85,15 +88,17 @@
85
88
  return {
86
89
  view,
87
90
  mode: "live-preview",
88
- readonly: false,
91
+ readonly,
89
92
  sourcePath,
90
93
  getValue: () => activeEditor?.getValue() ?? value,
91
94
  setValue(nextValue) {
95
+ if (readonly) return;
92
96
  activeEditor?.setValue(nextValue);
93
97
  onChange?.(nextValue);
94
98
  },
95
99
  focus: () => activeEditor?.focus(),
96
100
  insertMarkdown(markdown, selection) {
101
+ if (readonly) return;
97
102
  activeEditor?.replaceSelection(markdown, selection);
98
103
  activeEditor?.focus();
99
104
  },
@@ -104,7 +109,7 @@
104
109
  return createMiraCodeMirrorExtensions({
105
110
  includeBaseExtensions: false,
106
111
  mode: "live-preview",
107
- readonly: false,
112
+ readonly,
108
113
  lineWrapping: true,
109
114
  spellcheck: true,
110
115
  blockControls: false,
@@ -122,6 +127,7 @@
122
127
  frontmatterConfig,
123
128
  runtimeContext: (view) => runtimeContext(codeEditor, view),
124
129
  onChange(replacement, from, to) {
130
+ if (readonly) return;
125
131
  codeEditor?.getView()?.dispatch({
126
132
  changes: { from, to, insert: replacement },
127
133
  });
@@ -212,6 +218,7 @@
212
218
  <MiraCodeEditor
213
219
  bind:this={codeEditor}
214
220
  {value}
221
+ {readonly}
215
222
  extensions={codeMirrorExtensions}
216
223
  lineWrapping={true}
217
224
  spellcheck={true}
@@ -223,6 +230,8 @@
223
230
  height="fill"
224
231
  minHeight="100%"
225
232
  class="mira-editable-markdown-preview__editor-host"
226
- onChange={(nextValue) => onChange?.(nextValue)}
233
+ onChange={(nextValue) => {
234
+ if (!readonly) onChange?.(nextValue);
235
+ }}
227
236
  />
228
237
  </div>
@@ -1,6 +1,7 @@
1
1
  import { type MiraAssetResolver, type MiraExtension, type MiraFileAdapter, type MiraImageConfig, type MiraLinkResolver, type MiraMarkdownAuthoringConfig } from "@lapismd/mira/extensions";
2
2
  type Props = {
3
3
  value: string;
4
+ readonly?: boolean;
4
5
  extensions?: MiraExtension[];
5
6
  sourcePath?: string;
6
7
  linkResolver?: MiraLinkResolver;
@@ -1 +1 @@
1
- {"version":3,"file":"editor-surface.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/editor-surface.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EACjC,MAAM,0BAA0B,CAAC;AAKlC,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AAsLJ,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"editor-surface.svelte.d.ts","sourceRoot":"","sources":["../../../src/preview/editable-markdown-preview/editor-surface.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,EAGH,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EACjC,MAAM,0BAA0B,CAAC;AAKlC,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB,CAAC;AA6LJ,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}