@latentic/live-markdown 0.3.1 → 0.4.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 (341) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +2 -2
  3. package/dist/chunk-V6TY7KAL.js +8 -0
  4. package/dist/chunk-V6TY7KAL.js.map +1 -0
  5. package/dist/codemirror/CodeMirrorMarkdownEditor.d.ts +106 -0
  6. package/dist/codemirror/CodeMirrorMarkdownEditor.js +482 -0
  7. package/dist/codemirror/CodeMirrorMarkdownEditor.js.map +1 -0
  8. package/dist/codemirror/byteOffset.d.ts +17 -0
  9. package/dist/codemirror/byteOffset.js +19 -0
  10. package/dist/codemirror/byteOffset.js.map +1 -0
  11. package/dist/codemirror/caretLayer.d.ts +19 -0
  12. package/dist/codemirror/caretLayer.js +44 -0
  13. package/dist/codemirror/caretLayer.js.map +1 -0
  14. package/dist/codemirror/clipboard/copyRich.d.ts +37 -0
  15. package/dist/codemirror/clipboard/copyRich.js +72 -0
  16. package/dist/codemirror/clipboard/copyRich.js.map +1 -0
  17. package/dist/codemirror/clipboard/htmlToMarkdown.d.ts +20 -0
  18. package/dist/codemirror/clipboard/htmlToMarkdown.js +91 -0
  19. package/dist/codemirror/clipboard/htmlToMarkdown.js.map +1 -0
  20. package/dist/codemirror/clipboard/pasteMarkdown.d.ts +18 -0
  21. package/dist/codemirror/clipboard/pasteMarkdown.js +41 -0
  22. package/dist/codemirror/clipboard/pasteMarkdown.js.map +1 -0
  23. package/dist/codemirror/code/codeHighlight.d.ts +13 -0
  24. package/dist/codemirror/code/codeHighlight.js +15 -0
  25. package/dist/codemirror/code/codeHighlight.js.map +1 -0
  26. package/dist/codemirror/code/codeLangAffordance.d.ts +17 -0
  27. package/dist/codemirror/code/codeLangAffordance.js +80 -0
  28. package/dist/codemirror/code/codeLangAffordance.js.map +1 -0
  29. package/dist/codemirror/code/codeLanguageMenu.d.ts +40 -0
  30. package/dist/codemirror/code/codeLanguageMenu.js +184 -0
  31. package/dist/codemirror/code/codeLanguageMenu.js.map +1 -0
  32. package/dist/codemirror/code/codePalette.d.ts +39 -0
  33. package/dist/codemirror/code/codePalette.js +53 -0
  34. package/dist/codemirror/code/codePalette.js.map +1 -0
  35. package/dist/codemirror/code/fenceAutoClose.d.ts +30 -0
  36. package/dist/codemirror/code/fenceAutoClose.js +171 -0
  37. package/dist/codemirror/code/fenceAutoClose.js.map +1 -0
  38. package/dist/codemirror/code/fenceCaretGuard.d.ts +28 -0
  39. package/dist/codemirror/code/fenceCaretGuard.js +66 -0
  40. package/dist/codemirror/code/fenceCaretGuard.js.map +1 -0
  41. package/dist/codemirror/code/fenceDeleteGuards.d.ts +22 -0
  42. package/dist/codemirror/code/fenceDeleteGuards.js +105 -0
  43. package/dist/codemirror/code/fenceDeleteGuards.js.map +1 -0
  44. package/dist/codemirror/code/fenceTabIndent.d.ts +8 -0
  45. package/dist/codemirror/code/fenceTabIndent.js +50 -0
  46. package/dist/codemirror/code/fenceTabIndent.js.map +1 -0
  47. package/dist/codemirror/code/highlightFence.d.ts +25 -0
  48. package/dist/codemirror/code/highlightFence.js +45 -0
  49. package/dist/codemirror/code/highlightFence.js.map +1 -0
  50. package/dist/codemirror/code/index.d.ts +9 -0
  51. package/dist/codemirror/code/index.js +8 -0
  52. package/dist/codemirror/code/index.js.map +1 -0
  53. package/dist/codemirror/core/codeContext.d.ts +32 -0
  54. package/dist/codemirror/core/codeContext.js +22 -0
  55. package/dist/codemirror/core/codeContext.js.map +1 -0
  56. package/dist/codemirror/core/editorTestHarness.d.ts +31 -0
  57. package/dist/codemirror/core/editorTestHarness.js +69 -0
  58. package/dist/codemirror/core/editorTestHarness.js.map +1 -0
  59. package/dist/codemirror/core/editorTheme.d.ts +39 -0
  60. package/dist/codemirror/core/editorTheme.js +498 -0
  61. package/dist/codemirror/core/editorTheme.js.map +1 -0
  62. package/dist/codemirror/core/hostFacets.d.ts +58 -0
  63. package/dist/codemirror/core/hostFacets.js +27 -0
  64. package/dist/codemirror/core/hostFacets.js.map +1 -0
  65. package/dist/codemirror/core/hrWidget.d.ts +22 -0
  66. package/dist/codemirror/core/hrWidget.js +22 -0
  67. package/dist/codemirror/core/hrWidget.js.map +1 -0
  68. package/dist/codemirror/core/htmlEscape.d.ts +6 -0
  69. package/dist/codemirror/core/htmlEscape.js +12 -0
  70. package/dist/codemirror/core/htmlEscape.js.map +1 -0
  71. package/dist/codemirror/core/index.d.ts +13 -0
  72. package/dist/codemirror/core/index.js +9 -0
  73. package/dist/codemirror/core/index.js.map +1 -0
  74. package/dist/codemirror/core/inlineScan.d.ts +49 -0
  75. package/dist/codemirror/core/inlineScan.js +31 -0
  76. package/dist/codemirror/core/inlineScan.js.map +1 -0
  77. package/dist/codemirror/core/lineStructure.d.ts +47 -0
  78. package/dist/codemirror/core/lineStructure.js +64 -0
  79. package/dist/codemirror/core/lineStructure.js.map +1 -0
  80. package/dist/codemirror/core/linkResolution.d.ts +36 -0
  81. package/dist/codemirror/core/linkResolution.js +58 -0
  82. package/dist/codemirror/core/linkResolution.js.map +1 -0
  83. package/dist/codemirror/core/paint.d.ts +118 -0
  84. package/dist/codemirror/core/paint.js +42 -0
  85. package/dist/codemirror/core/paint.js.map +1 -0
  86. package/dist/codemirror/core/parseToEnd.d.ts +24 -0
  87. package/dist/codemirror/core/parseToEnd.js +38 -0
  88. package/dist/codemirror/core/parseToEnd.js.map +1 -0
  89. package/dist/codemirror/core/plugin.d.ts +32 -0
  90. package/dist/codemirror/core/plugin.js +161 -0
  91. package/dist/codemirror/core/plugin.js.map +1 -0
  92. package/dist/codemirror/core/registry.d.ts +38 -0
  93. package/dist/codemirror/core/registry.js +133 -0
  94. package/dist/codemirror/core/registry.js.map +1 -0
  95. package/dist/codemirror/core/testKeys.d.ts +17 -0
  96. package/dist/codemirror/core/testKeys.js +11 -0
  97. package/dist/codemirror/core/testKeys.js.map +1 -0
  98. package/dist/codemirror/core/treeAt.d.ts +31 -0
  99. package/dist/codemirror/core/treeAt.js +10 -0
  100. package/dist/codemirror/core/treeAt.js.map +1 -0
  101. package/dist/codemirror/extensions/footnoteExtension.d.ts +9 -0
  102. package/dist/codemirror/extensions/footnoteExtension.js +14 -0
  103. package/dist/codemirror/extensions/footnoteExtension.js.map +1 -0
  104. package/dist/codemirror/extensions/highlightExtension.d.ts +9 -0
  105. package/dist/codemirror/extensions/highlightExtension.js +14 -0
  106. package/dist/codemirror/extensions/highlightExtension.js.map +1 -0
  107. package/dist/codemirror/extensions/index.d.ts +12 -0
  108. package/dist/codemirror/extensions/index.js +19 -0
  109. package/dist/codemirror/extensions/index.js.map +1 -0
  110. package/dist/codemirror/extensions/loader.d.ts +24 -0
  111. package/dist/codemirror/extensions/loader.js +33 -0
  112. package/dist/codemirror/extensions/loader.js.map +1 -0
  113. package/dist/codemirror/extensions/mathExtension.d.ts +9 -0
  114. package/dist/codemirror/extensions/mathExtension.js +14 -0
  115. package/dist/codemirror/extensions/mathExtension.js.map +1 -0
  116. package/dist/codemirror/extensions/mermaidExtension.d.ts +9 -0
  117. package/dist/codemirror/extensions/mermaidExtension.js +12 -0
  118. package/dist/codemirror/extensions/mermaidExtension.js.map +1 -0
  119. package/dist/codemirror/extensions/tableExtension.d.ts +13 -0
  120. package/dist/codemirror/extensions/tableExtension.js +39 -0
  121. package/dist/codemirror/extensions/tableExtension.js.map +1 -0
  122. package/dist/codemirror/extensions/types.d.ts +39 -0
  123. package/dist/codemirror/extensions/types.js +1 -0
  124. package/dist/codemirror/extensions/types.js.map +1 -0
  125. package/dist/codemirror/extensions/wikilinkExtension.d.ts +9 -0
  126. package/dist/codemirror/extensions/wikilinkExtension.js +14 -0
  127. package/dist/codemirror/extensions/wikilinkExtension.js.map +1 -0
  128. package/dist/codemirror/features/blockCommandSteps.d.ts +20 -0
  129. package/dist/codemirror/features/blockCommandSteps.js +83 -0
  130. package/dist/codemirror/features/blockCommandSteps.js.map +1 -0
  131. package/dist/codemirror/footnote/footnotePlugin.d.ts +10 -0
  132. package/dist/codemirror/footnote/footnotePlugin.js +78 -0
  133. package/dist/codemirror/footnote/footnotePlugin.js.map +1 -0
  134. package/dist/codemirror/footnote/footnoteScanRule.d.ts +9 -0
  135. package/dist/codemirror/footnote/footnoteScanRule.js +12 -0
  136. package/dist/codemirror/footnote/footnoteScanRule.js.map +1 -0
  137. package/dist/codemirror/footnote/index.d.ts +2 -0
  138. package/dist/codemirror/footnote/index.js +2 -0
  139. package/dist/codemirror/footnote/index.js.map +1 -0
  140. package/dist/codemirror/format/blockCommands.d.ts +17 -0
  141. package/dist/codemirror/format/blockCommands.js +176 -0
  142. package/dist/codemirror/format/blockCommands.js.map +1 -0
  143. package/dist/codemirror/format/formatCommands.d.ts +11 -0
  144. package/dist/codemirror/format/formatCommands.js +132 -0
  145. package/dist/codemirror/format/formatCommands.js.map +1 -0
  146. package/dist/codemirror/format/index.d.ts +4 -0
  147. package/dist/codemirror/format/index.js +3 -0
  148. package/dist/codemirror/format/index.js.map +1 -0
  149. package/dist/codemirror/highlight/highlightPlugin.d.ts +10 -0
  150. package/dist/codemirror/highlight/highlightPlugin.js +66 -0
  151. package/dist/codemirror/highlight/highlightPlugin.js.map +1 -0
  152. package/dist/codemirror/highlight/highlightScanRule.d.ts +8 -0
  153. package/dist/codemirror/highlight/highlightScanRule.js +12 -0
  154. package/dist/codemirror/highlight/highlightScanRule.js.map +1 -0
  155. package/dist/codemirror/highlight/index.d.ts +2 -0
  156. package/dist/codemirror/highlight/index.js +2 -0
  157. package/dist/codemirror/highlight/index.js.map +1 -0
  158. package/dist/codemirror/html/htmlWidget.d.ts +23 -0
  159. package/dist/codemirror/html/htmlWidget.js +67 -0
  160. package/dist/codemirror/html/htmlWidget.js.map +1 -0
  161. package/dist/codemirror/html/index.d.ts +4 -0
  162. package/dist/codemirror/html/index.js +2 -0
  163. package/dist/codemirror/html/index.js.map +1 -0
  164. package/dist/codemirror/image/imageActionMenu.d.ts +14 -0
  165. package/dist/codemirror/image/imageActionMenu.js +112 -0
  166. package/dist/codemirror/image/imageActionMenu.js.map +1 -0
  167. package/dist/codemirror/image/imageEditEvent.d.ts +20 -0
  168. package/dist/codemirror/image/imageEditEvent.js +6 -0
  169. package/dist/codemirror/image/imageEditEvent.js.map +1 -0
  170. package/dist/codemirror/image/imageInsertHandlers.d.ts +13 -0
  171. package/dist/codemirror/image/imageInsertHandlers.js +64 -0
  172. package/dist/codemirror/image/imageInsertHandlers.js.map +1 -0
  173. package/dist/codemirror/image/imageWidget.d.ts +49 -0
  174. package/dist/codemirror/image/imageWidget.js +83 -0
  175. package/dist/codemirror/image/imageWidget.js.map +1 -0
  176. package/dist/codemirror/image/index.d.ts +8 -0
  177. package/dist/codemirror/image/index.js +5 -0
  178. package/dist/codemirror/image/index.js.map +1 -0
  179. package/dist/codemirror/interaction/clickModel.d.ts +43 -0
  180. package/dist/codemirror/interaction/clickModel.js +99 -0
  181. package/dist/codemirror/interaction/clickModel.js.map +1 -0
  182. package/dist/codemirror/interaction/cursorModel.d.ts +10 -0
  183. package/dist/codemirror/interaction/cursorModel.js +58 -0
  184. package/dist/codemirror/interaction/cursorModel.js.map +1 -0
  185. package/dist/codemirror/interaction/deleteNormalizer.d.ts +18 -0
  186. package/dist/codemirror/interaction/deleteNormalizer.js +157 -0
  187. package/dist/codemirror/interaction/deleteNormalizer.js.map +1 -0
  188. package/dist/codemirror/interaction/flankingGuard.d.ts +20 -0
  189. package/dist/codemirror/interaction/flankingGuard.js +48 -0
  190. package/dist/codemirror/interaction/flankingGuard.js.map +1 -0
  191. package/dist/codemirror/interaction/index.d.ts +7 -0
  192. package/dist/codemirror/interaction/index.js +6 -0
  193. package/dist/codemirror/interaction/index.js.map +1 -0
  194. package/dist/codemirror/interaction/visiblePosition.d.ts +43 -0
  195. package/dist/codemirror/interaction/visiblePosition.js +98 -0
  196. package/dist/codemirror/interaction/visiblePosition.js.map +1 -0
  197. package/dist/codemirror/list/bulletWidget.d.ts +61 -0
  198. package/dist/codemirror/list/bulletWidget.js +84 -0
  199. package/dist/codemirror/list/bulletWidget.js.map +1 -0
  200. package/dist/codemirror/list/index.d.ts +4 -0
  201. package/dist/codemirror/list/index.js +3 -0
  202. package/dist/codemirror/list/index.js.map +1 -0
  203. package/dist/codemirror/list/listContinuation.d.ts +28 -0
  204. package/dist/codemirror/list/listContinuation.js +61 -0
  205. package/dist/codemirror/list/listContinuation.js.map +1 -0
  206. package/dist/codemirror/list/listIndent.d.ts +8 -0
  207. package/dist/codemirror/list/listIndent.js +95 -0
  208. package/dist/codemirror/list/listIndent.js.map +1 -0
  209. package/dist/codemirror/list/taskCheckboxWidget.d.ts +42 -0
  210. package/dist/codemirror/list/taskCheckboxWidget.js +47 -0
  211. package/dist/codemirror/list/taskCheckboxWidget.js.map +1 -0
  212. package/dist/codemirror/math/index.d.ts +3 -0
  213. package/dist/codemirror/math/index.js +2 -0
  214. package/dist/codemirror/math/index.js.map +1 -0
  215. package/dist/codemirror/math/mathPlugin.d.ts +10 -0
  216. package/dist/codemirror/math/mathPlugin.js +73 -0
  217. package/dist/codemirror/math/mathPlugin.js.map +1 -0
  218. package/dist/codemirror/math/mathScanRule.d.ts +16 -0
  219. package/dist/codemirror/math/mathScanRule.js +18 -0
  220. package/dist/codemirror/math/mathScanRule.js.map +1 -0
  221. package/dist/codemirror/math/mathWidget.d.ts +15 -0
  222. package/dist/codemirror/math/mathWidget.js +36 -0
  223. package/dist/codemirror/math/mathWidget.js.map +1 -0
  224. package/dist/codemirror/mermaid/index.d.ts +4 -0
  225. package/dist/codemirror/mermaid/index.js +3 -0
  226. package/dist/codemirror/mermaid/index.js.map +1 -0
  227. package/dist/codemirror/mermaid/mermaidPlugin.d.ts +25 -0
  228. package/dist/codemirror/mermaid/mermaidPlugin.js +78 -0
  229. package/dist/codemirror/mermaid/mermaidPlugin.js.map +1 -0
  230. package/dist/codemirror/mermaid/mermaidRender.d.ts +42 -0
  231. package/dist/codemirror/mermaid/mermaidRender.js +136 -0
  232. package/dist/codemirror/mermaid/mermaidRender.js.map +1 -0
  233. package/dist/codemirror/mermaid/mermaidWidget.d.ts +42 -0
  234. package/dist/codemirror/mermaid/mermaidWidget.js +142 -0
  235. package/dist/codemirror/mermaid/mermaidWidget.js.map +1 -0
  236. package/dist/codemirror/selectionLayer.d.ts +43 -0
  237. package/dist/codemirror/selectionLayer.js +135 -0
  238. package/dist/codemirror/selectionLayer.js.map +1 -0
  239. package/dist/codemirror/table/cellDividerWidget.d.ts +9 -0
  240. package/dist/codemirror/table/cellDividerWidget.js +19 -0
  241. package/dist/codemirror/table/cellDividerWidget.js.map +1 -0
  242. package/dist/codemirror/table/index.d.ts +5 -0
  243. package/dist/codemirror/table/index.js +4 -0
  244. package/dist/codemirror/table/index.js.map +1 -0
  245. package/dist/codemirror/table/tableArmed.d.ts +27 -0
  246. package/dist/codemirror/table/tableArmed.js +43 -0
  247. package/dist/codemirror/table/tableArmed.js.map +1 -0
  248. package/dist/codemirror/table/tableCell.d.ts +19 -0
  249. package/dist/codemirror/table/tableCell.js +15 -0
  250. package/dist/codemirror/table/tableCell.js.map +1 -0
  251. package/dist/codemirror/table/tableCellNav.d.ts +51 -0
  252. package/dist/codemirror/table/tableCellNav.js +47 -0
  253. package/dist/codemirror/table/tableCellNav.js.map +1 -0
  254. package/dist/codemirror/table/tableContextMenu.d.ts +22 -0
  255. package/dist/codemirror/table/tableContextMenu.js +139 -0
  256. package/dist/codemirror/table/tableContextMenu.js.map +1 -0
  257. package/dist/codemirror/table/tableEditCommands.d.ts +29 -0
  258. package/dist/codemirror/table/tableEditCommands.js +86 -0
  259. package/dist/codemirror/table/tableEditCommands.js.map +1 -0
  260. package/dist/codemirror/table/tableExcerpt.d.ts +29 -0
  261. package/dist/codemirror/table/tableExcerpt.js +34 -0
  262. package/dist/codemirror/table/tableExcerpt.js.map +1 -0
  263. package/dist/codemirror/table/tableField.d.ts +6 -0
  264. package/dist/codemirror/table/tableField.js +37 -0
  265. package/dist/codemirror/table/tableField.js.map +1 -0
  266. package/dist/codemirror/table/tableGeometry.d.ts +33 -0
  267. package/dist/codemirror/table/tableGeometry.js +28 -0
  268. package/dist/codemirror/table/tableGeometry.js.map +1 -0
  269. package/dist/codemirror/table/tableInline.d.ts +37 -0
  270. package/dist/codemirror/table/tableInline.js +105 -0
  271. package/dist/codemirror/table/tableInline.js.map +1 -0
  272. package/dist/codemirror/table/tableModel.d.ts +45 -0
  273. package/dist/codemirror/table/tableModel.js +98 -0
  274. package/dist/codemirror/table/tableModel.js.map +1 -0
  275. package/dist/codemirror/tablev2/bridgeRules.d.ts +48 -0
  276. package/dist/codemirror/tablev2/bridgeRules.js +42 -0
  277. package/dist/codemirror/tablev2/bridgeRules.js.map +1 -0
  278. package/dist/codemirror/tablev2/cellEditingSurface.d.ts +79 -0
  279. package/dist/codemirror/tablev2/cellEditingSurface.js +70 -0
  280. package/dist/codemirror/tablev2/cellEditingSurface.js.map +1 -0
  281. package/dist/codemirror/tablev2/cellText.d.ts +11 -0
  282. package/dist/codemirror/tablev2/cellText.js +12 -0
  283. package/dist/codemirror/tablev2/cellText.js.map +1 -0
  284. package/dist/codemirror/tablev2/inlineCellSurface.d.ts +38 -0
  285. package/dist/codemirror/tablev2/inlineCellSurface.js +162 -0
  286. package/dist/codemirror/tablev2/inlineCellSurface.js.map +1 -0
  287. package/dist/codemirror/tablev2/overlayCellSurface.d.ts +36 -0
  288. package/dist/codemirror/tablev2/overlayCellSurface.js +150 -0
  289. package/dist/codemirror/tablev2/overlayCellSurface.js.map +1 -0
  290. package/dist/codemirror/tablev2/tableEditingSteps.d.ts +12 -0
  291. package/dist/codemirror/tablev2/tableEditingSteps.js +518 -0
  292. package/dist/codemirror/tablev2/tableEditingSteps.js.map +1 -0
  293. package/dist/codemirror/tablev2/tableV2HoverControls.d.ts +23 -0
  294. package/dist/codemirror/tablev2/tableV2HoverControls.js +89 -0
  295. package/dist/codemirror/tablev2/tableV2HoverControls.js.map +1 -0
  296. package/dist/codemirror/tablev2/tableV2Interaction.d.ts +29 -0
  297. package/dist/codemirror/tablev2/tableV2Interaction.js +224 -0
  298. package/dist/codemirror/tablev2/tableV2Interaction.js.map +1 -0
  299. package/dist/codemirror/tablev2/tableV2Selection.d.ts +45 -0
  300. package/dist/codemirror/tablev2/tableV2Selection.js +81 -0
  301. package/dist/codemirror/tablev2/tableV2Selection.js.map +1 -0
  302. package/dist/codemirror/tablev2/tableV2Sync.d.ts +13 -0
  303. package/dist/codemirror/tablev2/tableV2Sync.js +13 -0
  304. package/dist/codemirror/tablev2/tableV2Sync.js.map +1 -0
  305. package/dist/codemirror/tablev2/tableWidgetV2.d.ts +46 -0
  306. package/dist/codemirror/tablev2/tableWidgetV2.js +139 -0
  307. package/dist/codemirror/tablev2/tableWidgetV2.js.map +1 -0
  308. package/dist/codemirror/updateBus.d.ts +29 -0
  309. package/dist/codemirror/updateBus.js +26 -0
  310. package/dist/codemirror/updateBus.js.map +1 -0
  311. package/dist/codemirror/wikilink/index.d.ts +3 -0
  312. package/dist/codemirror/wikilink/index.js +2 -0
  313. package/dist/codemirror/wikilink/index.js.map +1 -0
  314. package/dist/codemirror/wikilink/wikilinkPlugin.d.ts +40 -0
  315. package/dist/codemirror/wikilink/wikilinkPlugin.js +89 -0
  316. package/dist/codemirror/wikilink/wikilinkPlugin.js.map +1 -0
  317. package/dist/codemirror/wikilink/wikilinkScanRule.d.ts +9 -0
  318. package/dist/codemirror/wikilink/wikilinkScanRule.js +13 -0
  319. package/dist/codemirror/wikilink/wikilinkScanRule.js.map +1 -0
  320. package/dist/frontmatter.d.ts +79 -0
  321. package/dist/frontmatter.js +58 -0
  322. package/dist/frontmatter.js.map +1 -0
  323. package/dist/imageInsert.d.ts +66 -0
  324. package/dist/imageInsert.js +111 -0
  325. package/dist/imageInsert.js.map +1 -0
  326. package/dist/imageSrcResolver.d.ts +55 -0
  327. package/dist/imageSrcResolver.js +49 -0
  328. package/dist/imageSrcResolver.js.map +1 -0
  329. package/dist/index.d.ts +35 -880
  330. package/dist/index.js +128 -5996
  331. package/dist/index.js.map +1 -1
  332. package/dist/links/wikilink.d.ts +26 -0
  333. package/dist/links/wikilink.js +54 -0
  334. package/dist/links/wikilink.js.map +1 -0
  335. package/dist/links/workspaceLink.d.ts +34 -0
  336. package/dist/links/workspaceLink.js +60 -0
  337. package/dist/links/workspaceLink.js.map +1 -0
  338. package/dist/types.d.ts +20 -0
  339. package/dist/types.js +1 -0
  340. package/dist/types.js.map +1 -0
  341. package/package.json +7 -3
