@rightkit/document-workspace 0.0.0-stage → 0.1.1

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 (262) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE-APACHE +201 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +74 -2
  5. package/dist/app/App.d.ts +1 -0
  6. package/dist/app/App.js +6 -0
  7. package/dist/app/AppDialogs.d.ts +52 -0
  8. package/dist/app/AppDialogs.js +23 -0
  9. package/dist/app/AppDialogsHost.d.ts +31 -0
  10. package/dist/app/AppDialogsHost.js +30 -0
  11. package/dist/app/AppLifecycle.d.ts +19 -0
  12. package/dist/app/AppLifecycle.js +87 -0
  13. package/dist/app/AppProvider.d.ts +317 -0
  14. package/dist/app/AppProvider.js +217 -0
  15. package/dist/app/AppRoot.d.ts +8 -0
  16. package/dist/app/AppRoot.js +159 -0
  17. package/dist/app/AppShell.d.ts +2 -0
  18. package/dist/app/AppShell.js +81 -0
  19. package/dist/app/CommandPalette.d.ts +13 -0
  20. package/dist/app/CommandPalette.js +47 -0
  21. package/dist/app/DocActionBar.d.ts +36 -0
  22. package/dist/app/DocActionBar.js +300 -0
  23. package/dist/app/DocumentContextMenu.d.ts +29 -0
  24. package/dist/app/DocumentContextMenu.js +122 -0
  25. package/dist/app/DocumentPane.d.ts +52 -0
  26. package/dist/app/DocumentPane.js +30 -0
  27. package/dist/app/DocumentRouterTable.d.ts +58 -0
  28. package/dist/app/DocumentRouterTable.js +143 -0
  29. package/dist/app/ErrorBoundary.d.ts +12 -0
  30. package/dist/app/ErrorBoundary.js +16 -0
  31. package/dist/app/FindBar.d.ts +12 -0
  32. package/dist/app/FindBar.js +199 -0
  33. package/dist/app/LiveTitle.d.ts +14 -0
  34. package/dist/app/LiveTitle.js +14 -0
  35. package/dist/app/OpeningProgress.d.ts +13 -0
  36. package/dist/app/OpeningProgress.js +21 -0
  37. package/dist/app/PrintPreviewWindow.d.ts +2 -0
  38. package/dist/app/PrintPreviewWindow.js +57 -0
  39. package/dist/app/ShortcutHelp.d.ts +3 -0
  40. package/dist/app/ShortcutHelp.js +99 -0
  41. package/dist/app/Sidebar.d.ts +36 -0
  42. package/dist/app/Sidebar.js +121 -0
  43. package/dist/app/ToastViewport.d.ts +1 -0
  44. package/dist/app/ToastViewport.js +31 -0
  45. package/dist/app/Toolbar.d.ts +26 -0
  46. package/dist/app/Toolbar.js +63 -0
  47. package/dist/app/activeFormatSavers.d.ts +7 -0
  48. package/dist/app/activeFormatSavers.js +4 -0
  49. package/dist/app/clipboardPaths.d.ts +1 -0
  50. package/dist/app/clipboardPaths.js +31 -0
  51. package/dist/app/documentDrafts.d.ts +17 -0
  52. package/dist/app/documentDrafts.js +104 -0
  53. package/dist/app/draftResolution.d.ts +5 -0
  54. package/dist/app/draftResolution.js +25 -0
  55. package/dist/app/markdownPaletteActions.d.ts +8 -0
  56. package/dist/app/markdownPaletteActions.js +107 -0
  57. package/dist/app/resourceCensusDev.d.ts +41 -0
  58. package/dist/app/resourceCensusDev.js +518 -0
  59. package/dist/app/setupRecovery.d.ts +34 -0
  60. package/dist/app/setupRecovery.js +70 -0
  61. package/dist/app/shell/DocStatsPill.d.ts +18 -0
  62. package/dist/app/shell/DocStatsPill.js +32 -0
  63. package/dist/app/shell/DocumentTools.d.ts +9 -0
  64. package/dist/app/shell/DocumentTools.js +73 -0
  65. package/dist/app/shell/InfoInspector.d.ts +9 -0
  66. package/dist/app/shell/InfoInspector.js +67 -0
  67. package/dist/app/shell/StartPage.d.ts +9 -0
  68. package/dist/app/shell/StartPage.js +49 -0
  69. package/dist/app/shell/readEdit.d.ts +6 -0
  70. package/dist/app/shell/readEdit.js +6 -0
  71. package/dist/app/sidebar/SidebarDocumentMenu.d.ts +20 -0
  72. package/dist/app/sidebar/SidebarDocumentMenu.js +56 -0
  73. package/dist/app/sidebar/SidebarExpandedPanel.d.ts +9 -0
  74. package/dist/app/sidebar/SidebarExpandedPanel.js +78 -0
  75. package/dist/app/sidebar/SidebarIcons.d.ts +3 -0
  76. package/dist/app/sidebar/SidebarIcons.js +18 -0
  77. package/dist/app/sidebar/SidebarMenus.d.ts +19 -0
  78. package/dist/app/sidebar/SidebarMenus.js +64 -0
  79. package/dist/app/sidebar/SidebarPathUtils.d.ts +10 -0
  80. package/dist/app/sidebar/SidebarPathUtils.js +55 -0
  81. package/dist/app/sidebar/SidebarPrimitives.d.ts +12 -0
  82. package/dist/app/sidebar/SidebarPrimitives.js +45 -0
  83. package/dist/app/sidebar/SidebarRail.d.ts +5 -0
  84. package/dist/app/sidebar/SidebarRail.js +37 -0
  85. package/dist/app/sidebar/explorer/ExplorerRowMenu.d.ts +21 -0
  86. package/dist/app/sidebar/explorer/ExplorerRowMenu.js +37 -0
  87. package/dist/app/sidebar/explorer/ExplorerSections.d.ts +16 -0
  88. package/dist/app/sidebar/explorer/ExplorerSections.js +259 -0
  89. package/dist/app/sidebar/explorer/ExplorerTree.d.ts +46 -0
  90. package/dist/app/sidebar/explorer/ExplorerTree.js +387 -0
  91. package/dist/app/sidebar/explorer/explorerState.d.ts +37 -0
  92. package/dist/app/sidebar/explorer/explorerState.js +135 -0
  93. package/dist/app/tabMountPolicy.d.ts +45 -0
  94. package/dist/app/tabMountPolicy.js +104 -0
  95. package/dist/app/tabWarmOrder.d.ts +7 -0
  96. package/dist/app/tabWarmOrder.js +48 -0
  97. package/dist/app/tabs/TabFuseCurves.d.ts +3 -0
  98. package/dist/app/tabs/TabFuseCurves.js +15 -0
  99. package/dist/app/tabs/TabOverview.d.ts +24 -0
  100. package/dist/app/tabs/TabOverview.js +121 -0
  101. package/dist/app/tabs/TabStrip.d.ts +42 -0
  102. package/dist/app/tabs/TabStrip.js +380 -0
  103. package/dist/app/tabs/tabIds.d.ts +5 -0
  104. package/dist/app/tabs/tabIds.js +7 -0
  105. package/dist/app/tabs/useTabDirty.d.ts +3 -0
  106. package/dist/app/tabs/useTabDirty.js +11 -0
  107. package/dist/app/useAppChromeState.d.ts +21 -0
  108. package/dist/app/useAppChromeState.js +48 -0
  109. package/dist/app/useAppCommands.d.ts +66 -0
  110. package/dist/app/useAppCommands.js +71 -0
  111. package/dist/app/useAppDocumentCore.d.ts +210 -0
  112. package/dist/app/useAppDocumentCore.js +40 -0
  113. package/dist/app/useAppEffects.d.ts +18 -0
  114. package/dist/app/useAppEffects.js +52 -0
  115. package/dist/app/useAppPaneSearch.d.ts +37 -0
  116. package/dist/app/useAppPaneSearch.js +74 -0
  117. package/dist/app/useAppShellSetup.d.ts +40 -0
  118. package/dist/app/useAppShellSetup.js +52 -0
  119. package/dist/app/useAppSlots.d.ts +28 -0
  120. package/dist/app/useAppSlots.js +40 -0
  121. package/dist/app/useAppTabChrome.d.ts +51 -0
  122. package/dist/app/useAppTabChrome.js +66 -0
  123. package/dist/app/useAutoSave.d.ts +34 -0
  124. package/dist/app/useAutoSave.js +116 -0
  125. package/dist/app/useCloseAll.d.ts +52 -0
  126. package/dist/app/useCloseAll.js +295 -0
  127. package/dist/app/useClosedTabEviction.d.ts +10 -0
  128. package/dist/app/useClosedTabEviction.js +38 -0
  129. package/dist/app/useCommandPalette.d.ts +44 -0
  130. package/dist/app/useCommandPalette.js +254 -0
  131. package/dist/app/useCrossDocSearch.d.ts +7 -0
  132. package/dist/app/useCrossDocSearch.js +94 -0
  133. package/dist/app/useDistractionFree.d.ts +21 -0
  134. package/dist/app/useDistractionFree.js +73 -0
  135. package/dist/app/useDocumentCreation.d.ts +18 -0
  136. package/dist/app/useDocumentCreation.js +63 -0
  137. package/dist/app/useDocumentDirty.d.ts +31 -0
  138. package/dist/app/useDocumentDirty.js +46 -0
  139. package/dist/app/useDocumentLoader.d.ts +55 -0
  140. package/dist/app/useDocumentLoader.js +267 -0
  141. package/dist/app/useDocumentOutputActions.d.ts +6 -0
  142. package/dist/app/useDocumentOutputActions.js +45 -0
  143. package/dist/app/useDocumentRuntimeEffects.d.ts +36 -0
  144. package/dist/app/useDocumentRuntimeEffects.js +458 -0
  145. package/dist/app/useDocumentSaver.d.ts +58 -0
  146. package/dist/app/useDocumentSaver.js +511 -0
  147. package/dist/app/useDocumentTabs.d.ts +41 -0
  148. package/dist/app/useDocumentTabs.js +207 -0
  149. package/dist/app/useDocumentWatcher.d.ts +83 -0
  150. package/dist/app/useDocumentWatcher.js +393 -0
  151. package/dist/app/useDocumentZoom.d.ts +24 -0
  152. package/dist/app/useDocumentZoom.js +104 -0
  153. package/dist/app/useDocuments.d.ts +169 -0
  154. package/dist/app/useDocuments.js +455 -0
  155. package/dist/app/useDraftConfirmGate.d.ts +27 -0
  156. package/dist/app/useDraftConfirmGate.js +47 -0
  157. package/dist/app/useFileDragOverlay.d.ts +12 -0
  158. package/dist/app/useFileDragOverlay.js +49 -0
  159. package/dist/app/useFormatApis.d.ts +13 -0
  160. package/dist/app/useFormatApis.js +62 -0
  161. package/dist/app/useFormatDirtyState.d.ts +29 -0
  162. package/dist/app/useFormatDirtyState.js +81 -0
  163. package/dist/app/useGlobalShortcuts.d.ts +47 -0
  164. package/dist/app/useGlobalShortcuts.js +359 -0
  165. package/dist/app/useHtmlSession.d.ts +68 -0
  166. package/dist/app/useHtmlSession.js +463 -0
  167. package/dist/app/useHtmlSessionProps.d.ts +33 -0
  168. package/dist/app/useHtmlSessionProps.js +57 -0
  169. package/dist/app/useLibrary.d.ts +21 -0
  170. package/dist/app/useLibrary.js +81 -0
  171. package/dist/app/useOpenFromClipboard.d.ts +7 -0
  172. package/dist/app/useOpenFromClipboard.js +44 -0
  173. package/dist/app/usePaneLiveness.d.ts +29 -0
  174. package/dist/app/usePaneLiveness.js +199 -0
  175. package/dist/app/usePendingSavePaths.d.ts +19 -0
  176. package/dist/app/usePendingSavePaths.js +67 -0
  177. package/dist/app/useReadyShow.d.ts +12 -0
  178. package/dist/app/useReadyShow.js +142 -0
  179. package/dist/app/useSearchController.d.ts +22 -0
  180. package/dist/app/useSearchController.js +114 -0
  181. package/dist/app/useSetupRecovery.d.ts +41 -0
  182. package/dist/app/useSetupRecovery.js +153 -0
  183. package/dist/app/useTabChrome.d.ts +40 -0
  184. package/dist/app/useTabChrome.js +115 -0
  185. package/dist/app/useViewState.d.ts +27 -0
  186. package/dist/app/useViewState.js +160 -0
  187. package/dist/appName.d.ts +2 -0
  188. package/dist/appName.js +8 -0
  189. package/dist/documents/DocumentRouter.d.ts +102 -0
  190. package/dist/documents/DocumentRouter.js +153 -0
  191. package/dist/documents/FileTypeIcon.d.ts +6 -0
  192. package/dist/documents/FileTypeIcon.js +93 -0
  193. package/dist/documents/ImageDocument.d.ts +14 -0
  194. package/dist/documents/ImageDocument.js +61 -0
  195. package/dist/documents/capabilities.d.ts +17 -0
  196. package/dist/documents/capabilities.js +18 -0
  197. package/dist/documents/html/HtmlDocument.d.ts +15 -0
  198. package/dist/documents/html/HtmlDocument.js +584 -0
  199. package/dist/documents/html/HtmlDocumentLayout.d.ts +87 -0
  200. package/dist/documents/html/HtmlDocumentLayout.js +25 -0
  201. package/dist/documents/html/HtmlDocumentProps.d.ts +60 -0
  202. package/dist/documents/html/HtmlDocumentProps.js +1 -0
  203. package/dist/documents/html/HtmlDocumentSource.d.ts +34 -0
  204. package/dist/documents/html/HtmlDocumentSource.js +28 -0
  205. package/dist/documents/markdown/MarkdownSplitPane.d.ts +115 -0
  206. package/dist/documents/markdown/MarkdownSplitPane.js +352 -0
  207. package/dist/documents/mdx/MdxSplitPane.d.ts +32 -0
  208. package/dist/documents/mdx/MdxSplitPane.js +60 -0
  209. package/dist/documents/txt/LinkDialog.d.ts +8 -0
  210. package/dist/documents/txt/LinkDialog.js +34 -0
  211. package/dist/documents/txt/MarkdownSourceToolbar.d.ts +8 -0
  212. package/dist/documents/txt/MarkdownSourceToolbar.js +25 -0
  213. package/dist/documents/txt/SourceEditorToolbar.d.ts +12 -0
  214. package/dist/documents/txt/SourceEditorToolbar.js +4 -0
  215. package/dist/documents/txt/TxtEditor.d.ts +39 -0
  216. package/dist/documents/txt/TxtEditor.js +186 -0
  217. package/dist/documents/txt/sourceEditorTypes.d.ts +49 -0
  218. package/dist/documents/txt/sourceEditorTypes.js +1 -0
  219. package/dist/documents/txt/sourceExtensions.d.ts +38 -0
  220. package/dist/documents/txt/sourceExtensions.js +444 -0
  221. package/dist/documents/txt/sourceFormatting.d.ts +18 -0
  222. package/dist/documents/txt/sourceFormatting.js +183 -0
  223. package/dist/documents/txt/sourceTheme.d.ts +5 -0
  224. package/dist/documents/txt/sourceTheme.js +220 -0
  225. package/dist/documents/txt/useCodeMirrorSourceEditor.d.ts +69 -0
  226. package/dist/documents/txt/useCodeMirrorSourceEditor.js +546 -0
  227. package/dist/documents/txt/useSourceSearch.d.ts +39 -0
  228. package/dist/documents/txt/useSourceSearch.js +122 -0
  229. package/dist/documents/txt/useTextEditorCommands.d.ts +26 -0
  230. package/dist/documents/txt/useTextEditorCommands.js +151 -0
  231. package/dist/documents/web/LivePreviewPane.d.ts +11 -0
  232. package/dist/documents/web/LivePreviewPane.js +58 -0
  233. package/dist/env.d.ts +66 -0
  234. package/dist/index.d.ts +121 -0
  235. package/dist/index.js +123 -0
  236. package/dist/settings/AppearanceMenu.d.ts +9 -0
  237. package/dist/settings/AppearanceMenu.js +54 -0
  238. package/dist/settings/SettingsPanel.d.ts +7 -0
  239. package/dist/settings/SettingsPanel.js +104 -0
  240. package/dist/settings/publishedSections.d.ts +22 -0
  241. package/dist/settings/publishedSections.js +79 -0
  242. package/dist/settings/sections/AboutSection.d.ts +1 -0
  243. package/dist/settings/sections/AboutSection.js +13 -0
  244. package/dist/settings/sections/DiagnosticsSection.d.ts +1 -0
  245. package/dist/settings/sections/DiagnosticsSection.js +42 -0
  246. package/dist/settings/sections/PrivacySection.d.ts +3 -0
  247. package/dist/settings/sections/PrivacySection.js +51 -0
  248. package/dist/settings/sections/UpdateLicenseBlock.d.ts +10 -0
  249. package/dist/settings/sections/UpdateLicenseBlock.js +158 -0
  250. package/dist/state/explorer.d.ts +32 -0
  251. package/dist/state/explorer.js +111 -0
  252. package/dist/state/legal.d.ts +51 -0
  253. package/dist/state/legal.js +130 -0
  254. package/dist/state/library.d.ts +33 -0
  255. package/dist/state/library.js +110 -0
  256. package/dist/state/updateLicense.d.ts +31 -0
  257. package/dist/state/updateLicense.js +340 -0
  258. package/dist/styles/explorer.css +219 -0
  259. package/dist/styles/index.css +1477 -0
  260. package/dist/styles/tabs.css +467 -0
  261. package/dist/styles.css +6 -0
  262. package/package.json +88 -3
