@latentic/live-markdown 0.3.0 → 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 +38 -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 -5989
  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,105 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import { docTree, inCode } from "../core/codeContext.js";
3
+ import { escapeAttr, escapeText } from "../core/htmlEscape.js";
4
+ import { inlineScanRulesFacet, scanInline } from "../core/inlineScan.js";
5
+ import { NODE_RULES } from "../core/registry.js";
6
+ function codeText(state, node) {
7
+ let innerFrom = node.from;
8
+ let innerTo = node.to;
9
+ let seenMark = false;
10
+ for (let child = node.firstChild; child; child = child.nextSibling) {
11
+ if (child.name !== "CodeMark") continue;
12
+ if (!seenMark) {
13
+ innerFrom = child.to;
14
+ seenMark = true;
15
+ }
16
+ innerTo = child.from;
17
+ }
18
+ return state.sliceDoc(innerFrom, innerTo);
19
+ }
20
+ function renderLink(state, node, className) {
21
+ let url = "";
22
+ let labelFrom = -1;
23
+ let labelTo = -1;
24
+ for (let child = node.firstChild; child; child = child.nextSibling) {
25
+ if (child.name === "URL") url = state.sliceDoc(child.from, child.to);
26
+ else if (child.name === "LinkMark") {
27
+ const mark = state.sliceDoc(child.from, child.to);
28
+ if (mark === "[") labelFrom = child.to;
29
+ else if (mark === "]" && labelTo < 0) labelTo = child.from;
30
+ }
31
+ }
32
+ if (labelFrom < 0 || labelTo < 0) return state.sliceDoc(node.from, node.to);
33
+ const label = renderRange(state, node, labelFrom, labelTo);
34
+ return url ? `<a href="${escapeAttr(url)}" class="${className}">${label}</a>` : `<span class="${className}">${label}</span>`;
35
+ }
36
+ function renderMark(state, node, className) {
37
+ if (node.name === "InlineCode") {
38
+ return `<span class="${className}">${escapeText(codeText(state, node))}</span>`;
39
+ }
40
+ if (node.name === "Link") {
41
+ return renderLink(state, node, className);
42
+ }
43
+ return `<span class="${className}">${renderRange(state, node, node.from, node.to)}</span>`;
44
+ }
45
+ function renderNode(state, parent, node) {
46
+ const rule = NODE_RULES[node.name];
47
+ if (!rule) return state.sliceDoc(node.from, node.to);
48
+ const paint = rule({
49
+ name: node.name,
50
+ from: node.from,
51
+ to: node.to,
52
+ parentName: parent.name,
53
+ node,
54
+ state
55
+ });
56
+ switch (paint.paint) {
57
+ case "mark":
58
+ return renderMark(state, node, paint.className);
59
+ case "hide": {
60
+ const hidden = paint.range ?? node;
61
+ return state.sliceDoc(node.from, hidden.from) + state.sliceDoc(hidden.to, node.to);
62
+ }
63
+ case "widget":
64
+ return state.sliceDoc(node.from, node.to);
65
+ default:
66
+ return renderRange(state, node, node.from, node.to);
67
+ }
68
+ }
69
+ function renderRange(state, parent, from, to) {
70
+ let html = "";
71
+ let pos = from;
72
+ for (let child = parent.firstChild; child; child = child.nextSibling) {
73
+ if (child.to <= from || child.from >= to) continue;
74
+ if (child.from > pos) html += state.sliceDoc(pos, child.from);
75
+ html += renderNode(state, parent, child);
76
+ pos = child.to;
77
+ }
78
+ if (pos < to) html += state.sliceDoc(pos, to);
79
+ return html;
80
+ }
81
+ function straddlesChild(cell, from, to) {
82
+ for (let child = cell.firstChild; child; child = child.nextSibling) {
83
+ if (child.from < from && child.to > from) return true;
84
+ if (child.from < to && child.to > to) return true;
85
+ }
86
+ return false;
87
+ }
88
+ function renderInlineCell(state, cell) {
89
+ const rules = state.facet(inlineScanRulesFacet);
90
+ const tree = docTree(state);
91
+ let html = "";
92
+ let pos = cell.from;
93
+ for (const span of scanInline(rules, state.sliceDoc(cell.from, cell.to), cell.from)) {
94
+ if (span.from < pos) continue;
95
+ if (inCode(tree, span.from) || inCode(tree, span.to - 1)) continue;
96
+ if (straddlesChild(cell, span.from, span.to)) continue;
97
+ html += renderRange(state, cell, pos, span.from) + span.html;
98
+ pos = span.to;
99
+ }
100
+ return (html + renderRange(state, cell, pos, cell.to)).trim();
101
+ }
102
+ export {
103
+ renderInlineCell
104
+ };
105
+ //# sourceMappingURL=tableInline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/table/tableInline.ts"],"sourcesContent":["/**\n * Renders a table cell's inline markdown to an HTML string by walking the Lezer\n * inline nodes already parsed inside the `TableCell`, styled through the SAME\n * {@link NODE_RULES} the live editor uses: a `mark` paint becomes a `<span>`\n * carrying that rule's class (`cm-strong`, `cm-inline-code`, `cm-link`, …), so\n * a cell's bold/code/link is painted by the exact `.cm-*` theme rules as body\n * text — not a second, drifting set of styles. Hidden chrome drops out;\n * not-yet-styled constructs pass through as raw markdown, matching how the\n * body leaves them today. Cells render STRINGS, not DOM, so a `widget` paint\n * passes the node's raw source through (the cell's DOMPurify pass keeps\n * allow-listed inline HTML like `<br>` and drops the rest).\n *\n * Reading the parsed tree (rather than re-parsing the cell string) preserves\n * escaped pipes and leaves literal inline HTML (`<br>`) in the gaps between\n * nodes intact — the cell's DOMPurify pass (tableCell.ts) sanitises the result.\n */\n\nimport { type EditorState } from \"@codemirror/state\";\n\nimport { docTree, inCode } from \"../core/codeContext\";\nimport { escapeAttr, escapeText } from \"../core/htmlEscape\";\nimport { inlineScanRulesFacet, scanInline } from \"../core/inlineScan\";\nimport { type NodeLike } from \"../core/paint\";\nimport { NODE_RULES } from \"../core/registry\";\n\ntype SyntaxNodeLike = {\n readonly name: string;\n readonly from: number;\n readonly to: number;\n readonly firstChild: SyntaxNodeLike | null;\n readonly nextSibling: SyntaxNodeLike | null;\n};\n\n/**\n * `InlineCode` content sits between its two `CodeMark` backtick children and is\n * literal — no nested markdown — so it's entity-escaped rather than recursed.\n */\nfunction codeText(state: EditorState, node: SyntaxNodeLike): string {\n let innerFrom = node.from;\n let innerTo = node.to;\n let seenMark = false;\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.name !== \"CodeMark\") continue;\n if (!seenMark) {\n innerFrom = child.to;\n seenMark = true;\n }\n innerTo = child.from;\n }\n return state.sliceDoc(innerFrom, innerTo);\n}\n\nfunction renderLink(state: EditorState, node: SyntaxNodeLike, className: string): string {\n let url = \"\";\n let labelFrom = -1;\n let labelTo = -1;\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.name === \"URL\") url = state.sliceDoc(child.from, child.to);\n else if (child.name === \"LinkMark\") {\n const mark = state.sliceDoc(child.from, child.to);\n if (mark === \"[\") labelFrom = child.to;\n else if (mark === \"]\" && labelTo < 0) labelTo = child.from;\n }\n }\n if (labelFrom < 0 || labelTo < 0) return state.sliceDoc(node.from, node.to);\n const label = renderRange(state, node, labelFrom, labelTo);\n // Keep the anchor — the widget's click handler routes a Cmd-click through to\n // the host opener — but carry `.cm-link` so it matches body links.\n return url\n ? `<a href=\"${escapeAttr(url)}\" class=\"${className}\">${label}</a>`\n : `<span class=\"${className}\">${label}</span>`;\n}\n\n/** A registry `mark` node → `<span class=\"…\">`, reusing the editor's own class. */\nfunction renderMark(state: EditorState, node: SyntaxNodeLike, className: string): string {\n if (node.name === \"InlineCode\") {\n // Literal content between the backtick `CodeMark`s — entity-escaped, no recursion.\n return `<span class=\"${className}\">${escapeText(codeText(state, node))}</span>`;\n }\n if (node.name === \"Link\") {\n return renderLink(state, node, className);\n }\n return `<span class=\"${className}\">${renderRange(state, node, node.from, node.to)}</span>`;\n}\n\nfunction renderNode(state: EditorState, parent: SyntaxNodeLike, node: SyntaxNodeLike): string {\n const rule = NODE_RULES[node.name];\n // An unknown node (no rule) is emitted verbatim.\n if (!rule) return state.sliceDoc(node.from, node.to);\n const paint = rule({\n name: node.name,\n from: node.from,\n to: node.to,\n parentName: parent.name,\n node: node as unknown as NodeLike,\n state,\n });\n switch (paint.paint) {\n case \"mark\":\n return renderMark(state, node, paint.className);\n case \"hide\": {\n // Emit whatever the rule did NOT hide — \"\" for whole-node chrome\n // (`**`, `` ` ``, a Link's URL), the escaped character for `\\x`.\n const hidden = paint.range ?? node;\n return state.sliceDoc(node.from, hidden.from) + state.sliceDoc(hidden.to, node.to);\n }\n case \"widget\":\n // Cells render strings, not DOM — the raw source passes through and\n // the cell's DOMPurify pass keeps allow-listed tags (`<br>`).\n return state.sliceDoc(node.from, node.to);\n default:\n // none / lineClass: recurse so nested styled marks still render, while\n // this node's own (unstyled) markup passes through as raw text.\n return renderRange(state, node, node.from, node.to);\n }\n}\n\n/**\n * Render `parent`'s inline content clipped to `[from, to)`: each child node\n * becomes its tag, and the un-tokenised text in the gaps between children\n * (plain text, inline HTML) is emitted verbatim.\n */\nfunction renderRange(\n state: EditorState,\n parent: SyntaxNodeLike,\n from: number,\n to: number,\n): string {\n let html = \"\";\n let pos = from;\n for (let child = parent.firstChild; child; child = child.nextSibling) {\n if (child.to <= from || child.from >= to) continue;\n if (child.from > pos) html += state.sliceDoc(pos, child.from);\n html += renderNode(state, parent, child);\n pos = child.to;\n }\n if (pos < to) html += state.sliceDoc(pos, to);\n return html;\n}\n\n/**\n * A scanned span may stand in for whole child nodes, but must not cut one in\n * half: {@link renderRange} emits a straddling child in full at both ends of the\n * span, which would render it twice.\n */\nfunction straddlesChild(cell: SyntaxNodeLike, from: number, to: number): boolean {\n for (let child = cell.firstChild; child; child = child.nextSibling) {\n if (child.from < from && child.to > from) return true;\n if (child.from < to && child.to > to) return true;\n }\n return false;\n}\n\n/**\n * Inline-render one `TableCell` node to a (still-to-be-sanitised) HTML string.\n *\n * The constructs Lezer parses come from the tree; the four it does not\n * (wikilink, highlight, footnote, math) are carved out of the cell's text first\n * and take precedence over the tree walk — the same order the body renders in,\n * where a scanning plugin's replace decoration covers the marks beneath it.\n */\nexport function renderInlineCell(state: EditorState, cell: SyntaxNodeLike): string {\n const rules = state.facet(inlineScanRulesFacet);\n const tree = docTree(state);\n let html = \"\";\n let pos = cell.from;\n for (const span of scanInline(rules, state.sliceDoc(cell.from, cell.to), cell.from)) {\n // Code is literal, exactly as in the body: `$x$` inside a code span is text.\n if (span.from < pos) continue;\n if (inCode(tree, span.from) || inCode(tree, span.to - 1)) continue;\n if (straddlesChild(cell, span.from, span.to)) continue;\n html += renderRange(state, cell, pos, span.from) + span.html;\n pos = span.to;\n }\n return (html + renderRange(state, cell, pos, cell.to)).trim();\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,45 @@
1
+ import { EditorState } from '@codemirror/state';
2
+
3
+ /**
4
+ * Turns a Lezer `Table` node into the per-table row/column models the widget
5
+ * renders. Reading the parsed tree (not re-splitting the source on `|`) keeps
6
+ * the model aligned with Lezer's boundaries:
7
+ *
8
+ * - Escaped pipes (`x \| y`) stay inside one `TableCell`.
9
+ * - Cell inline markdown (`**b**`, `` `c` ``, links) renders via the cell's
10
+ * inline child nodes (see {@link renderInlineCell}).
11
+ * - Trailing prose Lezer folds into the table (no blank-line gap) carries no
12
+ * `TableDelimiter`, so it's dropped rather than rendered as a junk row.
13
+ * - Tables written with no blank line between them are merged by Lezer into a
14
+ * single node; each interior delimiter row begins a new table, so one node
15
+ * can yield several models.
16
+ */
17
+
18
+ type SyntaxNodeLike = {
19
+ readonly name: string;
20
+ readonly from: number;
21
+ readonly to: number;
22
+ readonly firstChild: SyntaxNodeLike | null;
23
+ readonly nextSibling: SyntaxNodeLike | null;
24
+ };
25
+ interface TableCellData {
26
+ /** Inline-rendered HTML (sanitised at render time). */
27
+ html: string;
28
+ /** The cell's content range in the document — the span a cell editor edits. */
29
+ from: number;
30
+ to: number;
31
+ }
32
+ interface TableData {
33
+ header: TableCellData[];
34
+ rows: TableCellData[][];
35
+ alignments: Array<"left" | "right" | "center" | null>;
36
+ }
37
+ /** One rendered table plus the document range its source occupies. */
38
+ interface TableModel {
39
+ data: TableData;
40
+ from: number;
41
+ to: number;
42
+ }
43
+ declare function parseTableNode(state: EditorState, table: SyntaxNodeLike): TableModel[];
44
+
45
+ export { type TableCellData, type TableData, type TableModel, parseTableNode };
@@ -0,0 +1,98 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import { renderInlineCell } from "./tableInline.js";
3
+ function alignmentFor(spec) {
4
+ const t = spec.trim();
5
+ if (!t) return null;
6
+ const left = t.startsWith(":");
7
+ const right = t.endsWith(":");
8
+ if (left && right) return "center";
9
+ if (right) return "right";
10
+ if (left) return "left";
11
+ return null;
12
+ }
13
+ function cells(state, row) {
14
+ const out = [];
15
+ let lastPipeTo = null;
16
+ let sawCell = false;
17
+ for (let child = row.firstChild; child; child = child.nextSibling) {
18
+ if (child.name === "TableCell") {
19
+ out.push({ html: renderInlineCell(state, child), from: child.from, to: child.to });
20
+ sawCell = true;
21
+ } else if (child.name === "TableDelimiter") {
22
+ if (lastPipeTo !== null && !sawCell) {
23
+ out.push({ html: "", from: lastPipeTo, to: child.from });
24
+ }
25
+ lastPipeTo = child.to;
26
+ sawCell = false;
27
+ }
28
+ }
29
+ return out;
30
+ }
31
+ function isContentRow(row) {
32
+ for (let child = row.firstChild; child; child = child.nextSibling) {
33
+ if (child.name === "TableDelimiter") return true;
34
+ }
35
+ return false;
36
+ }
37
+ function alignmentsFrom(state, delimiterLine) {
38
+ return state.sliceDoc(delimiterLine.from, delimiterLine.to).replace(/^\s*\|/, "").replace(/\|\s*$/, "").split("|").map((s) => s.trim());
39
+ }
40
+ function rowCellTexts(state, row) {
41
+ const cells2 = [];
42
+ for (let child = row.firstChild; child; child = child.nextSibling) {
43
+ if (child.name === "TableCell") cells2.push(state.sliceDoc(child.from, child.to).trim());
44
+ }
45
+ return cells2;
46
+ }
47
+ function isDelimiterCells(cells2) {
48
+ return cells2.length > 0 && cells2.every((c) => /^:?-+:?$/.test(c));
49
+ }
50
+ function isDelimiterRow(state, node) {
51
+ if (node.name === "TableDelimiter") return true;
52
+ return isDelimiterCells(rowCellTexts(state, node));
53
+ }
54
+ function tableItems(state, table) {
55
+ const items = [];
56
+ for (let child = table.firstChild; child; child = child.nextSibling) {
57
+ if (child.name === "TableHeader" || child.name === "TableRow" || child.name === "TableDelimiter") {
58
+ items.push({ node: child, isDelimiter: isDelimiterRow(state, child) });
59
+ }
60
+ }
61
+ return items;
62
+ }
63
+ function bodyRows(state, items, delimiterIndex) {
64
+ const rows = [];
65
+ let to = items[delimiterIndex].node.to;
66
+ for (let j = delimiterIndex + 1; j < items.length; j++) {
67
+ if (items[j].isDelimiter) break;
68
+ if (items[j + 1]?.isDelimiter) break;
69
+ if (!isContentRow(items[j].node)) continue;
70
+ rows.push(cells(state, items[j].node));
71
+ to = items[j].node.to;
72
+ }
73
+ return { rows, to };
74
+ }
75
+ function parseTableNode(state, table) {
76
+ const items = tableItems(state, table);
77
+ const models = [];
78
+ for (let k = 0; k < items.length; k++) {
79
+ if (!items[k].isDelimiter) continue;
80
+ const headerItem = items[k - 1];
81
+ if (!headerItem || headerItem.isDelimiter) continue;
82
+ const { rows, to } = bodyRows(state, items, k);
83
+ models.push({
84
+ data: {
85
+ header: cells(state, headerItem.node),
86
+ rows,
87
+ alignments: alignmentsFrom(state, items[k].node).map(alignmentFor)
88
+ },
89
+ from: headerItem.node.from,
90
+ to
91
+ });
92
+ }
93
+ return models;
94
+ }
95
+ export {
96
+ parseTableNode
97
+ };
98
+ //# sourceMappingURL=tableModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/table/tableModel.ts"],"sourcesContent":["/**\n * Turns a Lezer `Table` node into the per-table row/column models the widget\n * renders. Reading the parsed tree (not re-splitting the source on `|`) keeps\n * the model aligned with Lezer's boundaries:\n *\n * - Escaped pipes (`x \\| y`) stay inside one `TableCell`.\n * - Cell inline markdown (`**b**`, `` `c` ``, links) renders via the cell's\n * inline child nodes (see {@link renderInlineCell}).\n * - Trailing prose Lezer folds into the table (no blank-line gap) carries no\n * `TableDelimiter`, so it's dropped rather than rendered as a junk row.\n * - Tables written with no blank line between them are merged by Lezer into a\n * single node; each interior delimiter row begins a new table, so one node\n * can yield several models.\n */\n\nimport { type EditorState } from \"@codemirror/state\";\n\nimport { renderInlineCell } from \"./tableInline\";\n\ntype SyntaxNodeLike = {\n readonly name: string;\n readonly from: number;\n readonly to: number;\n readonly firstChild: SyntaxNodeLike | null;\n readonly nextSibling: SyntaxNodeLike | null;\n};\n\nexport interface TableCellData {\n /** Inline-rendered HTML (sanitised at render time). */\n html: string;\n /** The cell's content range in the document — the span a cell editor edits. */\n from: number;\n to: number;\n}\n\nexport interface TableData {\n header: TableCellData[];\n rows: TableCellData[][];\n alignments: Array<\"left\" | \"right\" | \"center\" | null>;\n}\n\n/** One rendered table plus the document range its source occupies. */\nexport interface TableModel {\n data: TableData;\n from: number;\n to: number;\n}\n\nfunction alignmentFor(spec: string): \"left\" | \"right\" | \"center\" | null {\n const t = spec.trim();\n if (!t) return null;\n const left = t.startsWith(\":\");\n const right = t.endsWith(\":\");\n if (left && right) return \"center\";\n if (right) return \"right\";\n if (left) return \"left\";\n return null;\n}\n\n/**\n * A row's cells in document order, including empty ones. Lezer emits a\n * `TableCell` only for non-empty cells, so an empty cell shows up as two\n * adjacent `TableDelimiter` pipes with nothing between — reconstruct those as\n * empty cells (range = the gap) so blank or freshly inserted rows and columns\n * still render and stay editable. Walking the pipe/cell nodes (rather than\n * splitting on `|`) keeps an escaped pipe (`x \\| y`) inside its one cell.\n */\nfunction cells(state: EditorState, row: SyntaxNodeLike): TableCellData[] {\n const out: TableCellData[] = [];\n let lastPipeTo: number | null = null;\n let sawCell = false;\n for (let child = row.firstChild; child; child = child.nextSibling) {\n if (child.name === \"TableCell\") {\n out.push({ html: renderInlineCell(state, child), from: child.from, to: child.to });\n sawCell = true;\n } else if (child.name === \"TableDelimiter\") {\n if (lastPipeTo !== null && !sawCell) {\n out.push({ html: \"\", from: lastPipeTo, to: child.from });\n }\n lastPipeTo = child.to;\n sawCell = false;\n }\n }\n return out;\n}\n\n/**\n * A genuine GFM row carries at least one `TableDelimiter` (the `|` pipes).\n * Lezer folds a blank-line-less trailing paragraph into the table as a\n * `TableRow` with a single cell and no delimiter — prose, not a row.\n */\nfunction isContentRow(row: SyntaxNodeLike): boolean {\n for (let child = row.firstChild; child; child = child.nextSibling) {\n if (child.name === \"TableDelimiter\") return true;\n }\n return false;\n}\n\nfunction alignmentsFrom(state: EditorState, delimiterLine: SyntaxNodeLike): string[] {\n return state\n .sliceDoc(delimiterLine.from, delimiterLine.to)\n .replace(/^\\s*\\|/, \"\")\n .replace(/\\|\\s*$/, \"\")\n .split(\"|\")\n .map((s) => s.trim());\n}\n\nfunction rowCellTexts(state: EditorState, row: SyntaxNodeLike): string[] {\n const cells: string[] = [];\n for (let child = row.firstChild; child; child = child.nextSibling) {\n if (child.name === \"TableCell\") cells.push(state.sliceDoc(child.from, child.to).trim());\n }\n return cells;\n}\n\n/** `| --- | :-: |`: every cell is a dash run with optional alignment colons. */\nfunction isDelimiterCells(cells: string[]): boolean {\n return cells.length > 0 && cells.every((c) => /^:?-+:?$/.test(c));\n}\n\n/**\n * Whether a line is a delimiter (alignment) row. Lezer tags only the FIRST\n * one as a `TableDelimiter` node; the separator of a back-to-back table is a\n * plain `TableRow` whose cells happen to be dash runs, so those are detected by\n * content.\n */\nfunction isDelimiterRow(state: EditorState, node: SyntaxNodeLike): boolean {\n if (node.name === \"TableDelimiter\") return true;\n return isDelimiterCells(rowCellTexts(state, node));\n}\n\ninterface Item {\n node: SyntaxNodeLike;\n isDelimiter: boolean;\n}\n\n/** The Table node's header/row lines and delimiter lines, in document order. */\nfunction tableItems(state: EditorState, table: SyntaxNodeLike): Item[] {\n const items: Item[] = [];\n for (let child = table.firstChild; child; child = child.nextSibling) {\n if (\n child.name === \"TableHeader\" ||\n child.name === \"TableRow\" ||\n child.name === \"TableDelimiter\"\n ) {\n items.push({ node: child, isDelimiter: isDelimiterRow(state, child) });\n }\n }\n return items;\n}\n\n/**\n * Body rows for the table whose delimiter is at `delimiterIndex`: content rows\n * up to the header of the next back-to-back table (the row immediately before\n * the next delimiter), skipping folded-in prose.\n */\nfunction bodyRows(\n state: EditorState,\n items: Item[],\n delimiterIndex: number,\n): { rows: TableCellData[][]; to: number } {\n const rows: TableCellData[][] = [];\n let to = items[delimiterIndex].node.to;\n for (let j = delimiterIndex + 1; j < items.length; j++) {\n if (items[j].isDelimiter) break;\n if (items[j + 1]?.isDelimiter) break;\n if (!isContentRow(items[j].node)) continue;\n rows.push(cells(state, items[j].node));\n to = items[j].node.to;\n }\n return { rows, to };\n}\n\nexport function parseTableNode(state: EditorState, table: SyntaxNodeLike): TableModel[] {\n const items = tableItems(state, table);\n const models: TableModel[] = [];\n for (let k = 0; k < items.length; k++) {\n if (!items[k].isDelimiter) continue;\n const headerItem = items[k - 1];\n if (!headerItem || headerItem.isDelimiter) continue;\n const { rows, to } = bodyRows(state, items, k);\n models.push({\n data: {\n header: cells(state, headerItem.node),\n rows,\n alignments: alignmentsFrom(state, items[k].node).map(alignmentFor),\n },\n from: headerItem.node.from,\n to,\n });\n }\n return models;\n}\n"],"mappings":"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","names":["cells"]}
@@ -0,0 +1,48 @@
1
+ import { TableModel } from '../table/tableModel.js';
2
+ import '@codemirror/state';
3
+
4
+ /**
5
+ * The bridge's key decisions (ADR 0001): given where the caret sits inside a
6
+ * cell, either the browser handles the key natively (mid-text editing) or the
7
+ * bridge takes over at a boundary — stepping to a neighbour cell or exiting
8
+ * the table. Pure — the grid math delegates to {@link stepCell}; geometry
9
+ * (wrapped-line detection) arrives as booleans computed by the surface.
10
+ *
11
+ * Structural invariant: no key ever merges cells or rows. Backspace/Delete at
12
+ * a cell edge NAVIGATES; structure changes only happen through explicit
13
+ * commands (tableEditCommands).
14
+ */
15
+
16
+ type BridgeKey = "Tab" | "Shift-Tab" | "ArrowRight" | "ArrowLeft" | "ArrowUp" | "ArrowDown" | "Backspace" | "Delete" | "Enter";
17
+ interface BridgeInput {
18
+ /** Grid dimensions: rows includes the header. */
19
+ rows: number;
20
+ cols: number;
21
+ /** Caret cell (row 0 = header) and text position. */
22
+ row: number;
23
+ col: number;
24
+ offset: number;
25
+ length: number;
26
+ /** Real-geometry flags from the surface (wrapped cells). */
27
+ onFirstVisualLine: boolean;
28
+ onLastVisualLine: boolean;
29
+ }
30
+ type BridgeAction = {
31
+ kind: "native";
32
+ } | {
33
+ kind: "focusCell";
34
+ row: number;
35
+ col: number;
36
+ caret: "start" | "end";
37
+ } | {
38
+ kind: "exit";
39
+ edge: "before" | "after";
40
+ };
41
+ /** Dimensions of `model` as BridgeInput expects them. */
42
+ declare function gridSize(model: TableModel): {
43
+ rows: number;
44
+ cols: number;
45
+ };
46
+ declare function bridgeKey(input: BridgeInput, key: BridgeKey): BridgeAction;
47
+
48
+ export { type BridgeAction, type BridgeInput, type BridgeKey, bridgeKey, gridSize };
@@ -0,0 +1,42 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import { rowCount, stepGrid } from "../table/tableCellNav.js";
3
+ const NATIVE = { kind: "native" };
4
+ function gridSize(model) {
5
+ return { rows: rowCount(model), cols: model.data.header.length };
6
+ }
7
+ function resolve(input, dir, caret) {
8
+ const target = stepGrid(input.rows, input.cols, input.row, input.col, dir);
9
+ if (target.kind === "cell") return { kind: "focusCell", row: target.row, col: target.col, caret };
10
+ return { kind: "exit", edge: target.edge === "above" || target.edge === "before" ? "before" : "after" };
11
+ }
12
+ function bridgeKey(input, key) {
13
+ const atStart = input.offset === 0;
14
+ const atEnd = input.offset >= input.length;
15
+ switch (key) {
16
+ case "Tab":
17
+ return resolve(input, "next", "start");
18
+ case "Shift-Tab":
19
+ return resolve(input, "prev", "end");
20
+ case "ArrowRight":
21
+ return atEnd ? resolve(input, "next", "start") : NATIVE;
22
+ case "ArrowLeft":
23
+ return atStart ? resolve(input, "prev", "end") : NATIVE;
24
+ case "ArrowDown":
25
+ return input.onLastVisualLine ? resolve(input, "down", "start") : NATIVE;
26
+ case "ArrowUp":
27
+ return input.onFirstVisualLine ? resolve(input, "up", "start") : NATIVE;
28
+ case "Backspace":
29
+ return atStart ? resolve(input, "prev", "end") : NATIVE;
30
+ case "Delete":
31
+ return atEnd ? resolve(input, "next", "start") : NATIVE;
32
+ case "Enter":
33
+ return resolve(input, "down", "start");
34
+ default:
35
+ return NATIVE;
36
+ }
37
+ }
38
+ export {
39
+ bridgeKey,
40
+ gridSize
41
+ };
42
+ //# sourceMappingURL=bridgeRules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/tablev2/bridgeRules.ts"],"sourcesContent":["/**\n * The bridge's key decisions (ADR 0001): given where the caret sits inside a\n * cell, either the browser handles the key natively (mid-text editing) or the\n * bridge takes over at a boundary — stepping to a neighbour cell or exiting\n * the table. Pure — the grid math delegates to {@link stepCell}; geometry\n * (wrapped-line detection) arrives as booleans computed by the surface.\n *\n * Structural invariant: no key ever merges cells or rows. Backspace/Delete at\n * a cell edge NAVIGATES; structure changes only happen through explicit\n * commands (tableEditCommands).\n */\n\nimport { type NavDir, type NavTarget, rowCount, stepGrid } from \"../table/tableCellNav\";\nimport { type TableModel } from \"../table/tableModel\";\n\nexport type BridgeKey =\n | \"Tab\"\n | \"Shift-Tab\"\n | \"ArrowRight\"\n | \"ArrowLeft\"\n | \"ArrowUp\"\n | \"ArrowDown\"\n | \"Backspace\"\n | \"Delete\"\n | \"Enter\";\n\nexport interface BridgeInput {\n /** Grid dimensions: rows includes the header. */\n rows: number;\n cols: number;\n /** Caret cell (row 0 = header) and text position. */\n row: number;\n col: number;\n offset: number;\n length: number;\n /** Real-geometry flags from the surface (wrapped cells). */\n onFirstVisualLine: boolean;\n onLastVisualLine: boolean;\n}\n\nexport type BridgeAction =\n | { kind: \"native\" }\n | { kind: \"focusCell\"; row: number; col: number; caret: \"start\" | \"end\" }\n | { kind: \"exit\"; edge: \"before\" | \"after\" };\n\nconst NATIVE: BridgeAction = { kind: \"native\" };\n\n/** Dimensions of `model` as BridgeInput expects them. */\nexport function gridSize(model: TableModel): { rows: number; cols: number } {\n return { rows: rowCount(model), cols: model.data.header.length };\n}\n\nfunction resolve(input: BridgeInput, dir: NavDir, caret: \"start\" | \"end\"): BridgeAction {\n const target: NavTarget = stepGrid(input.rows, input.cols, input.row, input.col, dir);\n if (target.kind === \"cell\") return { kind: \"focusCell\", row: target.row, col: target.col, caret };\n return { kind: \"exit\", edge: target.edge === \"above\" || target.edge === \"before\" ? \"before\" : \"after\" };\n}\n\nexport function bridgeKey(input: BridgeInput, key: BridgeKey): BridgeAction {\n const atStart = input.offset === 0;\n const atEnd = input.offset >= input.length;\n switch (key) {\n case \"Tab\":\n return resolve(input, \"next\", \"start\");\n case \"Shift-Tab\":\n return resolve(input, \"prev\", \"end\");\n case \"ArrowRight\":\n return atEnd ? resolve(input, \"next\", \"start\") : NATIVE;\n case \"ArrowLeft\":\n return atStart ? resolve(input, \"prev\", \"end\") : NATIVE;\n case \"ArrowDown\":\n return input.onLastVisualLine ? resolve(input, \"down\", \"start\") : NATIVE;\n case \"ArrowUp\":\n return input.onFirstVisualLine ? resolve(input, \"up\", \"start\") : NATIVE;\n case \"Backspace\":\n return atStart ? resolve(input, \"prev\", \"end\") : NATIVE;\n case \"Delete\":\n return atEnd ? resolve(input, \"next\", \"start\") : NATIVE;\n case \"Enter\":\n return resolve(input, \"down\", \"start\");\n default:\n return NATIVE;\n }\n}\n"],"mappings":";AAYA,SAAsC,UAAU,gBAAgB;AAiChE,MAAM,SAAuB,EAAE,MAAM,SAAS;AAGvC,SAAS,SAAS,OAAmD;AAC1E,SAAO,EAAE,MAAM,SAAS,KAAK,GAAG,MAAM,MAAM,KAAK,OAAO,OAAO;AACjE;AAEA,SAAS,QAAQ,OAAoB,KAAa,OAAsC;AACtF,QAAM,SAAoB,SAAS,MAAM,MAAM,MAAM,MAAM,MAAM,KAAK,MAAM,KAAK,GAAG;AACpF,MAAI,OAAO,SAAS,OAAQ,QAAO,EAAE,MAAM,aAAa,KAAK,OAAO,KAAK,KAAK,OAAO,KAAK,MAAM;AAChG,SAAO,EAAE,MAAM,QAAQ,MAAM,OAAO,SAAS,WAAW,OAAO,SAAS,WAAW,WAAW,QAAQ;AACxG;AAEO,SAAS,UAAU,OAAoB,KAA8B;AAC1E,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,QAAQ,MAAM,UAAU,MAAM;AACpC,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO,QAAQ,OAAO,QAAQ,OAAO;AAAA,IACvC,KAAK;AACH,aAAO,QAAQ,OAAO,QAAQ,KAAK;AAAA,IACrC,KAAK;AACH,aAAO,QAAQ,QAAQ,OAAO,QAAQ,OAAO,IAAI;AAAA,IACnD,KAAK;AACH,aAAO,UAAU,QAAQ,OAAO,QAAQ,KAAK,IAAI;AAAA,IACnD,KAAK;AACH,aAAO,MAAM,mBAAmB,QAAQ,OAAO,QAAQ,OAAO,IAAI;AAAA,IACpE,KAAK;AACH,aAAO,MAAM,oBAAoB,QAAQ,OAAO,MAAM,OAAO,IAAI;AAAA,IACnE,KAAK;AACH,aAAO,UAAU,QAAQ,OAAO,QAAQ,KAAK,IAAI;AAAA,IACnD,KAAK;AACH,aAAO,QAAQ,QAAQ,OAAO,QAAQ,OAAO,IAAI;AAAA,IACnD,KAAK;AACH,aAAO,QAAQ,OAAO,QAAQ,OAAO;AAAA,IACvC;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
@@ -0,0 +1,79 @@
1
+ import { ChangeDesc, EditorState } from '@codemirror/state';
2
+ import { EditorView } from '@codemirror/view';
3
+
4
+ /**
5
+ * The swappable cell-editing seam (ADR 0001 §Editing surface).
6
+ *
7
+ * The table model, bridge rules, commands, and menu are identical for both
8
+ * candidate surfaces; only *where typing physically happens* differs:
9
+ *
10
+ * - inline (B): the cell `<td>` itself becomes contenteditable.
11
+ * - overlay (C): one shared editor is positioned over the cell rect,
12
+ * portaled outside CodeMirror's DOM.
13
+ *
14
+ * A surface manages at most ONE active edit. It is told about document
15
+ * changes (`mapThrough`) and widget DOM updates (`reanchor`) by the tableV2
16
+ * extension, and resolves the cell's CURRENT source range only at commit
17
+ * time — so edits merge cleanly with concurrent external changes.
18
+ */
19
+
20
+ interface CellRef {
21
+ /** 0 = header row; 1.. = body rows. */
22
+ row: number;
23
+ col: number;
24
+ }
25
+ interface ActiveEdit {
26
+ ref: CellRef;
27
+ /** Live unescaped cell text. */
28
+ text: string;
29
+ /** Caret offset within `text`. */
30
+ caret: number;
31
+ }
32
+ interface CellEditingSurface {
33
+ readonly kind: "inline" | "overlay";
34
+ /** Begin editing `ref` in the table anchored at `tableFrom` (source start).
35
+ * Returns false when the cell can't be resolved. */
36
+ begin(view: EditorView, tableFrom: number, ref: CellRef, caret?: number): boolean;
37
+ active(): ActiveEdit | null;
38
+ /** The DOM element that hosts typing while an edit is active. */
39
+ editingElement(): HTMLElement | null;
40
+ /** Move the active edit's caret — DOM selection AND the live mirror, so a
41
+ * bridge key arriving before the async selectionchange reads the truth. */
42
+ placeCaret(offset: number): void;
43
+ /** The current source position of the active edit's table, or null. */
44
+ anchor(): number | null;
45
+ /** Keep the table anchor position current across document changes. */
46
+ mapThrough(changes: ChangeDesc): void;
47
+ /** Called after the widget DOM was patched or recreated: re-attach the
48
+ * editing UI, preserving live text, caret, and focus. */
49
+ reanchor(view: EditorView): void;
50
+ /** Resolve the cell's current range and write the live text (if changed);
51
+ * ends the edit. */
52
+ commit(view: EditorView): void;
53
+ /** End the edit without writing. */
54
+ cancel(): void;
55
+ }
56
+ /** The rendered element for a cell, resolved through the widget's CURRENT
57
+ * source-anchor stamp (re-stamped on every toDOM/updateDOM). */
58
+ declare function cellElement(view: EditorView, tableFrom: number, ref: CellRef): HTMLElement | null;
59
+ /** The cell's current source range, from the freshly-parsed model. */
60
+ declare function cellRange(state: EditorState, tableFrom: number, ref: CellRef): {
61
+ from: number;
62
+ to: number;
63
+ } | null;
64
+ /** Collapse the selection at `offset` within `el` (flat text content). */
65
+ declare function setCaret(el: HTMLElement, offset: number): void;
66
+ /** The selection's caret offset within `el`, or null when it's elsewhere. */
67
+ declare function caretOffset(el: HTMLElement): number | null;
68
+ /** Caret offset at a viewport point inside `el`, or null when the point
69
+ * resolves elsewhere (borders, padding gutters). WebKit API. */
70
+ declare function offsetAtPoint(el: HTMLElement, x: number, y: number): number | null;
71
+ /** Whether the caret sits on the first/last VISUAL line of `el` — a wrapped
72
+ * cell spans several. Vertical bridge motion only leaves the cell from its
73
+ * edge lines. Empty or unmeasurable selections count as single-line. */
74
+ declare function visualEdges(el: HTMLElement): {
75
+ onFirstVisualLine: boolean;
76
+ onLastVisualLine: boolean;
77
+ };
78
+
79
+ export { type ActiveEdit, type CellEditingSurface, type CellRef, caretOffset, cellElement, cellRange, offsetAtPoint, setCaret, visualEdges };
@@ -0,0 +1,70 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ import { cellAt } from "../table/tableCellNav.js";
3
+ import { modelAt } from "../table/tableGeometry.js";
4
+ function cellElement(view, tableFrom, ref) {
5
+ for (const wrap of view.dom.querySelectorAll("[data-tablev2-from]")) {
6
+ if (Number(wrap.dataset.tablev2From) !== tableFrom) continue;
7
+ return wrap.querySelector(`[data-row="${ref.row}"][data-col="${ref.col}"]`);
8
+ }
9
+ return null;
10
+ }
11
+ function cellRange(state, tableFrom, ref) {
12
+ const model = modelAt(state, tableFrom);
13
+ if (!model) return null;
14
+ const cell = cellAt(model, ref.row, ref.col);
15
+ return cell ? { from: cell.from, to: cell.to } : null;
16
+ }
17
+ function setCaret(el, offset) {
18
+ let textNode = el.firstChild;
19
+ if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
20
+ textNode = el.ownerDocument.createTextNode(el.textContent ?? "");
21
+ el.textContent = "";
22
+ el.appendChild(textNode);
23
+ }
24
+ const max = textNode.textContent?.length ?? 0;
25
+ el.ownerDocument.getSelection()?.collapse(textNode, Math.max(0, Math.min(offset, max)));
26
+ }
27
+ function caretOffset(el) {
28
+ const sel = el.ownerDocument.getSelection();
29
+ if (!sel || sel.rangeCount === 0) return null;
30
+ const range = sel.getRangeAt(0);
31
+ if (!el.contains(range.startContainer)) return null;
32
+ const pre = range.cloneRange();
33
+ pre.selectNodeContents(el);
34
+ pre.setEnd(range.startContainer, range.startOffset);
35
+ return pre.toString().length;
36
+ }
37
+ function offsetAtPoint(el, x, y) {
38
+ const doc = el.ownerDocument;
39
+ const range = doc.caretRangeFromPoint?.(x, y);
40
+ if (!range || !el.contains(range.startContainer)) return null;
41
+ const pre = range.cloneRange();
42
+ pre.selectNodeContents(el);
43
+ pre.setEnd(range.startContainer, range.startOffset);
44
+ return pre.toString().length;
45
+ }
46
+ function visualEdges(el) {
47
+ const single = { onFirstVisualLine: true, onLastVisualLine: true };
48
+ const sel = el.ownerDocument.getSelection();
49
+ if (!sel || sel.rangeCount === 0) return single;
50
+ const range = sel.getRangeAt(0);
51
+ if (!el.contains(range.startContainer)) return single;
52
+ const rects = range.getClientRects();
53
+ if (rects.length === 0) return single;
54
+ const caret = rects[0];
55
+ const elRect = el.getBoundingClientRect();
56
+ const line = caret.height || parseFloat(getComputedStyle(el).lineHeight) || 16;
57
+ return {
58
+ onFirstVisualLine: caret.top - elRect.top < line * 0.75,
59
+ onLastVisualLine: elRect.bottom - caret.bottom < line * 0.75
60
+ };
61
+ }
62
+ export {
63
+ caretOffset,
64
+ cellElement,
65
+ cellRange,
66
+ offsetAtPoint,
67
+ setCaret,
68
+ visualEdges
69
+ };
70
+ //# sourceMappingURL=cellEditingSurface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/tablev2/cellEditingSurface.ts"],"sourcesContent":["/**\n * The swappable cell-editing seam (ADR 0001 §Editing surface).\n *\n * The table model, bridge rules, commands, and menu are identical for both\n * candidate surfaces; only *where typing physically happens* differs:\n *\n * - inline (B): the cell `<td>` itself becomes contenteditable.\n * - overlay (C): one shared editor is positioned over the cell rect,\n * portaled outside CodeMirror's DOM.\n *\n * A surface manages at most ONE active edit. It is told about document\n * changes (`mapThrough`) and widget DOM updates (`reanchor`) by the tableV2\n * extension, and resolves the cell's CURRENT source range only at commit\n * time — so edits merge cleanly with concurrent external changes.\n */\n\nimport { type ChangeDesc, type EditorState } from \"@codemirror/state\";\nimport { type EditorView } from \"@codemirror/view\";\n\nimport { cellAt } from \"../table/tableCellNav\";\nimport { modelAt } from \"../table/tableGeometry\";\n\nexport interface CellRef {\n /** 0 = header row; 1.. = body rows. */\n row: number;\n col: number;\n}\n\nexport interface ActiveEdit {\n ref: CellRef;\n /** Live unescaped cell text. */\n text: string;\n /** Caret offset within `text`. */\n caret: number;\n}\n\nexport interface CellEditingSurface {\n readonly kind: \"inline\" | \"overlay\";\n /** Begin editing `ref` in the table anchored at `tableFrom` (source start).\n * Returns false when the cell can't be resolved. */\n begin(view: EditorView, tableFrom: number, ref: CellRef, caret?: number): boolean;\n active(): ActiveEdit | null;\n /** The DOM element that hosts typing while an edit is active. */\n editingElement(): HTMLElement | null;\n /** Move the active edit's caret — DOM selection AND the live mirror, so a\n * bridge key arriving before the async selectionchange reads the truth. */\n placeCaret(offset: number): void;\n /** The current source position of the active edit's table, or null. */\n anchor(): number | null;\n /** Keep the table anchor position current across document changes. */\n mapThrough(changes: ChangeDesc): void;\n /** Called after the widget DOM was patched or recreated: re-attach the\n * editing UI, preserving live text, caret, and focus. */\n reanchor(view: EditorView): void;\n /** Resolve the cell's current range and write the live text (if changed);\n * ends the edit. */\n commit(view: EditorView): void;\n /** End the edit without writing. */\n cancel(): void;\n}\n\n/** The rendered element for a cell, resolved through the widget's CURRENT\n * source-anchor stamp (re-stamped on every toDOM/updateDOM). */\nexport function cellElement(\n view: EditorView,\n tableFrom: number,\n ref: CellRef,\n): HTMLElement | null {\n for (const wrap of view.dom.querySelectorAll<HTMLElement>(\"[data-tablev2-from]\")) {\n if (Number(wrap.dataset.tablev2From) !== tableFrom) continue;\n return wrap.querySelector<HTMLElement>(`[data-row=\"${ref.row}\"][data-col=\"${ref.col}\"]`);\n }\n return null;\n}\n\n/** The cell's current source range, from the freshly-parsed model. */\nexport function cellRange(\n state: EditorState,\n tableFrom: number,\n ref: CellRef,\n): { from: number; to: number } | null {\n const model = modelAt(state, tableFrom);\n if (!model) return null;\n const cell = cellAt(model, ref.row, ref.col);\n return cell ? { from: cell.from, to: cell.to } : null;\n}\n\n/** Collapse the selection at `offset` within `el` (flat text content). */\nexport function setCaret(el: HTMLElement, offset: number): void {\n let textNode = el.firstChild;\n if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {\n textNode = el.ownerDocument.createTextNode(el.textContent ?? \"\");\n el.textContent = \"\";\n el.appendChild(textNode);\n }\n const max = textNode.textContent?.length ?? 0;\n el.ownerDocument.getSelection()?.collapse(textNode, Math.max(0, Math.min(offset, max)));\n}\n\n/** The selection's caret offset within `el`, or null when it's elsewhere. */\nexport function caretOffset(el: HTMLElement): number | null {\n const sel = el.ownerDocument.getSelection();\n if (!sel || sel.rangeCount === 0) return null;\n const range = sel.getRangeAt(0);\n if (!el.contains(range.startContainer)) return null;\n const pre = range.cloneRange();\n pre.selectNodeContents(el);\n pre.setEnd(range.startContainer, range.startOffset);\n return pre.toString().length;\n}\n\n/** Caret offset at a viewport point inside `el`, or null when the point\n * resolves elsewhere (borders, padding gutters). WebKit API. */\nexport function offsetAtPoint(el: HTMLElement, x: number, y: number): number | null {\n const doc = el.ownerDocument as Document & {\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n };\n const range = doc.caretRangeFromPoint?.(x, y);\n if (!range || !el.contains(range.startContainer)) return null;\n const pre = range.cloneRange();\n pre.selectNodeContents(el);\n pre.setEnd(range.startContainer, range.startOffset);\n return pre.toString().length;\n}\n\n/** Whether the caret sits on the first/last VISUAL line of `el` — a wrapped\n * cell spans several. Vertical bridge motion only leaves the cell from its\n * edge lines. Empty or unmeasurable selections count as single-line. */\nexport function visualEdges(el: HTMLElement): {\n onFirstVisualLine: boolean;\n onLastVisualLine: boolean;\n} {\n const single = { onFirstVisualLine: true, onLastVisualLine: true };\n const sel = el.ownerDocument.getSelection();\n if (!sel || sel.rangeCount === 0) return single;\n const range = sel.getRangeAt(0);\n if (!el.contains(range.startContainer)) return single;\n const rects = range.getClientRects();\n if (rects.length === 0) return single;\n const caret = rects[0];\n const elRect = el.getBoundingClientRect();\n const line = caret.height || parseFloat(getComputedStyle(el).lineHeight) || 16;\n return {\n onFirstVisualLine: caret.top - elRect.top < line * 0.75,\n onLastVisualLine: elRect.bottom - caret.bottom < line * 0.75,\n };\n}\n"],"mappings":";AAmBA,SAAS,cAAc;AACvB,SAAS,eAAe;AA2CjB,SAAS,YACd,MACA,WACA,KACoB;AACpB,aAAW,QAAQ,KAAK,IAAI,iBAA8B,qBAAqB,GAAG;AAChF,QAAI,OAAO,KAAK,QAAQ,WAAW,MAAM,UAAW;AACpD,WAAO,KAAK,cAA2B,cAAc,IAAI,GAAG,gBAAgB,IAAI,GAAG,IAAI;AAAA,EACzF;AACA,SAAO;AACT;AAGO,SAAS,UACd,OACA,WACA,KACqC;AACrC,QAAM,QAAQ,QAAQ,OAAO,SAAS;AACtC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,OAAO,OAAO,IAAI,KAAK,IAAI,GAAG;AAC3C,SAAO,OAAO,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,GAAG,IAAI;AACnD;AAGO,SAAS,SAAS,IAAiB,QAAsB;AAC9D,MAAI,WAAW,GAAG;AAClB,MAAI,CAAC,YAAY,SAAS,aAAa,KAAK,WAAW;AACrD,eAAW,GAAG,cAAc,eAAe,GAAG,eAAe,EAAE;AAC/D,OAAG,cAAc;AACjB,OAAG,YAAY,QAAQ;AAAA,EACzB;AACA,QAAM,MAAM,SAAS,aAAa,UAAU;AAC5C,KAAG,cAAc,aAAa,GAAG,SAAS,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,GAAG,CAAC,CAAC;AACxF;AAGO,SAAS,YAAY,IAAgC;AAC1D,QAAM,MAAM,GAAG,cAAc,aAAa;AAC1C,MAAI,CAAC,OAAO,IAAI,eAAe,EAAG,QAAO;AACzC,QAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,MAAI,CAAC,GAAG,SAAS,MAAM,cAAc,EAAG,QAAO;AAC/C,QAAM,MAAM,MAAM,WAAW;AAC7B,MAAI,mBAAmB,EAAE;AACzB,MAAI,OAAO,MAAM,gBAAgB,MAAM,WAAW;AAClD,SAAO,IAAI,SAAS,EAAE;AACxB;AAIO,SAAS,cAAc,IAAiB,GAAW,GAA0B;AAClF,QAAM,MAAM,GAAG;AAGf,QAAM,QAAQ,IAAI,sBAAsB,GAAG,CAAC;AAC5C,MAAI,CAAC,SAAS,CAAC,GAAG,SAAS,MAAM,cAAc,EAAG,QAAO;AACzD,QAAM,MAAM,MAAM,WAAW;AAC7B,MAAI,mBAAmB,EAAE;AACzB,MAAI,OAAO,MAAM,gBAAgB,MAAM,WAAW;AAClD,SAAO,IAAI,SAAS,EAAE;AACxB;AAKO,SAAS,YAAY,IAG1B;AACA,QAAM,SAAS,EAAE,mBAAmB,MAAM,kBAAkB,KAAK;AACjE,QAAM,MAAM,GAAG,cAAc,aAAa;AAC1C,MAAI,CAAC,OAAO,IAAI,eAAe,EAAG,QAAO;AACzC,QAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,MAAI,CAAC,GAAG,SAAS,MAAM,cAAc,EAAG,QAAO;AAC/C,QAAM,QAAQ,MAAM,eAAe;AACnC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,QAAQ,MAAM,CAAC;AACrB,QAAM,SAAS,GAAG,sBAAsB;AACxC,QAAM,OAAO,MAAM,UAAU,WAAW,iBAAiB,EAAE,EAAE,UAAU,KAAK;AAC5E,SAAO;AAAA,IACL,mBAAmB,MAAM,MAAM,OAAO,MAAM,OAAO;AAAA,IACnD,kBAAkB,OAAO,SAAS,MAAM,SAAS,OAAO;AAAA,EAC1D;AACF;","names":[]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Cell text ↔ source transforms (GFM). A raw `|` inside a cell starts a new
3
+ * column; the only literal pipe is `\|`. Surfaces edit the UNESCAPED text and
4
+ * re-escape on commit, so typing `|` in a cell can never shift the row.
5
+ * Canonical home for the redesign (ADR 0001); the nested-editor copies retire
6
+ * with `tableCellSubview.ts`.
7
+ */
8
+ declare function unescapePipes(source: string): string;
9
+ declare function escapePipes(text: string): string;
10
+
11
+ export { escapePipes, unescapePipes };
@@ -0,0 +1,12 @@
1
+ import "../../chunk-V6TY7KAL.js";
2
+ function unescapePipes(source) {
3
+ return source.replace(/\\\|/g, "|");
4
+ }
5
+ function escapePipes(text) {
6
+ return text.replace(/\|/g, "\\|");
7
+ }
8
+ export {
9
+ escapePipes,
10
+ unescapePipes
11
+ };
12
+ //# sourceMappingURL=cellText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/codemirror/tablev2/cellText.ts"],"sourcesContent":["/**\n * Cell text ↔ source transforms (GFM). A raw `|` inside a cell starts a new\n * column; the only literal pipe is `\\|`. Surfaces edit the UNESCAPED text and\n * re-escape on commit, so typing `|` in a cell can never shift the row.\n * Canonical home for the redesign (ADR 0001); the nested-editor copies retire\n * with `tableCellSubview.ts`.\n */\n\nexport function unescapePipes(source: string): string {\n return source.replace(/\\\\\\|/g, \"|\");\n}\n\nexport function escapePipes(text: string): string {\n return text.replace(/\\|/g, \"\\\\|\");\n}\n"],"mappings":";AAQO,SAAS,cAAc,QAAwB;AACpD,SAAO,OAAO,QAAQ,SAAS,GAAG;AACpC;AAEO,SAAS,YAAY,MAAsB;AAChD,SAAO,KAAK,QAAQ,OAAO,KAAK;AAClC;","names":[]}
@@ -0,0 +1,38 @@
1
+ import { ChangeDesc } from '@codemirror/state';
2
+ import { EditorView } from '@codemirror/view';
3
+ import { CellEditingSurface, CellRef, ActiveEdit } from './cellEditingSurface.js';
4
+
5
+ /**
6
+ * Surface B — the cell `<td>` itself edits (ADR 0001 §Editing surface).
7
+ *
8
+ * `begin` swaps the rendered cell content for the raw text and flips the cell
9
+ * to `contenteditable="plaintext-only"`; the browser owns caret, typing, and
10
+ * intra-cell selection from there. Live text and caret are mirrored into
11
+ * surface state on every input/selection change, because the DOM copy is NOT
12
+ * durable: any widget patch rewrites cell innerHTML from (stale) data, and a
13
+ * full widget recreate replaces the element wholesale. `reanchor` restores
14
+ * text, caret, and focus onto whatever element currently renders the cell.
15
+ */
16
+
17
+ declare class InlineCellSurface implements CellEditingSurface {
18
+ readonly kind: "inline";
19
+ private edit;
20
+ private readonly onInput;
21
+ private readonly onSelectionChange;
22
+ private readonly onFocusOut;
23
+ private readonly onBeforeInput;
24
+ begin(view: EditorView, tableFrom: number, ref: CellRef, caret?: number): boolean;
25
+ active(): ActiveEdit | null;
26
+ editingElement(): HTMLElement | null;
27
+ placeCaret(offset: number): void;
28
+ anchor(): number | null;
29
+ mapThrough(changes: ChangeDesc): void;
30
+ reanchor(view: EditorView): void;
31
+ commit(view: EditorView): void;
32
+ cancel(): void;
33
+ private attach;
34
+ private applyEditableState;
35
+ private teardown;
36
+ }
37
+
38
+ export { InlineCellSurface };