flea-qml 0.0.0-stage → 0.1.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 (625) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +478 -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 +402 -0
  51. package/src/archiveops.js +697 -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 +129 -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/transfer.js +669 -0
  82. package/src/trash-record.js +41 -0
  83. package/src/trash.js +210 -0
  84. package/src/trashbrowse.js +326 -0
  85. package/src/uistate.js +393 -0
  86. package/src/uistore.js +168 -0
  87. package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
  88. package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
  89. package/src/vendor/LICENSES/MIT-katex.txt +21 -0
  90. package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
  91. package/src/vendor/LICENSES/MIT-pele.txt +40 -0
  92. package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
  93. package/src/vendor/LICENSES/MIT-temml.txt +21 -0
  94. package/src/vendor/pele.js +145 -0
  95. package/src/vendor/temml.mjs +14708 -0
  96. package/src/watch.js +98 -0
  97. package/src/wayland/client.js +109 -0
  98. package/src/wayland/protocol.js +55 -0
  99. package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
  100. package/src/wayland/protocols/wayland.xml +3248 -0
  101. package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
  102. package/src/wayland/resource-io.js +6 -0
  103. package/src/wayland/socket-discovery.js +26 -0
  104. package/src/wayland/transport-posix.js +120 -0
  105. package/src/wayland/transport-win32.js +11 -0
  106. package/src/wayland/transport.js +3 -0
  107. package/src/wayland/win32-resources.js +80 -0
  108. package/src/wayland/win32-wire.js +62 -0
  109. package/test/archive.test.js +80 -0
  110. package/test/bench-markdown-scroll.mjs +190 -0
  111. package/test/clip-host.test.js +113 -0
  112. package/test/code-preview.test.js +35 -0
  113. package/test/compare-ui-paths.test.js +24 -0
  114. package/test/compare.test.js +54 -0
  115. package/test/delete-trash.test.js +67 -0
  116. package/test/dirsize.test.js +138 -0
  117. package/test/file-ops.test.js +241 -0
  118. package/test/find-contents.test.js +161 -0
  119. package/test/find-input.test.js +66 -0
  120. package/test/fixtures/pele-parity.json +1006 -0
  121. package/test/highlight-launcher.test.js +35 -0
  122. package/test/html-preview.test.js +22 -0
  123. package/test/input.test.js +15 -0
  124. package/test/keymap.test.js +26 -0
  125. package/test/language-icons.test.js +36 -0
  126. package/test/launcher.test.js +51 -0
  127. package/test/manual-code-scroll.mjs +28 -0
  128. package/test/manual-column-scroll.mjs +24 -0
  129. package/test/manual-compare-ui.mjs +20 -0
  130. package/test/manual-find-status.mjs +37 -0
  131. package/test/manual-html-security.mjs +23 -0
  132. package/test/manual-html-ui.mjs +30 -0
  133. package/test/manual-syntax-preview.mjs +26 -0
  134. package/test/manual-trash-ui.mjs +86 -0
  135. package/test/markdown-diagrams.test.js +93 -0
  136. package/test/markdown-html.test.js +105 -0
  137. package/test/mathml.test.js +92 -0
  138. package/test/menu-transfer.test.js +57 -0
  139. package/test/office-preview.test.js +154 -0
  140. package/test/pele-parity.test.js +28 -0
  141. package/test/places.test.js +134 -0
  142. package/test/preview-keys.test.js +60 -0
  143. package/test/preview-language.test.js +22 -0
  144. package/test/status-filename.test.js +20 -0
  145. package/test/transfer-replace-merge.test.js +187 -0
  146. package/test/trash-address.test.js +23 -0
  147. package/test/trash-view.test.js +37 -0
  148. package/test/trashbrowse.test.js +135 -0
  149. package/ui/AboutFacts.qml +78 -0
  150. package/ui/ArchiveCards.qml +68 -0
  151. package/ui/ArchiveCompressDialog.qml +378 -0
  152. package/ui/ArchivePasswordDialog.qml +257 -0
  153. package/ui/Backend.qml +771 -0
  154. package/ui/BulkOldNames.qml +47 -0
  155. package/ui/BulkRenameDialog.qml +380 -0
  156. package/ui/CardFrame.qml +67 -0
  157. package/ui/CardScroll.qml +79 -0
  158. package/ui/CheckBox.qml +73 -0
  159. package/ui/ChromeBar.qml +360 -0
  160. package/ui/ChromeButton.qml +131 -0
  161. package/ui/ChromeModes.qml +43 -0
  162. package/ui/CodeLines.qml +256 -0
  163. package/ui/CodeRefusal.qml +52 -0
  164. package/ui/CollideConfirm.qml +147 -0
  165. package/ui/CollideHost.qml +167 -0
  166. package/ui/ColumnPane.qml +523 -0
  167. package/ui/ColumnRow.qml +380 -0
  168. package/ui/ColumnsArea.qml +594 -0
  169. package/ui/ColumnsLanding.qml +147 -0
  170. package/ui/CompareView.qml +321 -0
  171. package/ui/ContextMenu.qml +743 -0
  172. package/ui/ConvertDialog.qml +456 -0
  173. package/ui/CountedWorker.qml +7 -0
  174. package/ui/Crumb.qml +64 -0
  175. package/ui/CrumbDrop.qml +25 -0
  176. package/ui/CsvTable.qml +394 -0
  177. package/ui/CursorMark.qml +41 -0
  178. package/ui/DefaultClaim.qml +130 -0
  179. package/ui/DeviceLock.qml +47 -0
  180. package/ui/DeviceMounts.qml +540 -0
  181. package/ui/DialogButton.qml +150 -0
  182. package/ui/DialogField.qml +147 -0
  183. package/ui/DialogHeader.qml +31 -0
  184. package/ui/DialogScrim.qml +20 -0
  185. package/ui/DialogTitle.qml +37 -0
  186. package/ui/Divider.qml +9 -0
  187. package/ui/DropInto.qml +126 -0
  188. package/ui/DropTarget.qml +35 -0
  189. package/ui/DropboxMark.qml +60 -0
  190. package/ui/EmptyState.qml +150 -0
  191. package/ui/EscapeHint.qml +11 -0
  192. package/ui/FactsTable.qml +54 -0
  193. package/ui/FastScrollHandler.qml +476 -0
  194. package/ui/FatNamesConfirm.qml +157 -0
  195. package/ui/Favourites.qml +143 -0
  196. package/ui/FigureService.qml +120 -0
  197. package/ui/FileDrag.qml +267 -0
  198. package/ui/FilterStrip.qml +133 -0
  199. package/ui/FitMetrics.qml +22 -0
  200. package/ui/FlashDriveRows.qml +137 -0
  201. package/ui/FlashHost.qml +72 -0
  202. package/ui/FlashImageRow.qml +104 -0
  203. package/ui/FlashRunner.qml +119 -0
  204. package/ui/FlashStepRow.qml +172 -0
  205. package/ui/FlashStrip.qml +38 -0
  206. package/ui/FlashView.qml +397 -0
  207. package/ui/FleaMark.qml +88 -0
  208. package/ui/FlyoutFade.qml +23 -0
  209. package/ui/FontPane.qml +170 -0
  210. package/ui/Glass.qml +114 -0
  211. package/ui/GlassTagger.qml +59 -0
  212. package/ui/Glyph.qml +64 -0
  213. package/ui/GlyphSolid.qml +22 -0
  214. package/ui/GridArea.qml +664 -0
  215. package/ui/GridTile.qml +325 -0
  216. package/ui/GvfsBridge.qml +164 -0
  217. package/ui/Header.qml +433 -0
  218. package/ui/HoverTimers.qml +39 -0
  219. package/ui/HtmlClip.qml +30 -0
  220. package/ui/HtmlPane.qml +63 -0
  221. package/ui/HyprlandMark.qml +45 -0
  222. package/ui/Ipc.qml +1005 -0
  223. package/ui/IpcControls.qml +7 -0
  224. package/ui/IpcMenuState.qml +48 -0
  225. package/ui/IpcPreviewState.qml +185 -0
  226. package/ui/JumpPath.qml +51 -0
  227. package/ui/KeymapSheet.qml +561 -0
  228. package/ui/KeymapSheetResult.qml +89 -0
  229. package/ui/KindStack.qml +40 -0
  230. package/ui/LangMark.qml +51 -0
  231. package/ui/LangMarkLoader.qml +26 -0
  232. package/ui/List.qml +480 -0
  233. package/ui/LoadingState.qml +54 -0
  234. package/ui/LocalSend.qml +56 -0
  235. package/ui/LocalSendMark.qml +73 -0
  236. package/ui/MarkdownBlockView.qml +311 -0
  237. package/ui/MarkdownBlocks.qml +35 -0
  238. package/ui/MarkdownFigure.qml +254 -0
  239. package/ui/MarkdownImages.qml +72 -0
  240. package/ui/MarkdownList.qml +81 -0
  241. package/ui/MarkdownMathsText.qml +97 -0
  242. package/ui/MarkdownPane.qml +83 -0
  243. package/ui/MarkdownPictures.qml +41 -0
  244. package/ui/MarkdownQuote.qml +52 -0
  245. package/ui/MarkdownRemote.qml +82 -0
  246. package/ui/MarkdownSource.qml +155 -0
  247. package/ui/MarkdownTable.qml +222 -0
  248. package/ui/MarkdownTableScroll.qml +64 -0
  249. package/ui/MarkdownTableWheel.qml +126 -0
  250. package/ui/MarkdownText.qml +87 -0
  251. package/ui/MarkdownWorker.js +132 -0
  252. package/ui/MatchText.qml +99 -0
  253. package/ui/MediaSession.qml +38 -0
  254. package/ui/MediaSound.qml +26 -0
  255. package/ui/MediaStrip.qml +191 -0
  256. package/ui/MediaTrack.qml +36 -0
  257. package/ui/MediaVolume.qml +54 -0
  258. package/ui/MenuActionDialog.qml +396 -0
  259. package/ui/MenuEdgeFade.qml +24 -0
  260. package/ui/MenuHost.qml +227 -0
  261. package/ui/MenuRow.qml +351 -0
  262. package/ui/MountListing.qml +100 -0
  263. package/ui/NetworkDialog.qml +435 -0
  264. package/ui/NetworkForm.qml +426 -0
  265. package/ui/NetworkMounts.qml +913 -0
  266. package/ui/NetworkPlaces.qml +127 -0
  267. package/ui/OpenWithDialog.qml +613 -0
  268. package/ui/Opener.qml +115 -0
  269. package/ui/Pane.qml +1296 -0
  270. package/ui/PaneMenuActions.qml +527 -0
  271. package/ui/PanePath.qml +90 -0
  272. package/ui/PaneRail.qml +239 -0
  273. package/ui/PaneStates.qml +88 -0
  274. package/ui/PaneSwap.qml +339 -0
  275. package/ui/PaneWire.qml +605 -0
  276. package/ui/ParkedWait.qml +9 -0
  277. package/ui/PathEntry.qml +186 -0
  278. package/ui/PathJump.qml +400 -0
  279. package/ui/PdfViewer.qml +297 -0
  280. package/ui/PermissionsDialog.qml +658 -0
  281. package/ui/PermissionsHeadings.qml +31 -0
  282. package/ui/PhoneMounts.qml +67 -0
  283. package/ui/PickerAnswers.qml +75 -0
  284. package/ui/PickerBox.qml +26 -0
  285. package/ui/PickerChrome.qml +295 -0
  286. package/ui/PickerFilter.qml +97 -0
  287. package/ui/PickerGrid.qml +308 -0
  288. package/ui/PickerHeader.qml +28 -0
  289. package/ui/PickerLifecycle.qml +27 -0
  290. package/ui/PickerList.qml +218 -0
  291. package/ui/PickerListing.qml +149 -0
  292. package/ui/PickerPathBar.qml +127 -0
  293. package/ui/PickerPlaces.qml +189 -0
  294. package/ui/PickerRecent.qml +92 -0
  295. package/ui/PickerSave.qml +101 -0
  296. package/ui/PickerSelection.qml +155 -0
  297. package/ui/PickerWindow.qml +846 -0
  298. package/ui/PowerSectorsReader.qml +10 -0
  299. package/ui/PrebuildDriver.qml +146 -0
  300. package/ui/Preview.qml +1004 -0
  301. package/ui/PreviewAnimation.qml +24 -0
  302. package/ui/PreviewArchive.qml +66 -0
  303. package/ui/PreviewColumn.qml +551 -0
  304. package/ui/PreviewEdge.qml +63 -0
  305. package/ui/PreviewFacts.qml +30 -0
  306. package/ui/PreviewFactsLine.qml +34 -0
  307. package/ui/PreviewHtml.qml +233 -0
  308. package/ui/PreviewImage.qml +253 -0
  309. package/ui/PreviewImagePan.qml +13 -0
  310. package/ui/PreviewImageSharp.qml +32 -0
  311. package/ui/PreviewLines.qml +106 -0
  312. package/ui/PreviewMarkdown.qml +706 -0
  313. package/ui/PreviewMedia.qml +250 -0
  314. package/ui/PreviewPdf.qml +482 -0
  315. package/ui/PreviewScroll.qml +201 -0
  316. package/ui/PreviewSwap.qml +335 -0
  317. package/ui/PreviewText.qml +149 -0
  318. package/ui/ProtocolChip.qml +18 -0
  319. package/ui/QuickLookArchive.qml +38 -0
  320. package/ui/QuickLookBar.qml +103 -0
  321. package/ui/QuickLookPrepare.qml +355 -0
  322. package/ui/QuickLookSwap.qml +10 -0
  323. package/ui/QuickLookWarm.qml +65 -0
  324. package/ui/RailDrop.qml +155 -0
  325. package/ui/RailHeading.qml +19 -0
  326. package/ui/RailPlaces.qml +38 -0
  327. package/ui/RailTrashRow.qml +67 -0
  328. package/ui/RenameField.qml +353 -0
  329. package/ui/RendererRetry.qml +11 -0
  330. package/ui/ResizeHandle.qml +52 -0
  331. package/ui/Reveal.qml +54 -0
  332. package/ui/Row.qml +476 -0
  333. package/ui/RowDrag.qml +213 -0
  334. package/ui/RowDropTarget.qml +27 -0
  335. package/ui/RunCard.qml +286 -0
  336. package/ui/Scripts.qml +65 -0
  337. package/ui/SearchStrip.qml +232 -0
  338. package/ui/SelectionBand.qml +140 -0
  339. package/ui/SelectionPreview.qml +370 -0
  340. package/ui/SettingsFavourite.qml +122 -0
  341. package/ui/SettingsGroup.qml +96 -0
  342. package/ui/SettingsHint.qml +12 -0
  343. package/ui/SettingsMetrics.qml +29 -0
  344. package/ui/SettingsPane.qml +178 -0
  345. package/ui/SettingsPanel.qml +547 -0
  346. package/ui/SettingsRail.qml +128 -0
  347. package/ui/SettingsRow.qml +409 -0
  348. package/ui/SettingsRuler.qml +85 -0
  349. package/ui/SettingsSegment.qml +85 -0
  350. package/ui/ShareBrowser.qml +113 -0
  351. package/ui/ShareLink.qml +67 -0
  352. package/ui/ShelfPins.qml +101 -0
  353. package/ui/Sidebar.qml +732 -0
  354. package/ui/SidebarRow.qml +358 -0
  355. package/ui/Spinner.qml +60 -0
  356. package/ui/StableModel.qml +89 -0
  357. package/ui/StateMessage.qml +84 -0
  358. package/ui/StatusBar.qml +512 -0
  359. package/ui/StatusFileName.qml +27 -0
  360. package/ui/TabBar.qml +673 -0
  361. package/ui/TabDragGeometry.qml +60 -0
  362. package/ui/TagMenuMark.qml +52 -0
  363. package/ui/TagRailSection.qml +53 -0
  364. package/ui/TagSlot.qml +40 -0
  365. package/ui/TagState.qml +150 -0
  366. package/ui/TagSwatch.qml +28 -0
  367. package/ui/Taildrop.qml +86 -0
  368. package/ui/TailscaleMark.qml +50 -0
  369. package/ui/Theme.qml +460 -0
  370. package/ui/ThemeColors.qml +43 -0
  371. package/ui/TransferCard.qml +239 -0
  372. package/ui/TrashConfirm.qml +129 -0
  373. package/ui/TrashDropHandler.qml +11 -0
  374. package/ui/TrashHost.qml +202 -0
  375. package/ui/TrashMonitor.qml +30 -0
  376. package/ui/TrashToolbar.qml +19 -0
  377. package/ui/TrashView.qml +492 -0
  378. package/ui/UnlockDialog.qml +450 -0
  379. package/ui/UnlockHost.qml +206 -0
  380. package/ui/UpdateCheck.qml +97 -0
  381. package/ui/UserDirs.qml +25 -0
  382. package/ui/ViewState.qml +565 -0
  383. package/ui/ViewportScrollBar.qml +195 -0
  384. package/ui/ViewportScrollBars.qml +25 -0
  385. package/ui/WebPreview.qml +33 -0
  386. package/ui/WebPreviewView.qml +26 -0
  387. package/ui/WindowBody.qml +827 -0
  388. package/ui/WindowDrag.qml +35 -0
  389. package/ui/boot/Commons/AudioNodes.qml +50 -0
  390. package/ui/boot/Commons/AudioNodesModel.js +96 -0
  391. package/ui/boot/Commons/Border.qml +243 -0
  392. package/ui/boot/Commons/BorderGeometry.js +373 -0
  393. package/ui/boot/Commons/Color.qml +258 -0
  394. package/ui/boot/Commons/I18n.qml +118 -0
  395. package/ui/boot/Commons/InputDevices.qml +112 -0
  396. package/ui/boot/Commons/InputMethodState.qml +38 -0
  397. package/ui/boot/Commons/IpcRegistry.qml +77 -0
  398. package/ui/boot/Commons/Numbers.js +19 -0
  399. package/ui/boot/Commons/Plural.js +91 -0
  400. package/ui/boot/Commons/ShellIpc.qml +12 -0
  401. package/ui/boot/Commons/Style.qml +561 -0
  402. package/ui/boot/Commons/Translations.qml +100 -0
  403. package/ui/boot/Commons/UntypedInput.qml +152 -0
  404. package/ui/boot/Commons/Util.qml +188 -0
  405. package/ui/boot/Commons/qmldir +13 -0
  406. package/ui/boot/LICENSE-omarchy +20 -0
  407. package/ui/boot/Ui/BackgroundMedia.qml +49 -0
  408. package/ui/boot/Ui/BarIconButton.qml +106 -0
  409. package/ui/boot/Ui/BarIconContent.qml +38 -0
  410. package/ui/boot/Ui/BarIndicator.qml +53 -0
  411. package/ui/boot/Ui/BarWidget.qml +50 -0
  412. package/ui/boot/Ui/BorderOverlay.qml +54 -0
  413. package/ui/boot/Ui/BorderSurface.qml +40 -0
  414. package/ui/boot/Ui/Button.qml +224 -0
  415. package/ui/boot/Ui/ButtonGroup.qml +131 -0
  416. package/ui/boot/Ui/ConfirmDialog.qml +134 -0
  417. package/ui/boot/Ui/CursorSurface.qml +42 -0
  418. package/ui/boot/Ui/Dropdown.qml +245 -0
  419. package/ui/boot/Ui/FilterInput.qml +26 -0
  420. package/ui/boot/Ui/IconContentBounds.qml +141 -0
  421. package/ui/boot/Ui/KeyboardPanel.qml +453 -0
  422. package/ui/boot/Ui/MultiSelect.qml +624 -0
  423. package/ui/boot/Ui/NumberField.qml +86 -0
  424. package/ui/boot/Ui/OpticalGlyph.qml +68 -0
  425. package/ui/boot/Ui/OverlayWindow.qml +102 -0
  426. package/ui/boot/Ui/Panel.qml +60 -0
  427. package/ui/boot/Ui/PanelActionButton.qml +105 -0
  428. package/ui/boot/Ui/PanelController.qml +16 -0
  429. package/ui/boot/Ui/PanelHero.qml +112 -0
  430. package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
  431. package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
  432. package/ui/boot/Ui/PanelSeparator.qml +19 -0
  433. package/ui/boot/Ui/PanelSlider.qml +156 -0
  434. package/ui/boot/Ui/PanelToolTip.qml +50 -0
  435. package/ui/boot/Ui/PluginBarApi.qml +89 -0
  436. package/ui/boot/Ui/PointerMoveGate.qml +54 -0
  437. package/ui/boot/Ui/PopupCard.qml +181 -0
  438. package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
  439. package/ui/boot/Ui/SearchableDropdown.qml +354 -0
  440. package/ui/boot/Ui/SizedImage.qml +125 -0
  441. package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
  442. package/ui/boot/Ui/TextField.qml +58 -0
  443. package/ui/boot/Ui/Toggle.qml +118 -0
  444. package/ui/boot/Ui/ToggleSwitch.qml +115 -0
  445. package/ui/boot/Ui/WidgetButton.qml +172 -0
  446. package/ui/boot/Ui/qmldir +41 -0
  447. package/ui/boot/fleatab.qml +50 -0
  448. package/ui/boot/picker.qml +39 -0
  449. package/ui/boot/shell.qml +122 -0
  450. package/ui/boot/tabtearoff.qml +51 -0
  451. package/ui/js/Anchor.js +379 -0
  452. package/ui/js/AnchorHold.js +162 -0
  453. package/ui/js/Archive.js +157 -0
  454. package/ui/js/ArchiveCard.js +44 -0
  455. package/ui/js/ArchiveOps.js +44 -0
  456. package/ui/js/BackReturn.js +118 -0
  457. package/ui/js/BulkRename.js +100 -0
  458. package/ui/js/Buttons.js +54 -0
  459. package/ui/js/ChromeKeys.js +116 -0
  460. package/ui/js/ClipMarks.js +73 -0
  461. package/ui/js/ClipSelection.js +67 -0
  462. package/ui/js/Clipboard.js +179 -0
  463. package/ui/js/Cloud.js +97 -0
  464. package/ui/js/CodeRuns.js +72 -0
  465. package/ui/js/Collide.js +212 -0
  466. package/ui/js/ColumnFit.js +28 -0
  467. package/ui/js/ColumnMenu.js +111 -0
  468. package/ui/js/Columns.js +298 -0
  469. package/ui/js/ColumnsCarry.js +103 -0
  470. package/ui/js/Compare.js +74 -0
  471. package/ui/js/Contrast.js +157 -0
  472. package/ui/js/ControlReader.js +42 -0
  473. package/ui/js/Convert.js +52 -0
  474. package/ui/js/CopyAs.js +52 -0
  475. package/ui/js/Crumbs.js +178 -0
  476. package/ui/js/Csv.js +231 -0
  477. package/ui/js/Density.js +44 -0
  478. package/ui/js/Devices.js +440 -0
  479. package/ui/js/DirSizes.js +180 -0
  480. package/ui/js/Drag.js +364 -0
  481. package/ui/js/DragOut.js +166 -0
  482. package/ui/js/DropDev.js +52 -0
  483. package/ui/js/Dropbox.js +41 -0
  484. package/ui/js/Eject.js +217 -0
  485. package/ui/js/Errors.js +188 -0
  486. package/ui/js/ExtThumbs.js +115 -0
  487. package/ui/js/Facts.js +402 -0
  488. package/ui/js/FigureDate.js +14 -0
  489. package/ui/js/Filter.js +285 -0
  490. package/ui/js/Find.js +46 -0
  491. package/ui/js/Flash.js +184 -0
  492. package/ui/js/FlashCard.js +79 -0
  493. package/ui/js/FlashEndings.js +125 -0
  494. package/ui/js/FlashPane.js +116 -0
  495. package/ui/js/FleaBin.js +12 -0
  496. package/ui/js/Focus.js +502 -0
  497. package/ui/js/FolderSorts.js +108 -0
  498. package/ui/js/FolderViews.js +44 -0
  499. package/ui/js/Format.js +305 -0
  500. package/ui/js/Fuzzy.js +141 -0
  501. package/ui/js/GlassTag.js +72 -0
  502. package/ui/js/Grid.js +33 -0
  503. package/ui/js/GridGeometry.js +90 -0
  504. package/ui/js/GridNames.js +153 -0
  505. package/ui/js/GvfsBridge.js +200 -0
  506. package/ui/js/HostClipboard.js +29 -0
  507. package/ui/js/Icons.js +218 -0
  508. package/ui/js/Input.js +50 -0
  509. package/ui/js/Jump.js +200 -0
  510. package/ui/js/KeyName.js +64 -0
  511. package/ui/js/Keymap.js +401 -0
  512. package/ui/js/Kinds.js +164 -0
  513. package/ui/js/LICENSES/ISC-lucide.txt +43 -0
  514. package/ui/js/LangMarkPaths.js +47 -0
  515. package/ui/js/LangMarks.js +120 -0
  516. package/ui/js/Lists.js +11 -0
  517. package/ui/js/LocalSend.js +39 -0
  518. package/ui/js/LockedMenu.js +63 -0
  519. package/ui/js/MakeDefault.js +186 -0
  520. package/ui/js/MarkBox.js +7 -0
  521. package/ui/js/Markdown.js +119 -0
  522. package/ui/js/MarkdownLists.js +86 -0
  523. package/ui/js/MarkdownMaths.js +58 -0
  524. package/ui/js/MarkdownPictures.js +32 -0
  525. package/ui/js/MarkdownPrepared.js +139 -0
  526. package/ui/js/MarkdownTableFit.js +34 -0
  527. package/ui/js/Marks.js +148 -0
  528. package/ui/js/Marquee.js +96 -0
  529. package/ui/js/Match.js +93 -0
  530. package/ui/js/Material.js +109 -0
  531. package/ui/js/MdBlocks.js +437 -0
  532. package/ui/js/MdBreak.js +71 -0
  533. package/ui/js/MdChunks.js +70 -0
  534. package/ui/js/MdContainer.js +137 -0
  535. package/ui/js/MdDocument.js +337 -0
  536. package/ui/js/MdEmph.js +97 -0
  537. package/ui/js/MdEntity.js +108 -0
  538. package/ui/js/MdEntityTable.js +223 -0
  539. package/ui/js/MdEscape.js +59 -0
  540. package/ui/js/MdFront.js +37 -0
  541. package/ui/js/MdHold.js +32 -0
  542. package/ui/js/MdHtml.js +307 -0
  543. package/ui/js/MdHtmlBlock.js +290 -0
  544. package/ui/js/MdHtmlHeading.js +53 -0
  545. package/ui/js/MdHtmlImage.js +179 -0
  546. package/ui/js/MdInline.js +154 -0
  547. package/ui/js/MdItems.js +212 -0
  548. package/ui/js/MdLeaf.js +309 -0
  549. package/ui/js/MdLink.js +196 -0
  550. package/ui/js/MdMath.js +67 -0
  551. package/ui/js/MdParagraphs.js +138 -0
  552. package/ui/js/MdRefs.js +232 -0
  553. package/ui/js/MdResolve.js +226 -0
  554. package/ui/js/MdRun.js +300 -0
  555. package/ui/js/MdUrl.js +226 -0
  556. package/ui/js/Menu.js +514 -0
  557. package/ui/js/MenuContext.js +85 -0
  558. package/ui/js/MenuFit.js +13 -0
  559. package/ui/js/MenuRefresh.js +74 -0
  560. package/ui/js/MenuWheel.js +35 -0
  561. package/ui/js/Messages.js +186 -0
  562. package/ui/js/Motion.js +16 -0
  563. package/ui/js/Mounts.js +320 -0
  564. package/ui/js/MouseNav.js +13 -0
  565. package/ui/js/Nav.js +329 -0
  566. package/ui/js/NetFs.js +26 -0
  567. package/ui/js/OpenWith.js +83 -0
  568. package/ui/js/Ops.js +585 -0
  569. package/ui/js/Palette.js +33 -0
  570. package/ui/js/PathBar.js +260 -0
  571. package/ui/js/Permissions.js +179 -0
  572. package/ui/js/Phones.js +112 -0
  573. package/ui/js/Picker.js +353 -0
  574. package/ui/js/PlaceMenu.js +96 -0
  575. package/ui/js/Places.js +265 -0
  576. package/ui/js/PreviewAsk.js +21 -0
  577. package/ui/js/PreviewKeys.js +155 -0
  578. package/ui/js/PreviewSettle.js +29 -0
  579. package/ui/js/PreviewSwap.js +101 -0
  580. package/ui/js/PropertyFacts.js +144 -0
  581. package/ui/js/Protocols.js +296 -0
  582. package/ui/js/QuickLookKinds.js +27 -0
  583. package/ui/js/QuickLookRect.js +24 -0
  584. package/ui/js/RailDrop.js +51 -0
  585. package/ui/js/RailKeys.js +87 -0
  586. package/ui/js/RailMenu.js +133 -0
  587. package/ui/js/Recent.js +135 -0
  588. package/ui/js/RecentMode.js +156 -0
  589. package/ui/js/Reload.js +60 -0
  590. package/ui/js/Renderer.js +9 -0
  591. package/ui/js/RunFile.js +143 -0
  592. package/ui/js/Scripts.js +28 -0
  593. package/ui/js/Scroll.js +304 -0
  594. package/ui/js/ScrollOff.js +69 -0
  595. package/ui/js/Search.js +478 -0
  596. package/ui/js/Selection.js +97 -0
  597. package/ui/js/Settings.js +476 -0
  598. package/ui/js/SettingsAbout.js +97 -0
  599. package/ui/js/SettingsShelf.js +52 -0
  600. package/ui/js/SheetKeys.js +42 -0
  601. package/ui/js/SheetQuery.js +281 -0
  602. package/ui/js/ShelfPile.js +27 -0
  603. package/ui/js/SlowClick.js +53 -0
  604. package/ui/js/SlowOp.js +6 -0
  605. package/ui/js/Sort.js +134 -0
  606. package/ui/js/Startup.js +63 -0
  607. package/ui/js/StateWords.js +17 -0
  608. package/ui/js/Status.js +238 -0
  609. package/ui/js/Swap.js +166 -0
  610. package/ui/js/TabMove.js +39 -0
  611. package/ui/js/Tabs.js +736 -0
  612. package/ui/js/Tags.js +134 -0
  613. package/ui/js/Taildrop.js +128 -0
  614. package/ui/js/Tap.js +174 -0
  615. package/ui/js/TextSize.js +107 -0
  616. package/ui/js/Thumbs.js +158 -0
  617. package/ui/js/Transfer.js +172 -0
  618. package/ui/js/Trash.js +81 -0
  619. package/ui/js/TrashDates.js +47 -0
  620. package/ui/js/TrashDrop.js +64 -0
  621. package/ui/js/UiState.js +438 -0
  622. package/ui/js/Unlock.js +152 -0
  623. package/ui/js/Update.js +130 -0
  624. package/ui/js/UserDirs.js +56 -0
  625. package/ui/qmldir +228 -0