@@ -0,0 +1,122 @@
1
+ import { useCallback, useRef } from "react";
2
+ import { findLiteralMatches } from "@rightkit/document-core/documents/searchUtils";
3
+ import { setSearchHighlights } from "./sourceExtensions.js";
4
+ import { scrollPosIntoView } from "@rightkit/document-core/documents/txt/cmScroll";
5
+ export function useSourceSearch({ viewRef, readOnlyRef, }) {
6
+ const searchRef = useRef({
7
+ query: "",
8
+ options: { matchCase: false, wholeWord: false },
9
+ matches: [],
10
+ activeIndex: -1,
11
+ });
12
+ const searchedDocumentRef = useRef(null);
13
+ const dispatchSearchHighlights = useCallback((matches, activeIndex) => {
14
+ const view = viewRef.current;
15
+ if (!view)
16
+ return;
17
+ const active = activeIndex >= 0 ? matches[activeIndex] : null;
18
+ const selection = active
19
+ ? { anchor: active.start, head: active.end }
20
+ : view.state.selection.main.empty
21
+ ? undefined
22
+ : { anchor: view.state.selection.main.head };
23
+ view.dispatch({
24
+ effects: setSearchHighlights.of({ matches, activeIndex }),
25
+ selection,
26
+ });
27
+ if (active)
28
+ scrollPosIntoView(view, active.start);
29
+ }, [viewRef]);
30
+ const clearSearch = useCallback(() => {
31
+ searchedDocumentRef.current = null;
32
+ searchRef.current = {
33
+ query: "",
34
+ options: searchRef.current.options,
35
+ matches: [],
36
+ activeIndex: -1,
37
+ };
38
+ dispatchSearchHighlights([], -1);
39
+ }, [dispatchSearchHighlights]);
40
+ const runFind = useCallback((query, options) => {
41
+ const view = viewRef.current;
42
+ if (!view || !query) {
43
+ searchedDocumentRef.current = null;
44
+ searchRef.current = { query, options, matches: [], activeIndex: -1 };
45
+ dispatchSearchHighlights([], -1);
46
+ return { count: 0, activeIndex: -1 };
47
+ }
48
+ const source = view.state.doc.toString();
49
+ const matches = findLiteralMatches(source, query, options);
50
+ const activeIndex = matches.length ? 0 : -1;
51
+ searchedDocumentRef.current = view.state.doc;
52
+ searchRef.current = { query, options, matches, activeIndex };
53
+ dispatchSearchHighlights(matches, activeIndex);
54
+ return { count: matches.length, activeIndex };
55
+ }, [dispatchSearchHighlights, viewRef]);
56
+ const refreshSearch = useCallback(() => {
57
+ const view = viewRef.current;
58
+ const cur = searchRef.current;
59
+ if (!view || !cur.query)
60
+ return { count: 0, activeIndex: -1 };
61
+ const matches = findLiteralMatches(view.state.doc.toString(), cur.query, cur.options);
62
+ const selection = view.state.selection.main;
63
+ const selectedIndex = matches.findIndex((match) => match.start === selection.from && match.end === selection.to);
64
+ const activeIndex = matches.length
65
+ ? selectedIndex >= 0
66
+ ? selectedIndex
67
+ : Math.min(Math.max(cur.activeIndex, 0), matches.length - 1)
68
+ : -1;
69
+ searchedDocumentRef.current = view.state.doc;
70
+ searchRef.current = { ...cur, matches, activeIndex };
71
+ dispatchSearchHighlights(matches, activeIndex);
72
+ return { count: matches.length, activeIndex };
73
+ }, [dispatchSearchHighlights, viewRef]);
74
+ const stepSearch = useCallback((delta) => {
75
+ if (viewRef.current?.state.doc !== searchedDocumentRef.current)
76
+ refreshSearch();
77
+ const cur = searchRef.current;
78
+ const count = cur.matches.length;
79
+ if (!count)
80
+ return { count: 0, activeIndex: -1 };
81
+ const activeIndex = (cur.activeIndex + delta + count) % count;
82
+ searchRef.current = { ...cur, activeIndex };
83
+ dispatchSearchHighlights(cur.matches, activeIndex);
84
+ return { count, activeIndex };
85
+ }, [dispatchSearchHighlights, refreshSearch, viewRef]);
86
+ const replaceAndFind = useCallback((replacement, all) => {
87
+ const view = viewRef.current;
88
+ const cur = searchRef.current;
89
+ if (!view || readOnlyRef.current)
90
+ return { count: cur.matches.length, activeIndex: cur.activeIndex };
91
+ // CodeMirror maps its selection/decorations on edits; cached match offsets do not move.
92
+ // Recompute from the live document before selecting or replacing a cached range.
93
+ if (view.state.doc !== searchedDocumentRef.current)
94
+ refreshSearch();
95
+ const current = searchRef.current;
96
+ const matches = all
97
+ ? current.matches
98
+ : current.matches[current.activeIndex]
99
+ ? [current.matches[current.activeIndex]]
100
+ : [];
101
+ if (matches.length) {
102
+ view.dispatch({
103
+ changes: matches.map((match) => ({
104
+ from: match.start,
105
+ to: match.end,
106
+ insert: replacement,
107
+ })),
108
+ userEvent: "input.replace",
109
+ });
110
+ }
111
+ return runFind(current.query, current.options);
112
+ }, [readOnlyRef, refreshSearch, runFind, viewRef]);
113
+ return {
114
+ clearSearch,
115
+ dispatchSearchHighlights,
116
+ replaceAndFind,
117
+ refreshSearch,
118
+ runFind,
119
+ searchRef,
120
+ stepSearch,
121
+ };
122
+ }
@@ -0,0 +1,26 @@
1
+ import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2
+ import { EditorView } from "@codemirror/view";
3
+ import { type SourceLanguage } from "./sourceFormatting.js";
4
+ import type { SourceLinkPrefix, SourceLinkState } from "./sourceEditorTypes.js";
5
+ export declare function useTextEditorCommands({ formatOnSaveRef, language, onSaveRef, readOnlyRef, setLinkState, setSourceFolded, sourceFolded, viewRef, }: {
6
+ formatOnSaveRef: MutableRefObject<boolean>;
7
+ language: SourceLanguage;
8
+ onSaveRef: MutableRefObject<() => void>;
9
+ readOnlyRef: MutableRefObject<boolean>;
10
+ setLinkState: Dispatch<SetStateAction<SourceLinkState | null>>;
11
+ setSourceFolded: Dispatch<SetStateAction<boolean>>;
12
+ sourceFolded: boolean;
13
+ viewRef: MutableRefObject<EditorView | null>;
14
+ }): {
15
+ formatFromEditor: () => void;
16
+ formatTablesFromEditor: () => void;
17
+ goToLine: (lineNumber: number) => void;
18
+ insertBlock: (block: string, caretOffset?: number) => void;
19
+ insertLinkFromDialog: (state: SourceLinkState | null, label: string, url: string) => void;
20
+ linePrefix: (prefix: string) => void;
21
+ openLink: (prefix: SourceLinkPrefix) => void;
22
+ saveFromEditor: () => void;
23
+ setHeading: (level: number) => void;
24
+ toggleFoldAll: () => void;
25
+ wrapInline: (before: string, after: string) => void;
26
+ };
@@ -0,0 +1,151 @@
1
+ import { useCallback } from "react";
2
+ import { foldAll, unfoldAll } from "@codemirror/language";
3
+ import { EditorView } from "@codemirror/view";
4
+ import { applyInlineWrap, buildMarkdownLink, formatSource, } from "./sourceFormatting.js";
5
+ export function useTextEditorCommands({ formatOnSaveRef, language, onSaveRef, readOnlyRef, setLinkState, setSourceFolded, sourceFolded, viewRef, }) {
6
+ const edit = useCallback((fn) => {
7
+ const view = viewRef.current;
8
+ if (!view || readOnlyRef.current)
9
+ return;
10
+ const sel = view.state.selection.main;
11
+ const result = fn(view.state.doc.toString(), sel.from, sel.to);
12
+ view.focus();
13
+ view.dispatch({
14
+ changes: { from: 0, to: view.state.doc.length, insert: result.value },
15
+ selection: { anchor: result.start, head: result.end },
16
+ userEvent: "input",
17
+ });
18
+ }, [readOnlyRef, viewRef]);
19
+ const wrapInline = useCallback((before, after) => edit((value, start, end) => applyInlineWrap(value, start, end, before, after)), [edit]);
20
+ const openLink = useCallback((prefix) => {
21
+ const view = viewRef.current;
22
+ if (!view || readOnlyRef.current)
23
+ return;
24
+ const sel = view.state.selection.main;
25
+ setLinkState({
26
+ start: sel.from,
27
+ end: sel.to,
28
+ text: view.state.sliceDoc(sel.from, sel.to),
29
+ prefix,
30
+ });
31
+ }, [readOnlyRef, setLinkState, viewRef]);
32
+ const formatFromEditor = useCallback(() => {
33
+ const view = viewRef.current;
34
+ if (!view || readOnlyRef.current)
35
+ return;
36
+ const current = view.state.doc.toString();
37
+ const next = formatSource(language, current);
38
+ if (next === current)
39
+ return;
40
+ view.focus();
41
+ view.dispatch({
42
+ changes: { from: 0, to: view.state.doc.length, insert: next },
43
+ selection: { anchor: Math.min(view.state.selection.main.head, next.length) },
44
+ userEvent: "input.format",
45
+ });
46
+ }, [language, readOnlyRef, viewRef]);
47
+ const formatTablesFromEditor = useCallback(() => {
48
+ const view = viewRef.current;
49
+ if (!view || readOnlyRef.current || language !== "markdown")
50
+ return;
51
+ const current = view.state.doc.toString();
52
+ void import("@rightkit/markdown-editor/documents/markdown/markdownTools").then(({ formatMarkdownTables }) => {
53
+ const next = formatMarkdownTables(current);
54
+ if (next === current)
55
+ return;
56
+ const liveView = viewRef.current;
57
+ if (!liveView)
58
+ return;
59
+ liveView.focus();
60
+ liveView.dispatch({
61
+ changes: { from: 0, to: liveView.state.doc.length, insert: next },
62
+ selection: { anchor: Math.min(liveView.state.selection.main.head, next.length) },
63
+ userEvent: "input.format",
64
+ });
65
+ });
66
+ }, [language, readOnlyRef, viewRef]);
67
+ const saveFromEditor = useCallback(() => {
68
+ if (formatOnSaveRef.current && language !== "plain")
69
+ formatFromEditor();
70
+ onSaveRef.current();
71
+ }, [formatFromEditor, formatOnSaveRef, language, onSaveRef]);
72
+ const toggleFoldAll = useCallback(() => {
73
+ const view = viewRef.current;
74
+ if (!view)
75
+ return;
76
+ if (sourceFolded)
77
+ unfoldAll(view);
78
+ else
79
+ foldAll(view);
80
+ setSourceFolded((value) => !value);
81
+ }, [setSourceFolded, sourceFolded, viewRef]);
82
+ const goToLine = useCallback((lineNumber) => {
83
+ const view = viewRef.current;
84
+ if (!view)
85
+ return;
86
+ const line = view.state.doc.line(Math.max(1, Math.min(lineNumber, view.state.doc.lines)));
87
+ view.focus();
88
+ view.dispatch({
89
+ selection: { anchor: line.from },
90
+ effects: EditorView.scrollIntoView(line.from, { y: "center" }),
91
+ });
92
+ }, [viewRef]);
93
+ const insertLinkFromDialog = (state, label, url) => {
94
+ const view = viewRef.current;
95
+ if (!view || !state || readOnlyRef.current)
96
+ return;
97
+ const md = buildMarkdownLink(state.prefix, label, url);
98
+ view.focus();
99
+ view.dispatch({
100
+ changes: { from: state.start, to: state.end, insert: md },
101
+ selection: { anchor: state.start + md.length },
102
+ userEvent: "input",
103
+ });
104
+ };
105
+ const linePrefix = (prefix) => edit((value, start, end) => {
106
+ const lineStart = value.lastIndexOf("\n", start - 1) + 1;
107
+ return {
108
+ value: value.slice(0, lineStart) + prefix + value.slice(lineStart),
109
+ start: start + prefix.length,
110
+ end: end + prefix.length,
111
+ };
112
+ });
113
+ const setHeading = (level) => edit((value, start, end) => {
114
+ const lineStart = value.lastIndexOf("\n", start - 1) + 1;
115
+ const nextLine = value.indexOf("\n", start);
116
+ const lineEnd = nextLine === -1 ? value.length : nextLine;
117
+ const line = value.slice(lineStart, lineEnd);
118
+ const stripped = line.replace(/^#{1,6}\s+/, "");
119
+ const prefix = level === 0 ? "" : `${"#".repeat(level)} `;
120
+ const nextLineText = prefix + stripped;
121
+ const delta = nextLineText.length - line.length;
122
+ return {
123
+ value: value.slice(0, lineStart) + nextLineText + value.slice(lineEnd),
124
+ start: start + delta,
125
+ end: end + delta,
126
+ };
127
+ });
128
+ const insertBlock = (block, caretOffset = block.length) => edit((value, start) => {
129
+ const lineStart = value.lastIndexOf("\n", start - 1) + 1;
130
+ const prefix = start === lineStart ? "" : "\n";
131
+ const insert = prefix + block;
132
+ return {
133
+ value: value.slice(0, start) + insert + value.slice(start),
134
+ start: start + prefix.length + caretOffset,
135
+ end: start + prefix.length + caretOffset,
136
+ };
137
+ });
138
+ return {
139
+ formatFromEditor,
140
+ formatTablesFromEditor,
141
+ goToLine,
142
+ insertBlock,
143
+ insertLinkFromDialog,
144
+ linePrefix,
145
+ openLink,
146
+ saveFromEditor,
147
+ setHeading,
148
+ toggleFoldAll,
149
+ wrapInline,
150
+ };
151
+ }
@@ -0,0 +1,11 @@
1
+ import type { LoadedDocument } from "@rightkit/document-core/documents/types";
2
+ interface Props {
3
+ doc: LoadedDocument;
4
+ }
5
+ /**
6
+ * Preview of an explicit URL (Open URL → http(s)://...). Local `.html` files are NOT
7
+ * handled here anymore — they're owned by the normal html document tab (HtmlDocument), which renders
8
+ * the interactive/code/safe modes. `web` tabs are session-only URL previews.
9
+ */
10
+ export declare function LivePreviewPane({ doc }: Props): import("react").JSX.Element;
11
+ export {};
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import { openDevtools } from "@rightkit/document-core/state/tauriBridge";
4
+ import { isHostAppOrigin } from "@rightkit/document-core/documents/web/webUrl";
5
+ import { PreviewMessage } from "@rightkit/document-core/documents/PreviewMessage";
6
+ import { viewportWidthPx } from "@rightkit/document-core/documents/previewViewport";
7
+ import { PreviewChrome } from "@rightkit/document-core/documents/PreviewChrome";
8
+ import { acquireResource } from "@rightkit/document-core/app/resourceCensus";
9
+ import { hostAppName } from "../../appName.js";
10
+ /**
11
+ * Preview of an explicit URL (Open URL → http(s)://...). Local `.html` files are NOT
12
+ * handled here anymore — they're owned by the normal html document tab (HtmlDocument), which renders
13
+ * the interactive/code/safe modes. `web` tabs are session-only URL previews.
14
+ */
15
+ export function LivePreviewPane({ doc }) {
16
+ if (!doc.web) {
17
+ return (_jsx(PreviewMessage, { title: "Preview unavailable", body: "This tab is missing its web session metadata." }));
18
+ }
19
+ return _jsx(LiveUrlPreview, { web: doc.web, documentPath: doc.path });
20
+ }
21
+ function LiveUrlPreview({ web, documentPath }) {
22
+ const [reloadKey, setReloadKey] = useState(0);
23
+ const [viewport, setViewport] = useState("desktop");
24
+ const blockedOwnOrigin = isHostAppOrigin(web.url);
25
+ useEffect(() => {
26
+ if (blockedOwnOrigin)
27
+ return;
28
+ const release = acquireResource({
29
+ kind: "web-iframe",
30
+ documentPath,
31
+ format: "web",
32
+ });
33
+ return release;
34
+ }, [blockedOwnOrigin, documentPath]);
35
+ // Ctrl+R / F5 (dispatched from the global shortcut handler as "viewright:web-reload") remounts the
36
+ // iframe — same as the chrome reload button — so the URL re-fetches from its server.
37
+ useEffect(() => {
38
+ const onReload = () => setReloadKey((n) => n + 1);
39
+ window.addEventListener("viewright:web-reload", onReload);
40
+ return () => window.removeEventListener("viewright:web-reload", onReload);
41
+ }, []);
42
+ const width = viewportWidthPx(viewport); // null = full-width desktop; otherwise a device frame
43
+ // Security note (audited 2026-06-02): `allow-scripts allow-same-origin` is the documented
44
+ // sandbox-escape combo ONLY when the framed content is same-origin with this app — then it could
45
+ // reach window.frameElement and strip its own sandbox. Here `src` is a CROSS-ORIGIN web URL, so the
46
+ // framed page cannot access frameElement and cannot escape. `allow-same-origin` is required so the
47
+ // previewed page keeps its own cookies/storage/fetch + HMR. The self-origin block prevents the app
48
+ // from framing itself — do NOT remove allow-same-origin; no real security gain.
49
+ // `allow-popups` lets target=_blank links fire a new-window request, which Rust
50
+ // (context_menu::route_new_windows_to_tabs) intercepts for loopback URLs and reopens as a VR web
51
+ // tab; external target=_blank links still go to the OS browser by design.
52
+ const frame = (_jsx("iframe", { title: "Live URL preview", src: web.url, sandbox: "allow-scripts allow-same-origin allow-forms allow-popups", className: "h-full w-full border-0 bg-panel" }, reloadKey));
53
+ return (_jsxs("div", { className: "flex h-full min-h-0 flex-col bg-ink", children: [_jsx(PreviewChrome, { address: web.url, viewport: viewport, onViewport: setViewport, onReload: () => setReloadKey((n) => n + 1), trailing: {
54
+ label: "devtools",
55
+ ariaLabel: "Open DevTools",
56
+ onClick: () => void openDevtools(),
57
+ } }), blockedOwnOrigin ? (_jsx(PreviewMessage, { title: `${hostAppName()} cannot frame itself`, body: "Open a different localhost app or port." })) : width ? (_jsx("div", { className: "flex min-h-0 flex-1 justify-center overflow-auto bg-ink/50 p-4", children: _jsx("div", { className: "h-full overflow-hidden rounded-md border border-line bg-panel shadow-2xl", style: { width, maxWidth: "100%" }, children: frame }) })) : (_jsx("div", { className: "min-h-0 flex-1", children: frame }))] }));
58
+ }
package/dist/env.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ declare module "*.css";
4
+ declare module "*.svg" {
5
+ const src: string;
6
+ export default src;
7
+ }
8
+ declare module "*.png" {
9
+ const src: string;
10
+ export default src;
11
+ }
12
+ declare module "*.txt?raw" {
13
+ const text: string;
14
+ export default text;
15
+ }
16
+ declare module "*.tsv?raw" {
17
+ const text: string;
18
+ export default text;
19
+ }
20
+ declare module "*?url" {
21
+ const src: string;
22
+ export default src;
23
+ }
24
+
25
+ // Build-time switches a host may define (Vite `define`); every read is typeof-guarded.
26
+ declare const __RIGHTKIT_QA__: boolean | undefined;
27
+ declare const __RIGHTKIT_DEMO__: boolean | undefined;
28
+ declare const __RIGHTKIT_MOCK__: boolean | undefined;
29
+ declare const __APP_VERSION__: string | undefined;
30
+
31
+ interface Window {
32
+ /** UI QA only: the data source a QA shell selects. */
33
+ __RIGHTKIT_QA_DATA_SOURCE__?: "engine";
34
+ }
35
+
36
+ declare module "@rightkit-host/legal/legal-manifest.json" {
37
+ const manifest: {
38
+ documents: Array<{ id: string; role: string; title: string; publicUrl: string; version?: string; sha256?: string; [key: string]: unknown }>;
39
+ [key: string]: unknown;
40
+ };
41
+ export default manifest;
42
+ }
43
+ declare module "@rightkit-host/legal/legal-manifest.json?raw" {
44
+ const text: string;
45
+ export default text;
46
+ }
47
+ declare module "@rightkit-host/src/generated/legal-contract.json" {
48
+ const contract: { acceptanceVersion: string; materialSha256: string; [key: string]: unknown };
49
+ export default contract;
50
+ }
51
+ declare module "@rightkit-host/package.json" {
52
+ export const version: string;
53
+ const pkg: { name: string; version: string };
54
+ export default pkg;
55
+ }
56
+ declare module "@rightkit-host/legal/*.md?raw" {
57
+ const text: string;
58
+ export default text;
59
+ }
60
+
61
+ declare module "virtual:rightkit-legal" {
62
+ export const LEGAL_DOCUMENTS: readonly { title: string; content: string }[];
63
+ export const LEGAL_VERSION: string;
64
+ export const LEGAL_DOCUMENTS_HASH: string;
65
+ export const LEGAL_RECEIPT_DOCUMENTS: readonly { id: string; role: string; version: string; sha256: string; treatment: string; material: boolean }[];
66
+ }
@@ -0,0 +1,121 @@
1
+ export * from "./app/App.js";
2
+ export * from "./app/AppDialogs.js";
3
+ export * from "./app/AppDialogsHost.js";
4
+ export * from "./app/AppLifecycle.js";
5
+ export * from "./app/AppProvider.js";
6
+ export * from "./app/AppRoot.js";
7
+ export * from "./app/AppShell.js";
8
+ export * from "./app/CommandPalette.js";
9
+ export * from "./app/DocActionBar.js";
10
+ export * from "./app/DocumentContextMenu.js";
11
+ export * from "./app/DocumentPane.js";
12
+ export * from "./app/DocumentRouterTable.js";
13
+ export * from "./app/ErrorBoundary.js";
14
+ export * from "./app/FindBar.js";
15
+ export * from "./app/LiveTitle.js";
16
+ export * from "./app/OpeningProgress.js";
17
+ export * from "./app/PrintPreviewWindow.js";
18
+ export * from "./app/ShortcutHelp.js";
19
+ export * from "./app/Sidebar.js";
20
+ export * from "./app/ToastViewport.js";
21
+ export * from "./app/Toolbar.js";
22
+ export * from "./app/activeFormatSavers.js";
23
+ export * from "./app/clipboardPaths.js";
24
+ export * from "./app/documentDrafts.js";
25
+ export * from "./app/draftResolution.js";
26
+ export * from "./app/markdownPaletteActions.js";
27
+ export * from "./app/resourceCensusDev.js";
28
+ export * from "./app/setupRecovery.js";
29
+ export * from "./app/shell/DocStatsPill.js";
30
+ export * from "./app/shell/DocumentTools.js";
31
+ export * from "./app/shell/InfoInspector.js";
32
+ export * from "./app/shell/StartPage.js";
33
+ export * from "./app/shell/readEdit.js";
34
+ export * from "./app/sidebar/SidebarDocumentMenu.js";
35
+ export * from "./app/sidebar/SidebarExpandedPanel.js";
36
+ export * from "./app/sidebar/SidebarIcons.js";
37
+ export * from "./app/sidebar/SidebarMenus.js";
38
+ export * from "./app/sidebar/SidebarPathUtils.js";
39
+ export * from "./app/sidebar/SidebarPrimitives.js";
40
+ export * from "./app/sidebar/SidebarRail.js";
41
+ export * from "./app/sidebar/explorer/ExplorerRowMenu.js";
42
+ export * from "./app/sidebar/explorer/ExplorerSections.js";
43
+ export * from "./app/sidebar/explorer/ExplorerTree.js";
44
+ export * from "./app/sidebar/explorer/explorerState.js";
45
+ export * from "./app/tabMountPolicy.js";
46
+ export * from "./app/tabWarmOrder.js";
47
+ export * from "./app/tabs/TabFuseCurves.js";
48
+ export * from "./app/tabs/TabOverview.js";
49
+ export * from "./app/tabs/TabStrip.js";
50
+ export * from "./app/tabs/tabIds.js";
51
+ export * from "./app/tabs/useTabDirty.js";
52
+ export * from "./app/useAppChromeState.js";
53
+ export * from "./app/useAppCommands.js";
54
+ export * from "./app/useAppDocumentCore.js";
55
+ export * from "./app/useAppEffects.js";
56
+ export * from "./app/useAppPaneSearch.js";
57
+ export * from "./app/useAppShellSetup.js";
58
+ export * from "./app/useAppSlots.js";
59
+ export * from "./app/useAppTabChrome.js";
60
+ export * from "./app/useAutoSave.js";
61
+ export * from "./app/useCloseAll.js";
62
+ export * from "./app/useClosedTabEviction.js";
63
+ export * from "./app/useCommandPalette.js";
64
+ export * from "./app/useCrossDocSearch.js";
65
+ export * from "./app/useDistractionFree.js";
66
+ export * from "./app/useDocumentCreation.js";
67
+ export * from "./app/useDocumentDirty.js";
68
+ export * from "./app/useDocumentLoader.js";
69
+ export * from "./app/useDocumentOutputActions.js";
70
+ export * from "./app/useDocumentRuntimeEffects.js";
71
+ export * from "./app/useDocumentSaver.js";
72
+ export * from "./app/useDocumentTabs.js";
73
+ export * from "./app/useDocumentWatcher.js";
74
+ export * from "./app/useDocumentZoom.js";
75
+ export * from "./app/useDraftConfirmGate.js";
76
+ export * from "./app/useFileDragOverlay.js";
77
+ export * from "./app/useFormatApis.js";
78
+ export * from "./app/useFormatDirtyState.js";
79
+ export * from "./app/useGlobalShortcuts.js";
80
+ export * from "./app/useHtmlSession.js";
81
+ export * from "./app/useHtmlSessionProps.js";
82
+ export * from "./app/useLibrary.js";
83
+ export * from "./app/useOpenFromClipboard.js";
84
+ export * from "./app/usePaneLiveness.js";
85
+ export * from "./app/usePendingSavePaths.js";
86
+ export * from "./app/useReadyShow.js";
87
+ export * from "./app/useSearchController.js";
88
+ export * from "./app/useSetupRecovery.js";
89
+ export * from "./app/useTabChrome.js";
90
+ export * from "./app/useViewState.js";
91
+ export * from "./appName.js";
92
+ export * from "./documents/DocumentRouter.js";
93
+ export * from "./documents/FileTypeIcon.js";
94
+ export * from "./documents/ImageDocument.js";
95
+ export * from "./documents/capabilities.js";
96
+ export * from "./documents/html/HtmlDocument.js";
97
+ export * from "./documents/html/HtmlDocumentLayout.js";
98
+ export * from "./documents/html/HtmlDocumentSource.js";
99
+ export * from "./documents/markdown/MarkdownSplitPane.js";
100
+ export * from "./documents/mdx/MdxSplitPane.js";
101
+ export * from "./documents/txt/LinkDialog.js";
102
+ export * from "./documents/txt/MarkdownSourceToolbar.js";
103
+ export * from "./documents/txt/SourceEditorToolbar.js";
104
+ export * from "./documents/txt/TxtEditor.js";
105
+ export * from "./documents/txt/sourceExtensions.js";
106
+ export * from "./documents/txt/sourceTheme.js";
107
+ export * from "./documents/txt/useCodeMirrorSourceEditor.js";
108
+ export * from "./documents/txt/useSourceSearch.js";
109
+ export * from "./documents/txt/useTextEditorCommands.js";
110
+ export * from "./documents/web/LivePreviewPane.js";
111
+ export * from "./settings/AppearanceMenu.js";
112
+ export * from "./settings/SettingsPanel.js";
113
+ export * from "./settings/publishedSections.js";
114
+ export * from "./settings/sections/AboutSection.js";
115
+ export * from "./settings/sections/DiagnosticsSection.js";
116
+ export * from "./settings/sections/PrivacySection.js";
117
+ export * from "./settings/sections/UpdateLicenseBlock.js";
118
+ export * from "./state/explorer.js";
119
+ export * from "./state/legal.js";
120
+ export * from "./state/library.js";
121
+ export * from "./state/updateLicense.js";