flea-qml 0.0.0-stage → 0.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 (637) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +511 -2
  3. package/THIRD-PARTY-NOTICES.md +29 -0
  4. package/demos/App.java +5 -0
  5. package/demos/Dockerfile +4 -0
  6. package/demos/Main.kt +3 -0
  7. package/demos/Program.cs +1 -0
  8. package/demos/README.md +12 -0
  9. package/demos/app.dart +3 -0
  10. package/demos/app.deb +0 -0
  11. package/demos/app.js +1 -0
  12. package/demos/backup.tar +0 -0
  13. package/demos/budget.xlsx +0 -0
  14. package/demos/build.sh +2 -0
  15. package/demos/bundle.zip +0 -0
  16. package/demos/clip.mp4 +0 -0
  17. package/demos/data.sqlite +0 -0
  18. package/demos/disk.iso +0 -0
  19. package/demos/engine.cpp +5 -0
  20. package/demos/firmware.bin +0 -0
  21. package/demos/flake.nix +4 -0
  22. package/demos/folder/inside.txt +1 -0
  23. package/demos/font.ttf +0 -0
  24. package/demos/index.html +5 -0
  25. package/demos/index.php +2 -0
  26. package/demos/init.lua +1 -0
  27. package/demos/letter.docx +0 -0
  28. package/demos/lib.rs +3 -0
  29. package/demos/main.c +6 -0
  30. package/demos/main.h +3 -0
  31. package/demos/math-and-diagrams.md +200 -0
  32. package/demos/notes.tar.gz +0 -0
  33. package/demos/notes.txt +3 -0
  34. package/demos/photo.png +0 -0
  35. package/demos/program +2 -0
  36. package/demos/report.pdf +32 -0
  37. package/demos/script.py +1 -0
  38. package/demos/server.go +7 -0
  39. package/demos/settings.json +4 -0
  40. package/demos/slides.pptx +0 -0
  41. package/demos/song.mp3 +0 -0
  42. package/demos/style.css +4 -0
  43. package/demos/tool.rb +1 -0
  44. package/demos/types.ts +2 -0
  45. package/docs/pele.md +23 -0
  46. package/docs/protocol.md +3420 -0
  47. package/docs/temml.md +63 -0
  48. package/index.js +107 -0
  49. package/package.json +34 -4
  50. package/src/archive.js +407 -0
  51. package/src/archiveops.js +728 -0
  52. package/src/backend.js +369 -0
  53. package/src/bulkrename.js +95 -0
  54. package/src/clip-host.js +76 -0
  55. package/src/clip.js +462 -0
  56. package/src/code.js +168 -0
  57. package/src/compare.js +74 -0
  58. package/src/create.js +128 -0
  59. package/src/dirsize.js +147 -0
  60. package/src/figure-svg.js +530 -0
  61. package/src/figure-thread.js +23 -0
  62. package/src/figure.js +132 -0
  63. package/src/find.js +55 -0
  64. package/src/flea.js +39 -0
  65. package/src/fsinfo.js +39 -0
  66. package/src/highlight.js +141 -0
  67. package/src/html.js +52 -0
  68. package/src/kinds.js +89 -0
  69. package/src/listing.js +130 -0
  70. package/src/markdown-html.js +317 -0
  71. package/src/mathml.js +186 -0
  72. package/src/menu.js +180 -0
  73. package/src/meta.js +135 -0
  74. package/src/office.js +810 -0
  75. package/src/order.js +100 -0
  76. package/src/peek.js +49 -0
  77. package/src/pele-wrapper.js +695 -0
  78. package/src/permissions.js +180 -0
  79. package/src/places.js +313 -0
  80. package/src/preview-language.js +10 -0
  81. package/src/terminal-server.js +95 -0
  82. package/src/terminal-shell.js +26 -0
  83. package/src/transfer.js +669 -0
  84. package/src/trash-record.js +41 -0
  85. package/src/trash.js +210 -0
  86. package/src/trashbrowse.js +327 -0
  87. package/src/uistate.js +393 -0
  88. package/src/uistore.js +168 -0
  89. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  90. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  91. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  92. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  93. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  94. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  95. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  96. package/src/vendor/pele.js +145 -0
  97. package/src/vendor/temml.mjs +14708 -0
  98. package/src/watch.js +98 -0
  99. package/src/wayland/client.js +109 -0
  100. package/src/wayland/protocol.js +55 -0
  101. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  102. package/src/wayland/protocols/wayland.xml +3248 -0
  103. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  104. package/src/wayland/resource-io.js +6 -0
  105. package/src/wayland/socket-discovery.js +26 -0
  106. package/src/wayland/transport-posix.js +120 -0
  107. package/src/wayland/transport-win32.js +11 -0
  108. package/src/wayland/transport.js +3 -0
  109. package/src/wayland/win32-resources.js +80 -0
  110. package/src/wayland/win32-wire.js +62 -0
  111. package/test/archive.test.js +80 -0
  112. package/test/bench-markdown-scroll.mjs +190 -0
  113. package/test/clip-host.test.js +113 -0
  114. package/test/code-preview.test.js +35 -0
  115. package/test/compare-ui-paths.test.js +24 -0
  116. package/test/compare.test.js +54 -0
  117. package/test/delete-trash.test.js +67 -0
  118. package/test/dirsize.test.js +138 -0
  119. package/test/file-ops.test.js +307 -0
  120. package/test/file-url.test.js +24 -0
  121. package/test/find-contents.test.js +161 -0
  122. package/test/find-input.test.js +66 -0
  123. package/test/fixtures/pele-parity.json +1006 -0
  124. package/test/highlight-launcher.test.js +35 -0
  125. package/test/html-preview.test.js +22 -0
  126. package/test/input.test.js +15 -0
  127. package/test/keymap.test.js +26 -0
  128. package/test/language-icons.test.js +36 -0
  129. package/test/launcher.test.js +51 -0
  130. package/test/manual-archive-here-ui.mjs +47 -0
  131. package/test/manual-code-scroll.mjs +28 -0
  132. package/test/manual-column-scroll.mjs +24 -0
  133. package/test/manual-compare-ui.mjs +20 -0
  134. package/test/manual-find-status.mjs +37 -0
  135. package/test/manual-folder-focus.mjs +63 -0
  136. package/test/manual-html-security.mjs +23 -0
  137. package/test/manual-html-ui.mjs +30 -0
  138. package/test/manual-syntax-preview.mjs +26 -0
  139. package/test/manual-terminal-lifecycle.mjs +42 -0
  140. package/test/manual-terminal-navigation.mjs +48 -0
  141. package/test/manual-terminal-ui.mjs +47 -0
  142. package/test/manual-trash-ui.mjs +86 -0
  143. package/test/markdown-diagrams.test.js +93 -0
  144. package/test/markdown-html.test.js +105 -0
  145. package/test/mathml.test.js +92 -0
  146. package/test/menu-transfer.test.js +57 -0
  147. package/test/office-preview.test.js +154 -0
  148. package/test/pele-parity.test.js +28 -0
  149. package/test/places.test.js +134 -0
  150. package/test/preview-keys.test.js +60 -0
  151. package/test/preview-language.test.js +22 -0
  152. package/test/status-filename.test.js +20 -0
  153. package/test/transfer-replace-merge.test.js +187 -0
  154. package/test/trash-address.test.js +23 -0
  155. package/test/trash-view.test.js +37 -0
  156. package/test/trashbrowse.test.js +135 -0
  157. package/ui/AboutFacts.qml +78 -0
  158. package/ui/ArchiveCards.qml +95 -0
  159. package/ui/ArchiveCompressDialog.qml +378 -0
  160. package/ui/ArchiveHereConfirm.qml +127 -0
  161. package/ui/ArchivePasswordDialog.qml +257 -0
  162. package/ui/Backend.qml +775 -0
  163. package/ui/BulkOldNames.qml +47 -0
  164. package/ui/BulkRenameDialog.qml +380 -0
  165. package/ui/CardFrame.qml +67 -0
  166. package/ui/CardScroll.qml +79 -0
  167. package/ui/CheckBox.qml +73 -0
  168. package/ui/ChromeBar.qml +360 -0
  169. package/ui/ChromeButton.qml +131 -0
  170. package/ui/ChromeModes.qml +43 -0
  171. package/ui/CodeLines.qml +256 -0
  172. package/ui/CodeRefusal.qml +52 -0
  173. package/ui/CollideConfirm.qml +147 -0
  174. package/ui/CollideHost.qml +167 -0
  175. package/ui/ColumnPane.qml +525 -0
  176. package/ui/ColumnRow.qml +380 -0
  177. package/ui/ColumnsArea.qml +594 -0
  178. package/ui/ColumnsLanding.qml +147 -0
  179. package/ui/CompareView.qml +321 -0
  180. package/ui/ContextMenu.qml +743 -0
  181. package/ui/ConvertDialog.qml +456 -0
  182. package/ui/CountedWorker.qml +7 -0
  183. package/ui/Crumb.qml +64 -0
  184. package/ui/CrumbDrop.qml +25 -0
  185. package/ui/CsvTable.qml +394 -0
  186. package/ui/CursorMark.qml +41 -0
  187. package/ui/DefaultClaim.qml +130 -0
  188. package/ui/DeviceLock.qml +47 -0
  189. package/ui/DeviceMounts.qml +540 -0
  190. package/ui/DialogButton.qml +150 -0
  191. package/ui/DialogField.qml +147 -0
  192. package/ui/DialogHeader.qml +31 -0
  193. package/ui/DialogScrim.qml +20 -0
  194. package/ui/DialogTitle.qml +37 -0
  195. package/ui/Divider.qml +9 -0
  196. package/ui/DropInto.qml +126 -0
  197. package/ui/DropTarget.qml +35 -0
  198. package/ui/DropboxMark.qml +60 -0
  199. package/ui/EmptyState.qml +150 -0
  200. package/ui/EscapeHint.qml +11 -0
  201. package/ui/FactsTable.qml +54 -0
  202. package/ui/FastScrollHandler.qml +476 -0
  203. package/ui/FatNamesConfirm.qml +157 -0
  204. package/ui/Favourites.qml +143 -0
  205. package/ui/FigureService.qml +120 -0
  206. package/ui/FileDrag.qml +267 -0
  207. package/ui/FilterStrip.qml +133 -0
  208. package/ui/FitMetrics.qml +22 -0
  209. package/ui/FlashDriveRows.qml +137 -0
  210. package/ui/FlashHost.qml +72 -0
  211. package/ui/FlashImageRow.qml +104 -0
  212. package/ui/FlashRunner.qml +119 -0
  213. package/ui/FlashStepRow.qml +172 -0
  214. package/ui/FlashStrip.qml +38 -0
  215. package/ui/FlashView.qml +397 -0
  216. package/ui/FleaMark.qml +88 -0
  217. package/ui/FlyoutFade.qml +23 -0
  218. package/ui/FontPane.qml +170 -0
  219. package/ui/Glass.qml +114 -0
  220. package/ui/GlassTagger.qml +59 -0
  221. package/ui/Glyph.qml +64 -0
  222. package/ui/GlyphSolid.qml +22 -0
  223. package/ui/GridArea.qml +664 -0
  224. package/ui/GridTile.qml +325 -0
  225. package/ui/GvfsBridge.qml +164 -0
  226. package/ui/Header.qml +433 -0
  227. package/ui/HoverTimers.qml +39 -0
  228. package/ui/HtmlClip.qml +30 -0
  229. package/ui/HtmlPane.qml +63 -0
  230. package/ui/HyprlandMark.qml +45 -0
  231. package/ui/Ipc.qml +1005 -0
  232. package/ui/IpcControls.qml +7 -0
  233. package/ui/IpcMenuState.qml +48 -0
  234. package/ui/IpcPreviewState.qml +185 -0
  235. package/ui/JumpPath.qml +51 -0
  236. package/ui/KeymapSheet.qml +561 -0
  237. package/ui/KeymapSheetResult.qml +89 -0
  238. package/ui/KindStack.qml +40 -0
  239. package/ui/LangMark.qml +51 -0
  240. package/ui/LangMarkLoader.qml +26 -0
  241. package/ui/List.qml +480 -0
  242. package/ui/LoadingState.qml +54 -0
  243. package/ui/LocalSend.qml +56 -0
  244. package/ui/LocalSendMark.qml +73 -0
  245. package/ui/MarkdownBlockView.qml +311 -0
  246. package/ui/MarkdownBlocks.qml +35 -0
  247. package/ui/MarkdownFigure.qml +254 -0
  248. package/ui/MarkdownImages.qml +72 -0
  249. package/ui/MarkdownList.qml +81 -0
  250. package/ui/MarkdownMathsText.qml +97 -0
  251. package/ui/MarkdownPane.qml +83 -0
  252. package/ui/MarkdownPictures.qml +41 -0
  253. package/ui/MarkdownQuote.qml +52 -0
  254. package/ui/MarkdownRemote.qml +82 -0
  255. package/ui/MarkdownSource.qml +155 -0
  256. package/ui/MarkdownTable.qml +222 -0
  257. package/ui/MarkdownTableScroll.qml +64 -0
  258. package/ui/MarkdownTableWheel.qml +126 -0
  259. package/ui/MarkdownText.qml +87 -0
  260. package/ui/MarkdownWorker.js +132 -0
  261. package/ui/MatchText.qml +99 -0
  262. package/ui/MediaSession.qml +38 -0
  263. package/ui/MediaSound.qml +26 -0
  264. package/ui/MediaStrip.qml +191 -0
  265. package/ui/MediaTrack.qml +36 -0
  266. package/ui/MediaVolume.qml +54 -0
  267. package/ui/MenuActionDialog.qml +396 -0
  268. package/ui/MenuEdgeFade.qml +24 -0
  269. package/ui/MenuHost.qml +227 -0
  270. package/ui/MenuRow.qml +351 -0
  271. package/ui/MountListing.qml +100 -0
  272. package/ui/NetworkDialog.qml +435 -0
  273. package/ui/NetworkForm.qml +426 -0
  274. package/ui/NetworkMounts.qml +913 -0
  275. package/ui/NetworkPlaces.qml +127 -0
  276. package/ui/OpenWithDialog.qml +613 -0
  277. package/ui/Opener.qml +95 -0
  278. package/ui/Pane.qml +1320 -0
  279. package/ui/PaneMenuActions.qml +527 -0
  280. package/ui/PanePath.qml +90 -0
  281. package/ui/PaneRail.qml +268 -0
  282. package/ui/PaneStates.qml +88 -0
  283. package/ui/PaneSwap.qml +339 -0
  284. package/ui/PaneWire.qml +601 -0
  285. package/ui/ParkedWait.qml +9 -0
  286. package/ui/PathEntry.qml +186 -0
  287. package/ui/PathJump.qml +400 -0
  288. package/ui/PdfViewer.qml +297 -0
  289. package/ui/PermissionsDialog.qml +658 -0
  290. package/ui/PermissionsHeadings.qml +31 -0
  291. package/ui/PhoneMounts.qml +67 -0
  292. package/ui/PickerAnswers.qml +75 -0
  293. package/ui/PickerBox.qml +26 -0
  294. package/ui/PickerChrome.qml +295 -0
  295. package/ui/PickerFilter.qml +97 -0
  296. package/ui/PickerGrid.qml +308 -0
  297. package/ui/PickerHeader.qml +28 -0
  298. package/ui/PickerLifecycle.qml +27 -0
  299. package/ui/PickerList.qml +218 -0
  300. package/ui/PickerListing.qml +149 -0
  301. package/ui/PickerPathBar.qml +127 -0
  302. package/ui/PickerPlaces.qml +189 -0
  303. package/ui/PickerRecent.qml +92 -0
  304. package/ui/PickerSave.qml +101 -0
  305. package/ui/PickerSelection.qml +155 -0
  306. package/ui/PickerWindow.qml +846 -0
  307. package/ui/PowerSectorsReader.qml +10 -0
  308. package/ui/PrebuildDriver.qml +146 -0
  309. package/ui/Preview.qml +1005 -0
  310. package/ui/PreviewAnimation.qml +24 -0
  311. package/ui/PreviewArchive.qml +91 -0
  312. package/ui/PreviewColumn.qml +553 -0
  313. package/ui/PreviewEdge.qml +63 -0
  314. package/ui/PreviewFacts.qml +30 -0
  315. package/ui/PreviewFactsLine.qml +34 -0
  316. package/ui/PreviewHtml.qml +233 -0
  317. package/ui/PreviewImage.qml +253 -0
  318. package/ui/PreviewImagePan.qml +13 -0
  319. package/ui/PreviewImageSharp.qml +32 -0
  320. package/ui/PreviewLines.qml +106 -0
  321. package/ui/PreviewMarkdown.qml +706 -0
  322. package/ui/PreviewMedia.qml +250 -0
  323. package/ui/PreviewPdf.qml +482 -0
  324. package/ui/PreviewScroll.qml +201 -0
  325. package/ui/PreviewSwap.qml +335 -0
  326. package/ui/PreviewText.qml +149 -0
  327. package/ui/ProtocolChip.qml +18 -0
  328. package/ui/QuickLookArchive.qml +41 -0
  329. package/ui/QuickLookBar.qml +103 -0
  330. package/ui/QuickLookPrepare.qml +355 -0
  331. package/ui/QuickLookSwap.qml +10 -0
  332. package/ui/QuickLookWarm.qml +65 -0
  333. package/ui/RailDrop.qml +155 -0
  334. package/ui/RailHeading.qml +19 -0
  335. package/ui/RailPlaces.qml +38 -0
  336. package/ui/RailTrashRow.qml +67 -0
  337. package/ui/RenameField.qml +353 -0
  338. package/ui/RendererRetry.qml +11 -0
  339. package/ui/ResizeHandle.qml +52 -0
  340. package/ui/Reveal.qml +54 -0
  341. package/ui/Row.qml +476 -0
  342. package/ui/RowDrag.qml +213 -0
  343. package/ui/RowDropTarget.qml +27 -0
  344. package/ui/RunCard.qml +286 -0
  345. package/ui/Scripts.qml +65 -0
  346. package/ui/SearchStrip.qml +232 -0
  347. package/ui/SelectionBand.qml +140 -0
  348. package/ui/SelectionPreview.qml +370 -0
  349. package/ui/SettingsFavourite.qml +122 -0
  350. package/ui/SettingsGroup.qml +96 -0
  351. package/ui/SettingsHint.qml +12 -0
  352. package/ui/SettingsMetrics.qml +29 -0
  353. package/ui/SettingsPane.qml +178 -0
  354. package/ui/SettingsPanel.qml +547 -0
  355. package/ui/SettingsRail.qml +128 -0
  356. package/ui/SettingsRow.qml +409 -0
  357. package/ui/SettingsRuler.qml +85 -0
  358. package/ui/SettingsSegment.qml +85 -0
  359. package/ui/ShareBrowser.qml +113 -0
  360. package/ui/ShareLink.qml +67 -0
  361. package/ui/ShelfPins.qml +101 -0
  362. package/ui/Sidebar.qml +728 -0
  363. package/ui/SidebarRow.qml +358 -0
  364. package/ui/Spinner.qml +60 -0
  365. package/ui/StableModel.qml +89 -0
  366. package/ui/StateMessage.qml +84 -0
  367. package/ui/StatusBar.qml +512 -0
  368. package/ui/StatusFileName.qml +27 -0
  369. package/ui/TabBar.qml +673 -0
  370. package/ui/TabDragGeometry.qml +60 -0
  371. package/ui/TagMenuMark.qml +52 -0
  372. package/ui/TagRailSection.qml +53 -0
  373. package/ui/TagSlot.qml +40 -0
  374. package/ui/TagState.qml +150 -0
  375. package/ui/TagSwatch.qml +28 -0
  376. package/ui/Taildrop.qml +86 -0
  377. package/ui/TailscaleMark.qml +50 -0
  378. package/ui/TerminalService.qml +69 -0
  379. package/ui/TerminalTab.qml +48 -0
  380. package/ui/TerminalTabs.qml +27 -0
  381. package/ui/Theme.qml +460 -0
  382. package/ui/ThemeColors.qml +43 -0
  383. package/ui/TransferCard.qml +239 -0
  384. package/ui/TrashConfirm.qml +129 -0
  385. package/ui/TrashDropHandler.qml +11 -0
  386. package/ui/TrashHost.qml +202 -0
  387. package/ui/TrashMonitor.qml +30 -0
  388. package/ui/TrashToolbar.qml +19 -0
  389. package/ui/TrashView.qml +492 -0
  390. package/ui/UnlockDialog.qml +450 -0
  391. package/ui/UnlockHost.qml +206 -0
  392. package/ui/UpdateCheck.qml +97 -0
  393. package/ui/UserDirs.qml +25 -0
  394. package/ui/ViewState.qml +565 -0
  395. package/ui/ViewportScrollBar.qml +195 -0
  396. package/ui/ViewportScrollBars.qml +25 -0
  397. package/ui/WebPreview.qml +33 -0
  398. package/ui/WebPreviewView.qml +26 -0
  399. package/ui/WindowBody.qml +829 -0
  400. package/ui/WindowDrag.qml +35 -0
  401. package/ui/boot/Commons/AudioNodes.qml +50 -0
  402. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  403. package/ui/boot/Commons/Border.qml +243 -0
  404. package/ui/boot/Commons/BorderGeometry.js +373 -0
  405. package/ui/boot/Commons/Color.qml +258 -0
  406. package/ui/boot/Commons/I18n.qml +118 -0
  407. package/ui/boot/Commons/InputDevices.qml +112 -0
  408. package/ui/boot/Commons/InputMethodState.qml +38 -0
  409. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  410. package/ui/boot/Commons/Numbers.js +19 -0
  411. package/ui/boot/Commons/Plural.js +91 -0
  412. package/ui/boot/Commons/ShellIpc.qml +12 -0
  413. package/ui/boot/Commons/Style.qml +561 -0
  414. package/ui/boot/Commons/Translations.qml +100 -0
  415. package/ui/boot/Commons/UntypedInput.qml +152 -0
  416. package/ui/boot/Commons/Util.qml +188 -0
  417. package/ui/boot/Commons/qmldir +13 -0
  418. package/ui/boot/LICENSE-omarchy +20 -0
  419. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  420. package/ui/boot/Ui/BarIconButton.qml +106 -0
  421. package/ui/boot/Ui/BarIconContent.qml +38 -0
  422. package/ui/boot/Ui/BarIndicator.qml +53 -0
  423. package/ui/boot/Ui/BarWidget.qml +50 -0
  424. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  425. package/ui/boot/Ui/BorderSurface.qml +40 -0
  426. package/ui/boot/Ui/Button.qml +224 -0
  427. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  428. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  429. package/ui/boot/Ui/CursorSurface.qml +42 -0
  430. package/ui/boot/Ui/Dropdown.qml +245 -0
  431. package/ui/boot/Ui/FilterInput.qml +26 -0
  432. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  433. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  434. package/ui/boot/Ui/MultiSelect.qml +624 -0
  435. package/ui/boot/Ui/NumberField.qml +86 -0
  436. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  437. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  438. package/ui/boot/Ui/Panel.qml +60 -0
  439. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  440. package/ui/boot/Ui/PanelController.qml +16 -0
  441. package/ui/boot/Ui/PanelHero.qml +112 -0
  442. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  443. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  444. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  445. package/ui/boot/Ui/PanelSlider.qml +156 -0
  446. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  447. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  448. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  449. package/ui/boot/Ui/PopupCard.qml +181 -0
  450. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  451. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  452. package/ui/boot/Ui/SizedImage.qml +125 -0
  453. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  454. package/ui/boot/Ui/TextField.qml +58 -0
  455. package/ui/boot/Ui/Toggle.qml +118 -0
  456. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  457. package/ui/boot/Ui/WidgetButton.qml +172 -0
  458. package/ui/boot/Ui/qmldir +41 -0
  459. package/ui/boot/fleatab.qml +50 -0
  460. package/ui/boot/picker.qml +39 -0
  461. package/ui/boot/shell.qml +131 -0
  462. package/ui/boot/tabtearoff.qml +51 -0
  463. package/ui/js/Anchor.js +379 -0
  464. package/ui/js/AnchorHold.js +162 -0
  465. package/ui/js/Archive.js +157 -0
  466. package/ui/js/ArchiveCard.js +44 -0
  467. package/ui/js/ArchiveOps.js +44 -0
  468. package/ui/js/BackReturn.js +118 -0
  469. package/ui/js/BulkRename.js +100 -0
  470. package/ui/js/Buttons.js +54 -0
  471. package/ui/js/ChromeKeys.js +116 -0
  472. package/ui/js/ClipMarks.js +73 -0
  473. package/ui/js/ClipSelection.js +67 -0
  474. package/ui/js/Clipboard.js +179 -0
  475. package/ui/js/Cloud.js +97 -0
  476. package/ui/js/CodeRuns.js +72 -0
  477. package/ui/js/Collide.js +212 -0
  478. package/ui/js/ColumnFit.js +28 -0
  479. package/ui/js/ColumnMenu.js +111 -0
  480. package/ui/js/Columns.js +298 -0
  481. package/ui/js/ColumnsCarry.js +103 -0
  482. package/ui/js/Compare.js +74 -0
  483. package/ui/js/Contrast.js +157 -0
  484. package/ui/js/ControlReader.js +42 -0
  485. package/ui/js/Convert.js +52 -0
  486. package/ui/js/CopyAs.js +52 -0
  487. package/ui/js/Crumbs.js +178 -0
  488. package/ui/js/Csv.js +231 -0
  489. package/ui/js/Density.js +44 -0
  490. package/ui/js/Devices.js +440 -0
  491. package/ui/js/DirSizes.js +180 -0
  492. package/ui/js/Drag.js +360 -0
  493. package/ui/js/DragOut.js +166 -0
  494. package/ui/js/DropDev.js +52 -0
  495. package/ui/js/Dropbox.js +41 -0
  496. package/ui/js/Eject.js +217 -0
  497. package/ui/js/Errors.js +188 -0
  498. package/ui/js/ExtThumbs.js +115 -0
  499. package/ui/js/Facts.js +402 -0
  500. package/ui/js/FigureDate.js +14 -0
  501. package/ui/js/Filter.js +285 -0
  502. package/ui/js/Find.js +46 -0
  503. package/ui/js/Flash.js +184 -0
  504. package/ui/js/FlashCard.js +79 -0
  505. package/ui/js/FlashEndings.js +125 -0
  506. package/ui/js/FlashPane.js +116 -0
  507. package/ui/js/FleaBin.js +12 -0
  508. package/ui/js/Focus.js +504 -0
  509. package/ui/js/FolderSorts.js +108 -0
  510. package/ui/js/FolderViews.js +44 -0
  511. package/ui/js/Format.js +314 -0
  512. package/ui/js/Fuzzy.js +141 -0
  513. package/ui/js/GlassTag.js +72 -0
  514. package/ui/js/Grid.js +33 -0
  515. package/ui/js/GridGeometry.js +90 -0
  516. package/ui/js/GridNames.js +153 -0
  517. package/ui/js/GvfsBridge.js +200 -0
  518. package/ui/js/HostClipboard.js +29 -0
  519. package/ui/js/Icons.js +218 -0
  520. package/ui/js/Input.js +50 -0
  521. package/ui/js/Jump.js +200 -0
  522. package/ui/js/KeyName.js +64 -0
  523. package/ui/js/Keymap.js +401 -0
  524. package/ui/js/Kinds.js +164 -0
  525. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  526. package/ui/js/LangMarkPaths.js +47 -0
  527. package/ui/js/LangMarks.js +120 -0
  528. package/ui/js/Lists.js +11 -0
  529. package/ui/js/LocalSend.js +39 -0
  530. package/ui/js/LockedMenu.js +63 -0
  531. package/ui/js/MakeDefault.js +186 -0
  532. package/ui/js/MarkBox.js +7 -0
  533. package/ui/js/Markdown.js +119 -0
  534. package/ui/js/MarkdownLists.js +86 -0
  535. package/ui/js/MarkdownMaths.js +58 -0
  536. package/ui/js/MarkdownPictures.js +32 -0
  537. package/ui/js/MarkdownPrepared.js +139 -0
  538. package/ui/js/MarkdownTableFit.js +34 -0
  539. package/ui/js/Marks.js +148 -0
  540. package/ui/js/Marquee.js +96 -0
  541. package/ui/js/Match.js +93 -0
  542. package/ui/js/Material.js +109 -0
  543. package/ui/js/MdBlocks.js +437 -0
  544. package/ui/js/MdBreak.js +71 -0
  545. package/ui/js/MdChunks.js +70 -0
  546. package/ui/js/MdContainer.js +137 -0
  547. package/ui/js/MdDocument.js +337 -0
  548. package/ui/js/MdEmph.js +97 -0
  549. package/ui/js/MdEntity.js +108 -0
  550. package/ui/js/MdEntityTable.js +223 -0
  551. package/ui/js/MdEscape.js +59 -0
  552. package/ui/js/MdFront.js +37 -0
  553. package/ui/js/MdHold.js +32 -0
  554. package/ui/js/MdHtml.js +307 -0
  555. package/ui/js/MdHtmlBlock.js +290 -0
  556. package/ui/js/MdHtmlHeading.js +53 -0
  557. package/ui/js/MdHtmlImage.js +179 -0
  558. package/ui/js/MdInline.js +154 -0
  559. package/ui/js/MdItems.js +212 -0
  560. package/ui/js/MdLeaf.js +309 -0
  561. package/ui/js/MdLink.js +196 -0
  562. package/ui/js/MdMath.js +67 -0
  563. package/ui/js/MdParagraphs.js +138 -0
  564. package/ui/js/MdRefs.js +232 -0
  565. package/ui/js/MdResolve.js +226 -0
  566. package/ui/js/MdRun.js +300 -0
  567. package/ui/js/MdUrl.js +226 -0
  568. package/ui/js/Menu.js +514 -0
  569. package/ui/js/MenuContext.js +85 -0
  570. package/ui/js/MenuFit.js +13 -0
  571. package/ui/js/MenuRefresh.js +74 -0
  572. package/ui/js/MenuWheel.js +35 -0
  573. package/ui/js/Messages.js +186 -0
  574. package/ui/js/Motion.js +16 -0
  575. package/ui/js/Mounts.js +320 -0
  576. package/ui/js/MouseNav.js +13 -0
  577. package/ui/js/Nav.js +329 -0
  578. package/ui/js/NetFs.js +26 -0
  579. package/ui/js/OpenWith.js +83 -0
  580. package/ui/js/Ops.js +585 -0
  581. package/ui/js/Palette.js +33 -0
  582. package/ui/js/PathBar.js +260 -0
  583. package/ui/js/Permissions.js +179 -0
  584. package/ui/js/Phones.js +112 -0
  585. package/ui/js/Picker.js +353 -0
  586. package/ui/js/PlaceMenu.js +96 -0
  587. package/ui/js/Places.js +265 -0
  588. package/ui/js/PreviewAsk.js +21 -0
  589. package/ui/js/PreviewKeys.js +155 -0
  590. package/ui/js/PreviewSettle.js +29 -0
  591. package/ui/js/PreviewSwap.js +101 -0
  592. package/ui/js/PropertyFacts.js +144 -0
  593. package/ui/js/Protocols.js +296 -0
  594. package/ui/js/QuickLookKinds.js +27 -0
  595. package/ui/js/QuickLookRect.js +24 -0
  596. package/ui/js/RailDrop.js +51 -0
  597. package/ui/js/RailKeys.js +87 -0
  598. package/ui/js/RailMenu.js +133 -0
  599. package/ui/js/Recent.js +135 -0
  600. package/ui/js/RecentMode.js +156 -0
  601. package/ui/js/Reload.js +60 -0
  602. package/ui/js/Renderer.js +9 -0
  603. package/ui/js/RunFile.js +143 -0
  604. package/ui/js/Scripts.js +28 -0
  605. package/ui/js/Scroll.js +304 -0
  606. package/ui/js/ScrollOff.js +69 -0
  607. package/ui/js/Search.js +478 -0
  608. package/ui/js/Selection.js +97 -0
  609. package/ui/js/Settings.js +476 -0
  610. package/ui/js/SettingsAbout.js +97 -0
  611. package/ui/js/SettingsShelf.js +52 -0
  612. package/ui/js/SheetKeys.js +42 -0
  613. package/ui/js/SheetQuery.js +281 -0
  614. package/ui/js/ShelfPile.js +27 -0
  615. package/ui/js/SlowClick.js +53 -0
  616. package/ui/js/SlowOp.js +6 -0
  617. package/ui/js/Sort.js +134 -0
  618. package/ui/js/Startup.js +63 -0
  619. package/ui/js/StateWords.js +17 -0
  620. package/ui/js/Status.js +238 -0
  621. package/ui/js/Swap.js +166 -0
  622. package/ui/js/TabMove.js +39 -0
  623. package/ui/js/Tabs.js +751 -0
  624. package/ui/js/Tags.js +134 -0
  625. package/ui/js/Taildrop.js +128 -0
  626. package/ui/js/Tap.js +180 -0
  627. package/ui/js/TextSize.js +107 -0
  628. package/ui/js/Thumbs.js +158 -0
  629. package/ui/js/Transfer.js +172 -0
  630. package/ui/js/Trash.js +84 -0
  631. package/ui/js/TrashDates.js +47 -0
  632. package/ui/js/TrashDrop.js +64 -0
  633. package/ui/js/UiState.js +438 -0
  634. package/ui/js/Unlock.js +152 -0
  635. package/ui/js/Update.js +130 -0
  636. package/ui/js/UserDirs.js +56 -0
  637. package/ui/qmldir +230 -0
