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
@@ -0,0 +1,42 @@
1
+ .pragma library
2
+ .import "Input.js" as Input
3
+
4
+ // The keymap sheet's key decisions; imports no QML, so tests drive it.
5
+
6
+ // Sample input: isBareModifier(Qt.Key_Shift) is true, isBareModifier(Qt.Key_A) is false.
7
+ // A bare modifier carries no text, so without this the sheet would close under a shifted letter.
8
+ function isBareModifier(key) {
9
+ return key === Qt.Key_Shift || key === Qt.Key_Control || key === Qt.Key_Alt
10
+ || key === Qt.Key_AltGr || key === Qt.Key_Meta || key === Qt.Key_CapsLock
11
+ }
12
+
13
+ // Sample input: sheetKey("co", Qt.Key_Shift, "") is "ignore".
14
+ // The one decision the sheet's Keys.onPressed runs, so the handler owns no key meaning of its own.
15
+ function sheetKey(query, key, text) {
16
+ if (key === Qt.Key_Escape)
17
+ return "close"
18
+ if (String(query).length > 0) {
19
+ if (key === Qt.Key_Up)
20
+ return "up"
21
+ if (key === Qt.Key_Down)
22
+ return "down"
23
+ if (key === Qt.Key_Return || key === Qt.Key_Enter)
24
+ return "activate"
25
+ }
26
+ if (key === Qt.Key_Backspace)
27
+ return String(query).length > 0 ? "backspace" : "close"
28
+ if (Input.isPrintable(text))
29
+ return "type"
30
+ // Delete edits nothing forward, so it is ignored rather than typed or closed on.
31
+ if (key === Qt.Key_Delete || isBareModifier(key))
32
+ return "ignore"
33
+ return "close"
34
+ }
35
+
36
+ // Sample input: stepCursor(0, -1, 3) is 2, stepCursor(2, 1, 3) is 0.
37
+ // The cursor wraps at both ends; with no rows it parks at the first.
38
+ function stepCursor(cursor, delta, count) {
39
+ if (!(count > 0))
40
+ return 0
41
+ return (((cursor + delta) % count) + count) % count
42
+ }
@@ -0,0 +1,281 @@
1
+ .pragma library
2
+ .import "Format.js" as Format
3
+ .import "Recent.js" as Recent
4
+ .import "Swap.js" as Swap
5
+ .import "Places.js" as Places
6
+ .import "Focus.js" as Focus
7
+
8
+ // The sheet's four-section query filter; imports no QML, so tests drive it.
9
+
10
+ var RESULT_LIMIT = 50
11
+
12
+ // The one non-listing context a sheet row can carry, named as the UI names that surface; the others have no name on screen.
13
+ var CONTEXT_NAMES = { media: "Preview" }
14
+
15
+ // Sample input: whereForContext("media") is "Preview", whereForContext("listing") is "".
16
+ // A key that works in one place only says where, in that place's name; a context the UI never names says nothing.
17
+ function whereForContext(context) {
18
+ var text = String(context || "")
19
+ if (text.indexOf(",") >= 0 || !Object.prototype.hasOwnProperty.call(CONTEXT_NAMES, text)) {
20
+ return ""
21
+ }
22
+ return CONTEXT_NAMES[text]
23
+ }
24
+
25
+ // Section 0 from the generated sheet; the caller hands in sheetFor rows.
26
+ function actionCandidates(sheetRows) {
27
+ var out = []
28
+ var rows = sheetRows || []
29
+ for (var i = 0; i < rows.length; i++) {
30
+ out.push({ label: String(rows[i].label || ""), keys: String(rows[i].keys || ""),
31
+ section: 0, where: whereForContext(rows[i].context),
32
+ action: String(rows[i].action || ""), disabled: false, danger: false })
33
+ }
34
+ return out
35
+ }
36
+
37
+ // Section 1 from the menu's own model, hidden rows included; disabled rows never run.
38
+ function menuCandidates(entries, hintFor) {
39
+ var out = []
40
+ var rows = entries || []
41
+ var hint = typeof hintFor === "function" ? hintFor : function () { return "" }
42
+ for (var i = 0; i < rows.length; i++) {
43
+ var entry = rows[i]
44
+ if (!entry || entry.separator === true) {
45
+ continue
46
+ }
47
+ var action = String(entry.action || entry.id || "")
48
+ out.push({ label: String(entry.label || ""), keys: String(hint(action) || ""),
49
+ section: 1, where: "", menuAction: actionWithSub(action, ""),
50
+ disabled: entry.disabled === true, danger: entry.danger === true })
51
+ var sub = entry.submenu || []
52
+ for (var j = 0; j < sub.length; j++) {
53
+ if (!sub[j] || sub[j].separator === true) {
54
+ continue
55
+ }
56
+ var leafId = String(sub[j].id || "")
57
+ // A leaf with its own sheet wording reads whole, with no muted flyout suffix.
58
+ var sheetLabel = String(sub[j].sheetLabel || "")
59
+ out.push({ label: sheetLabel.length > 0 ? sheetLabel : String(sub[j].label || ""), keys: "",
60
+ section: 1, where: sheetLabel.length > 0 ? "" : String(entry.label || ""),
61
+ menuAction: actionWithSub(action, leafId), parentAction: action,
62
+ disabled: entry.disabled === true || sub[j].disabled === true,
63
+ danger: entry.danger === true })
64
+ }
65
+ }
66
+ return out
67
+ }
68
+
69
+ function actionWithSub(action, leafId) {
70
+ return leafId.length > 0 ? action + ":" + leafId : action
71
+ }
72
+
73
+ // The group name the rail shows: Favorites, Places, or the network/device group.
74
+ function placeWhere(entry) {
75
+ var group = String((entry && entry.group) || "")
76
+ // flea-qml: a drive found by looking is a plain folder row drawn under DEVICES.
77
+ if (entry && entry.volume === true) {
78
+ return "Devices"
79
+ }
80
+ if (group === "favourite" || group === "favorite") {
81
+ return "Favorites"
82
+ }
83
+ if (group === "network") {
84
+ return "Network"
85
+ }
86
+ if (group === "device") {
87
+ return "Devices"
88
+ }
89
+ return "Places"
90
+ }
91
+
92
+ // Section 2 from the rail's entries; an exact NAME match ranks first.
93
+ function placeCandidates(railEntries) {
94
+ var out = []
95
+ var rows = railEntries || []
96
+ for (var i = 0; i < rows.length; i++) {
97
+ var entry = rows[i]
98
+ if (!entry || String(entry.label || "").length === 0) {
99
+ continue
100
+ }
101
+ if (String(entry.kind || "") === "recent") {
102
+ continue
103
+ }
104
+ out.push({ label: "Open " + entry.label, name: String(entry.label),
105
+ keys: "", section: 2, where: placeWhere(entry), railIndex: i, entry: entry })
106
+ }
107
+ return out
108
+ }
109
+
110
+ // Section 3 from the xbel source, read once per query line and bounded by Recent.LIMIT.
111
+ function recentCandidates(recentPaths, home) {
112
+ var out = []
113
+ var rows = recentPaths || []
114
+ var bound = Math.min(rows.length, Recent.LIMIT)
115
+ for (var i = 0; i < bound; i++) {
116
+ var path = String(rows[i] || "")
117
+ if (path.length === 0) {
118
+ continue
119
+ }
120
+ var leaf = Recent.nameOf(path)
121
+ var parent = Format.tilde(Recent.locationOf(path), String(home || ""))
122
+ out.push({ label: "Open " + leaf, keys: "", section: 3,
123
+ where: parent, path: path })
124
+ }
125
+ return out
126
+ }
127
+
128
+ // The matched run the specimen washes. Case-insensitive substring, null when none.
129
+ function matchOf(label, query) {
130
+ var text = String(label || "").toLowerCase()
131
+ var needle = String(query || "").trim().toLowerCase()
132
+ if (needle.length === 0) {
133
+ return null
134
+ }
135
+ var at = text.indexOf(needle)
136
+ if (at < 0) {
137
+ return null
138
+ }
139
+ return { start: at, length: needle.length }
140
+ }
141
+
142
+ // Sample input: a key row {action: "trash"} then a menu row {menuAction: "trash", label: "Move to Trash"} keeps the key row only, carrying menuLabel "Move to Trash".
143
+ // One action, one row: the key row stays, the menu's wording rides on it to be searched, and a disabled menu row's verdict rides on it too, so a folder that refuses Rename refuses it here.
144
+ function unique(candidates) {
145
+ var at = {}
146
+ var out = []
147
+ var list = candidates || []
148
+ for (var i = 0; i < list.length; i++) {
149
+ var run = String(list[i].action || list[i].menuAction || "")
150
+ if (run.length === 0) {
151
+ out.push(list[i])
152
+ } else if (at[run] === undefined) {
153
+ at[run] = out.length
154
+ out.push(list[i])
155
+ } else if (list[i].section === 1 && out[at[run]].section === 0) {
156
+ var held = Object.assign({}, out[at[run]], { menuLabel: String(list[i].label || ""),
157
+ menuAction: list[i].menuAction })
158
+ if (list[i].disabled === true) {
159
+ held.disabled = true
160
+ }
161
+ out[at[run]] = held
162
+ }
163
+ }
164
+ return out
165
+ }
166
+
167
+ // The row as the query reads it: the key row's wording when it matches, else the menu's wording that did.
168
+ function worded(row, needle) {
169
+ var label = String(row.label || "").toLowerCase()
170
+ var menuLabel = String(row.menuLabel || "")
171
+ if (label.indexOf(needle) < 0 && menuLabel.toLowerCase().indexOf(needle) >= 0) {
172
+ return Object.assign({}, row, { label: menuLabel })
173
+ }
174
+ return row
175
+ }
176
+
177
+ // Sample query: "down" matches "Open Downloads" but not "trash".
178
+ function rank(candidates, query) {
179
+ var needle = String(query || "").trim().toLowerCase()
180
+ var list = unique(candidates)
181
+ if (needle.length === 0) {
182
+ return list.slice(0, RESULT_LIMIT)
183
+ }
184
+ var exactPlace = []
185
+ var exact = []
186
+ var matched = []
187
+ var keyed = []
188
+ for (var i = 0; i < list.length; i++) {
189
+ var label = String(list[i].label || "").toLowerCase()
190
+ var menuLabel = String(list[i].menuLabel || "").toLowerCase()
191
+ var keys = String(list[i].keys || "").toLowerCase()
192
+ var name = String(list[i].name || "").toLowerCase()
193
+ // An exact NAME match ranks first, so "? trash Enter" opens Trash.
194
+ if (name.length > 0 && name === needle) {
195
+ exactPlace.push(list[i])
196
+ } else if (label === needle || menuLabel === needle) {
197
+ exact.push(worded(list[i], needle))
198
+ } else if (label.indexOf(needle) >= 0 || menuLabel.indexOf(needle) >= 0) {
199
+ matched.push(worded(list[i], needle))
200
+ } else if (keys.length > 0 && keys.indexOf(needle) >= 0) {
201
+ keyed.push(list[i])
202
+ }
203
+ }
204
+ return withoutListedParents(exactPlace.concat(exact, matched, keyed).slice(0, RESULT_LIMIT))
205
+ }
206
+
207
+ // A flyout parent whose leaves the bounded list shows is not itself a row; a key row, a leafless parent and a parent whose leaves the bound cut stay.
208
+ function withoutListedParents(rows) {
209
+ var listed = {}
210
+ for (var i = 0; i < rows.length; i++) {
211
+ if (String(rows[i].parentAction || "").length > 0) {
212
+ listed[rows[i].parentAction] = true
213
+ }
214
+ }
215
+ return rows.filter(function (row) {
216
+ return !(row.section === 1 && !row.parentAction && listed[String(row.menuAction || "")] === true)
217
+ })
218
+ }
219
+
220
+ // Enter runs the highlighted row as its own surface would.
221
+ function dispatch(candidate) {
222
+ var row = candidate || {}
223
+ if (row.disabled === true) {
224
+ return { kind: "disabled" }
225
+ }
226
+ if (row.section === 0 && String(row.action || "").length > 0) {
227
+ return { kind: "action", action: String(row.action) }
228
+ }
229
+ if (row.section === 1 && String(row.menuAction || "").length > 0) {
230
+ if (row.danger === true) {
231
+ return { kind: "confirm", menuAction: String(row.menuAction) }
232
+ }
233
+ return { kind: "menu", menuAction: String(row.menuAction) }
234
+ }
235
+ if (row.section === 2 && row.entry) {
236
+ return { kind: "place", railIndex: row.railIndex, entry: row.entry }
237
+ }
238
+ if (row.section === 3 && String(row.path || "").length > 0) {
239
+ return { kind: "recent", path: String(row.path) }
240
+ }
241
+ return { kind: "none" }
242
+ }
243
+
244
+ // Enter skips the key gate, so Swap.swallows refuses listing actions here while allowing navigation.
245
+ function runAction(holder, action, close) {
246
+ if (Swap.swallows(holder.listInFlight, action)) {
247
+ holder.message(Swap.LOADING, false)
248
+ return
249
+ }
250
+ close()
251
+ if (holder.sheetAction) holder.sheetAction(action)
252
+ else Focus.dispatchAction(action, holder)
253
+ }
254
+
255
+ // Every menu row resolves its rows through the snapshot, so it refuses while a listing is out, unlike navigations; the holder runs the row.
256
+ function runMenu(holder, menuAction, close) {
257
+ if (holder.listInFlight === true) {
258
+ holder.message(Swap.LOADING, false)
259
+ return
260
+ }
261
+ close()
262
+ holder.sheetMenuAction(menuAction)
263
+ }
264
+
265
+ // Sample input: entries two favourites both labelled "src", decided with railIndex 1 answers 1.
266
+ // The rail rebuilds on its poll, so the row is resolved by the rail's own identity, never by label.
267
+ function placeIndex(entries, decided) {
268
+ var list = entries || []
269
+ var row = decided || {}
270
+ var want = Places.railIdentity(row.entry)
271
+ if (want.length === 0)
272
+ return -1
273
+ var at = Number(row.railIndex)
274
+ if (at >= 0 && at < list.length && Places.railIdentity(list[at]) === want)
275
+ return at
276
+ for (var i = 0; i < list.length; i++) {
277
+ if (Places.railIdentity(list[i]) === want)
278
+ return i
279
+ }
280
+ return -1
281
+ }
@@ -0,0 +1,27 @@
1
+ .pragma library
2
+
3
+ // The pile file the bar plugin writes, read here for the Settings panel's Pinned list. Sample input:
4
+ // {"items":[{"path":"/home/gm/Invoices","name":"Invoices","folder":true,"pinned":true}]}
5
+ function pinned(text) {
6
+ var doc = {}
7
+ try {
8
+ doc = JSON.parse(String(text || "")) || {}
9
+ } catch (e) {
10
+ return []
11
+ }
12
+ var items = doc.items instanceof Array ? doc.items : []
13
+ var out = []
14
+ for (var i = 0; i < items.length; i++) {
15
+ if (items[i] && items[i].pinned === true && typeof items[i].path === "string") {
16
+ out.push({ path: items[i].path, name: leaf(items[i].path),
17
+ folder: items[i].folder === true, missing: items[i].missing === true })
18
+ }
19
+ }
20
+ return out
21
+ }
22
+
23
+ function leaf(path) {
24
+ var trimmed = String(path).replace(/\/+$/, "")
25
+ var at = trimmed.lastIndexOf("/")
26
+ return at < 0 ? trimmed : trimmed.substring(at + 1)
27
+ }
@@ -0,0 +1,53 @@
1
+ .pragma library
2
+
3
+ // Slow-click rename shared by the list, grid and columns views: tap arms the pane timer, double click cancels, fire renames a still-held sole row.
4
+ var CLEARED = -2 // SlowClick.cancel's cleared value, read by Pane.qml's slowClickIndex.
5
+
6
+ // Pre-tap sole-selection fact the views capture before Tap.tapped selects for this tap.
7
+ function wasSoleSelection(pane, index) {
8
+ if (!pane || index < 0) return false
9
+ if (pane.selectionCount() !== 1 || !pane.isSelected(index)) return false
10
+ return pane.cursorIndex === index
11
+ }
12
+ // Whether this tap starts the timer; records every tap so a tap on another row re-arms.
13
+ function arm(pane, index, modifiers, now, interval, dragging, wasSole) {
14
+ var plain = (modifiers & (Qt.ControlModifier | Qt.ShiftModifier)) === 0
15
+ var drag = dragging === undefined ? pane.dragActive : dragging
16
+ var priorAt = pane.slowClickAt || 0
17
+ var priorIndex = pane.slowClickIndex === undefined ? CLEARED : pane.slowClickIndex
18
+ pane.slowClickAt = now
19
+ pane.slowClickIndex = index
20
+ if (!(index >= 0 && plain && pane.singleClick !== true && pane.clickRename !== false
21
+ && pane.searchMode === "" && pane.renamingIndex < 0 && !pane.renamePending
22
+ && pane.selectionBand === null && drag !== true))
23
+ return false
24
+ if (wasSole !== undefined) {
25
+ if (!wasSole) return false
26
+ } else if (!wasSoleSelection(pane, index)) {
27
+ return false
28
+ }
29
+ return priorIndex === index && now - priorAt > interval
30
+ }
31
+
32
+ // The timer firing renames only when the cursor and sole selection still hold the armed row.
33
+ function fire(pane, dragging) {
34
+ var index = pane.slowClickIndex
35
+ pane.slowClickIndex = CLEARED
36
+ if (index === undefined || index < 0) return false
37
+ if (pane.menuVisible === true) return false
38
+ var liveDrag = dragging === undefined ? pane.dragActive : dragging
39
+ if (liveDrag === true) return false
40
+ if (pane.renamingIndex >= 0 || pane.renamePending) return false
41
+ if (pane.singleClick === true || pane.clickRename === false) return false
42
+ if (pane.searchMode !== "" || pane.selectionBand !== null) return false
43
+ var picked = pane.selectedIndices()
44
+ if (picked.length !== 1 || picked[0] !== index || pane.cursorIndex !== index) return false
45
+ // The pointer chose this row, so the reveal carries context 0 and the list never moves under it.
46
+ pane.act("rename", 0, null, 0)
47
+ return true
48
+ }
49
+
50
+ // A second tap in time, or a tap failing the arm, disarms without renaming.
51
+ function cancel(pane) {
52
+ pane.slowClickIndex = CLEARED
53
+ }
@@ -0,0 +1,6 @@
1
+ .pragma library
2
+
3
+ // The late reply closes exactly what the in-time reply would close.
4
+ function closesRename(request, path) {
5
+ return !!request && path === request.destination
6
+ }
package/ui/js/Sort.js ADDED
@@ -0,0 +1,134 @@
1
+ .pragma library
2
+
3
+ .import "DirSizes.js" as DirSizes
4
+ .import "FolderSorts.js" as FolderSorts
5
+ .import "RecentMode.js" as RecentMode
6
+ .import "Thumbs.js" as Thumbs
7
+
8
+ // What the header's click and the s and S keys do, taking ui/Pane.qml's root the way Nav.js and
9
+ // Ops.js do: the pane holds the state, this holds what the state does. ui/Backend.qml records the
10
+ // order the listing is actually in, because list re-sorts by name ascending and only this file
11
+ // changes it after that.
12
+
13
+ // The orders the backend can actually produce, in the order s steps through them, and the only keys
14
+ // that may move the recorded order. It is not the list of what gets refused: docs/protocol.md "sort"
15
+ // refuses every other key by name, and the backend is the one that says so, see ui/js/Errors.js, aliased from FolderSorts.ORDERS, the one key table.
16
+ var ORDERS = FolderSorts.ORDERS
17
+
18
+ // The three sort decisions, kept apart from what a pane does with them: the chooser makes the same ones over its narrower list.
19
+
20
+ // The sorted column reverses; any other starts ascending, the order the canvas header draws beside "Name".
21
+ function columnOrder(orders, by, desc, key) {
22
+ if (orders.indexOf(key) < 0)
23
+ return null
24
+ return { key: key, desc: by === key ? !desc : false }
25
+ }
26
+
27
+ // Always ascending, column and direction separate; an outside order, a saved kind in the chooser, starts over at the first.
28
+ function nextOrder(orders, by) {
29
+ return { key: orders[(orders.indexOf(by) + 1) % orders.length], desc: false }
30
+ }
31
+
32
+ // Whichever order the listing is in, offered or inherited: the user asked for the reverse of what they have.
33
+ function reverseOrder(by, desc) {
34
+ return { key: by, desc: !desc }
35
+ }
36
+
37
+ // An edit open or a rename pending holds the sort and commits an open edit; it applies once the rename settles.
38
+ function holdForRename(pane, request) {
39
+ if (!(pane.renamingIndex >= 0 || pane.renamePending)) return false
40
+ pane.pendingSort = request
41
+ if (pane.renamingIndex >= 0 && !pane.renamePending) pane.commitOpenRename()
42
+ return true
43
+ }
44
+
45
+ // ui/Header.qml's click: only ORDERS leave this file except the forget row.
46
+ function column(pane, key) {
47
+ // The flyout's last row (issue 179) forgets the folder and lists it on the default.
48
+ // Recent stands on the root, so forgetting re-asks its history instead of listing the root over it.
49
+ if (key === "__default__") {
50
+ // Forgetting re-lists, so it holds like any other sort request.
51
+ if (holdForRename(pane, { forget: true })) return
52
+ if ((pane.recentMode || "").length > 0) {
53
+ RecentMode.run(pane, pane.recentPaths || [], pane.recentVisits, pane.recentMode)
54
+ return
55
+ }
56
+ if (pane.backend && pane.backend.forgetFolderSort)
57
+ pane.backend.forgetFolderSort(pane.path)
58
+ // A preserved pane skips the reset a list would do, so refresh here or it keeps its old order.
59
+ if (pane.backend && pane.backend.resetSort)
60
+ pane.backend.resetSort(pane.path)
61
+ pane.openWithoutHistory(pane.path)
62
+ return
63
+ }
64
+ // Unsupported columns remain labels rather than sending a sort the backend must refuse.
65
+ var order = columnOrder(ORDERS, pane.backend.sortBy, pane.backend.sortDesc, key)
66
+ if (order)
67
+ resort(pane, order.key, order.desc)
68
+ }
69
+
70
+ // s walks ORDERS so it never lands on a refusal-only column; an aimed click earns the reason, a walking key only noise.
71
+ function next(pane) {
72
+ var order = nextOrder(ORDERS, pane.backend.sortBy)
73
+ resort(pane, order.key, order.desc)
74
+ }
75
+
76
+ // S: the capital-is-the-variant pair g/G and j/J use.
77
+ function reverse(pane) {
78
+ var order = reverseOrder(pane.backend.sortBy, pane.backend.sortDesc)
79
+ resort(pane, order.key, order.desc)
80
+ }
81
+
82
+ // The request goes out for every key, so the refusal is the backend's alone. Only an order it will
83
+ // really produce moves the recorded one, or the mark would describe a listing that never changed.
84
+ function resort(pane, key, desc) {
85
+ if (holdForRename(pane, { key: key, desc: desc })) return
86
+ // Asking for the order the listing is already in would drop every row-indexed cache and put the
87
+ // cursor back to redraw the rows already on screen, so it is not asked for at all.
88
+ if (pane.backend.sortBy === key && pane.backend.sortDesc === desc) {
89
+ return
90
+ }
91
+ pane.backend.sort(key, desc)
92
+ if (ORDERS.indexOf(key) < 0) {
93
+ return
94
+ }
95
+ pane.backend.sortBy = key
96
+ pane.backend.sortDesc = desc
97
+ // A walk's rows are matches, not the folder's, so sorting them writes nothing. Recent stands
98
+ // on the root, so its order is never remembered as the root's own.
99
+ if (pane.backend && pane.backend.rememberFolderSort
100
+ && (pane.searchMode || "") === "" && (pane.recentMode || "") === "")
101
+ pane.backend.rememberFolderSort(pane.path, key, desc)
102
+ // A reorder moves every row, so the caches keyed by a row index are as stale as a new listing's,
103
+ // and a selection of row indices would silently come to name different files.
104
+ pane.thumbState = Thumbs.empty()
105
+ pane.dirSizeState = DirSizes.empty()
106
+ pane.clearSelection()
107
+ pane.setCursor(0)
108
+ // sort emits no rows of its own, so the reordered window is asked for here; see docs/protocol.md.
109
+ pane.backend.window(0, pane.windowSize)
110
+ }
111
+
112
+ // The held sort a resort deferred; runs when the edit ends or the listing lands.
113
+ function applyPending(pane) {
114
+ var held = pane.pendingSort
115
+ if (!held) return
116
+ // Not settled yet, or nowhere to send it: the hold stands.
117
+ if (pane.listInFlight || pane.renamingIndex >= 0 || pane.renamePending) return
118
+ if (!pane.backend || pane.backend.quitting || !pane.backend.running) { pane.pendingSort = null; return }
119
+ pane.pendingSort = null
120
+ if (held.forget) { column(pane, "__default__"); return }
121
+ resort(pane, held.key, held.desc)
122
+ }
123
+
124
+ // Each flag is read the way its reader reads it, and state.sort stays as written because Pane.openWithoutHistory compares it with ViewState's own.
125
+ // Sample input: preferences({}) and preferences({hidden: false, foldersFirst: true, groupByKind: false, hiddenLast: false, rememberSort: true}) are the same string.
126
+ function preferences(state) {
127
+ return JSON.stringify([state.hidden === true, state.sort, state.foldersFirst !== false,
128
+ state.groupByKind === true, state.hiddenLast === true, state.rememberSort !== false])
129
+ }
130
+
131
+ // A sorted column's title: the label and the geometric mark of the direction, characters the stock monospace has, so the mark scales with the font like the label.
132
+ function title(label, descending) {
133
+ return label + " " + (descending ? "\u25be" : "\u25b4")
134
+ }
@@ -0,0 +1,63 @@
1
+ .pragma library
2
+
3
+ // Where a window opens, and where a new tab opens. Both were fixed before 0.2.1: a window always
4
+ // opened on $HOME unless the command line named a path, and a new tab always cloned the folder the
5
+ // pane was resting on. Settings > View > Opening now decides, and this is the only place that reads
6
+ // those keys, so the panel, ui/shell.qml and ui/js/Tabs.js can never disagree about the answer.
7
+
8
+ // Sample state, as ui/ViewState.qml holds it:
9
+ // {startIn: "folder", startFolder: "/home/gm/Work", lastPath: "/home/gm/Pictures", newTab: "home"}
10
+ // argvPath is FLEA_PATH, which ui/shell.qml reads off the command line.
11
+ function startPath(state, home, argvPath) {
12
+ // A path the caller named outranks every setting: a file manager asked to open somewhere opens
13
+ // there, and this is the same precedence the --select flag already has over the remembered pair.
14
+ if (argvPath && String(argvPath).length > 0)
15
+ return String(argvPath)
16
+ var data = state || {}
17
+ var mode = data.startIn || "home"
18
+ if (mode === "last")
19
+ return orHome(data.lastPath, home)
20
+ if (mode === "folder")
21
+ return orHome(data.startFolder, home)
22
+ return home
23
+ }
24
+
25
+ // A named folder goes to the focused side while the other keeps its own; launchSide says which took it.
26
+ // Sample dual state, as ui/ViewState.qml holds it: {paths: ["/home/gm", "/home/gm/Work"], focus: 1}.
27
+ function dualPaths(dual, start, argvPath) {
28
+ var saved = (dual || {}).paths || []
29
+ var named = argvPath && String(argvPath).length > 0 ? String(argvPath) : ""
30
+ // With no pair both sides open where one pane would, and a named folder outranks start here too.
31
+ if (saved.length !== 2) {
32
+ var only = named.length > 0 ? named : start
33
+ return { paths: [only, only], launchSide: named.length > 0 ? 0 : -1 }
34
+ }
35
+ if (named.length === 0)
36
+ return { paths: [String(saved[0]), String(saved[1])], launchSide: -1 }
37
+ if ((dual || {}).focus === 1)
38
+ return { paths: [String(saved[0]), named], launchSide: 1 }
39
+ return { paths: [named, String(saved[1])], launchSide: 0 }
40
+ }
41
+
42
+ // here is the folder the pane is resting on, which is what a new tab used to clone unconditionally.
43
+ function newTabPath(state, here, home) {
44
+ var mode = (state || {}).newTab || "current"
45
+ if (mode === "home")
46
+ return home
47
+ if (mode === "start")
48
+ return startPath(state, home, "")
49
+ return here
50
+ }
51
+
52
+ // A chosen folder can be deleted or renamed between two runs, and a remembered one can be a stick
53
+ // that is no longer plugged in. Nothing here can stat a path, so an empty setting falls back to home
54
+ // and a path that no longer exists is left to the listing's own error, which names what is wrong.
55
+ function orHome(path, home) {
56
+ return path && String(path).length > 0 ? String(path) : home
57
+ }
58
+
59
+ // How long a restored folder waits for its first listing before it stops loading.
60
+ var LISTING_WAIT_MS = 10000
61
+
62
+ // How long the favourite inspector waits for its answer before its guard clears anyway.
63
+ var INSPECT_WAIT_MS = 10000
@@ -0,0 +1,17 @@
1
+ .pragma library
2
+
3
+ .import "Format.js" as Format
4
+
5
+ // Permissions refusals keep their short state words; unavailable app rows use error ink alone.
6
+ var WORDS = {
7
+ permissionsLink: "symlink",
8
+ permissionsSpecial: "special file",
9
+ permissionsNotYours: "not yours"
10
+ }
11
+
12
+ // A link names itself; any other kind that is neither a file nor a folder is special, and a mode never read names nothing.
13
+ function permissions(mode) {
14
+ var kind = (Number(mode) || 0) & Format.S_IFMT
15
+ if (kind === 0) return ""
16
+ return kind === Format.S_IFLNK ? WORDS.permissionsLink : WORDS.permissionsSpecial
17
+ }