@@ -0,0 +1,87 @@
1
+ import QtQuick
2
+
3
+ // The padding sets the baseline as CSS does: on every wrapped line of rich text, on the first line of plain text.
4
+ Text {
5
+ id: root
6
+
7
+ // md_rendered: line-height 1.7 over the text's own pixel size.
8
+ readonly property real boxRatio: 1.7
9
+ readonly property bool rich: root.textFormat !== Text.PlainText
10
+ readonly property real box: Math.round(root.font.pixelSize * root.boxRatio)
11
+ // QTextLine rounds the font's height up, so the first line is ceil(height) tall.
12
+ readonly property real lead: Math.max(0, root.box - Math.ceil(metrics.height))
13
+ // Qt's FixedHeight line puts its baseline this share down the box whatever the font, so the padding moves it to the centred one.
14
+ readonly property real fixedBaselineShare: 0.8
15
+ readonly property int centredBaseline: Math.round((root.box - metrics.height) / 2 + metrics.ascent)
16
+ // The hosts set the Markdown here; a text with a picture draws it with the pictures wider than the text scaled to its width.
17
+ property string markdown: ""
18
+ // A text whose picture is taller than the box draws on proportional lines, which grow with it; the ratio keeps every other line at the box.
19
+ // Sample input: "Built with ![logo](file:///d/p.png) here" holds one picture; the parser writes every local inline picture this way.
20
+ property bool growsForPictures: true
21
+ readonly property bool holdsPicture: root.growsForPictures && root.rich && /!\[[^\]]*\]\(file:/i.test(root.markdown)
22
+ // Built the first time a text holds a picture: a text without one owns no object for it, which the block cost gates count.
23
+ property Item pictures: null
24
+ function syncPictures() {
25
+ if (root.pictures === null && root.holdsPicture)
26
+ root.pictures = Qt.createComponent("MarkdownPictures.qml").createObject(root, { host: root })
27
+ }
28
+ onHoldsPictureChanged: root.syncPictures()
29
+ Component.onCompleted: root.syncPictures()
30
+ readonly property bool grown: root.pictures !== null && root.holdsPicture && root.pictures.tallest > root.box
31
+ readonly property real naturalLine: Math.ceil(metrics.height)
32
+ // Proportional lines keep the font's own ascent above the baseline and put the stretch below it.
33
+ readonly property int naturalBaseline: Math.round(metrics.ascent)
34
+ readonly property int restBaseline: root.grown ? root.naturalBaseline : Math.round(root.box * root.fixedBaselineShare)
35
+ // The tallest picture's line rests on its bottom edge at the baseline, so it is the picture plus the font's own descent.
36
+ readonly property real pictureLine: root.grown ? root.pictures.tallest + root.naturalLine - root.naturalBaseline : 0
37
+ // A one-line text takes back the stretch the ratio put under its picture; a second line would be half a box taller at least.
38
+ readonly property real stretch: root.grown && root.contentHeight < root.pictureLine * root.box / root.naturalLine + root.box / 2 ? root.contentHeight - root.pictureLine : 0
39
+ // Rich text shifts by the gap between the two baselines (negative when Qt sits it low); plain text sits at the top of its natural line.
40
+ readonly property int lift: root.rich ? root.centredBaseline - root.restBaseline : Math.floor(root.lead / 2)
41
+ // The first line's drawn baseline: Qt reports a FixedHeight line's baselineOffset at the ascent, short of where it draws.
42
+ readonly property real drawnBaseline: root.rich && !root.grown ? root.topPadding + root.restBaseline : root.baselineOffset
43
+ // The document's body size; the preview column scales it down from Quick Look's.
44
+ property int bodyPx: Theme.font.body
45
+ // Rows of a table add their own cell padding on top of the box.
46
+ property int cellPad: 0
47
+
48
+ // The parser pads a code chip with a no-break space in a span carrying this mark (MdEscape.CHIP_PAD_MARK), as Qt reads no em there.
49
+ readonly property string chipPadMark: '<span style="font-size:chippad">'
50
+ // The board pads a chip 4 px a side at body 14; the span's px is that over the face's space advance, so the pad's advance is those 4 px.
51
+ readonly property real chipPadBoardPx: 4
52
+ readonly property real boardBodyPx: 14
53
+ // advanceWidth is a call no binding tracks, so reading the metrics' font size and family measures the space again once the font settles.
54
+ readonly property int chipPadPx: {
55
+ metrics.font.pixelSize
56
+ metrics.font.family
57
+ return Math.max(1, Math.round(root.chipPadBoardPx * root.bodyPx / root.boardBodyPx * root.bodyPx / Math.max(1, metrics.advanceWidth(" "))))
58
+ }
59
+ function padSized(source) {
60
+ return source.indexOf(root.chipPadMark) < 0 ? source : source.split(root.chipPadMark).join('<span style="font-size:' + root.chipPadPx + 'px">')
61
+ }
62
+
63
+ // The host supplies the scheme gate (Markdown.isExternalLink), as no import of the parser fits the standalone probe copy.
64
+ property var linkGate: null
65
+ // One handler for every Markdown text: a link the gate passes opens in the default application, all else opens nothing.
66
+ onLinkActivated: function (link) {
67
+ if (root.linkGate !== null && root.linkGate(link))
68
+ Qt.openUrlExternally(link)
69
+ }
70
+
71
+ text: root.padSized(root.pictures !== null ? root.pictures.shown : root.markdown)
72
+ textFormat: Text.MarkdownText
73
+ wrapMode: Text.Wrap
74
+ color: Theme.color.foreground
75
+ linkColor: Theme.color.foreground
76
+ font.family: Theme.font.family
77
+ font.pixelSize: root.bodyPx
78
+ lineHeight: root.grown ? root.box / root.naturalLine : root.rich ? root.box : 1
79
+ lineHeightMode: root.rich && !root.grown ? Text.FixedHeight : Text.ProportionalHeight
80
+ topPadding: root.cellPad + root.lift
81
+ bottomPadding: root.cellPad + root.lead - root.lift - root.stretch
82
+
83
+ FontMetrics {
84
+ id: metrics
85
+ font: root.font
86
+ }
87
+ }
@@ -0,0 +1,132 @@
1
+ // MarkdownWorker.js: PreviewMarkdown's parser thread; WorkerScript binds no `.import` aliases, so Qt.include shares one scope with unique names.
2
+ Qt.include("js/Format.js");
3
+ Qt.include("js/MdUrl.js");
4
+ Qt.include("js/MdHtml.js");
5
+ Qt.include("js/MdHtmlImage.js");
6
+ Qt.include("js/MdHtmlBlock.js");
7
+ Qt.include("js/MdHtmlHeading.js");
8
+ Qt.include("js/MdEscape.js");
9
+ Qt.include("js/MdInline.js");
10
+ Qt.include("js/MdLink.js");
11
+ Qt.include("js/MdContainer.js");
12
+ Qt.include("js/MdRefs.js");
13
+ Qt.include("js/MdEntityTable.js");
14
+ Qt.include("js/MdEntity.js");
15
+ Qt.include("js/MdResolve.js");
16
+ Qt.include("js/MdEmph.js");
17
+ Qt.include("js/MdBreak.js");
18
+ Qt.include("js/MdHold.js");
19
+ Qt.include("js/MdRun.js");
20
+ Qt.include("js/MdParagraphs.js");
21
+ Qt.include("js/MdLeaf.js");
22
+ Qt.include("js/MdItems.js");
23
+ Qt.include("js/MarkdownLists.js");
24
+ Qt.include("js/MdChunks.js");
25
+ Qt.include("js/MdDocument.js");
26
+ Qt.include("js/MdMath.js");
27
+ Qt.include("js/MdFront.js");
28
+ Qt.include("js/MdBlocks.js");
29
+
30
+ var Format = { fileUri: fileUri };
31
+ var MdUrl = { canonicalUrl: canonicalUrl, classifyImage: classifyImage, placeholder: placeholder, srcsetPick: srcsetPick, strippedTarget: strippedTarget, targetAllowed: targetAllowed };
32
+ var MdHtml = { closeToken: closeToken, openToken: openToken, documentText: documentText, normalizedTarget: normalizedTarget, readTag: readTag, sanitizeTag: sanitizeTag, tagHead: tagHead, MAX_TAG_LENGTH: MAX_TAG_LENGTH };
33
+ var MdHtmlImage = { imageUnit: imageUnit, rawImage: rawImage, isCentred: isCentred, linkOf: linkOf, wrapperTail: wrapperTail, LEADING_BREAK: LEADING_BREAK, WRAPPER_OPEN: WRAPPER_OPEN };
34
+ var MdHtmlBlock = { splitHtmlImages: splitHtmlImages, separateBlocks: separateBlocks, htmlHeading: htmlHeading, NESTING_TAG: NESTING_TAG };
35
+ var MdHtmlHeading = { DRAWN_PICTURE: DRAWN_PICTURE, headingUnit: headingUnit, headingPicture: headingPicture, nestDepth: nestDepth };
36
+ var MdEscape = { chipPad: chipPad, escapeText: escapeText, isAsciiPunct: isAsciiPunct };
37
+ var MdInline = { INTERVAL_STRIDE: INTERVAL_STRIDE, MATH_SPAN: MATH_SPAN, isSpace: isSpace, codeHtml: codeHtml, escapeDecodedText: escapeDecodedText, escapeHtmlText: escapeHtmlText, isPunct: isPunct, linkHtml: linkHtml, linkInk: linkInk, spanIntervals: spanIntervals };
38
+ var MdLink = { angleClose: angleClose, normalizeLabel: normalizeLabel, readAutolink: readAutolink, readBarelink: readBarelink, readInlineTarget: readInlineTarget, readLabelRef: readLabelRef };
39
+ var MdRefs = { readDefinition: readDefinition, hideTitle: hideTitle, storeDefinition: storeDefinition, readDefinitionParts: readDefinitionParts, readFootnoteDefinition: readFootnoteDefinition, killDefinition: killDefinition, readFootnoteRef: readFootnoteRef, skipDropContent: skipDropContent, definitionAt: definitionAt, hideDefinition: hideDefinition };
40
+ var MdEntityTable = { namedValue: namedValue };
41
+ var MdEntity = { lineBlank: lineBlank, lineRestart: lineRestart, lineState: lineState, spaceRunAt: spaceRunAt, decodeReferences: decodeReferences, referenceAt: referenceAt };
42
+ var MdEmph = { literal: literal, process: process, runAt: runAt };
43
+ var MdBreak = { isRuleLine: isRuleLine, lineBreak: lineBreak, quoteMarkAt: quoteMarkAt };
44
+ var MdResolve = { bareAt: bareAt, parseAngle: parseAngle, plainText: plainText, readDestination: readDestination, resolvePair: resolvePair, styledSpan: styledSpan };
45
+ var MdHold = { hold: hold };
46
+ var MdRun = { parseInline: parseInline };
47
+ var MdParagraphs = { cutAfter: cutAfter };
48
+ var MdLeaf = { alertTitle: alertTitle, atxHeading: atxHeading, chunkTable: chunkTable, LIST_CHUNK_ITEMS: LIST_CHUNK_ITEMS, headingSafe: headingSafe, delimAligns: delimAligns, fenceOpen: fenceOpen, isThematic: isThematic, isSetext: isSetext, setextLevel: setextLevel, splitRow: splitRow, standaloneImage: standaloneImage, tableBlock: tableBlock, taskText: taskText, pinTaskBox: pinTaskBox };
49
+ var MdContainer = { readListMarker: readListMarker, indentationAt: indentationAt, takeIndent: takeIndent, quoteAt: quoteAt, takeQuote: takeQuote, listAt: listAt, takeList: takeList, startsBlock: startsBlock, textAt: textAt, unindent: unindent, expandLead: expandLead };
50
+ var MdItems = { builder: builder, isRaw: isRaw, listBlock: listBlock, quoteBlocks: quoteBlocks, visibleLines: visibleLines };
51
+ var MarkdownLists = { ORDERED_START: ORDERED_START, runStep: runStep };
52
+ var MdChunks = { chunkList: chunkList };
53
+ var MdMath = { displayAt: displayAt, inlineSources: inlineSources, splitDisplay: splitDisplay };
54
+ var MdFront = { closeAt: closeAt, sendFront: sendFront };
55
+ var MdDocument = { writer: writer, preparedText: preparedText };
56
+ var MdBlocks = { blocks: blocks, blockJob: blockJob, sliceDue: sliceDue, SLICE_MS: SLICE_MS };
57
+ // Short aliases the libraries use for each other, matching their `.import` names.
58
+ var Names = MdEntityTable;
59
+ var Md = MdInline;
60
+ var Link = MdLink;
61
+ var Esc = MdEscape;
62
+ var Run = MdRun;
63
+ var Hold = MdHold;
64
+ var Emph = MdEmph;
65
+ var Ent = MdEntity;
66
+ var Brk = MdBreak;
67
+ var Refs = MdRefs;
68
+ var Leaf = MdLeaf;
69
+ var Res = MdResolve;
70
+ var Container = MdContainer;
71
+ var Document = MdDocument;
72
+ var Front = MdFront;
73
+ var Items = MdItems;
74
+ var Chunks = MdChunks;
75
+ var Lists = MarkdownLists;
76
+ var Maths = MdMath;
77
+ var Html = MdHtml;
78
+ var HtmlImage = MdHtmlImage;
79
+ var HtmlBlock = MdHtmlBlock;
80
+ var HtmlHeading = MdHtmlHeading;
81
+
82
+ // The live request's parse, run one slice a message so a newer request or a cancel is read between two slices.
83
+ var held = null;
84
+ WorkerScript.onMessage = function (msg) {
85
+ if (msg.cancel === true) {
86
+ held = null;
87
+ return;
88
+ }
89
+ // Liveness is the pane's protocol: only a request carrying a head field is acked, sliced and beaten, other askers see full replies alone.
90
+ if (msg.cont === true) {
91
+ if (held === null || held.seq !== msg.seq)
92
+ return;
93
+ } else if (msg.head !== undefined) {
94
+ WorkerScript.sendMessage({ seq: msg.seq, ack: true });
95
+ try {
96
+ held = { seq: msg.seq, parse: MdBlocks.blockJob(msg.source, msg.dir, msg.chrome, msg.ink, msg.head, function (head) {
97
+ // A first parse of a file sends its head ahead, so the first screen draws while the rest is still parsing.
98
+ WorkerScript.sendMessage({ seq: msg.seq, blocks: head, error: '', partial: true });
99
+ }, function () {
100
+ WorkerScript.sendMessage({ seq: msg.seq, progress: true });
101
+ }) };
102
+ } catch (e) {
103
+ held = null;
104
+ WorkerScript.sendMessage({ seq: msg.seq, blocks: [], error: String(e) });
105
+ return;
106
+ }
107
+ } else {
108
+ var plain = [];
109
+ var failure = '';
110
+ try {
111
+ plain = MdBlocks.blocks(msg.source, msg.dir, msg.chrome, msg.ink, msg.head, undefined, undefined);
112
+ } catch (e) {
113
+ failure = String(e);
114
+ }
115
+ WorkerScript.sendMessage({ seq: msg.seq, blocks: plain, error: failure });
116
+ return;
117
+ }
118
+ var blocks = [];
119
+ var error = '';
120
+ try {
121
+ blocks = held.parse.run(MdBlocks.sliceDue(MdBlocks.SLICE_MS));
122
+ } catch (e) {
123
+ error = String(e);
124
+ blocks = [];
125
+ }
126
+ if (blocks === null) {
127
+ WorkerScript.sendMessage({ seq: msg.seq, yielded: true });
128
+ return;
129
+ }
130
+ held = null;
131
+ WorkerScript.sendMessage({ seq: msg.seq, blocks: blocks, error: error });
132
+ };
@@ -0,0 +1,99 @@
1
+ import QtQuick
2
+
3
+ // A name with the search or filter match run marked by an accent wash. Three PlainText runs laid
4
+ // out left to right, never StyledText: a filename is arbitrary text and StyledText would render any
5
+ // markup found inside it. SearchFilter rule 3: the run keeps the foreground ink and the accent goes
6
+ // behind it, because accent against foreground is under 1.5:1 on nine of the 22 installed palettes
7
+ // and exactly 1.00 on kanagawa, where inked matches were the dimmest part of the name.
8
+ Item {
9
+ id: root
10
+
11
+ property string text: ""
12
+ // Where the run starts inside text, -1 for no run; ui/js/Match.js computes both.
13
+ property int matchStart: -1
14
+ property int matchLength: 0
15
+ property color color: Theme.color.foreground
16
+ property color accent: Theme.color.accent
17
+ property int pixelSize: Theme.font.body
18
+ // True while the strip that explains the run is up, so the content builds with it and no keystroke pays for it.
19
+ property bool armed: false
20
+ // Opt-in middle elision, so the match run keeps its place.
21
+ property bool elideMiddle: false
22
+
23
+ readonly property bool marked: root.matchStart >= 0 && root.matchLength > 0
24
+ readonly property string before: root.marked ? root.text.substring(0, root.matchStart) : root.text
25
+ readonly property string run: root.marked ? root.text.substring(root.matchStart, root.matchStart + root.matchLength) : ""
26
+ readonly property string after: root.marked ? root.text.substring(root.matchStart + root.matchLength) : ""
27
+
28
+ implicitHeight: beforeText.implicitHeight
29
+ // The marked run and its tail exist only while a match is marked, so their widths are the loaded item's.
30
+ implicitWidth: beforeText.implicitWidth + (markLoader.item ? markLoader.item.runsImplicitWidth : 0)
31
+
32
+ Text {
33
+ id: beforeText
34
+ anchors.verticalCenter: parent.verticalCenter
35
+ // Each run takes what is left of the slot, so the tail elides and nothing ever overflows.
36
+ width: Math.min(implicitWidth, root.width)
37
+ // A run clamped to zero paints nothing: an elided Text at width 0 still draws its full
38
+ // text on its first layout, so a late match (a head that fills the slot) overpaints
39
+ // whatever follows until any relayout. The accent wash below already gates the same way.
40
+ visible: width > 0
41
+ text: root.before
42
+ color: root.color
43
+ font.family: Theme.font.family
44
+ font.pixelSize: root.pixelSize
45
+ elide: root.elideMiddle && !root.marked ? Text.ElideMiddle : Text.ElideRight
46
+ textFormat: Text.PlainText
47
+ maximumLineCount: 1
48
+ }
49
+
50
+ // Built only while a match is marked: an unmarked name is the one run above, and most rows are unmarked.
51
+ Loader {
52
+ id: markLoader
53
+ active: root.marked || root.armed
54
+ anchors.left: beforeText.right
55
+ anchors.top: parent.top
56
+ anchors.bottom: parent.bottom
57
+ width: Math.max(0, root.width - beforeText.width)
58
+ sourceComponent: Item {
59
+ readonly property real runsImplicitWidth: runText.implicitWidth + afterText.implicitWidth
60
+
61
+ Rectangle {
62
+ anchors.fill: runText
63
+ visible: runText.width > 0
64
+ // The accent carries the row dim, so the wash multiplies it instead of replacing it.
65
+ color: Qt.rgba(root.accent.r, root.accent.g, root.accent.b, root.accent.a * Theme.washActive)
66
+ }
67
+
68
+ Text {
69
+ id: runText
70
+ anchors.left: parent.left
71
+ anchors.verticalCenter: parent.verticalCenter
72
+ width: Math.min(implicitWidth, parent.width)
73
+ visible: width > 0
74
+ text: root.run
75
+ color: root.color
76
+ font.family: Theme.font.family
77
+ font.pixelSize: root.pixelSize
78
+ elide: Text.ElideRight
79
+ textFormat: Text.PlainText
80
+ maximumLineCount: 1
81
+ }
82
+
83
+ Text {
84
+ id: afterText
85
+ anchors.left: runText.right
86
+ anchors.verticalCenter: parent.verticalCenter
87
+ width: Math.max(0, parent.width - runText.width)
88
+ visible: width > 0
89
+ text: root.after
90
+ color: root.color
91
+ font.family: Theme.font.family
92
+ font.pixelSize: root.pixelSize
93
+ elide: Text.ElideRight
94
+ textFormat: Text.PlainText
95
+ maximumLineCount: 1
96
+ }
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,38 @@
1
+ import QtQuick
2
+ import Quickshell
3
+ import Quickshell.Io
4
+
5
+ // One preview's MPRIS player (tools/flea-mpris): the helper starts when `active` first turns true, off the first frame.
6
+ QtObject {
7
+ id: root
8
+
9
+ // The PreviewMedia this speaks for, which carries out the helper's commands.
10
+ required property var media
11
+ property bool active: false
12
+ property bool ready: false
13
+ // The newest state line, written when the helper starts if it was not up yet.
14
+ property string last: ""
15
+
16
+ onActiveChanged: if (root.active) helper.running = true
17
+
18
+ function send(state) {
19
+ root.last = JSON.stringify(state)
20
+ if (root.ready) helper.write(root.last + "\n")
21
+ }
22
+
23
+ // Destroying the preview destroys this Process, which kills the helper; a UI that died instead closes its stdin.
24
+ property Process helper: Process {
25
+ id: helper
26
+ command: [Quickshell.env("FLEA_MPRIS") || "/usr/lib/flea/flea-mpris"]
27
+ stdinEnabled: true
28
+ stdout: SplitParser {
29
+ splitMarker: "\n"
30
+ onRead: function (line) { root.media.remote(line) }
31
+ }
32
+ onStarted: {
33
+ root.ready = true
34
+ if (root.last.length > 0) helper.write(root.last + "\n")
35
+ }
36
+ onExited: root.ready = false
37
+ }
38
+ }
@@ -0,0 +1,26 @@
1
+ pragma Singleton
2
+ import QtQuick
3
+
4
+ // MediaMute rule 3: mute is one session flag both media surfaces read, never written to ui.json; the level beside it is stored as preview.volume.
5
+ QtObject {
6
+ id: root
7
+
8
+ property bool muted: false
9
+
10
+ // The level under a press, 0 to 100, or -1 with none down, when the stored level shows.
11
+ property int held: -1
12
+ // Every Flea player plays at this, mute or not: 100 is the full-scale output a player had before the level existed.
13
+ readonly property int volume: root.held >= 0 ? root.held : ViewState.mediaVolume
14
+ // What the player takes: QtAudio.convertVolume(volume / 100, Logarithmic, Linear), which QML does not expose, as qtaudio.cpp computes it.
15
+ readonly property real gain: root.volume > 99 ? 1 : -Math.log(1 - root.volume / 100) / Math.log(100)
16
+
17
+ function toggle() { root.muted = !root.muted }
18
+
19
+ // A press or drag sets the level live and writes nothing; the release stores it once.
20
+ function setVolume(level) { root.held = level }
21
+
22
+ function keepVolume() {
23
+ ViewState.setMediaVolume(root.volume)
24
+ root.held = -1
25
+ }
26
+ }
@@ -0,0 +1,191 @@
1
+ import QtQuick
2
+ import qs.Commons
3
+ import "." as Flea
4
+ import "js/Format.js" as Format
5
+
6
+ // The transport the canvas draws under a media frame: a play/pause mark, a hairline seek with a square handle, a tabular clock and, under Quick Look, Media040's volume track. No filled chrome anywhere.
7
+ Item {
8
+ id: root
9
+
10
+ property bool playing: false
11
+ property real position: 0
12
+ property real duration: 0
13
+ // MediaMute rules 2 and 3: the state reads by glyph, off the one session flag both strips share.
14
+ readonly property bool muted: Flea.MediaSound.muted
15
+
16
+ // A tile borders four sides, which is the PreviewColumn artboard. Flush against the bottom of
17
+ // the Quick Look overlay that same border reads as a box, so there it is one top hairline.
18
+ property bool framed: true
19
+
20
+ signal toggled()
21
+ signal seeked(real ms)
22
+ // Any contact at all, so a host that hides this over a video can re-arm its own timer.
23
+ signal touched()
24
+
25
+ readonly property real fraction: root.duration > 0
26
+ ? Math.max(0, Math.min(1, root.position / root.duration)) : 0
27
+ // One second a click, the step ui/Preview.qml set on the qs.Ui slider this replaced.
28
+ readonly property int wheelStepMs: 1000
29
+
30
+ // A drag in flight draws from the pointer, not from the player, whose own advance would fight it.
31
+ property bool scrubbing: false
32
+ property real scrubFraction: 0
33
+ readonly property real shown: root.scrubbing ? root.scrubFraction : root.fraction
34
+
35
+ implicitHeight: Theme.chromeHeight
36
+
37
+ Rectangle {
38
+ anchors.fill: parent
39
+ color: Theme.color.surface
40
+ border.width: root.framed ? Theme.spacing.hairline : 0
41
+ border.color: Theme.color.mutedFrame
42
+ }
43
+
44
+ // The unframed form's own divider, the same hairline ChromeBar draws under itself.
45
+ Rectangle {
46
+ anchors.top: parent.top
47
+ anchors.left: parent.left
48
+ anchors.right: parent.right
49
+ visible: !root.framed
50
+ height: Theme.spacing.hairline
51
+ color: Theme.color.foreground
52
+ opacity: 0.12
53
+ }
54
+
55
+ // A test clicks each part itself rather than guess an offset; ui/shell.qml's previewSliderCentre reads seekItem, and volumeItem is null in the framed strip.
56
+ readonly property var playItem: playSlot
57
+ readonly property var seekItem: track
58
+ readonly property var muteItem: muteSlot
59
+ readonly property var volumeItem: volumeSlot.item
60
+
61
+ Item {
62
+ id: playSlot
63
+ anchors.left: parent.left
64
+ anchors.leftMargin: Theme.spacing.gap
65
+ anchors.verticalCenter: parent.verticalCenter
66
+ width: Math.max(Theme.hitMin, Theme.font.bodySmall)
67
+ height: Math.max(Theme.hitMin, Theme.font.bodySmall)
68
+
69
+ Accessible.role: Accessible.Button
70
+ Accessible.name: root.playing ? "Pause" : "Play"
71
+ Accessible.onPressAction: { root.touched(); root.toggled() }
72
+
73
+ Flea.Glyph {
74
+ anchors.centerIn: parent
75
+ width: Theme.font.bodySmall
76
+ height: Theme.font.bodySmall
77
+ name: root.playing ? "pause" : "play"
78
+ color: Theme.color.foreground
79
+ }
80
+
81
+ TapHandler {
82
+ acceptedButtons: Qt.LeftButton
83
+ gesturePolicy: TapHandler.ReleaseWithinBounds
84
+ onTapped: {
85
+ root.touched()
86
+ root.toggled()
87
+ }
88
+ }
89
+ }
90
+
91
+ Flea.MediaTrack {
92
+ id: track
93
+ anchors.left: playSlot.right
94
+ anchors.leftMargin: Theme.spacing.gap
95
+ anchors.right: clock.left
96
+ anchors.rightMargin: Theme.spacing.gap
97
+ anchors.top: parent.top
98
+ anchors.bottom: parent.bottom
99
+ fraction: root.shown
100
+
101
+ // Seeks once, on release: seeking on every dragged frame would fight the player's own
102
+ // advance. A press and release without moving is a click, so this covers both.
103
+ MouseArea {
104
+ anchors.fill: parent
105
+ hoverEnabled: true
106
+ cursorShape: Qt.PointingHandCursor
107
+ onPressed: function (mouse) {
108
+ root.scrubbing = true
109
+ root.scrubFraction = track.fractionAt(mouse.x)
110
+ root.touched()
111
+ }
112
+ onPositionChanged: function (mouse) {
113
+ if (root.scrubbing)
114
+ root.scrubFraction = track.fractionAt(mouse.x)
115
+ root.touched()
116
+ }
117
+ onReleased: {
118
+ root.scrubbing = false
119
+ root.touched()
120
+ if (root.duration > 0)
121
+ root.seeked(root.duration * root.scrubFraction)
122
+ }
123
+ // A wheel is not a position change, so this is the one interaction that has to re-arm a
124
+ // host's hide timer itself; the host clamps the absolute position this produces.
125
+ onWheel: function (wheel) {
126
+ root.touched()
127
+ if (root.duration > 0)
128
+ root.seeked(root.position + (wheel.angleDelta.y > 0 ? root.wheelStepMs : -root.wheelStepMs))
129
+ }
130
+ }
131
+ }
132
+
133
+ // MediaMute rule 1: one mark after the clock in the chrome ink, drawn by the play mark's Glyph; the track gives up its width, and under Quick Look the mark sits one gap left of the volume track.
134
+ Item {
135
+ id: muteSlot
136
+ anchors.right: root.framed ? parent.right : volumeSlot.left
137
+ anchors.rightMargin: Theme.spacing.gap
138
+ anchors.verticalCenter: parent.verticalCenter
139
+ width: Math.max(Theme.hitMin, Theme.font.bodySmall)
140
+ height: Math.max(Theme.hitMin, Theme.font.bodySmall)
141
+
142
+ Accessible.role: Accessible.Button
143
+ Accessible.name: root.muted ? "Unmute" : "Mute"
144
+ Accessible.onPressAction: { root.touched(); Flea.MediaSound.toggle() }
145
+
146
+ Flea.Glyph {
147
+ anchors.centerIn: parent
148
+ width: Theme.font.bodySmall
149
+ height: Theme.font.bodySmall
150
+ // Rule 2: both states are foreground, because a muted player is a mode and not a
151
+ // control that cannot be pressed.
152
+ name: root.muted ? "volume-x" : "volume"
153
+ color: Theme.color.foreground
154
+ }
155
+
156
+ TapHandler {
157
+ acceptedButtons: Qt.LeftButton
158
+ gesturePolicy: TapHandler.ReleaseWithinBounds
159
+ onTapped: {
160
+ root.touched()
161
+ Flea.MediaSound.toggle()
162
+ }
163
+ }
164
+ }
165
+
166
+ // Media040's level, built with the strip so its first frame already draws the stored one.
167
+ Loader {
168
+ id: volumeSlot
169
+ active: !root.framed
170
+ anchors.right: parent.right
171
+ anchors.rightMargin: Theme.spacing.gap
172
+ anchors.top: parent.top
173
+ anchors.bottom: parent.bottom
174
+ // Media040 draws a 60 px track at bodySmall 13, in resolved pixels, so space() would scale it twice.
175
+ width: Math.round(60 * Theme.font.bodySmall / 13)
176
+ sourceComponent: Flea.MediaVolume {}
177
+ onLoaded: item.touched.connect(root.touched)
178
+ }
179
+
180
+ Text {
181
+ id: clock
182
+ anchors.right: muteSlot.left
183
+ anchors.rightMargin: Theme.spacing.gap
184
+ anchors.verticalCenter: parent.verticalCenter
185
+ text: Format.duration(root.position) + " / " + Format.duration(root.duration)
186
+ color: Theme.color.muted
187
+ font.family: Theme.font.family
188
+ font.pixelSize: Theme.font.caption
189
+ textFormat: Text.PlainText
190
+ }
191
+ }
@@ -0,0 +1,36 @@
1
+ import QtQuick
2
+
3
+ // The hairline track of the media strip, drawn for the seek and, under Quick Look, the volume: the played part and a square handle in the accent frame ink, the host adds its MouseArea.
4
+ Item {
5
+ id: root
6
+
7
+ property real fraction: 0
8
+ // A square handle, sized off the caption token so it scales with the text like everything else.
9
+ readonly property int handle: Math.round(Theme.font.caption * 0.5)
10
+
11
+ function fractionAt(x) {
12
+ return Math.max(0, Math.min(1, x / Math.max(1, root.width)))
13
+ }
14
+
15
+ Rectangle {
16
+ anchors.verticalCenter: parent.verticalCenter
17
+ width: parent.width
18
+ height: Theme.spacing.hairline * 2
19
+ color: Theme.color.mutedFrame
20
+ }
21
+
22
+ Rectangle {
23
+ anchors.verticalCenter: parent.verticalCenter
24
+ width: parent.width * root.fraction
25
+ height: Theme.spacing.hairline * 2
26
+ color: Theme.color.accentFrame
27
+ }
28
+
29
+ Rectangle {
30
+ x: Math.round(parent.width * root.fraction) - root.handle / 2
31
+ anchors.verticalCenter: parent.verticalCenter
32
+ width: root.handle
33
+ height: root.handle
34
+ color: Theme.color.accentFrame
35
+ }
36
+ }
@@ -0,0 +1,54 @@
1
+ import QtQuick
2
+ import "." as Flea
3
+
4
+ // Media040's level on the Quick Look strip: a track that sets Flea.MediaSound's volume live and stores it on release; mute leaves it alone.
5
+ Flea.MediaTrack {
6
+ id: root
7
+
8
+ // Any contact at all, so a host that hides the strip over a video can re-arm its own timer.
9
+ signal touched()
10
+
11
+ // True while this track's own press holds the level, so closing Quick Look under a button still down lets it go.
12
+ property bool pressing: false
13
+
14
+ fraction: Flea.MediaSound.volume / 100
15
+
16
+ Component.onDestruction: if (root.pressing) Flea.MediaSound.held = -1
17
+
18
+ Accessible.role: Accessible.Slider
19
+ Accessible.name: "Volume"
20
+ // A screen reader steps the level by 5 and stores it as a release would.
21
+ Accessible.onIncreaseAction: root.nudge(5)
22
+ Accessible.onDecreaseAction: root.nudge(-5)
23
+
24
+ function nudge(delta) {
25
+ Flea.MediaSound.setVolume(Math.max(0, Math.min(100, Flea.MediaSound.volume + delta)))
26
+ Flea.MediaSound.keepVolume()
27
+ }
28
+
29
+ MouseArea {
30
+ anchors.fill: parent
31
+ hoverEnabled: true
32
+ cursorShape: Qt.PointingHandCursor
33
+ onPressed: function (mouse) {
34
+ root.pressing = true
35
+ root.touched()
36
+ Flea.MediaSound.setVolume(Math.round(100 * root.fractionAt(mouse.x)))
37
+ }
38
+ onPositionChanged: function (mouse) {
39
+ root.touched()
40
+ if (pressed)
41
+ Flea.MediaSound.setVolume(Math.round(100 * root.fractionAt(mouse.x)))
42
+ }
43
+ onReleased: {
44
+ root.pressing = false
45
+ root.touched()
46
+ Flea.MediaSound.keepVolume()
47
+ }
48
+ // A stolen grab ends the drag like a release, so the level heard is the level kept.
49
+ onCanceled: {
50
+ root.pressing = false
51
+ Flea.MediaSound.keepVolume()
52
+ }
53
+ }
54
+ }