@bendyline/squisq-editor-react 2.0.1 → 2.2.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 (357) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +40 -0
  3. package/README.md +10 -2
  4. package/dist/index.d.ts +683 -60
  5. package/dist/index.js +9648 -3750
  6. package/dist/monaco.js +0 -1
  7. package/dist/styles/index.css +1160 -241
  8. package/package.json +10 -6
  9. package/dist/index.js.map +0 -1
  10. package/dist/monaco.js.map +0 -1
  11. package/src/BlockCardView.tsx +0 -121
  12. package/src/BlockPreviewPanel.tsx +0 -69
  13. package/src/BlockPropertiesPopover.tsx +0 -222
  14. package/src/DocumentSettingsDialog.tsx +0 -272
  15. package/src/DropZoneOverlay.tsx +0 -137
  16. package/src/EditorContext.tsx +0 -1247
  17. package/src/EditorShell.tsx +0 -1334
  18. package/src/EmojiPicker.tsx +0 -332
  19. package/src/FolderView.tsx +0 -131
  20. package/src/Icon.tsx +0 -26
  21. package/src/ImageEditor.tsx +0 -395
  22. package/src/ImageNodeView.tsx +0 -284
  23. package/src/ImageViewer.tsx +0 -221
  24. package/src/InlineIcon.ts +0 -84
  25. package/src/InlinePreviewGutter.tsx +0 -590
  26. package/src/LinkDialog.tsx +0 -276
  27. package/src/MediaBin.tsx +0 -500
  28. package/src/MentionExtension.tsx +0 -261
  29. package/src/OutlinePanel.tsx +0 -547
  30. package/src/PlainHtmlPreview.tsx +0 -277
  31. package/src/PreviewControls.tsx +0 -1250
  32. package/src/PreviewPanel.tsx +0 -422
  33. package/src/RawEditor.tsx +0 -731
  34. package/src/RecorderEntry.tsx +0 -159
  35. package/src/StatusBar.tsx +0 -51
  36. package/src/TemplateAnnotation.ts +0 -167
  37. package/src/TemplateContentPreview.tsx +0 -56
  38. package/src/TemplatePicker.tsx +0 -1314
  39. package/src/ThemeCustomizerPanel.tsx +0 -304
  40. package/src/ThemePicker.tsx +0 -433
  41. package/src/TimelineBlockPreview.tsx +0 -37
  42. package/src/TimelineTrack.tsx +0 -671
  43. package/src/Toolbar.tsx +0 -2587
  44. package/src/Tooltip.tsx +0 -142
  45. package/src/TransitionPicker.tsx +0 -390
  46. package/src/VersionHistoryPanel.tsx +0 -359
  47. package/src/ViewMenuPanel.tsx +0 -189
  48. package/src/ViewSwitcher.tsx +0 -56
  49. package/src/WysiwygEditor.tsx +0 -792
  50. package/src/__tests__/blockProperties.test.ts +0 -92
  51. package/src/__tests__/blockPropertiesPopoverTheme.test.tsx +0 -33
  52. package/src/__tests__/blockRange.test.ts +0 -105
  53. package/src/__tests__/blockTagActivity.test.ts +0 -183
  54. package/src/__tests__/buildDocumentPreviewMarkdown.test.ts +0 -75
  55. package/src/__tests__/buildPreviewDocContent.test.ts +0 -48
  56. package/src/__tests__/buildPreviewDocTransition.test.ts +0 -92
  57. package/src/__tests__/canvasSurfaceTextEditing.test.tsx +0 -60
  58. package/src/__tests__/codeContextSectionView.test.tsx +0 -97
  59. package/src/__tests__/codeContextZoneManager.test.ts +0 -127
  60. package/src/__tests__/createShapeLayer.test.ts +0 -46
  61. package/src/__tests__/customLayoutManagerTheme.test.tsx +0 -34
  62. package/src/__tests__/detectMarkdown.test.ts +0 -73
  63. package/src/__tests__/diffContextSections.test.ts +0 -39
  64. package/src/__tests__/documentSettingsDialog.test.tsx +0 -197
  65. package/src/__tests__/drawingShapeRoundTrip.test.ts +0 -49
  66. package/src/__tests__/editorScrollHandoff.test.tsx +0 -102
  67. package/src/__tests__/editorScrollSync.test.ts +0 -65
  68. package/src/__tests__/editorShellCodeContext.test.tsx +0 -86
  69. package/src/__tests__/editorShellProps.test.tsx +0 -485
  70. package/src/__tests__/embeddedMedia.test.ts +0 -48
  71. package/src/__tests__/emojiPicker.test.tsx +0 -93
  72. package/src/__tests__/fileKind.test.ts +0 -112
  73. package/src/__tests__/headingTransition.test.ts +0 -176
  74. package/src/__tests__/imageEditAffordance.test.tsx +0 -272
  75. package/src/__tests__/imageEditModalContract.test.tsx +0 -119
  76. package/src/__tests__/imageEditorShell.test.tsx +0 -94
  77. package/src/__tests__/imageEditorState.test.ts +0 -171
  78. package/src/__tests__/inlinePreviewGutter.test.tsx +0 -62
  79. package/src/__tests__/inlinePreviewGutterAllBlocks.test.tsx +0 -103
  80. package/src/__tests__/jsonEditor.test.tsx +0 -223
  81. package/src/__tests__/layersPanel.test.tsx +0 -167
  82. package/src/__tests__/layoutChildRoundTrip.test.ts +0 -71
  83. package/src/__tests__/linkDialogDocPicker.test.tsx +0 -137
  84. package/src/__tests__/majorApiTypes.test.ts +0 -26
  85. package/src/__tests__/mediaAttachmentFlow.test.ts +0 -110
  86. package/src/__tests__/mediaBinDrop.test.tsx +0 -90
  87. package/src/__tests__/mediaReferences.test.ts +0 -82
  88. package/src/__tests__/narrationSave.test.ts +0 -148
  89. package/src/__tests__/outlinePanel.test.tsx +0 -169
  90. package/src/__tests__/outlineSource.test.ts +0 -217
  91. package/src/__tests__/plainHtmlPreview.test.tsx +0 -125
  92. package/src/__tests__/presentationMode.test.tsx +0 -290
  93. package/src/__tests__/previewControls.test.tsx +0 -540
  94. package/src/__tests__/previewPanelAudioFailure.test.tsx +0 -46
  95. package/src/__tests__/previewPanelPresentation.test.tsx +0 -126
  96. package/src/__tests__/previewPanelTransforms.test.tsx +0 -117
  97. package/src/__tests__/propertiesPanel.test.tsx +0 -69
  98. package/src/__tests__/rawEditorModelIsolation.test.ts +0 -19
  99. package/src/__tests__/recorderFormats.test.ts +0 -146
  100. package/src/__tests__/recorderMediaInsert.test.ts +0 -86
  101. package/src/__tests__/recorderTheme.test.tsx +0 -42
  102. package/src/__tests__/recorderTimingJson.test.ts +0 -41
  103. package/src/__tests__/resolveBlockVisual.test.ts +0 -43
  104. package/src/__tests__/selectionConversions.test.ts +0 -80
  105. package/src/__tests__/statusBar.test.tsx +0 -27
  106. package/src/__tests__/teleprompter.test.tsx +0 -190
  107. package/src/__tests__/templateAnnotationRoundTrip.test.ts +0 -99
  108. package/src/__tests__/templateContentPreview.test.ts +0 -101
  109. package/src/__tests__/templatePickerMetadata.test.ts +0 -32
  110. package/src/__tests__/templatePickerPortal.test.tsx +0 -62
  111. package/src/__tests__/timelineSource.test.ts +0 -134
  112. package/src/__tests__/tiptapBridge.test.ts +0 -566
  113. package/src/__tests__/tiptapBridgeConformance.test.ts +0 -47
  114. package/src/__tests__/tiptapCodeBlockRoundTrip.test.ts +0 -109
  115. package/src/__tests__/tiptapImageRoundTrip.test.ts +0 -73
  116. package/src/__tests__/toolbarSelectionConversion.test.tsx +0 -164
  117. package/src/__tests__/tooltip.test.tsx +0 -72
  118. package/src/__tests__/transformStyleId.test.ts +0 -13
  119. package/src/__tests__/transitionCatalog.test.ts +0 -64
  120. package/src/__tests__/useBlockNavigator.test.tsx +0 -67
  121. package/src/__tests__/useImageEditor.test.tsx +0 -226
  122. package/src/__tests__/useJsonEditorTokens.test.ts +0 -59
  123. package/src/__tests__/useMediaRecorder.test.ts +0 -302
  124. package/src/__tests__/useTimelineClock.test.ts +0 -21
  125. package/src/__tests__/versionHistory.test.tsx +0 -197
  126. package/src/__tests__/viewMenuPanel.test.tsx +0 -130
  127. package/src/__tests__/wysiwygImageUpload.test.ts +0 -69
  128. package/src/__tests__/wysiwygTemplateBadgeFocus.test.tsx +0 -56
  129. package/src/asciiDiagram/AsciiDiagramExtension.ts +0 -343
  130. package/src/asciiDiagram/AsciiDiagramWidget.tsx +0 -254
  131. package/src/asciiDiagram/RepairableDiagramExtension.ts +0 -200
  132. package/src/asciiDiagram/__tests__/AsciiDiagramExtension.test.ts +0 -145
  133. package/src/asciiDiagram/__tests__/RepairableDiagramExtension.test.ts +0 -159
  134. package/src/asciiDiagram/__tests__/asciiDiagramCommands.test.ts +0 -284
  135. package/src/asciiDiagram/__tests__/asciiDiagramOps.test.ts +0 -114
  136. package/src/asciiDiagram/__tests__/asciiPaste.test.ts +0 -43
  137. package/src/asciiDiagram/asciiDiagramCommands.ts +0 -174
  138. package/src/asciiDiagram/asciiDiagramData.ts +0 -149
  139. package/src/asciiDiagram/asciiDiagramOps.ts +0 -238
  140. package/src/asciiDiagram/asciiPaste.ts +0 -19
  141. package/src/blockProperties.ts +0 -88
  142. package/src/blockRange.ts +0 -132
  143. package/src/blockSlice.ts +0 -75
  144. package/src/blockTagActivity.ts +0 -233
  145. package/src/buildDocumentPreviewMarkdown.ts +0 -168
  146. package/src/buildPreviewDoc.ts +0 -405
  147. package/src/codeContext/CodeContextSectionView.tsx +0 -124
  148. package/src/codeContext/CodeContextZoneManager.ts +0 -149
  149. package/src/codeContext/CodeContextZones.tsx +0 -121
  150. package/src/codeContext/diffContextSections.ts +0 -38
  151. package/src/codeContext/types.ts +0 -75
  152. package/src/customTemplates/AddBin.tsx +0 -126
  153. package/src/customTemplates/CustomLayoutManager.tsx +0 -234
  154. package/src/customTemplates/CustomTemplateContext.tsx +0 -188
  155. package/src/customTemplates/LayerToolbar.tsx +0 -580
  156. package/src/customTemplates/ShapeGlyph.tsx +0 -47
  157. package/src/customTemplates/TemplateDesigner.tsx +0 -433
  158. package/src/customTemplates/__tests__/library.test.ts +0 -96
  159. package/src/customTemplates/__tests__/normalizePositions.test.ts +0 -109
  160. package/src/customTemplates/__tests__/shapeDefs.test.ts +0 -49
  161. package/src/customTemplates/__tests__/useMemoryLayerAdapter.test.ts +0 -108
  162. package/src/customTemplates/designer.css +0 -732
  163. package/src/customTemplates/index.ts +0 -31
  164. package/src/customTemplates/library.ts +0 -110
  165. package/src/customTemplates/normalizePositions.ts +0 -75
  166. package/src/customTemplates/shapeDefs.ts +0 -131
  167. package/src/customTemplates/thumbnail.tsx +0 -63
  168. package/src/customTemplates/tokenDefs.ts +0 -60
  169. package/src/customTemplates/useDocCustomTemplates.ts +0 -52
  170. package/src/customTemplates/useMemoryLayerAdapter.ts +0 -129
  171. package/src/customThemes/CustomThemeContext.tsx +0 -185
  172. package/src/customThemes/CustomThemeDialog.tsx +0 -316
  173. package/src/customThemes/ImportThemeSection.tsx +0 -178
  174. package/src/customThemes/__tests__/CustomThemeContext.test.tsx +0 -64
  175. package/src/customThemes/__tests__/CustomThemeDialog.test.tsx +0 -47
  176. package/src/customThemes/__tests__/customThemeLibrary.test.ts +0 -60
  177. package/src/customThemes/__tests__/importThemeSection.test.tsx +0 -192
  178. package/src/customThemes/customThemeLibrary.ts +0 -100
  179. package/src/customThemes/index.ts +0 -37
  180. package/src/customThemes/themeControls.tsx +0 -229
  181. package/src/customThemes/themeDraft.ts +0 -288
  182. package/src/customThemes/useDocCustomThemes.ts +0 -49
  183. package/src/detectMarkdown.ts +0 -62
  184. package/src/diagram/DiagramCanvas.tsx +0 -259
  185. package/src/diagram/DiagramMaximizedOverlay.tsx +0 -46
  186. package/src/diagram/diagramCommands.ts +0 -604
  187. package/src/diagram/diagramConstants.ts +0 -17
  188. package/src/diagram/types.ts +0 -35
  189. package/src/editorScrollSync.ts +0 -73
  190. package/src/embeddedMedia.ts +0 -78
  191. package/src/emojiData.ts +0 -1317
  192. package/src/fileKind.ts +0 -158
  193. package/src/frontmatter.ts +0 -29
  194. package/src/frontmatterSettings.ts +0 -23
  195. package/src/headingTransition.ts +0 -291
  196. package/src/hooks/useFileDrop.ts +0 -266
  197. package/src/imageEditor/CanvasSurface.tsx +0 -703
  198. package/src/imageEditor/ImageVersionHistoryDropdown.tsx +0 -396
  199. package/src/imageEditor/LayersPanel.tsx +0 -218
  200. package/src/imageEditor/PropertiesPanel.tsx +0 -474
  201. package/src/imageEditor/Toolbar.tsx +0 -459
  202. package/src/imageEditor/createShapeLayer.ts +0 -280
  203. package/src/imageEditor/icons.tsx +0 -68
  204. package/src/imageEditor/image-editor.css +0 -574
  205. package/src/imageEditor/layers/EditorImageLayer.tsx +0 -45
  206. package/src/imageEditor/layers/EditorShapeLayer.tsx +0 -62
  207. package/src/imageEditor/layers/EditorTextLayer.tsx +0 -45
  208. package/src/imageEditor/layers/SelectionHandles.tsx +0 -86
  209. package/src/imageEditor/state.ts +0 -173
  210. package/src/imageEditor/useImageEditor.ts +0 -385
  211. package/src/imageEditor/useImageEditorTokens.ts +0 -70
  212. package/src/index.ts +0 -470
  213. package/src/jsonEditor/EmbeddedRichTextField.tsx +0 -81
  214. package/src/jsonEditor/JsonEditor.tsx +0 -81
  215. package/src/jsonEditor/JsonEditorContext.tsx +0 -81
  216. package/src/jsonEditor/RenderNode.tsx +0 -87
  217. package/src/jsonEditor/editors.tsx +0 -745
  218. package/src/jsonEditor/index.ts +0 -2
  219. package/src/jsonEditor/json-editor.css +0 -463
  220. package/src/jsonEditor/useJsonEditorTokens.ts +0 -33
  221. package/src/mediaDragMime.ts +0 -32
  222. package/src/mediaEntries.ts +0 -12
  223. package/src/mediaReferences.ts +0 -299
  224. package/src/monaco.ts +0 -35
  225. package/src/monacoWorkers.ts +0 -89
  226. package/src/outlineSource.ts +0 -171
  227. package/src/presentation/PresentationMode.tsx +0 -596
  228. package/src/rawEditorIsolation.ts +0 -18
  229. package/src/recorder/RecorderButton.tsx +0 -80
  230. package/src/recorder/RecorderModal.tsx +0 -706
  231. package/src/recorder/RecorderPanel.tsx +0 -77
  232. package/src/recorder/formats.ts +0 -159
  233. package/src/recorder/hooks/useMediaRecorder.ts +0 -436
  234. package/src/recorder/hooks/useStreamPreview.ts +0 -47
  235. package/src/recorder/insertMediaBlock.ts +0 -30
  236. package/src/recorder/sources/cameraStream.ts +0 -32
  237. package/src/recorder/sources/micStream.ts +0 -25
  238. package/src/recorder/sources/screenStream.ts +0 -162
  239. package/src/recorder/timingJson.ts +0 -66
  240. package/src/resolveBlockVisual.ts +0 -39
  241. package/src/scene/Scene.tsx +0 -616
  242. package/src/scene/SceneBlockExtension.ts +0 -205
  243. package/src/scene/SceneBlockToolbar.tsx +0 -201
  244. package/src/scene/SceneBlockWidget.tsx +0 -441
  245. package/src/scene/ScenePropsBar.tsx +0 -85
  246. package/src/scene/SceneSelection.tsx +0 -111
  247. package/src/scene/SceneSideToolbar.tsx +0 -89
  248. package/src/scene/SceneViewport.tsx +0 -106
  249. package/src/scene/ShapePalette.tsx +0 -196
  250. package/src/scene/__tests__/DiagramAdapter.test.ts +0 -142
  251. package/src/scene/__tests__/SceneBlockExtension.test.ts +0 -33
  252. package/src/scene/__tests__/bezierEdit.test.ts +0 -85
  253. package/src/scene/__tests__/blockLayers.test.ts +0 -57
  254. package/src/scene/__tests__/sceneIsolation.test.tsx +0 -119
  255. package/src/scene/__tests__/shapeLayers.test.ts +0 -106
  256. package/src/scene/__tests__/useSceneHitTest.test.ts +0 -90
  257. package/src/scene/__tests__/useScenePanZoom.test.ts +0 -103
  258. package/src/scene/adapters/DiagramAdapter.ts +0 -79
  259. package/src/scene/adapters/DrawingAdapter.ts +0 -420
  260. package/src/scene/adapters/LayoutAdapter.ts +0 -313
  261. package/src/scene/adapters/blockLayers.ts +0 -159
  262. package/src/scene/commands/SceneCommand.ts +0 -84
  263. package/src/scene/commands/drawingCommands.ts +0 -318
  264. package/src/scene/commands/layoutCommands.ts +0 -301
  265. package/src/scene/hooks/useSceneHitTest.ts +0 -105
  266. package/src/scene/hooks/useScenePanZoom.ts +0 -147
  267. package/src/scene/hooks/useSceneSelection.ts +0 -62
  268. package/src/scene/index.ts +0 -90
  269. package/src/scene/layers/DiagramEdges.tsx +0 -142
  270. package/src/scene/layers/edgeGeometry.ts +0 -104
  271. package/src/scene/layers/nodeCard.tsx +0 -164
  272. package/src/scene/layers/renderLayer.tsx +0 -70
  273. package/src/scene/layers/shapeLayers.ts +0 -201
  274. package/src/scene/paths/bezierEdit.ts +0 -208
  275. package/src/scene/scene.css +0 -792
  276. package/src/scene/text/SceneTextOverlay.tsx +0 -161
  277. package/src/scene/text/sceneTextChannel.ts +0 -46
  278. package/src/scene/text/sceneTextConfig.ts +0 -31
  279. package/src/scene/text/sceneTiptap.ts +0 -36
  280. package/src/scene/text/useSceneTextEditing.ts +0 -39
  281. package/src/scene/tools/ConnectTool.ts +0 -209
  282. package/src/scene/tools/DrawingConnectTool.ts +0 -231
  283. package/src/scene/tools/PathTool.ts +0 -158
  284. package/src/scene/tools/PlaceTool.ts +0 -47
  285. package/src/scene/tools/SceneTool.ts +0 -85
  286. package/src/scene/tools/SelectTool.ts +0 -300
  287. package/src/scene/tools/ShapeTool.ts +0 -143
  288. package/src/scene/tools/TextTool.ts +0 -72
  289. package/src/scene/tools/TokenTool.ts +0 -95
  290. package/src/scene/tools/createDrawShapeTool.ts +0 -82
  291. package/src/selectionConversions.ts +0 -155
  292. package/src/styles/ascii-diagram.css +0 -79
  293. package/src/styles/ascii-timeline.css +0 -596
  294. package/src/styles/code-context.css +0 -155
  295. package/src/styles/diagram.css +0 -183
  296. package/src/styles/editor.css +0 -6811
  297. package/src/styles/folder-view.css +0 -210
  298. package/src/styles/image-edit-affordance.css +0 -201
  299. package/src/styles/index.css +0 -18
  300. package/src/styles/tree-view.css +0 -189
  301. package/src/teleprompter/TeleprompterControls.tsx +0 -218
  302. package/src/teleprompter/TeleprompterSelfView.tsx +0 -22
  303. package/src/teleprompter/TeleprompterSurface.tsx +0 -267
  304. package/src/teleprompter/TeleprompterView.tsx +0 -338
  305. package/src/teleprompter/canvasRenderer.ts +0 -161
  306. package/src/teleprompter/floatingWindow.ts +0 -352
  307. package/src/teleprompter/index.ts +0 -61
  308. package/src/teleprompter/pcmWorklet.ts +0 -62
  309. package/src/teleprompter/recording/insertPreamble.ts +0 -80
  310. package/src/teleprompter/recording/narrationSave.ts +0 -134
  311. package/src/teleprompter/recording/useNarrationRecorder.ts +0 -367
  312. package/src/teleprompter/scrollModel.ts +0 -85
  313. package/src/teleprompter/teleprompterTheme.ts +0 -303
  314. package/src/teleprompter/types.ts +0 -38
  315. package/src/teleprompter/useFloatingWindow.ts +0 -74
  316. package/src/teleprompter/useMicAnalysis.ts +0 -211
  317. package/src/teleprompter/useTeleprompter.ts +0 -421
  318. package/src/templateContentPreviewResolver.ts +0 -360
  319. package/src/timeline/TimelineEditorWidget.tsx +0 -861
  320. package/src/timeline/TimelineViewExtension.ts +0 -252
  321. package/src/timeline/__tests__/TimelineEditorWidget.test.tsx +0 -414
  322. package/src/timeline/__tests__/TimelineViewExtension.test.ts +0 -163
  323. package/src/timeline/__tests__/timelineCommands.test.ts +0 -359
  324. package/src/timeline/__tests__/timelineOps.test.ts +0 -277
  325. package/src/timeline/__tests__/timelinePaste.test.ts +0 -34
  326. package/src/timeline/timelineCommands.ts +0 -421
  327. package/src/timeline/timelineData.ts +0 -54
  328. package/src/timeline/timelineOps.ts +0 -381
  329. package/src/timeline/timelinePaste.ts +0 -8
  330. package/src/timelineSource.ts +0 -244
  331. package/src/tiptap/TiptapAudio.tsx +0 -86
  332. package/src/tiptap/TiptapVideo.tsx +0 -119
  333. package/src/tiptap/useResolvedMediaSrc.ts +0 -47
  334. package/src/tiptapBridge.ts +0 -986
  335. package/src/tooltipPlacement.ts +0 -13
  336. package/src/transformStyleId.ts +0 -17
  337. package/src/transitionCatalog.ts +0 -159
  338. package/src/treeview/TreeOutlineWidget.tsx +0 -390
  339. package/src/treeview/TreeViewExtension.ts +0 -250
  340. package/src/treeview/__tests__/TreeOutlineWidget.test.tsx +0 -156
  341. package/src/treeview/__tests__/TreeViewExtension.test.ts +0 -122
  342. package/src/treeview/__tests__/treeOps.test.ts +0 -177
  343. package/src/treeview/__tests__/treePaste.test.ts +0 -40
  344. package/src/treeview/__tests__/treeViewCommands.test.ts +0 -179
  345. package/src/treeview/treeOps.ts +0 -231
  346. package/src/treeview/treePaste.ts +0 -13
  347. package/src/treeview/treeViewCommands.ts +0 -99
  348. package/src/treeview/treeViewData.ts +0 -41
  349. package/src/types/monaco-shims.d.ts +0 -10
  350. package/src/useBlockNavigator.ts +0 -153
  351. package/src/useHeadingLayout.ts +0 -294
  352. package/src/useMonacoLoader.ts +0 -82
  353. package/src/useTimelineClock.ts +0 -76
  354. package/src/utils/collectInlineFontAwesomeCss.ts +0 -69
  355. package/src/utils/dropUtils.ts +0 -136
  356. package/src/utils/normalizeMalformedAssetUrl.ts +0 -22
  357. package/src/wysiwygImageUpload.ts +0 -113