package/ui/js/Nav.js ADDED
@@ -0,0 +1,329 @@
1
+ .pragma library
2
+
3
+ .import "DirSizes.js" as DirSizes
4
+ .import "Filter.js" as Filter
5
+ .import "Kinds.js" as Kinds
6
+ .import "Thumbs.js" as Thumbs
7
+ .import "Search.js" as Search
8
+ .import "ColumnMenu.js" as ColumnMenu
9
+ .import "BackReturn.js" as BackReturn
10
+ .import "Anchor.js" as Anchor
11
+ .import "MouseNav.js" as MouseNav
12
+ .import "Swap.js" as Swap
13
+
14
+ // Where the pane has been and how it gets back, taking ui/Pane.qml's root the way Search.js and
15
+ // Ops.js do: the pane holds the state, this holds what the state does.
16
+
17
+ // A listing inside its deadline refuses a row action; a waiting one is let go by the navigation itself, see ui/Pane.qml openWithoutHistory.
18
+ function loading(pane) { return pane.listInFlight && pane.listingState !== "waiting" }
19
+
20
+ // While a listing is out, the folder it asked for is the pane's current place for every navigation, and the drawn path only until its answer lands.
21
+ function place(pane) { return pane.listInFlight && !!pane.listingPath ? pane.listingPath : pane.path }
22
+
23
+ // A new destination discards the forward branch and pushes the drawn place unless the listing out already did; a re-read keeps both.
24
+ function open(pane, newPath) {
25
+ if (place(pane).length > 0 && newPath !== place(pane)) {
26
+ if (!BackReturn.pending(pane))
27
+ pane.history = pane.history.concat([BackReturn.capture(pane)])
28
+ // A Back out pushed the drawn place onto the forward branch cleared below, so history takes it instead.
29
+ else if (BackReturn.pushedOnto(pane) === "forwardHistory")
30
+ pane.history = pane.history.concat([BackReturn.drawn(pane)])
31
+ pane.forwardHistory = []
32
+ }
33
+ pane.openWithoutHistory(newPath, { supersede: true })
34
+ }
35
+
36
+ function back(pane) {
37
+ if (pane.history.length === 0) {
38
+ return
39
+ }
40
+ BackReturn.travel(pane, "history", "forwardHistory")
41
+ }
42
+
43
+ function forward(pane) {
44
+ if (!pane.forwardHistory || pane.forwardHistory.length === 0) return
45
+ BackReturn.travel(pane, "forwardHistory", "history")
46
+ }
47
+
48
+ // The mouse back button follows history, or climbs when no history exists.
49
+ function mouseBack(pane) {
50
+ if (pane.recentMode === "trash") { pane.closeRecent(); return }
51
+ if (MouseNav.refused(pane)) {
52
+ return
53
+ }
54
+ if (pane.history.length > 0) {
55
+ back(pane)
56
+ return
57
+ }
58
+ parent(pane)
59
+ }
60
+
61
+ // Every listing the pane asks for; of options, ui/Pane.qml reads keepHidden and ui/js/Swap.js begin() the rest.
62
+ // A walk owns the rows until this lands, so leaving it is the shared step with the tabs:
63
+ // tab switches, Back, Up, rail clicks and jumps all funnel through here.
64
+ function openWithoutHistory(pane, newPath, options) {
65
+ Anchor.clearWaiting(pane)
66
+ var ask = options || {}
67
+ if (pane.listInFlight) {
68
+ // Only a navigation takes the place of a listing out; a re-list of the folder shown must not undo it.
69
+ if (ask.supersede !== true) {
70
+ pane.message("A directory is already loading.", false)
71
+ return
72
+ }
73
+ // The listing let go answers into nothing: its listed line names another folder and its rows follow it, see ui/js/Swap.js onListed.
74
+ pane.swap.stopWaiting()
75
+ BackReturn.dropOwed(pane)
76
+ }
77
+ // A hop elsewhere drops a waiting background menu, while the armed hop keeps its own request.
78
+ if (pane.pendingBackground && pane.pendingBackground.length > 0 && !ColumnMenu.samePath(newPath, pane.pendingBackground))
79
+ clearPendingBackground(pane)
80
+ Search.leaveWalk(pane)
81
+ pane.listInFlight = true
82
+ pane.listedSeen = false
83
+ // A hop into another view clears at once like a tab switch, so held rows never draw in a view they were not listed in.
84
+ var shown = pane.viewMode
85
+ if (pane.restoreView)
86
+ pane.restoreView(newPath)
87
+ // A manual reload's notice belongs to its own re-read: a navigation that lands first spends it.
88
+ pane.reloadFrom = -1
89
+ // The path is not written here. A refused listing never answers a listed line, so leaving the
90
+ // pane's own path alone is what keeps a refused hop from moving the breadcrumb onto a directory
91
+ // nobody could read; ui/PaneSwap.qml applyListed takes it from the answer instead. The directory
92
+ // asked for is recorded, because a drop landing while the reply is out means that one and not
93
+ // the directory being left; ui/Pane.qml dropPath reads it and only while this listing is out.
94
+ if (newPath !== pane.path) pane.linkTargetPendingId = 0 // A waiting Show original belongs to the listing being left, so leaving it drops the reveal.
95
+ pane.listingPath = newPath
96
+ // Verdicts stay the left directory's until fsinfo answers, so re-read keeps them.
97
+ if (newPath !== pane.path) { pane.storageClass = ""; pane.storageKnown = false; pane.fsAnswered = false; pane.systemVolume = false; pane.canTag = false }
98
+ if (pane.viewMode !== shown) ask.clearAtOnce = true
99
+ // A walk closed above keeps its rows and its strip until this listing lands.
100
+ if (pane.searchLeaving === true) ask.holdWalk = true
101
+ // A filter line held with its rows gives up the caret, so keys typed meanwhile meet the gate, not a query the swap forgets.
102
+ if (holdOrForget(pane, ask, ask.keptQuery) && pane.filterTyping)
103
+ Filter.commit(pane)
104
+ pane.appliedListingPreferences = pane.listingPreferences
105
+ // leaveWalk above has closed or is closing any search, so the armed row is this listing's to find; a path in another folder names none.
106
+ pane.backend.list(newPath, pane.windowSize, pane.showHidden, ask.wantChanged === true, pane.pendingSelect)
107
+ // One statfs per directory, not per row: the bar's right half only changes when the pane moves.
108
+ pane.backend.askFsInfo()
109
+ }
110
+
111
+ // A settled listing stays drawn until the new rows land, see AGENTS.md "The listing swap"; true when held, else forgotten at once, and a fallen-back loading mark stays through the newest request.
112
+ function holdOrForget(pane, ask, keptQuery) {
113
+ var fell = pane.swap.fellBack === true
114
+ var held = pane.swap.hold(ask)
115
+ if (!held) {
116
+ forget(pane, keptQuery)
117
+ if (fell) pane.swap.phase = Swap.expired(pane.swap.phase)
118
+ }
119
+ return held
120
+ }
121
+
122
+ // Everything a fresh listing forgets, written once: at the request, or by ui/PaneSwap.qml when held rows go.
123
+ function forget(pane, keptQuery) {
124
+ // An exit landing clears the drawn search state in the same turn its rows do.
125
+ if (pane.searchLeaving === true) Search.closeLeaving(pane)
126
+ // The editor row and the held sort belong to the replaced listing, so both go with it, before the count drops.
127
+ pane.pendingSort = null
128
+ pane.renamingIndex = -1
129
+ pane.total = 0
130
+ pane.held = 0
131
+ pane.rows = []
132
+ pane.kindNames = []
133
+ pane.thumbState = Thumbs.empty()
134
+ pane.dirSizeState = DirSizes.empty()
135
+ pane.cursorIndex = 0
136
+ pane.trashArmedAt = 0
137
+ // A re-list puts a different file at that index, so the tap record goes with the rename.
138
+ if (pane.cancelSlowClick) pane.cancelSlowClick()
139
+ // A filter narrows the rows already listed, so a new listing forgets it unless ui/js/Anchor.js hands it back.
140
+ Filter.close(pane)
141
+ if (keptQuery)
142
+ pane.filterQuery = keptQuery
143
+ pane.listingState = "loading"
144
+ pane.stateMessage = ""
145
+ pane.lockedMode = 0
146
+ pane.clearSelection()
147
+ pane.listArea.primeSettle()
148
+ }
149
+
150
+ // Which row the listing re-reveals after a rename. A rename the pointer committed keeps the row the
151
+ // pointer chose instead, because re-selecting the renamed one would undo the click a round trip
152
+ // after it landed. One shot: the next rename reveals again.
153
+ function renameRefreshTarget(pane, path) {
154
+ if (!pane.renameKeepsPointerRow) {
155
+ return path
156
+ }
157
+ pane.renameKeepsPointerRow = false
158
+ return ""
159
+ }
160
+
161
+ // An operation changed the directory under the listing, so it is read again. Passing the path the
162
+ // operation produced re-selects that row through pendingSelect instead of dropping the cursor to the
163
+ // top. It is not a navigation, so it never touches the history.
164
+ function refresh(pane, selectPath, keepSelection) {
165
+ pane.pendingSelect = selectPath ? selectPath : ""
166
+ pane.pendingMenu = false
167
+ clearPendingBackground(pane)
168
+ // A search keeps its rows and numbering, so one window ask re-stats the held rows; marks and cursor stay.
169
+ if (keepSelection === true && pane.searchMode === Search.RESULTS) {
170
+ pane.backend.window(pane.held, pane.windowSize)
171
+ return
172
+ }
173
+ if (keepSelection === true) {
174
+ // Metadata-only writes use the watcher's identity anchor and interaction debt.
175
+ pane.wire.stale = true
176
+ pane.wire.reread()
177
+ return
178
+ }
179
+ pane.openWithoutHistory(pane.path, { inPlace: true })
180
+ }
181
+
182
+ // The list request names the target, so its first rows answer alone looks for it at any depth, by listed name (NFC finds NFD).
183
+ function applyPendingSelect(pane) {
184
+ // A search arms its return while the query stands, so its own landings skip it until Esc.
185
+ if (pane.pendingSelect.length === 0 || (pane.searchMode || "").length > 0) {
186
+ return
187
+ }
188
+ var target = pane.pendingSelect
189
+ pane.pendingSelect = ""
190
+ var at = Anchor.selectMatch(pane.rows, target, pane.path)
191
+ if (at >= 0) {
192
+ var index = pane.held + at
193
+ pane.setCursor(index)
194
+ pane.selection.only(index, true)
195
+ pane.selectionAnchor = index
196
+ pane.selectionVersion++
197
+ if (pane.pendingMenu) {
198
+ pane.pendingMenu = false
199
+ pane.openCursorMenu()
200
+ }
201
+ return
202
+ }
203
+ // The row is not in this listing, so the intent behind it must not fire on some later match.
204
+ pane.pendingMenu = false
205
+ }
206
+
207
+ // A failed listing drops the deferred background menu, so no later rows open it.
208
+ function clearPendingBackground(pane) { ColumnMenu.clearPendingBackground(pane) }
209
+
210
+ // The deferred neighbour background, consumed on every landing by identity.
211
+ function applyPendingBackground(pane) { ColumnMenu.applyPendingBackground(pane) }
212
+
213
+ // The cursor row once Enter's three guards pass, else null with the reason shown; the in-flight guard stops a second Enter queueing a second listing.
214
+ function openableRow(pane) {
215
+ if (loading(pane)) {
216
+ pane.message("A directory is already loading.", false)
217
+ return null
218
+ }
219
+ var row = pane.rowFor(pane.cursorIndex)
220
+ if (!row) {
221
+ pane.message("That row has not loaded yet.", false)
222
+ return null
223
+ }
224
+ if (!Filter.cursorShown(pane)) {
225
+ pane.message("That row is hidden by the filter.", false)
226
+ return null
227
+ }
228
+ return row
229
+ }
230
+
231
+ // Enter on the cursor row: a directory navigates, an archive opens Flea's own view, anything else goes to the opener.
232
+ function openCursor(pane, opener) {
233
+ var row = openableRow(pane)
234
+ if (!row) return
235
+ var path = pane.join(Search.baseOf(pane), row.n)
236
+ if (row.d) {
237
+ pane.open(path)
238
+ return
239
+ }
240
+ // Handing an archive on opens another file manager, and this is ui/Preview.qml's own classifier; an AppImage is a program first, so it asks on the run card.
241
+ if (Kinds.quickLookKind(row.i, path) === Kinds.ARCHIVE && !/\.appimage$/i.test(row.n)) {
242
+ pane.quickLook().open(path, row.i, row.s, pane.kindNames[row.k] || "",
243
+ pane.thumbState && pane.thumbState.file ? Thumbs.fileFor(pane.thumbState, pane.cursorIndex) : "")
244
+ return
245
+ }
246
+ opener.open(path)
247
+ }
248
+
249
+ // The run card's open action uses the same xdg-open route as Enter.
250
+ function runCursor(pane, opener, verb) {
251
+ var row = openableRow(pane)
252
+ if (!row) return
253
+ var path = pane.join(Search.baseOf(pane), row.n)
254
+ if (verb === "open") opener.open(path)
255
+ else pane.runText(path)
256
+ }
257
+
258
+ // The folder the Locked tile names, for its own menu and every row that menu offers: the
259
+ // directory asked for while its tile is up, which is the parent's own path when the folder
260
+ // failed on its own re-read. "" while no Locked tile is drawn, so the background menu stands.
261
+ function lockedTarget(pane) {
262
+ if (pane.listingState !== "locked") return ""
263
+ var asked = pane.listingPath || ""
264
+ return asked.length > 0 ? trimSlash(asked) : pane.path
265
+ }
266
+
267
+ // The path helpers the columns view needs. A root has no parent and no leaf of its own.
268
+ function trimSlash(path) {
269
+ // A bookmark can carry one trailing slash, which no row name ever has; "/" alone keeps its own.
270
+ var text = String(path)
271
+ return text.length > 1 && text.charAt(text.length - 1) === "/" ? text.substring(0, text.length - 1) : text
272
+ }
273
+
274
+ function parentOf(path) {
275
+ var text = trimSlash(path)
276
+ var cut = text.lastIndexOf("/")
277
+ return cut <= 0 ? "/" : text.substring(0, cut)
278
+ }
279
+
280
+ function leafOf(path) {
281
+ var text = String(path)
282
+ var cut = text.lastIndexOf("/")
283
+ return cut < 0 || cut === text.length - 1 ? text : text.substring(cut + 1)
284
+ }
285
+
286
+ // Issue 193: a hop that is out, refused or waiting climbs from the folder it asked for; ui/Pane.qml canGoUp reads it too.
287
+ function climbsFromListing(pane) {
288
+ return (pane.listInFlight || pane.listingState === "locked" || pane.listingState === "waiting") && !!pane.listingPath && pane.listingPath !== pane.path
289
+ }
290
+
291
+ // Backspace, h and the chrome's up arrow, stopping at the root; the parent lands on the directory left, at any depth.
292
+ function parent(pane) {
293
+ if (climbsFromListing(pane)) {
294
+ pane.pendingSelect = trimSlash(pane.listingPath)
295
+ pane.open(parentOf(pane.listingPath))
296
+ return
297
+ }
298
+ if (pane.path === "/") {
299
+ return
300
+ }
301
+ var here = pane.path
302
+ var cut = here.lastIndexOf("/")
303
+ pane.pendingSelect = here
304
+ pane.open(cut <= 0 ? "/" : here.substring(0, cut))
305
+ }
306
+
307
+ // A click on the folder already shown is a no-op, so the rail and columns routes land here.
308
+ function showing(pane, path) {
309
+ if (trimSlash(path) !== pane.path) return false
310
+ if (pane.listInFlight) return false
311
+ if ((pane.searchMode || "").length > 0) return false
312
+ if (!pane.trash || pane.trash.opened) return false
313
+ return pane.listingState === "ready" || pane.listingState === "empty"
314
+ }
315
+
316
+ // Same-path Enter re-lists only a failed or locked listing; Trash, search and in-flight stay a no-op.
317
+ function pathFailed(pane) {
318
+ if (!pane || pane.listInFlight) return false
319
+ if ((pane.searchMode || "").length > 0) return false
320
+ if (!pane.trash || pane.trash.opened) return false
321
+ return pane.listingState === "error" || pane.listingState === "locked"
322
+ }
323
+
324
+ // The rail's and the columns view's route in: the shown folder returns false and lists nothing.
325
+ function openPlace(pane, path) {
326
+ if (showing(pane, path)) return false
327
+ pane.open(path)
328
+ return true
329
+ }
package/ui/js/NetFs.js ADDED
@@ -0,0 +1,26 @@
1
+ .pragma library
2
+
3
+ // One shared list of network filesystem types for Cloud.js and the Rust netfs module.
4
+ // Sample input: "fuse.sshfs" trues, "ext4" falses, "NFS4" trues, "fuse.portal" falses.
5
+ function isNetworkFstype(fstype) {
6
+ if (isCifsFstype(fstype))
7
+ return true
8
+ switch (String(fstype || "").toLowerCase()) {
9
+ case "nfs": case "nfs4": case "9p": case "afs":
10
+ case "ceph": case "davfs": case "fuse.sshfs": case "fuse.rclone": case "fuse.s3fs":
11
+ case "fuse.gcsfuse": case "fuse.curlftpfs": case "fuse.juicefs": case "fuse.glusterfs":
12
+ case "fuse.ceph-fuse": case "fuse.smbnetfs": case "fuse.davfs2": case "fuse.gvfsd-fuse":
13
+ case "fuse.protondrive":
14
+ return true
15
+ }
16
+ return false
17
+ }
18
+
19
+ // RailEject callout 2: SMB-family fstypes draw the mark, the rest keep their square.
20
+ function isCifsFstype(fstype) {
21
+ switch (String(fstype || "").toLowerCase()) {
22
+ case "cifs": case "smb2": case "smb3": case "smbfs":
23
+ return true
24
+ }
25
+ return false
26
+ }
@@ -0,0 +1,83 @@
1
+ .pragma library
2
+
3
+ .import "Format.js" as Format
4
+
5
+ // The sentences the Open with card draws, each filled by Format.fill.
6
+ var WORDS = {
7
+ titleNamed: "Open %1 with",
8
+ alwaysKind: "Always use this application for %1 files",
9
+ registeredFor: "Registered for %1",
10
+ noMatch: "No application matches “%1”. Clear the search to see every installed application."
11
+ }
12
+
13
+ // OpenWith.html rule 5: the dialog draws two groups under eyebrows, the type's own registry first with
14
+ // the desktop's default at its head, then every installed application alphabetically. The search
15
+ // filters both, and a group that matches nothing takes its eyebrow with it.
16
+ function rows(handlers, installed, kind, query) {
17
+ var needle = String(query || "").trim().toLowerCase()
18
+ var out = []
19
+ var seat = 0
20
+ var registered = matching(handlers, needle)
21
+ if (registered.length) {
22
+ out.push({ eyebrow: Format.fill(WORDS.registeredFor, kind), rule: false })
23
+ for (var i = 0; i < registered.length; i++) out.push(seated(registered[i], seat++))
24
+ }
25
+ var every = matching(installed, needle)
26
+ if (every.length) {
27
+ out.push({ eyebrow: "All applications", rule: registered.length > 0 })
28
+ for (var j = 0; j < every.length; j++) out.push(seated(every[j], seat++))
29
+ }
30
+ return out
31
+ }
32
+
33
+ function matching(apps, needle) {
34
+ var out = []
35
+ for (var i = 0; i < (apps || []).length; i++) {
36
+ if (!needle.length || String(apps[i].label).toLowerCase().indexOf(needle) >= 0) out.push(apps[i])
37
+ }
38
+ return out
39
+ }
40
+
41
+ // A copy carrying the cursor seat it holds, so the drawn row never counts the list to find its own.
42
+ // A registered application is drawn twice, once per group, and the two copies take different seats.
43
+ // The seat is carried, not recounted: counting made this quadratic over a hundred-application box.
44
+ function seated(app, seat) {
45
+ return { id: app.id, label: app.label, icon: app.icon, default: app.default === true, at: seat }
46
+ }
47
+
48
+ // The rows the cursor can land on, in the order they are drawn; an eyebrow is a caption it steps over.
49
+ function applications(rows) {
50
+ var out = []
51
+ for (var i = 0; i < (rows || []).length; i++) {
52
+ if (rows[i].eyebrow === undefined) out.push(rows[i])
53
+ }
54
+ return out
55
+ }
56
+
57
+ // The row index a cursor position holds, so the drawn list and the keys agree on one order.
58
+ function rowOf(rows, cursor) {
59
+ var seen = -1
60
+ for (var i = 0; i < (rows || []).length; i++) {
61
+ if (rows[i].eyebrow !== undefined) continue
62
+ if (++seen === cursor) return i
63
+ }
64
+ return -1
65
+ }
66
+
67
+ // Rule 5's viewport: seven applications show before the list scrolls, and the eyebrows standing over
68
+ // them are in view too, so the height lands on a row boundary instead of cutting the eighth in half.
69
+ function viewportHeight(rows, applications, rowHeight, eyebrowHeight) {
70
+ var seen = 0, total = 0
71
+ for (var i = 0; i < (rows || []).length && seen < applications; i++) {
72
+ if (rows[i].eyebrow !== undefined) { total += eyebrowHeight; continue }
73
+ total += rowHeight
74
+ seen++
75
+ }
76
+ // Rule 6 keeps this height when a search matches nothing, so a short catalogue still fills it.
77
+ return seen < applications ? total + (applications - seen) * rowHeight : total
78
+ }
79
+
80
+ // The caption rule 6 centres in the list's own height when the search names nothing installed.
81
+ function noMatch(query) {
82
+ return Format.fill(WORDS.noMatch, String(query).trim())
83
+ }