@@ -0,0 +1,8 @@
1
+ import { InlineScanRule } from '../core/inlineScan.js';
2
+ import '@codemirror/state';
3
+
4
+ /** `==marked==` for the string renderers. */
5
+
6
+ declare const highlightScanRule: InlineScanRule;
7
+
8
+ export { highlightScanRule };
@@ -0,0 +1,12 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import { escapeText } from "../core/htmlEscape.js";
3
+ import { HIGHLIGHT_RE } from "./highlightPlugin.js";
4
+ const highlightScanRule = {
5
+ name: "highlight",
6
+ pattern: HIGHLIGHT_RE,
7
+ render: (match) => `<span class="cm-highlight">${escapeText(match[1] ?? "")}</span>`
8
+ };
9
+ export {
10
+ highlightScanRule
11
+ };
12
+ //# sourceMappingURL=highlightScanRule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/highlight/highlightScanRule.ts"],"sourcesContent":["/** `==marked==` for the string renderers. */\n\nimport { escapeText } from \"../core/htmlEscape\";\nimport { type InlineScanRule } from \"../core/inlineScan\";\nimport { HIGHLIGHT_RE } from \"./highlightPlugin\";\n\nexport const highlightScanRule: InlineScanRule = {\n name: \"highlight\",\n pattern: HIGHLIGHT_RE,\n render: (match) => `<span class=\"cm-highlight\">${escapeText(match[1] ?? \"\")}</span>`,\n};\n"],"mappings":";AAEA,SAAS,kBAAkB;AAE3B,SAAS,oBAAoB;AAEtB,MAAM,oBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ,CAAC,UAAU,8BAA8B,WAAW,MAAM,CAAC,KAAK,EAAE,CAAC;AAC7E;","names":[]}
@@ -0,0 +1,2 @@
1
+ export { HIGHLIGHT_RE, highlightPlugin } from './highlightPlugin.js';
2
+ import '@codemirror/view';
@@ -0,0 +1,2 @@
1
+ export * from "./highlightPlugin.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/highlight/index.ts"],"sourcesContent":["/** Highlight marks: `==text==` rendered as a highlighted span. */\nexport * from \"./highlightPlugin\";\n"],"mappings":"AACA,cAAc;","names":[]}
@@ -0,0 +1,23 @@
1
+ import { NodeRule } from '../core/paint.js';
2
+ import { WidgetType, EditorView } from '@codemirror/view';
3
+ import '@codemirror/state';
4
+
5
+ declare function htmlRendersVisibly(html: string): boolean;
6
+ declare class HtmlWidget extends WidgetType {
7
+ readonly html: string;
8
+ readonly isBlock: boolean;
9
+ constructor(html: string, isBlock: boolean);
10
+ eq(other: HtmlWidget): boolean;
11
+ toDOM(_view: EditorView): HTMLElement;
12
+ ignoreEvent(): boolean;
13
+ }
14
+ /** An inline `<tag>` → rendered HTML; a tag that sanitizes to nothing visible
15
+ * (`<yourname>`, `</b>`, `<script>`) stays raw text — never an invisible
16
+ * hole where the user's typing vanished. */
17
+ declare const htmlInlineRule: NodeRule;
18
+ /** A single-line HTML block → rendered HTML. Multi-line blocks stay raw
19
+ * source: they fail CM6's "no plugin-level multi-line replace" rule, until a
20
+ * StateField carries them (Phase 5). Same invisible-hole guard as inline. */
21
+ declare const htmlBlockRule: NodeRule;
22
+
23
+ export { HtmlWidget, htmlBlockRule, htmlInlineRule, htmlRendersVisibly };
@@ -0,0 +1,67 @@
1
+ import {
2
+ __publicField
3
+ } from "../../chunk-V6TY7KAL.js";
4
+ import DOMPurify from "dompurify";
5
+ import { none } from "../core/paint.js";
6
+ import { Decoration, WidgetType } from "@codemirror/view";
7
+ const SANITIZE_CONFIG = {
8
+ FORBID_TAGS: ["script", "style", "iframe", "object", "embed", "form", "input", "button"],
9
+ FORBID_ATTR: ["on*"],
10
+ ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel|data:image\/(?:png|jpeg|gif|webp|svg\+xml)):)/i,
11
+ RETURN_TRUSTED_TYPE: false
12
+ };
13
+ const visibilityVerdicts = /* @__PURE__ */ new Map();
14
+ const VERDICT_CACHE_MAX = 500;
15
+ function htmlRendersVisibly(html) {
16
+ if (typeof document === "undefined") return false;
17
+ const cached = visibilityVerdicts.get(html);
18
+ if (cached !== void 0) return cached;
19
+ const probe = document.createElement("template");
20
+ probe.innerHTML = DOMPurify.sanitize(html, SANITIZE_CONFIG);
21
+ const content = probe.content;
22
+ const visible = (content.textContent ?? "").trim() !== "" || content.querySelector("img, br, hr") !== null;
23
+ if (visibilityVerdicts.size >= VERDICT_CACHE_MAX) {
24
+ const oldest = visibilityVerdicts.keys().next().value;
25
+ if (oldest !== void 0) visibilityVerdicts.delete(oldest);
26
+ }
27
+ visibilityVerdicts.set(html, visible);
28
+ return visible;
29
+ }
30
+ class HtmlWidget extends WidgetType {
31
+ constructor(html, isBlock) {
32
+ super();
33
+ __publicField(this, "html", html);
34
+ __publicField(this, "isBlock", isBlock);
35
+ }
36
+ eq(other) {
37
+ return other.html === this.html && other.isBlock === this.isBlock;
38
+ }
39
+ toDOM(_view) {
40
+ const container = document.createElement(this.isBlock ? "div" : "span");
41
+ container.className = this.isBlock ? "cm-html-block" : "cm-html-inline";
42
+ container.innerHTML = DOMPurify.sanitize(this.html, SANITIZE_CONFIG);
43
+ return container;
44
+ }
45
+ ignoreEvent() {
46
+ return false;
47
+ }
48
+ }
49
+ const htmlInlineRule = (ctx) => {
50
+ const html = ctx.state.sliceDoc(ctx.from, ctx.to);
51
+ if (!htmlRendersVisibly(html)) return none;
52
+ return { paint: "widget", deco: Decoration.replace({ widget: new HtmlWidget(html, false) }) };
53
+ };
54
+ const htmlBlockRule = (ctx) => {
55
+ const doc = ctx.state.doc;
56
+ if (doc.lineAt(ctx.from).number !== doc.lineAt(ctx.to).number) return none;
57
+ const html = ctx.state.sliceDoc(ctx.from, ctx.to);
58
+ if (!htmlRendersVisibly(html)) return none;
59
+ return { paint: "widget", deco: Decoration.replace({ widget: new HtmlWidget(html, true) }) };
60
+ };
61
+ export {
62
+ HtmlWidget,
63
+ htmlBlockRule,
64
+ htmlInlineRule,
65
+ htmlRendersVisibly
66
+ };
67
+ //# sourceMappingURL=htmlWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/html/htmlWidget.ts"],"sourcesContent":["import DOMPurify from \"dompurify\";\n\nimport { type NodeRule, type Paint, none } from \"../core/paint\";\nimport { Decoration, EditorView, WidgetType } from \"@codemirror/view\";\n\nconst SANITIZE_CONFIG = {\n FORBID_TAGS: [\"script\", \"style\", \"iframe\", \"object\", \"embed\", \"form\", \"input\", \"button\"] as string[],\n FORBID_ATTR: [\"on*\"] as string[],\n ALLOWED_URI_REGEXP:\n /^(?:(?:https?|mailto|tel|data:image\\/(?:png|jpeg|gif|webp|svg\\+xml)):)/i,\n RETURN_TRUSTED_TYPE: false,\n};\n\n/**\n * Would this HTML draw anything the user can SEE once sanitized? A stripped\n * or unknown tag (`<yourname>`, `</b>`, `<script>…`) sanitizes to nothing —\n * replacing such a span with a widget renders the user's text invisibly, the\n * same dead-zone class as the hidden bare-URL bug. Callers keep the raw\n * source visible instead of widget-replacing when this is false.\n *\n * Memoized: the rules invoke this per HTML node on every painter rebuild\n * (each keystroke), and the verdict for a given string never changes — the\n * sanitize + template parse must not run repeatedly for unchanged spans.\n */\nconst visibilityVerdicts = new Map<string, boolean>();\nconst VERDICT_CACHE_MAX = 500;\n\nexport function htmlRendersVisibly(html: string): boolean {\n // Without a DOM there is nothing to probe; report invisible so rules leave\n // the raw source in place (never a widget a non-DOM host can't render).\n if (typeof document === \"undefined\") return false;\n const cached = visibilityVerdicts.get(html);\n if (cached !== undefined) return cached;\n const probe = document.createElement(\"template\");\n probe.innerHTML = DOMPurify.sanitize(html, SANITIZE_CONFIG) as unknown as string;\n const content = probe.content;\n const visible =\n (content.textContent ?? \"\").trim() !== \"\" || content.querySelector(\"img, br, hr\") !== null;\n if (visibilityVerdicts.size >= VERDICT_CACHE_MAX) {\n const oldest = visibilityVerdicts.keys().next().value;\n if (oldest !== undefined) visibilityVerdicts.delete(oldest);\n }\n visibilityVerdicts.set(html, visible);\n return visible;\n}\n\nexport class HtmlWidget extends WidgetType {\n constructor(\n readonly html: string,\n readonly isBlock: boolean,\n ) {\n super();\n }\n\n override eq(other: HtmlWidget): boolean {\n return other.html === this.html && other.isBlock === this.isBlock;\n }\n\n override toDOM(_view: EditorView): HTMLElement {\n const container = document.createElement(this.isBlock ? \"div\" : \"span\");\n container.className = this.isBlock ? \"cm-html-block\" : \"cm-html-inline\";\n container.innerHTML = DOMPurify.sanitize(this.html, SANITIZE_CONFIG) as unknown as string;\n return container;\n }\n\n override ignoreEvent(): boolean {\n return false;\n }\n}\n\n/* ---------------- The HTMLTag / HTMLBlock rules ---------------- */\n\n/** An inline `<tag>` → rendered HTML; a tag that sanitizes to nothing visible\n * (`<yourname>`, `</b>`, `<script>`) stays raw text — never an invisible\n * hole where the user's typing vanished. */\nexport const htmlInlineRule: NodeRule = (ctx): Paint => {\n const html = ctx.state.sliceDoc(ctx.from, ctx.to);\n if (!htmlRendersVisibly(html)) return none;\n return { paint: \"widget\", deco: Decoration.replace({ widget: new HtmlWidget(html, false) }) };\n};\n\n/** A single-line HTML block → rendered HTML. Multi-line blocks stay raw\n * source: they fail CM6's \"no plugin-level multi-line replace\" rule, until a\n * StateField carries them (Phase 5). Same invisible-hole guard as inline. */\nexport const htmlBlockRule: NodeRule = (ctx): Paint => {\n const doc = ctx.state.doc;\n if (doc.lineAt(ctx.from).number !== doc.lineAt(ctx.to).number) return none;\n const html = ctx.state.sliceDoc(ctx.from, ctx.to);\n if (!htmlRendersVisibly(html)) return none;\n return { paint: \"widget\", deco: Decoration.replace({ widget: new HtmlWidget(html, true) }) };\n};\n"],"mappings":";;;AAAA,OAAO,eAAe;AAEtB,SAAoC,YAAY;AAChD,SAAS,YAAwB,kBAAkB;AAEnD,MAAM,kBAAkB;AAAA,EACtB,aAAa,CAAC,UAAU,SAAS,UAAU,UAAU,SAAS,QAAQ,SAAS,QAAQ;AAAA,EACvF,aAAa,CAAC,KAAK;AAAA,EACnB,oBACE;AAAA,EACF,qBAAqB;AACvB;AAaA,MAAM,qBAAqB,oBAAI,IAAqB;AACpD,MAAM,oBAAoB;AAEnB,SAAS,mBAAmB,MAAuB;AAGxD,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,SAAS,mBAAmB,IAAI,IAAI;AAC1C,MAAI,WAAW,OAAW,QAAO;AACjC,QAAM,QAAQ,SAAS,cAAc,UAAU;AAC/C,QAAM,YAAY,UAAU,SAAS,MAAM,eAAe;AAC1D,QAAM,UAAU,MAAM;AACtB,QAAM,WACH,QAAQ,eAAe,IAAI,KAAK,MAAM,MAAM,QAAQ,cAAc,aAAa,MAAM;AACxF,MAAI,mBAAmB,QAAQ,mBAAmB;AAChD,UAAM,SAAS,mBAAmB,KAAK,EAAE,KAAK,EAAE;AAChD,QAAI,WAAW,OAAW,oBAAmB,OAAO,MAAM;AAAA,EAC5D;AACA,qBAAmB,IAAI,MAAM,OAAO;AACpC,SAAO;AACT;AAEO,MAAM,mBAAmB,WAAW;AAAA,EACzC,YACW,MACA,SACT;AACA,UAAM;AAHG;AACA;AAAA,EAGX;AAAA,EAES,GAAG,OAA4B;AACtC,WAAO,MAAM,SAAS,KAAK,QAAQ,MAAM,YAAY,KAAK;AAAA,EAC5D;AAAA,EAES,MAAM,OAAgC;AAC7C,UAAM,YAAY,SAAS,cAAc,KAAK,UAAU,QAAQ,MAAM;AACtE,cAAU,YAAY,KAAK,UAAU,kBAAkB;AACvD,cAAU,YAAY,UAAU,SAAS,KAAK,MAAM,eAAe;AACnE,WAAO;AAAA,EACT;AAAA,EAES,cAAuB;AAC9B,WAAO;AAAA,EACT;AACF;AAOO,MAAM,iBAA2B,CAAC,QAAe;AACtD,QAAM,OAAO,IAAI,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE;AAChD,MAAI,CAAC,mBAAmB,IAAI,EAAG,QAAO;AACtC,SAAO,EAAE,OAAO,UAAU,MAAM,WAAW,QAAQ,EAAE,QAAQ,IAAI,WAAW,MAAM,KAAK,EAAE,CAAC,EAAE;AAC9F;AAKO,MAAM,gBAA0B,CAAC,QAAe;AACrD,QAAM,MAAM,IAAI,MAAM;AACtB,MAAI,IAAI,OAAO,IAAI,IAAI,EAAE,WAAW,IAAI,OAAO,IAAI,EAAE,EAAE,OAAQ,QAAO;AACtE,QAAM,OAAO,IAAI,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE;AAChD,MAAI,CAAC,mBAAmB,IAAI,EAAG,QAAO;AACtC,SAAO,EAAE,OAAO,UAAU,MAAM,WAAW,QAAQ,EAAE,QAAQ,IAAI,WAAW,MAAM,IAAI,EAAE,CAAC,EAAE;AAC7F;","names":[]}
@@ -0,0 +1,4 @@
1
+ export { HtmlWidget, htmlBlockRule, htmlInlineRule, htmlRendersVisibly } from './htmlWidget.js';
2
+ import '../core/paint.js';
3
+ import '@codemirror/state';
4
+ import '@codemirror/view';
@@ -0,0 +1,2 @@
1
+ export * from "./htmlWidget.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/html/index.ts"],"sourcesContent":["/**\n * Inline/block HTML in markdown: DOMPurify-sanitized rendering, plus the\n * \"would this sanitize to something visible?\" guard that keeps stripped tags\n * (`<yourname>`, `</b>`) as visible raw text instead of invisible holes.\n */\nexport * from \"./htmlWidget\";\n"],"mappings":"AAKA,cAAc;","names":[]}
@@ -0,0 +1,14 @@
1
+ import { EditorView } from '@codemirror/view';
2
+
3
+ interface ShowMenuArgs {
4
+ x: number;
5
+ y: number;
6
+ view: EditorView;
7
+ alt: string;
8
+ rawSrc: string;
9
+ sourceFrom: number;
10
+ sourceTo: number;
11
+ }
12
+ declare function showImageActionMenu(args: ShowMenuArgs): void;
13
+
14
+ export { showImageActionMenu };
@@ -0,0 +1,112 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import {
3
+ buildImageMarkdown,
4
+ insertImageBlob
5
+ } from "../../imageInsert.js";
6
+ import { saveImageBytesFacet } from "../core/hostFacets.js";
7
+ import { IMAGE_EDIT_ALT_EVENT } from "./imageEditEvent.js";
8
+ function showImageActionMenu(args) {
9
+ const menu = document.createElement("div");
10
+ menu.className = "cm-image-menu";
11
+ menu.setAttribute("role", "menu");
12
+ menu.style.position = "fixed";
13
+ menu.style.left = `${args.x}px`;
14
+ menu.style.top = `${args.y}px`;
15
+ menu.style.zIndex = "1000";
16
+ function destroy() {
17
+ menu.remove();
18
+ document.removeEventListener("mousedown", onOutside, true);
19
+ document.removeEventListener("keydown", onEscape, true);
20
+ }
21
+ function onOutside(e) {
22
+ if (!menu.contains(e.target)) destroy();
23
+ }
24
+ function onEscape(e) {
25
+ if (e.key === "Escape") destroy();
26
+ }
27
+ function makeItem(label, onClick, danger = false) {
28
+ const b = document.createElement("button");
29
+ b.type = "button";
30
+ b.className = danger ? "cm-image-menu__item cm-image-menu__item--danger" : "cm-image-menu__item";
31
+ b.setAttribute("role", "menuitem");
32
+ b.textContent = label;
33
+ b.addEventListener("click", () => {
34
+ onClick();
35
+ destroy();
36
+ });
37
+ return b;
38
+ }
39
+ menu.appendChild(
40
+ makeItem("Edit alt text\u2026", () => {
41
+ const event = new CustomEvent(IMAGE_EDIT_ALT_EVENT, {
42
+ detail: {
43
+ view: args.view,
44
+ sourceFrom: args.sourceFrom,
45
+ sourceTo: args.sourceTo,
46
+ currentAlt: args.alt,
47
+ rawSrc: args.rawSrc
48
+ }
49
+ });
50
+ window.dispatchEvent(event);
51
+ })
52
+ );
53
+ menu.appendChild(
54
+ makeItem("Replace image\u2026", () => {
55
+ const input = document.createElement("input");
56
+ input.type = "file";
57
+ input.accept = "image/*";
58
+ input.onchange = () => {
59
+ const file = input.files?.[0];
60
+ if (!file) return;
61
+ void (async () => {
62
+ try {
63
+ const result = await insertImageBlob({
64
+ blob: file,
65
+ saveBytes: args.view.state.facet(saveImageBytesFacet)
66
+ });
67
+ const newMd = buildImageMarkdown(result);
68
+ args.view.dispatch({
69
+ changes: { from: args.sourceFrom, to: args.sourceTo, insert: newMd },
70
+ userEvent: "input.replace.image"
71
+ });
72
+ } catch (error) {
73
+ console.error("Failed to replace image:", error);
74
+ }
75
+ })();
76
+ };
77
+ input.click();
78
+ })
79
+ );
80
+ menu.appendChild(
81
+ makeItem("Copy markdown source", () => {
82
+ const source = args.view.state.sliceDoc(args.sourceFrom, args.sourceTo);
83
+ void navigator.clipboard.writeText(source);
84
+ })
85
+ );
86
+ menu.appendChild(
87
+ makeItem(
88
+ "Delete image",
89
+ () => {
90
+ args.view.dispatch({
91
+ changes: { from: args.sourceFrom, to: args.sourceTo, insert: "" },
92
+ userEvent: "delete.image"
93
+ });
94
+ },
95
+ true
96
+ )
97
+ );
98
+ document.body.appendChild(menu);
99
+ const rect = menu.getBoundingClientRect();
100
+ const overflowRight = rect.right - window.innerWidth;
101
+ if (overflowRight > 0) menu.style.left = `${args.x - overflowRight - 8}px`;
102
+ const overflowBottom = rect.bottom - window.innerHeight;
103
+ if (overflowBottom > 0) menu.style.top = `${args.y - overflowBottom - 8}px`;
104
+ setTimeout(() => {
105
+ document.addEventListener("mousedown", onOutside, true);
106
+ document.addEventListener("keydown", onEscape, true);
107
+ }, 0);
108
+ }
109
+ export {
110
+ showImageActionMenu
111
+ };
112
+ //# sourceMappingURL=imageActionMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/image/imageActionMenu.ts"],"sourcesContent":["import { EditorView } from \"@codemirror/view\";\n\nimport {\n buildImageMarkdown,\n insertImageBlob,\n} from \"../../imageInsert\";\nimport { saveImageBytesFacet } from \"../core/hostFacets\";\nimport { IMAGE_EDIT_ALT_EVENT, type ImageEditAltEventDetail } from \"./imageEditEvent\";\n\ninterface ShowMenuArgs {\n x: number;\n y: number;\n view: EditorView;\n alt: string;\n rawSrc: string;\n sourceFrom: number;\n sourceTo: number;\n}\n\nexport function showImageActionMenu(args: ShowMenuArgs): void {\n const menu = document.createElement(\"div\");\n menu.className = \"cm-image-menu\";\n menu.setAttribute(\"role\", \"menu\");\n menu.style.position = \"fixed\";\n menu.style.left = `${args.x}px`;\n menu.style.top = `${args.y}px`;\n menu.style.zIndex = \"1000\";\n\n function destroy() {\n menu.remove();\n document.removeEventListener(\"mousedown\", onOutside, true);\n document.removeEventListener(\"keydown\", onEscape, true);\n }\n\n function onOutside(e: MouseEvent) {\n if (!menu.contains(e.target as Node)) destroy();\n }\n\n function onEscape(e: KeyboardEvent) {\n if (e.key === \"Escape\") destroy();\n }\n\n function makeItem(label: string, onClick: () => void, danger = false): HTMLButtonElement {\n const b = document.createElement(\"button\");\n b.type = \"button\";\n b.className = danger\n ? \"cm-image-menu__item cm-image-menu__item--danger\"\n : \"cm-image-menu__item\";\n b.setAttribute(\"role\", \"menuitem\");\n b.textContent = label;\n b.addEventListener(\"click\", () => {\n onClick();\n destroy();\n });\n return b;\n }\n\n menu.appendChild(\n makeItem(\"Edit alt text…\", () => {\n const event = new CustomEvent<ImageEditAltEventDetail>(IMAGE_EDIT_ALT_EVENT, {\n detail: {\n view: args.view,\n sourceFrom: args.sourceFrom,\n sourceTo: args.sourceTo,\n currentAlt: args.alt,\n rawSrc: args.rawSrc,\n },\n });\n window.dispatchEvent(event);\n }),\n );\n\n menu.appendChild(\n makeItem(\"Replace image…\", () => {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*\";\n input.onchange = () => {\n const file = input.files?.[0];\n if (!file) return;\n void (async () => {\n try {\n const result = await insertImageBlob({\n blob: file,\n saveBytes: args.view.state.facet(saveImageBytesFacet),\n });\n const newMd = buildImageMarkdown(result);\n args.view.dispatch({\n changes: { from: args.sourceFrom, to: args.sourceTo, insert: newMd },\n userEvent: \"input.replace.image\",\n });\n } catch (error) {\n console.error(\"Failed to replace image:\", error);\n }\n })();\n };\n input.click();\n }),\n );\n\n menu.appendChild(\n makeItem(\"Copy markdown source\", () => {\n const source = args.view.state.sliceDoc(args.sourceFrom, args.sourceTo);\n void navigator.clipboard.writeText(source);\n }),\n );\n\n menu.appendChild(\n makeItem(\n \"Delete image\",\n () => {\n args.view.dispatch({\n changes: { from: args.sourceFrom, to: args.sourceTo, insert: \"\" },\n userEvent: \"delete.image\",\n });\n },\n true,\n ),\n );\n\n document.body.appendChild(menu);\n\n const rect = menu.getBoundingClientRect();\n const overflowRight = rect.right - window.innerWidth;\n if (overflowRight > 0) menu.style.left = `${args.x - overflowRight - 8}px`;\n const overflowBottom = rect.bottom - window.innerHeight;\n if (overflowBottom > 0) menu.style.top = `${args.y - overflowBottom - 8}px`;\n\n setTimeout(() => {\n document.addEventListener(\"mousedown\", onOutside, true);\n document.addEventListener(\"keydown\", onEscape, true);\n }, 0);\n}\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,2BAA2B;AACpC,SAAS,4BAA0D;AAY5D,SAAS,oBAAoB,MAA0B;AAC5D,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AACjB,OAAK,aAAa,QAAQ,MAAM;AAChC,OAAK,MAAM,WAAW;AACtB,OAAK,MAAM,OAAO,GAAG,KAAK,CAAC;AAC3B,OAAK,MAAM,MAAM,GAAG,KAAK,CAAC;AAC1B,OAAK,MAAM,SAAS;AAEpB,WAAS,UAAU;AACjB,SAAK,OAAO;AACZ,aAAS,oBAAoB,aAAa,WAAW,IAAI;AACzD,aAAS,oBAAoB,WAAW,UAAU,IAAI;AAAA,EACxD;AAEA,WAAS,UAAU,GAAe;AAChC,QAAI,CAAC,KAAK,SAAS,EAAE,MAAc,EAAG,SAAQ;AAAA,EAChD;AAEA,WAAS,SAAS,GAAkB;AAClC,QAAI,EAAE,QAAQ,SAAU,SAAQ;AAAA,EAClC;AAEA,WAAS,SAAS,OAAe,SAAqB,SAAS,OAA0B;AACvF,UAAM,IAAI,SAAS,cAAc,QAAQ;AACzC,MAAE,OAAO;AACT,MAAE,YAAY,SACV,oDACA;AACJ,MAAE,aAAa,QAAQ,UAAU;AACjC,MAAE,cAAc;AAChB,MAAE,iBAAiB,SAAS,MAAM;AAChC,cAAQ;AACR,cAAQ;AAAA,IACV,CAAC;AACD,WAAO;AAAA,EACT;AAEA,OAAK;AAAA,IACH,SAAS,uBAAkB,MAAM;AAC/B,YAAM,QAAQ,IAAI,YAAqC,sBAAsB;AAAA,QAC3E,QAAQ;AAAA,UACN,MAAM,KAAK;AAAA,UACX,YAAY,KAAK;AAAA,UACjB,UAAU,KAAK;AAAA,UACf,YAAY,KAAK;AAAA,UACjB,QAAQ,KAAK;AAAA,QACf;AAAA,MACF,CAAC;AACD,aAAO,cAAc,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,SAAS,uBAAkB,MAAM;AAC/B,YAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,YAAM,OAAO;AACb,YAAM,SAAS;AACf,YAAM,WAAW,MAAM;AACrB,cAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,YAAI,CAAC,KAAM;AACX,cAAM,YAAY;AAChB,cAAI;AACF,kBAAM,SAAS,MAAM,gBAAgB;AAAA,cACnC,MAAM;AAAA,cACN,WAAW,KAAK,KAAK,MAAM,MAAM,mBAAmB;AAAA,YACtD,CAAC;AACD,kBAAM,QAAQ,mBAAmB,MAAM;AACvC,iBAAK,KAAK,SAAS;AAAA,cACjB,SAAS,EAAE,MAAM,KAAK,YAAY,IAAI,KAAK,UAAU,QAAQ,MAAM;AAAA,cACnE,WAAW;AAAA,YACb,CAAC;AAAA,UACH,SAAS,OAAO;AACd,oBAAQ,MAAM,4BAA4B,KAAK;AAAA,UACjD;AAAA,QACF,GAAG;AAAA,MACL;AACA,YAAM,MAAM;AAAA,IACd,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH,SAAS,wBAAwB,MAAM;AACrC,YAAM,SAAS,KAAK,KAAK,MAAM,SAAS,KAAK,YAAY,KAAK,QAAQ;AACtE,WAAK,UAAU,UAAU,UAAU,MAAM;AAAA,IAC3C,CAAC;AAAA,EACH;AAEA,OAAK;AAAA,IACH;AAAA,MACE;AAAA,MACA,MAAM;AACJ,aAAK,KAAK,SAAS;AAAA,UACjB,SAAS,EAAE,MAAM,KAAK,YAAY,IAAI,KAAK,UAAU,QAAQ,GAAG;AAAA,UAChE,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,WAAS,KAAK,YAAY,IAAI;AAE9B,QAAM,OAAO,KAAK,sBAAsB;AACxC,QAAM,gBAAgB,KAAK,QAAQ,OAAO;AAC1C,MAAI,gBAAgB,EAAG,MAAK,MAAM,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAAC;AACtE,QAAM,iBAAiB,KAAK,SAAS,OAAO;AAC5C,MAAI,iBAAiB,EAAG,MAAK,MAAM,MAAM,GAAG,KAAK,IAAI,iBAAiB,CAAC;AAEvE,aAAW,MAAM;AACf,aAAS,iBAAiB,aAAa,WAAW,IAAI;AACtD,aAAS,iBAAiB,WAAW,UAAU,IAAI;AAAA,EACrD,GAAG,CAAC;AACN;","names":[]}
@@ -0,0 +1,20 @@
1
+ import { EditorView } from '@codemirror/view';
2
+
3
+ /**
4
+ * The "edit this image's alt text" custom-event contract — a plain constant and
5
+ * type with NO runtime CodeMirror dependency (the `EditorView` reference is
6
+ * `import type`, erased at build). The lazy-loaded editor dispatches this event;
7
+ * the host shell listens for it. Keeping the contract here means a host can
8
+ * import the event name without pulling the whole editor into its initial
9
+ * bundle (it previously came from `imageActionMenu`, which imports CodeMirror).
10
+ */
11
+ declare const IMAGE_EDIT_ALT_EVENT = "ai-editor:edit-image-alt";
12
+ interface ImageEditAltEventDetail {
13
+ view: EditorView;
14
+ sourceFrom: number;
15
+ sourceTo: number;
16
+ currentAlt: string;
17
+ rawSrc: string;
18
+ }
19
+
20
+ export { IMAGE_EDIT_ALT_EVENT, type ImageEditAltEventDetail };
@@ -0,0 +1,6 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ const IMAGE_EDIT_ALT_EVENT = "ai-editor:edit-image-alt";
3
+ export {
4
+ IMAGE_EDIT_ALT_EVENT
5
+ };
6
+ //# sourceMappingURL=imageEditEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/image/imageEditEvent.ts"],"sourcesContent":["import type { EditorView } from \"@codemirror/view\";\n\n/**\n * The \"edit this image's alt text\" custom-event contract — a plain constant and\n * type with NO runtime CodeMirror dependency (the `EditorView` reference is\n * `import type`, erased at build). The lazy-loaded editor dispatches this event;\n * the host shell listens for it. Keeping the contract here means a host can\n * import the event name without pulling the whole editor into its initial\n * bundle (it previously came from `imageActionMenu`, which imports CodeMirror).\n */\nexport const IMAGE_EDIT_ALT_EVENT = \"ai-editor:edit-image-alt\";\n\nexport interface ImageEditAltEventDetail {\n view: EditorView;\n sourceFrom: number;\n sourceTo: number;\n currentAlt: string;\n rawSrc: string;\n}\n"],"mappings":";AAUO,MAAM,uBAAuB;","names":[]}
@@ -0,0 +1,13 @@
1
+ import * as _codemirror_state from '@codemirror/state';
2
+ import { EditorView } from '@codemirror/view';
3
+
4
+ declare function insertBlobsAtCaret(view: EditorView, blobs: Blob[]): Promise<void>;
5
+ declare const imageInsertHandlers: _codemirror_state.Extension;
6
+ /**
7
+ * Open the browser's native file picker, then run the picked files
8
+ * through the same insert pipeline. Called by the toolbar's Image
9
+ * button.
10
+ */
11
+ declare function pickImageFileForCaret(view: EditorView): void;
12
+
13
+ export { imageInsertHandlers, insertBlobsAtCaret, pickImageFileForCaret };
@@ -0,0 +1,64 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import { EditorSelection } from "@codemirror/state";
3
+ import { EditorView } from "@codemirror/view";
4
+ import {
5
+ buildImageMarkdown,
6
+ extractImageBlobs,
7
+ extractImageFiles,
8
+ insertImageBlob
9
+ } from "../../imageInsert.js";
10
+ import { saveImageBytesFacet } from "../core/hostFacets.js";
11
+ async function insertBlobsAtCaret(view, blobs) {
12
+ const saveBytes = view.state.facet(saveImageBytesFacet);
13
+ for (const blob of blobs) {
14
+ try {
15
+ const result = await insertImageBlob({ blob, saveBytes });
16
+ const md = buildImageMarkdown(result);
17
+ const pos = view.state.selection.main.head;
18
+ const insert = md + "\n\n";
19
+ view.dispatch({
20
+ changes: { from: pos, insert },
21
+ selection: EditorSelection.cursor(pos + insert.length),
22
+ userEvent: "input.paste.image"
23
+ });
24
+ if (result.warning) {
25
+ console.info(`Image inserted with fallback: ${result.warning}`);
26
+ }
27
+ } catch (error) {
28
+ console.error("Failed to insert image:", error);
29
+ }
30
+ }
31
+ }
32
+ const imageInsertHandlers = EditorView.domEventHandlers({
33
+ paste(event, view) {
34
+ const blobs = extractImageBlobs(event.clipboardData?.items);
35
+ if (blobs.length === 0) return false;
36
+ event.preventDefault();
37
+ void insertBlobsAtCaret(view, blobs);
38
+ return true;
39
+ },
40
+ drop(event, view) {
41
+ const files = extractImageFiles(event.dataTransfer?.files);
42
+ if (files.length === 0) return false;
43
+ event.preventDefault();
44
+ void insertBlobsAtCaret(view, files);
45
+ return true;
46
+ }
47
+ });
48
+ function pickImageFileForCaret(view) {
49
+ const input = document.createElement("input");
50
+ input.type = "file";
51
+ input.accept = "image/*";
52
+ input.multiple = true;
53
+ input.onchange = () => {
54
+ const files = input.files ? Array.from(input.files) : [];
55
+ if (files.length > 0) void insertBlobsAtCaret(view, files);
56
+ };
57
+ input.click();
58
+ }
59
+ export {
60
+ imageInsertHandlers,
61
+ insertBlobsAtCaret,
62
+ pickImageFileForCaret
63
+ };
64
+ //# sourceMappingURL=imageInsertHandlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/image/imageInsertHandlers.ts"],"sourcesContent":["/**\n * Image insertion handlers for CM6 — paste image bytes from the\n * clipboard or drop image files into the editor, save them through\n * the existing `insertImageBlob` pipeline, then insert the\n * resulting `![alt](path)` markdown at the caret.\n *\n * Same pipeline the Tiptap editor uses; the editor surface differs\n * but the persistence + markdown-reference logic is shared.\n */\n\nimport { EditorSelection } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\n\nimport {\n buildImageMarkdown,\n extractImageBlobs,\n extractImageFiles,\n insertImageBlob,\n} from \"../../imageInsert\";\nimport { saveImageBytesFacet } from \"../core/hostFacets\";\n\nexport async function insertBlobsAtCaret(view: EditorView, blobs: Blob[]): Promise<void> {\n const saveBytes = view.state.facet(saveImageBytesFacet);\n for (const blob of blobs) {\n try {\n const result = await insertImageBlob({ blob, saveBytes });\n const md = buildImageMarkdown(result);\n const pos = view.state.selection.main.head;\n const insert = md + \"\\n\\n\";\n view.dispatch({\n changes: { from: pos, insert },\n selection: EditorSelection.cursor(pos + insert.length),\n userEvent: \"input.paste.image\",\n });\n if (result.warning) {\n // Browser-dev fallback to data URL — surface via console so\n // the user knows the markdown bloated.\n // eslint-disable-next-line no-console\n console.info(`Image inserted with fallback: ${result.warning}`);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(\"Failed to insert image:\", error);\n }\n }\n}\n\nexport const imageInsertHandlers = EditorView.domEventHandlers({\n paste(event, view) {\n const blobs = extractImageBlobs(event.clipboardData?.items);\n if (blobs.length === 0) return false;\n event.preventDefault();\n void insertBlobsAtCaret(view, blobs);\n return true;\n },\n drop(event, view) {\n const files = extractImageFiles(event.dataTransfer?.files);\n if (files.length === 0) return false;\n event.preventDefault();\n void insertBlobsAtCaret(view, files);\n return true;\n },\n});\n\n/**\n * Open the browser's native file picker, then run the picked files\n * through the same insert pipeline. Called by the toolbar's Image\n * button.\n */\nexport function pickImageFileForCaret(view: EditorView): void {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \"image/*\";\n input.multiple = true;\n input.onchange = () => {\n const files = input.files ? Array.from(input.files) : [];\n if (files.length > 0) void insertBlobsAtCaret(view, files);\n };\n input.click();\n}\n"],"mappings":";AAUA,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AAE3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,2BAA2B;AAEpC,eAAsB,mBAAmB,MAAkB,OAA8B;AACvF,QAAM,YAAY,KAAK,MAAM,MAAM,mBAAmB;AACtD,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,SAAS,MAAM,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACxD,YAAM,KAAK,mBAAmB,MAAM;AACpC,YAAM,MAAM,KAAK,MAAM,UAAU,KAAK;AACtC,YAAM,SAAS,KAAK;AACpB,WAAK,SAAS;AAAA,QACZ,SAAS,EAAE,MAAM,KAAK,OAAO;AAAA,QAC7B,WAAW,gBAAgB,OAAO,MAAM,OAAO,MAAM;AAAA,QACrD,WAAW;AAAA,MACb,CAAC;AACD,UAAI,OAAO,SAAS;AAIlB,gBAAQ,KAAK,iCAAiC,OAAO,OAAO,EAAE;AAAA,MAChE;AAAA,IACF,SAAS,OAAO;AAEd,cAAQ,MAAM,2BAA2B,KAAK;AAAA,IAChD;AAAA,EACF;AACF;AAEO,MAAM,sBAAsB,WAAW,iBAAiB;AAAA,EAC7D,MAAM,OAAO,MAAM;AACjB,UAAM,QAAQ,kBAAkB,MAAM,eAAe,KAAK;AAC1D,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,UAAM,eAAe;AACrB,SAAK,mBAAmB,MAAM,KAAK;AACnC,WAAO;AAAA,EACT;AAAA,EACA,KAAK,OAAO,MAAM;AAChB,UAAM,QAAQ,kBAAkB,MAAM,cAAc,KAAK;AACzD,QAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,UAAM,eAAe;AACrB,SAAK,mBAAmB,MAAM,KAAK;AACnC,WAAO;AAAA,EACT;AACF,CAAC;AAOM,SAAS,sBAAsB,MAAwB;AAC5D,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,OAAO;AACb,QAAM,SAAS;AACf,QAAM,WAAW;AACjB,QAAM,WAAW,MAAM;AACrB,UAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,CAAC;AACvD,QAAI,MAAM,SAAS,EAAG,MAAK,mBAAmB,MAAM,KAAK;AAAA,EAC3D;AACA,QAAM,MAAM;AACd;","names":[]}
@@ -0,0 +1,49 @@
1
+ import { Facet } from '@codemirror/state';
2
+ import { NodeRule } from '../core/paint.js';
3
+ import { WidgetType, EditorView } from '@codemirror/view';
4
+ import { ImageResolveContext } from '../../imageSrcResolver.js';
5
+
6
+ /**
7
+ * Inline image widget — renders markdown `![alt](url)` as a real
8
+ * `<img>` element.
9
+ *
10
+ * Source resolution goes through `resolveDisplaySrc` (the same
11
+ * function the Tiptap editor uses), so workspace-relative paths
12
+ * become `asset://…` URLs that the Tauri WebKit can stream from
13
+ * disk.
14
+ *
15
+ * Click handling is intentionally minimal in this phase: the widget
16
+ * doesn't intercept clicks, so a click lands the caret at the
17
+ * widget's boundary. Spec section 7.6 calls for "click selects image
18
+ * block + toolbar"; that ships when the image metadata editor lands
19
+ * in a later phase.
20
+ */
21
+
22
+ /**
23
+ * Resolver facet — wired by the React editor so the plugin can turn
24
+ * relative `images/foo.png` into a `<img src=…>` the webview can
25
+ * fetch. Combine returns the first registered resolver, or a no-op
26
+ * if none.
27
+ */
28
+ declare const imageContextFacet: Facet<ImageResolveContext, ImageResolveContext>;
29
+ declare class ImageWidget extends WidgetType {
30
+ readonly alt: string;
31
+ readonly rawSrc: string;
32
+ readonly ctx: ImageResolveContext;
33
+ /** Source range of the `![alt](src)` markdown that produced this widget. */
34
+ readonly sourceFrom: number;
35
+ readonly sourceTo: number;
36
+ private readonly measureKey;
37
+ constructor(alt: string, rawSrc: string, ctx: ImageResolveContext,
38
+ /** Source range of the `![alt](src)` markdown that produced this widget. */
39
+ sourceFrom: number, sourceTo: number);
40
+ eq(other: ImageWidget): boolean;
41
+ toDOM(view: EditorView): HTMLElement;
42
+ ignoreEvent(): boolean;
43
+ get estimatedHeight(): number;
44
+ }
45
+ /** `![alt](src)` → an inline `<img>` widget; src resolution via the host
46
+ * facet (workspace-relative paths → asset URLs). */
47
+ declare const imageRule: NodeRule;
48
+
49
+ export { ImageWidget, imageContextFacet, imageRule };
@@ -0,0 +1,83 @@
1
+ import {
2
+ __publicField
3
+ } from "../../chunk-V6TY7KAL.js";
4
+ import { Facet } from "@codemirror/state";
5
+ import { Decoration, WidgetType } from "@codemirror/view";
6
+ import { resolveImageSrcFacet } from "../core/hostFacets.js";
7
+ import { showImageActionMenu } from "./imageActionMenu.js";
8
+ const imageContextFacet = Facet.define({
9
+ combine: (values) => values[0] ?? { fileDir: null }
10
+ });
11
+ const measuredImageHeights = /* @__PURE__ */ new Map();
12
+ const IMAGE_ESTIMATE_PX = 200;
13
+ class ImageWidget extends WidgetType {
14
+ constructor(alt, rawSrc, ctx, sourceFrom, sourceTo) {
15
+ super();
16
+ __publicField(this, "alt", alt);
17
+ __publicField(this, "rawSrc", rawSrc);
18
+ __publicField(this, "ctx", ctx);
19
+ __publicField(this, "sourceFrom", sourceFrom);
20
+ __publicField(this, "sourceTo", sourceTo);
21
+ __publicField(this, "measureKey");
22
+ this.measureKey = `${ctx.fileDir ?? ""}
23
+ ${rawSrc}`;
24
+ }
25
+ eq(other) {
26
+ return other.alt === this.alt && other.rawSrc === this.rawSrc && other.ctx.fileDir === this.ctx.fileDir && other.sourceFrom === this.sourceFrom;
27
+ }
28
+ toDOM(view) {
29
+ const img = document.createElement("img");
30
+ img.className = "cm-image-widget";
31
+ img.alt = this.alt;
32
+ img.src = view.state.facet(resolveImageSrcFacet)(this.rawSrc, this.ctx);
33
+ img.loading = "lazy";
34
+ img.addEventListener("load", () => {
35
+ const height = img.offsetHeight || img.naturalHeight;
36
+ if (height > 0) {
37
+ measuredImageHeights.set(this.measureKey, height);
38
+ }
39
+ view.requestMeasure();
40
+ });
41
+ img.addEventListener("error", () => view.requestMeasure());
42
+ img.addEventListener("contextmenu", (e) => {
43
+ e.preventDefault();
44
+ e.stopPropagation();
45
+ showImageActionMenu({
46
+ x: e.clientX,
47
+ y: e.clientY,
48
+ view,
49
+ alt: this.alt,
50
+ rawSrc: this.rawSrc,
51
+ sourceFrom: this.sourceFrom,
52
+ sourceTo: this.sourceTo
53
+ });
54
+ });
55
+ return img;
56
+ }
57
+ ignoreEvent() {
58
+ return false;
59
+ }
60
+ get estimatedHeight() {
61
+ return measuredImageHeights.get(this.measureKey) ?? IMAGE_ESTIMATE_PX;
62
+ }
63
+ }
64
+ const imageRule = (ctx) => {
65
+ const state = ctx.state;
66
+ const label = ctx.node.getChild("LinkLabel");
67
+ const url = ctx.node.getChild("URL");
68
+ const alt = label ? state.sliceDoc(label.from, label.to) : "";
69
+ const rawSrc = url ? state.sliceDoc(url.from, url.to) : "";
70
+ const imageCtx = state.facet(imageContextFacet);
71
+ return {
72
+ paint: "widget",
73
+ deco: Decoration.replace({
74
+ widget: new ImageWidget(alt, rawSrc, imageCtx, ctx.from, ctx.to)
75
+ })
76
+ };
77
+ };
78
+ export {
79
+ ImageWidget,
80
+ imageContextFacet,
81
+ imageRule
82
+ };
83
+ //# sourceMappingURL=imageWidget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/image/imageWidget.ts"],"sourcesContent":["/**\n * Inline image widget — renders markdown `![alt](url)` as a real\n * `<img>` element.\n *\n * Source resolution goes through `resolveDisplaySrc` (the same\n * function the Tiptap editor uses), so workspace-relative paths\n * become `asset://…` URLs that the Tauri WebKit can stream from\n * disk.\n *\n * Click handling is intentionally minimal in this phase: the widget\n * doesn't intercept clicks, so a click lands the caret at the\n * widget's boundary. Spec section 7.6 calls for \"click selects image\n * block + toolbar\"; that ships when the image metadata editor lands\n * in a later phase.\n */\n\nimport { Facet } from \"@codemirror/state\";\nimport { type NodeRule, type Paint } from \"../core/paint\";\nimport { Decoration, EditorView, WidgetType } from \"@codemirror/view\";\n\nimport { type ImageResolveContext } from \"../../imageSrcResolver\";\nimport { resolveImageSrcFacet } from \"../core/hostFacets\";\nimport { showImageActionMenu } from \"./imageActionMenu\";\n\n/**\n * Resolver facet — wired by the React editor so the plugin can turn\n * relative `images/foo.png` into a `<img src=…>` the webview can\n * fetch. Combine returns the first registered resolver, or a no-op\n * if none.\n */\nexport const imageContextFacet = Facet.define<\n ImageResolveContext,\n ImageResolveContext\n>({\n combine: (values) => values[0] ?? { fileDir: null },\n});\n\n/** Rendered heights per image, so a re-render (tab switch, edits above)\n * reserves the real space instead of re-guessing. Keyed by resolve context +\n * src — the same image in two docs can render at different widths. */\nconst measuredImageHeights = new Map<string, number>();\n\n/** Pre-load estimate. CM6 places everything below an unmeasured widget with\n * this; images previously claimed one text line, so each unloaded image hid\n * ~180px of scroll error that surfaced as a viewport jump on load. */\nconst IMAGE_ESTIMATE_PX = 200;\n\nexport class ImageWidget extends WidgetType {\n private readonly measureKey: string;\n\n constructor(\n readonly alt: string,\n readonly rawSrc: string,\n readonly ctx: ImageResolveContext,\n /** Source range of the `![alt](src)` markdown that produced this widget. */\n readonly sourceFrom: number,\n readonly sourceTo: number,\n ) {\n super();\n this.measureKey = `${ctx.fileDir ?? \"\"}\\n${rawSrc}`;\n }\n\n override eq(other: ImageWidget): boolean {\n return (\n other.alt === this.alt &&\n other.rawSrc === this.rawSrc &&\n other.ctx.fileDir === this.ctx.fileDir &&\n other.sourceFrom === this.sourceFrom\n );\n }\n\n override toDOM(view: EditorView): HTMLElement {\n const img = document.createElement(\"img\");\n img.className = \"cm-image-widget\";\n img.alt = this.alt;\n img.src = view.state.facet(resolveImageSrcFacet)(this.rawSrc, this.ctx);\n img.loading = \"lazy\";\n // The real height arrives asynchronously; record it and re-measure NOW —\n // in a controlled pass — rather than letting CM discover the layout shift\n // during the user's next scroll or selection.\n img.addEventListener(\"load\", () => {\n const height = img.offsetHeight || img.naturalHeight;\n if (height > 0) {\n measuredImageHeights.set(this.measureKey, height);\n }\n view.requestMeasure();\n });\n img.addEventListener(\"error\", () => view.requestMeasure());\n img.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n showImageActionMenu({\n x: e.clientX,\n y: e.clientY,\n view,\n alt: this.alt,\n rawSrc: this.rawSrc,\n sourceFrom: this.sourceFrom,\n sourceTo: this.sourceTo,\n });\n });\n return img;\n }\n\n override ignoreEvent(): boolean {\n return false;\n }\n\n override get estimatedHeight(): number {\n return measuredImageHeights.get(this.measureKey) ?? IMAGE_ESTIMATE_PX;\n }\n}\n\n/* ---------------- The Image rule ---------------- */\n\n/** `![alt](src)` → an inline `<img>` widget; src resolution via the host\n * facet (workspace-relative paths → asset URLs). */\nexport const imageRule: NodeRule = (ctx): Paint => {\n const state = ctx.state;\n const label = ctx.node.getChild(\"LinkLabel\");\n const url = ctx.node.getChild(\"URL\");\n const alt = label ? state.sliceDoc(label.from, label.to) : \"\";\n const rawSrc = url ? state.sliceDoc(url.from, url.to) : \"\";\n const imageCtx = state.facet(imageContextFacet);\n return {\n paint: \"widget\",\n deco: Decoration.replace({\n widget: new ImageWidget(alt, rawSrc, imageCtx, ctx.from, ctx.to),\n }),\n };\n};\n"],"mappings":";;;AAgBA,SAAS,aAAa;AAEtB,SAAS,YAAwB,kBAAkB;AAGnD,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AAQ7B,MAAM,oBAAoB,MAAM,OAGrC;AAAA,EACA,SAAS,CAAC,WAAW,OAAO,CAAC,KAAK,EAAE,SAAS,KAAK;AACpD,CAAC;AAKD,MAAM,uBAAuB,oBAAI,IAAoB;AAKrD,MAAM,oBAAoB;AAEnB,MAAM,oBAAoB,WAAW;AAAA,EAG1C,YACW,KACA,QACA,KAEA,YACA,UACT;AACA,UAAM;AAPG;AACA;AACA;AAEA;AACA;AARX,wBAAiB;AAWf,SAAK,aAAa,GAAG,IAAI,WAAW,EAAE;AAAA,EAAK,MAAM;AAAA,EACnD;AAAA,EAES,GAAG,OAA6B;AACvC,WACE,MAAM,QAAQ,KAAK,OACnB,MAAM,WAAW,KAAK,UACtB,MAAM,IAAI,YAAY,KAAK,IAAI,WAC/B,MAAM,eAAe,KAAK;AAAA,EAE9B;AAAA,EAES,MAAM,MAA+B;AAC5C,UAAM,MAAM,SAAS,cAAc,KAAK;AACxC,QAAI,YAAY;AAChB,QAAI,MAAM,KAAK;AACf,QAAI,MAAM,KAAK,MAAM,MAAM,oBAAoB,EAAE,KAAK,QAAQ,KAAK,GAAG;AACtE,QAAI,UAAU;AAId,QAAI,iBAAiB,QAAQ,MAAM;AACjC,YAAM,SAAS,IAAI,gBAAgB,IAAI;AACvC,UAAI,SAAS,GAAG;AACd,6BAAqB,IAAI,KAAK,YAAY,MAAM;AAAA,MAClD;AACA,WAAK,eAAe;AAAA,IACtB,CAAC;AACD,QAAI,iBAAiB,SAAS,MAAM,KAAK,eAAe,CAAC;AACzD,QAAI,iBAAiB,eAAe,CAAC,MAAM;AACzC,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAClB,0BAAoB;AAAA,QAClB,GAAG,EAAE;AAAA,QACL,GAAG,EAAE;AAAA,QACL;AAAA,QACA,KAAK,KAAK;AAAA,QACV,QAAQ,KAAK;AAAA,QACb,YAAY,KAAK;AAAA,QACjB,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAES,cAAuB;AAC9B,WAAO;AAAA,EACT;AAAA,EAEA,IAAa,kBAA0B;AACrC,WAAO,qBAAqB,IAAI,KAAK,UAAU,KAAK;AAAA,EACtD;AACF;AAMO,MAAM,YAAsB,CAAC,QAAe;AACjD,QAAM,QAAQ,IAAI;AAClB,QAAM,QAAQ,IAAI,KAAK,SAAS,WAAW;AAC3C,QAAM,MAAM,IAAI,KAAK,SAAS,KAAK;AACnC,QAAM,MAAM,QAAQ,MAAM,SAAS,MAAM,MAAM,MAAM,EAAE,IAAI;AAC3D,QAAM,SAAS,MAAM,MAAM,SAAS,IAAI,MAAM,IAAI,EAAE,IAAI;AACxD,QAAM,WAAW,MAAM,MAAM,iBAAiB;AAC9C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,WAAW,QAAQ;AAAA,MACvB,QAAQ,IAAI,YAAY,KAAK,QAAQ,UAAU,IAAI,MAAM,IAAI,EAAE;AAAA,IACjE,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -0,0 +1,8 @@
1
+ export { ImageWidget, imageContextFacet, imageRule } from './imageWidget.js';
2
+ export { imageInsertHandlers, insertBlobsAtCaret, pickImageFileForCaret } from './imageInsertHandlers.js';
3
+ export { showImageActionMenu } from './imageActionMenu.js';
4
+ export { IMAGE_EDIT_ALT_EVENT, ImageEditAltEventDetail } from './imageEditEvent.js';
5
+ import '@codemirror/state';
6
+ import '../core/paint.js';
7
+ import '@codemirror/view';
8
+ import '../../imageSrcResolver.js';
@@ -0,0 +1,5 @@
1
+ export * from "./imageWidget.js";
2
+ export * from "./imageInsertHandlers.js";
3
+ export * from "./imageActionMenu.js";
4
+ export * from "./imageEditEvent.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/image/index.ts"],"sourcesContent":["/**\n * Inline images: the `![alt](src)` widget, paste/drop insert handlers, the\n * click action menu, and the CodeMirror-free alt-edit event contract.\n */\nexport * from \"./imageWidget\";\nexport * from \"./imageInsertHandlers\";\nexport * from \"./imageActionMenu\";\nexport * from \"./imageEditEvent\";\n"],"mappings":"AAIA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,43 @@
1
+ import * as _codemirror_state from '@codemirror/state';
2
+ import { Facet } from '@codemirror/state';
3
+ import { EditorView } from '@codemirror/view';
4
+
5
+ /**
6
+ * Navigation callback registered by the editor's React shell. Routes a
7
+ * clicked workspace-relative path back through `selectFile`.
8
+ */
9
+ declare const navigateToFacet: Facet<(path: string) => void, ((path: string) => void) | null>;
10
+ /**
11
+ * Walk up from a syntax node to find a `Link` ancestor and return
12
+ * its URL — or `null` if the click wasn't on a link.
13
+ */
14
+ declare function linkUrlAt(view: EditorView, pos: number): string | null;
15
+ /**
16
+ * If `pos` falls inside a `[[…]]` wikilink, return the workspace
17
+ * file path it resolves to (or null if unresolved). Wikilinks are
18
+ * detected via the same regex + code-context guard `wikilinkPlugin`
19
+ * uses; we re-scan the current line at click time because the plugin
20
+ * doesn't expose its matches.
21
+ */
22
+ declare function wikilinkTargetAt(view: EditorView, pos: number): string | null;
23
+ /** What a Cmd/Ctrl-clicked link resolves to. */
24
+ type LinkAction = {
25
+ kind: "navigate";
26
+ path: string;
27
+ } | {
28
+ kind: "open";
29
+ href: string;
30
+ };
31
+ /**
32
+ * Resolve the link under `pos` to an action. A markdown link `[t](href)` or a
33
+ * `[[wikilink]]` that names a known workspace file → navigate in-app; a markdown
34
+ * link with a URI scheme (`https:`, `mailto:`, …) → open in the browser; plain
35
+ * text, a broken internal link, or an in-page `#anchor` → null, leaving the
36
+ * click to CM6's default. Pure over editor state, so it's unit-testable with an
37
+ * explicit pos — the DOM click path can't run under jsdom's layout-less
38
+ * `posAtCoords`.
39
+ */
40
+ declare function linkActionAt(view: EditorView, pos: number): LinkAction | null;
41
+ declare const clickModel: _codemirror_state.Extension;
42
+
43
+ export { type LinkAction, clickModel, linkActionAt, linkUrlAt, navigateToFacet, wikilinkTargetAt };