@@ -1,299 +0,0 @@
1
- import { splitKeyValueToken, tokenizeAttrTokens } from '@bendyline/squisq/markdown';
2
-
3
- interface MediaReferenceRange {
4
- start: number;
5
- end: number;
6
- }
7
-
8
- interface MarkdownReferenceMatch {
9
- destination: string;
10
- range: MediaReferenceRange;
11
- }
12
-
13
- const MEDIA_REFERENCE_PARAM_KEYS = new Set([
14
- 'audio',
15
- 'file',
16
- 'href',
17
- 'image',
18
- 'imagesrc',
19
- 'path',
20
- 'poster',
21
- 'src',
22
- 'url',
23
- 'video',
24
- ]);
25
-
26
- const HTML_MEDIA_ATTRS = ['src', 'href', 'poster'] as const;
27
-
28
- /**
29
- * Collect media references from the document source. Used by the Files panel
30
- * to distinguish stored files that are actually referenced by the document
31
- * from files that only exist in the bin.
32
- */
33
- export function collectMediaReferencesFromMarkdown(source: string): ReadonlySet<string> {
34
- const refs = new Set<string>();
35
- collectMarkdownInlineReferences(source, refs);
36
- collectHtmlAttributeReferences(source, refs);
37
- collectAnnotationReferences(source, refs);
38
- return refs;
39
- }
40
-
41
- /**
42
- * Remove markdown/html references to a media asset without reparsing and
43
- * reserializing the whole document. This targets the ref shapes the editor
44
- * emits for uploaded files while preserving unrelated author formatting.
45
- */
46
- export function removeMediaReferencesFromMarkdown(source: string, mediaPath: string): string {
47
- if (!mediaPath) return source;
48
- const withoutMarkdownRefs = removeMarkdownInlineReferences(source, mediaPath);
49
- const withoutImageTags = removeHtmlTagsByAttribute(withoutMarkdownRefs, 'img', 'src', mediaPath);
50
- return removeHtmlTagsByAttribute(withoutImageTags, 'a', 'href', mediaPath);
51
- }
52
-
53
- function removeMarkdownInlineReferences(source: string, mediaPath: string): string {
54
- let result = '';
55
- let cursor = 0;
56
-
57
- while (cursor < source.length) {
58
- const range = findNextMarkdownReference(source, cursor, mediaPath);
59
- if (!range) break;
60
- result += source.slice(cursor, range.start);
61
- cursor = range.end;
62
- }
63
-
64
- return result + source.slice(cursor);
65
- }
66
-
67
- function findNextMarkdownReference(
68
- source: string,
69
- startIndex: number,
70
- mediaPath: string,
71
- ): MediaReferenceRange | null {
72
- const match = findNextMarkdownReferenceMatch(source, startIndex, mediaPath);
73
- return match?.range ?? null;
74
- }
75
-
76
- function collectMarkdownInlineReferences(source: string, refs: Set<string>): void {
77
- let cursor = 0;
78
- while (cursor < source.length) {
79
- const match = findNextMarkdownReferenceMatch(source, cursor);
80
- if (!match) return;
81
- refs.add(match.destination);
82
- cursor = Math.max(match.range.end, cursor + 1);
83
- }
84
- }
85
-
86
- function findNextMarkdownReferenceMatch(
87
- source: string,
88
- startIndex: number,
89
- mediaPath?: string,
90
- ): MarkdownReferenceMatch | null {
91
- let bracketIndex = source.indexOf('[', startIndex);
92
-
93
- while (bracketIndex !== -1) {
94
- const previous = source[bracketIndex - 1];
95
- const isImage = previous === '!';
96
- if (previous === '@') {
97
- bracketIndex = source.indexOf('[', bracketIndex + 1);
98
- continue;
99
- }
100
-
101
- const closeBracket = findClosingBracket(source, bracketIndex);
102
- if (closeBracket === -1 || source[closeBracket + 1] !== '(') {
103
- bracketIndex = source.indexOf('[', bracketIndex + 1);
104
- continue;
105
- }
106
-
107
- const openParen = closeBracket + 1;
108
- const closeParen = findClosingParen(source, openParen);
109
- if (closeParen === -1) {
110
- bracketIndex = source.indexOf('[', bracketIndex + 1);
111
- continue;
112
- }
113
-
114
- const destination = readLinkDestination(source.slice(openParen + 1, closeParen));
115
- if (destination && (mediaPath === undefined || destination === mediaPath)) {
116
- const tokenStart = isImage ? bracketIndex - 1 : bracketIndex;
117
- return {
118
- destination,
119
- range: expandStandaloneLine(source, tokenStart, closeParen + 1),
120
- };
121
- }
122
-
123
- bracketIndex = source.indexOf('[', bracketIndex + 1);
124
- }
125
-
126
- return null;
127
- }
128
-
129
- function collectHtmlAttributeReferences(source: string, refs: Set<string>): void {
130
- const tagPattern = /<[a-z][^>]*>/gi;
131
- let match: RegExpExecArray | null;
132
-
133
- while ((match = tagPattern.exec(source))) {
134
- const tag = match[0];
135
- for (const attrName of HTML_MEDIA_ATTRS) {
136
- const value = readHtmlAttribute(tag, attrName);
137
- if (value) refs.add(value);
138
- }
139
- }
140
- }
141
-
142
- function collectAnnotationReferences(source: string, refs: Set<string>): void {
143
- const annotationPattern = /\{\[([^\]]*)\]\}/g;
144
- let match: RegExpExecArray | null;
145
-
146
- while ((match = annotationPattern.exec(source))) {
147
- const inner = match[1];
148
- if (!inner) continue;
149
- const tokens = tokenizeAttrTokens(inner);
150
- for (const token of tokens) {
151
- const pair = splitKeyValueToken(token);
152
- if (!pair) continue;
153
- if (MEDIA_REFERENCE_PARAM_KEYS.has(pair.key.toLowerCase())) {
154
- refs.add(pair.value);
155
- }
156
- }
157
- }
158
- }
159
-
160
- function findClosingBracket(source: string, openIndex: number): number {
161
- let depth = 0;
162
- for (let i = openIndex; i < source.length; i++) {
163
- if (source[i] === '\\') {
164
- i += 1;
165
- continue;
166
- }
167
- if (source[i] === '[') depth += 1;
168
- if (source[i] === ']') {
169
- depth -= 1;
170
- if (depth === 0) return i;
171
- }
172
- }
173
- return -1;
174
- }
175
-
176
- function findClosingParen(source: string, openIndex: number): number {
177
- let depth = 0;
178
- let inAngleDestination = false;
179
-
180
- for (let i = openIndex; i < source.length; i++) {
181
- const ch = source[i];
182
- if (ch === '\\') {
183
- i += 1;
184
- continue;
185
- }
186
- if (inAngleDestination) {
187
- if (ch === '>') inAngleDestination = false;
188
- continue;
189
- }
190
- if (ch === '<') {
191
- inAngleDestination = true;
192
- continue;
193
- }
194
- if (ch === '(') {
195
- depth += 1;
196
- continue;
197
- }
198
- if (ch === ')') {
199
- depth -= 1;
200
- if (depth === 0) return i;
201
- }
202
- }
203
-
204
- return -1;
205
- }
206
-
207
- function readLinkDestination(raw: string): string {
208
- const content = raw.trimStart();
209
- if (!content) return '';
210
-
211
- if (content.startsWith('<')) {
212
- const close = findUnescaped(content, '>', 1);
213
- if (close === -1) return '';
214
- return unescapeMarkdownUrl(content.slice(1, close));
215
- }
216
-
217
- let depth = 0;
218
- for (let i = 0; i < content.length; i++) {
219
- const ch = content[i];
220
- if (ch === '\\') {
221
- i += 1;
222
- continue;
223
- }
224
- if (ch === '(') {
225
- depth += 1;
226
- continue;
227
- }
228
- if (ch === ')' && depth > 0) {
229
- depth -= 1;
230
- continue;
231
- }
232
- if (depth === 0 && /\s/.test(ch)) {
233
- return unescapeMarkdownUrl(content.slice(0, i));
234
- }
235
- }
236
-
237
- return unescapeMarkdownUrl(content);
238
- }
239
-
240
- function findUnescaped(source: string, needle: string, startIndex: number): number {
241
- for (let i = startIndex; i < source.length; i++) {
242
- if (source[i] === '\\') {
243
- i += 1;
244
- continue;
245
- }
246
- if (source[i] === needle) return i;
247
- }
248
- return -1;
249
- }
250
-
251
- function unescapeMarkdownUrl(value: string): string {
252
- return value.replace(/\\([\\`*{}[\]()#+\-.!_>])/g, '$1');
253
- }
254
-
255
- function expandStandaloneLine(source: string, start: number, end: number): MediaReferenceRange {
256
- const lineStart = source.lastIndexOf('\n', start - 1) + 1;
257
- const nextNewline = source.indexOf('\n', end);
258
- const lineEnd = nextNewline === -1 ? source.length : nextNewline;
259
- const before = source.slice(lineStart, start);
260
- const after = source.slice(end, lineEnd);
261
-
262
- if (before.trim() === '' && after.trim() === '') {
263
- return {
264
- start: lineStart,
265
- end: nextNewline === -1 ? lineEnd : lineEnd + 1,
266
- };
267
- }
268
-
269
- return { start, end };
270
- }
271
-
272
- function removeHtmlTagsByAttribute(
273
- source: string,
274
- tagName: 'a' | 'img',
275
- attrName: 'href' | 'src',
276
- mediaPath: string,
277
- ): string {
278
- const tagPattern = tagName === 'img' ? /<img\b[^>]*>/gi : /<a\b[^>]*>[\s\S]*?<\/a>/gi;
279
- return source.replace(tagPattern, (tag) => {
280
- const value = readHtmlAttribute(tag, attrName);
281
- return value === mediaPath ? '' : tag;
282
- });
283
- }
284
-
285
- function readHtmlAttribute(tag: string, attrName: string): string | null {
286
- const attrPattern = new RegExp(`\\b${attrName}\\s*=\\s*("([^"]*)"|'([^']*)'|([^\\s>]+))`, 'i');
287
- const match = attrPattern.exec(tag);
288
- if (!match) return null;
289
- return unescapeHtmlAttribute(match[2] ?? match[3] ?? match[4] ?? '');
290
- }
291
-
292
- function unescapeHtmlAttribute(value: string): string {
293
- return value
294
- .replace(/&lt;/g, '<')
295
- .replace(/&gt;/g, '>')
296
- .replace(/&quot;/g, '"')
297
- .replace(/&#39;|&apos;/g, "'")
298
- .replace(/&amp;/g, '&');
299
- }
package/src/monaco.ts DELETED
@@ -1,35 +0,0 @@
1
- /**
2
- * Canonical Monaco entry for squisq — and for apps downstream of it.
3
- *
4
- * Anything that needs Monaco (squisq's own RawEditor via {@link useMonacoLoader},
5
- * or a downstream app that wants its own editor) should get it from *here*
6
- * rather than importing `monaco-editor` directly. That guarantees a single
7
- * shared instance — one language / theme / completion-provider registry — and
8
- * gives squisq one place to decide which slice of Monaco ships. Downstream
9
- * hosts therefore need no bundler aliasing or hand-rolled "slim" Monaco entry
10
- * (getting that recipe wrong silently breaks features like the suggest widget).
11
- *
12
- * This is the FULL editor. `editor.main.js` pulls in:
13
- * - every editor-feature contribution — the suggest-widget controller
14
- * (completion popups), hover, folding, find, parameter hints, bracket
15
- * matching, …
16
- * - TM grammars for ~70 languages (syntax highlighting in fenced code), and
17
- * - the rich css / html / json / typescript language *services*.
18
- *
19
- * `editor.main.js` has no sibling `.d.ts` (only `editor.api.d.ts` is
20
- * published), so we take the types from `editor.api`: the side-effect import
21
- * registers all the contributions, and the re-export exposes the — now
22
- * augmented — API surface. Both reference the same underlying singleton.
23
- *
24
- * NOTE: the language *services* (css/html/json/typescript) need Monaco web
25
- * workers wired via `globalThis.MonacoEnvironment`. Without that host-side
26
- * setup their in-editor IntelliSense stays dormant — but highlighting,
27
- * editing, and custom completion providers (e.g. the `{[template]}` typeahead)
28
- * all run on the main thread and work with no worker configuration.
29
- */
30
-
31
- // Side-effect: register the full editor + all language contributions.
32
- import 'monaco-editor/esm/vs/editor/editor.main.js';
33
-
34
- // Typed API surface (the only barrel Monaco publishes declarations for).
35
- export * from 'monaco-editor/esm/vs/editor/editor.api';
@@ -1,89 +0,0 @@
1
- /**
2
- * Monaco language-service worker wiring.
3
- *
4
- * Monaco offloads its heavy language services — css / html / json / typescript
5
- * IntelliSense — plus a base editor service (word-based completions, link
6
- * detection, diffing) to web workers. Those worker bundles must be produced by
7
- * the HOST application's bundler: the mechanisms for it (Vite's `?worker`
8
- * import suffix, `new Worker(new URL(...))`, webpack loaders) are all
9
- * bundler-specific and cannot live inside this tsup-built library.
10
- *
11
- * So the division of labor is: the host supplies the five worker constructors
12
- * (one line each with Vite's `?worker`), and this helper owns the
13
- * `label → worker` mapping — the part that's fiddly and easy to get wrong.
14
- *
15
- * Call once, before the first editor mounts (typically in the app entry):
16
- *
17
- * ```ts
18
- * import { configureMonacoWorkers } from '@bendyline/squisq-editor-react';
19
- * import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
20
- * import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
21
- * import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
22
- * import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
23
- * import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
24
- *
25
- * configureMonacoWorkers({
26
- * editor: EditorWorker, json: JsonWorker, css: CssWorker,
27
- * html: HtmlWorker, ts: TsWorker,
28
- * });
29
- * ```
30
- *
31
- * This is purely additive: without it, highlighting, editing, and custom
32
- * completion providers (e.g. the `{[template]}` typeahead) still work — they
33
- * run on the main thread. Only the language-service IntelliSense is dormant
34
- * until the workers are wired.
35
- */
36
-
37
- /** Zero-arg worker constructor, as produced by Vite's `?worker` import. */
38
- export type MonacoWorkerConstructor = new () => Worker;
39
-
40
- export interface MonacoWorkerConstructors {
41
- /** Base editor worker (word completions, links, diff). Required. */
42
- editor: MonacoWorkerConstructor;
43
- /** JSON language service. */
44
- json?: MonacoWorkerConstructor;
45
- /** CSS/SCSS/LESS language service. */
46
- css?: MonacoWorkerConstructor;
47
- /** HTML/Handlebars/Razor language service. */
48
- html?: MonacoWorkerConstructor;
49
- /** TypeScript service — also handles JavaScript. */
50
- ts?: MonacoWorkerConstructor;
51
- }
52
-
53
- type MonacoEnvironmentHost = typeof globalThis & {
54
- MonacoEnvironment?: { getWorker(workerId: string, label: string): Worker };
55
- };
56
-
57
- /**
58
- * Install `globalThis.MonacoEnvironment.getWorker` so Monaco routes each
59
- * language to the matching worker, falling back to the base editor worker for
60
- * any label without a dedicated service (which is every plain language — its
61
- * grammar-based highlighting needs no worker).
62
- */
63
- export function configureMonacoWorkers(workers: MonacoWorkerConstructors): void {
64
- const host = globalThis as MonacoEnvironmentHost;
65
- host.MonacoEnvironment = {
66
- getWorker(_workerId: string, label: string): Worker {
67
- switch (label) {
68
- case 'json':
69
- if (workers.json) return new workers.json();
70
- break;
71
- case 'css':
72
- case 'scss':
73
- case 'less':
74
- if (workers.css) return new workers.css();
75
- break;
76
- case 'html':
77
- case 'handlebars':
78
- case 'razor':
79
- if (workers.html) return new workers.html();
80
- break;
81
- case 'typescript':
82
- case 'javascript':
83
- if (workers.ts) return new workers.ts();
84
- break;
85
- }
86
- return new workers.editor();
87
- },
88
- };
89
- }
@@ -1,171 +0,0 @@
1
- /**
2
- * Source-preserving section moves for the document outline.
3
- *
4
- * Markdown headings form a flat AST, so a section extends from its heading
5
- * through the next heading of equal or shallower depth. Reordering only direct
6
- * siblings keeps heading levels and hierarchy intact; promote/demote remains a
7
- * separate outline operation.
8
- */
9
-
10
- import { parseMarkdown } from '@bendyline/squisq/markdown';
11
-
12
- export type OutlineDropPlacement = 'before' | 'after';
13
-
14
- interface SourceHeading {
15
- line: number;
16
- depth: number;
17
- parentLine: number | null;
18
- start: number;
19
- end: number;
20
- }
21
-
22
- interface SectionSlot extends SourceHeading {
23
- content: string;
24
- gap: string;
25
- }
26
-
27
- /**
28
- * Move one heading-rooted section before or after a sibling section.
29
- *
30
- * The current source is parsed inside the helper so fenced-code lookalikes and
31
- * stale/non-heading line numbers are rejected. The moved section includes its
32
- * body and every descendant heading. Returns `null` for an invalid or no-op
33
- * move.
34
- */
35
- export function moveHeadingSectionInSource(
36
- source: string,
37
- fromHeadingLine: number,
38
- targetHeadingLine: number,
39
- placement: OutlineDropPlacement,
40
- ): string | null {
41
- if (fromHeadingLine === targetHeadingLine || (placement !== 'before' && placement !== 'after')) {
42
- return null;
43
- }
44
-
45
- const headings = readSourceHeadings(source);
46
- if (!headings) return null;
47
-
48
- const from = headings.find((heading) => heading.line === fromHeadingLine);
49
- const target = headings.find((heading) => heading.line === targetHeadingLine);
50
- if (!from || !target) return null;
51
-
52
- // A reorder must not silently promote, demote, or re-parent a section.
53
- if (from.depth !== target.depth || from.parentLine !== target.parentLine) return null;
54
-
55
- const siblings = headings.filter((heading) => heading.parentLine === from.parentLine);
56
- const fromIndex = siblings.findIndex((heading) => heading.line === fromHeadingLine);
57
- const targetIndex = siblings.findIndex((heading) => heading.line === targetHeadingLine);
58
- if (fromIndex < 0 || targetIndex < 0) return null;
59
-
60
- // Direct sibling ranges must be contiguous. Aborting here is safer than
61
- // rewriting source if a parser ever reports an unexpected position shape.
62
- for (let i = 0; i < siblings.length - 1; i++) {
63
- if (siblings[i].end !== siblings[i + 1].start) return null;
64
- }
65
-
66
- const slots: SectionSlot[] = siblings.map((heading) => {
67
- const raw = source.slice(heading.start, heading.end);
68
- const { content, gap } = splitTrailingLineGap(raw);
69
- return { ...heading, content, gap };
70
- });
71
-
72
- const reordered = [...slots];
73
- const [moved] = reordered.splice(fromIndex, 1);
74
- const targetAfterRemoval = reordered.findIndex((heading) => heading.line === targetHeadingLine);
75
- if (!moved || targetAfterRemoval < 0) return null;
76
-
77
- const insertionIndex = targetAfterRemoval + (placement === 'after' ? 1 : 0);
78
- reordered.splice(insertionIndex, 0, moved);
79
-
80
- if (reordered.every((heading, index) => heading.line === slots[index].line)) return null;
81
-
82
- // Whitespace belongs to positions, not to the section being moved. Keeping
83
- // the original slot gaps preserves blank-line style, CRLF, and the exact
84
- // final-newline state even when the former EOF section moves earlier.
85
- const replacement = reordered
86
- .map((heading, index) => heading.content + slots[index].gap)
87
- .join('');
88
- const rangeStart = slots[0].start;
89
- const rangeEnd = slots[slots.length - 1].end;
90
- const next = source.slice(0, rangeStart) + replacement + source.slice(rangeEnd);
91
-
92
- // The move should never change the number of authored headings. This also
93
- // catches any unforeseen boundary issue before the editor source is updated.
94
- const nextHeadings = readSourceHeadings(next);
95
- if (!nextHeadings || nextHeadings.length !== headings.length) return null;
96
-
97
- return next;
98
- }
99
-
100
- /** Parse source headings and derive their parent + complete-section range. */
101
- function readSourceHeadings(source: string): SourceHeading[] | null {
102
- try {
103
- const document = parseMarkdown(source);
104
- const lineStarts = sourceLineStarts(source);
105
- const headings: SourceHeading[] = [];
106
- const stack: SourceHeading[] = [];
107
-
108
- for (const node of document.children) {
109
- if (node.type !== 'heading' || !node.position) continue;
110
-
111
- const line = node.position.start.line;
112
- const start = lineStarts[line - 1];
113
- if (start == null) return null;
114
-
115
- while (stack.length > 0 && stack[stack.length - 1].depth >= node.depth) {
116
- stack.pop();
117
- }
118
-
119
- const heading: SourceHeading = {
120
- line,
121
- depth: node.depth,
122
- parentLine: stack[stack.length - 1]?.line ?? null,
123
- start,
124
- end: source.length,
125
- };
126
- headings.push(heading);
127
- stack.push(heading);
128
- }
129
-
130
- for (let i = 0; i < headings.length; i++) {
131
- const heading = headings[i];
132
- for (let j = i + 1; j < headings.length; j++) {
133
- if (headings[j].depth <= heading.depth) {
134
- heading.end = headings[j].start;
135
- break;
136
- }
137
- }
138
- }
139
-
140
- return headings;
141
- } catch (err: unknown) {
142
- // Source mutations are best-effort UI operations. A parse failure leaves
143
- // the current markdown untouched; EditorContext owns user-facing errors.
144
- void err;
145
- return null;
146
- }
147
- }
148
-
149
- /** 0-based offsets of every physical line, preserving mixed EOL sequences. */
150
- function sourceLineStarts(source: string): number[] {
151
- const starts = [0];
152
- const eol = /\r\n|\r|\n/g;
153
- let match: RegExpExecArray | null;
154
- while ((match = eol.exec(source)) != null) {
155
- starts.push(match.index + match[0].length);
156
- }
157
- return starts;
158
- }
159
-
160
- /**
161
- * Split the line-ending separator from a section without stealing spaces
162
- * before the first newline (which may be an authored Markdown hard break).
163
- */
164
- function splitTrailingLineGap(value: string): { content: string; gap: string } {
165
- const match = value.match(/(?:\r\n|\r|\n)(?:[ \t]*(?:\r\n|\r|\n))*[ \t]*$/);
166
- if (!match || match.index == null) return { content: value, gap: '' };
167
- return {
168
- content: value.slice(0, match.index),
169
- gap: value.slice(match.index),
170
- };
171
- }