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,307 @@
1
+ .pragma library
2
+
3
+ // MdHtml: one forward scan allowlists raw tags; only sanitized markup reaches md4c.
4
+ .import "MdUrl.js" as MdUrl
5
+ .import "MdEscape.js" as MdEscape
6
+ .import "MdInline.js" as MdInline
7
+
8
+ var TOKEN_OPEN = 57346
9
+ var TOKEN_CLOSE = 57347
10
+ var MAX_TAG_LENGTH = 4096
11
+
12
+ // Sample input: "\uE0020\uE003" becomes "\uFFFD0\uFFFD" before document parsing reserves its token markers; "a\r\nb\rc" becomes "a\nb\nc", the line endings CommonMark names.
13
+ function documentText(text) {
14
+ return String(text).replace(/[\uE002\uE003]/g, "\uFFFD").replace(/\r\n?/g, "\n")
15
+ }
16
+
17
+ // Held spans use private-use delimiters and one shared token table, restored after escaping.
18
+ function openToken() {
19
+ return String.fromCharCode(TOKEN_OPEN)
20
+ }
21
+
22
+ function closeToken() {
23
+ return String.fromCharCode(TOKEN_CLOSE)
24
+ }
25
+
26
+ function holdToken(tokens, html) {
27
+ var token = openToken() + tokens.length + closeToken()
28
+ tokens.push(html)
29
+ return token
30
+ }
31
+
32
+ // Tags whose content is dropped with them: active content and whole-document namespaces a preview must never instantiate.
33
+ var DROP_CONTENT = { script: 1, style: 1, iframe: 1, object: 1, embed: 1,
34
+ template: 1, noscript: 1, svg: 1, math: 1 }
35
+
36
+ // Tags re-emitted with the attributes below; any other tag is dropped and its content kept. font carries only the color the parser's own links wrap in.
37
+ var ALLOWED = { a: 1, b: 1, strong: 1, i: 1, em: 1, u: 1, s: 1, del: 1,
38
+ strike: 1, sub: 1, sup: 1, kbd: 1, code: 1, br: 1, small: 1, mark: 1,
39
+ span: 1, p: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, hr: 1,
40
+ img: 1, picture: 1, source: 1, details: 1, summary: 1, table: 1,
41
+ thead: 1, tbody: 1, tr: 1, th: 1, td: 1, ul: 1, ol: 1, li: 1,
42
+ blockquote: 1, pre: 1, font: 1 }
43
+
44
+ // Attributes that survive on any allowed tag. Every style, class, id, background, srcset, poster, data-* and on* attribute is dropped.
45
+ var GLOBAL_ATTRS = { align: 1, alt: 1, width: 1, height: 1, title: 1,
46
+ colspan: 1, rowspan: 1 }
47
+
48
+ // Void tags never take a closing tag.
49
+ var VOID = { br: 1, hr: 1, img: 1, source: 1 }
50
+
51
+ // The chip kbd and code tags wear, the same recipe as an inline code span.
52
+ var CHROME_PATTERN = /^#[0-9a-f]{6}([0-9a-f]{2})?$/i
53
+ var DISCLOSURE_OPEN = "\u25be"
54
+
55
+ // Qt draws a raw s tag struck on every build but drops del and strike, so all three are emitted as s.
56
+ var STRIKE_AS = { del: "s", strike: "s" }
57
+
58
+ function isNameChar(c) {
59
+ return (c >= "a" && c <= "z") || (c >= "A" && c <= "Z") || (c >= "0" && c <= "9")
60
+ }
61
+
62
+ function isHtmlWhitespace(c) {
63
+ return c === "\t" || c === "\n" || c === "\f" || c === "\r" || c === " "
64
+ }
65
+
66
+ // Sample: <img src="pic.png" alt="picture">. Quote-check only the candidate; a failed native search marks later openers dead, and oversized tags stay literal.
67
+ function readTag(text, i, dead) {
68
+ if (dead !== undefined && dead !== null && i < dead.tagDead)
69
+ return null
70
+ var cached = dead !== undefined && dead !== null && dead.tagClose > i
71
+ var gt = cached ? dead.tagClose : text.indexOf(">", i + 1)
72
+ if (dead !== undefined && dead !== null && gt >= 0)
73
+ dead.tagClose = gt
74
+ if (gt < 0) {
75
+ if (dead !== undefined && dead !== null)
76
+ dead.tagDead = text.length
77
+ return null
78
+ }
79
+ if (gt - i > MAX_TAG_LENGTH) {
80
+ if (dead !== undefined && dead !== null)
81
+ dead.tagDead = gt - MAX_TAG_LENGTH
82
+ return null
83
+ }
84
+ var candidate = text.slice(i, gt + 1)
85
+ var dq = candidate.indexOf('"')
86
+ var sq = candidate.indexOf("'")
87
+ if (dq < 0 && sq < 0)
88
+ return { tag: candidate, end: gt + 1 }
89
+ var quote = ""
90
+ var j = i + 1
91
+ while (j < gt) {
92
+ var c = text.charAt(j)
93
+ if (quote !== "") {
94
+ if (c === quote)
95
+ quote = ""
96
+ } else if (c === '"' || c === "'") {
97
+ quote = c
98
+ }
99
+ j++
100
+ }
101
+ if (quote !== "")
102
+ return null
103
+ return { tag: candidate, end: gt + 1 }
104
+ }
105
+
106
+ // Sample input: ' a=b/' keeps the slash in b/; ' ==/' names '=' with value '/'; ' a="b"/' sets the self-closing flag.
107
+ function scanAttributes(rest) {
108
+ var i = 0
109
+ var attributes = []
110
+ var valid = true
111
+ var selfClose = false
112
+ while (i < rest.length) {
113
+ while (i < rest.length && isHtmlWhitespace(rest.charAt(i)))
114
+ i++
115
+ if (i >= rest.length)
116
+ break
117
+ if (rest.charAt(i) === "/") {
118
+ selfClose = i === rest.length - 1
119
+ i++
120
+ continue
121
+ }
122
+ // Before an attribute name, even '=' starts the name; only a later '=' starts its value.
123
+ var aname = rest.charAt(i).toLowerCase()
124
+ i++
125
+ while (i < rest.length && !isHtmlWhitespace(rest.charAt(i))
126
+ && rest.charAt(i) !== "=" && rest.charAt(i) !== "/" && rest.charAt(i) !== ">") {
127
+ aname += rest.charAt(i).toLowerCase()
128
+ i++
129
+ }
130
+ if (!/^[A-Za-z_:][-A-Za-z0-9_.:]*$/.test(aname))
131
+ valid = false
132
+ while (i < rest.length && isHtmlWhitespace(rest.charAt(i)))
133
+ i++
134
+ var value = null
135
+ if (rest.charAt(i) === "=") {
136
+ i++
137
+ while (i < rest.length && isHtmlWhitespace(rest.charAt(i)))
138
+ i++
139
+ var q = rest.charAt(i)
140
+ if (q === '"' || q === "'") {
141
+ i++
142
+ var start = i
143
+ while (i < rest.length && rest.charAt(i) !== q)
144
+ i++
145
+ value = rest.slice(start, i)
146
+ i++
147
+ } else {
148
+ var begin = i
149
+ while (i < rest.length && !isHtmlWhitespace(rest.charAt(i)) && rest.charAt(i) !== ">")
150
+ i++
151
+ value = rest.slice(begin, i)
152
+ }
153
+ }
154
+ attributes.push({ name: aname, value: value })
155
+ }
156
+ return { attributes: attributes, valid: valid, selfClose: selfClose }
157
+ }
158
+
159
+ // Sample input: '<img src="pic.png"/>' yields name "img", its attributes and a self-closing flag.
160
+ function tagHead(tag) {
161
+ var i = 1
162
+ var closing = false
163
+ if (tag.charAt(i) === "/") {
164
+ closing = true
165
+ i++
166
+ }
167
+ var name = ""
168
+ while (i < tag.length && (isNameChar(tag.charAt(i)) || tag.charAt(i) === "-")) {
169
+ name += tag.charAt(i).toLowerCase()
170
+ i++
171
+ }
172
+ var rest = tag.slice(i, tag.length - 1)
173
+ var slashFirst = rest.charAt(0) === "/"
174
+ var whitespaceEnd = slashFirst ? 1 : 0
175
+ while (whitespaceEnd < rest.length && isHtmlWhitespace(rest.charAt(whitespaceEnd)))
176
+ whitespaceEnd++
177
+ var validHead = /^[a-z]/.test(name)
178
+ && (rest === "" || isHtmlWhitespace(rest.charAt(0)) || slashFirst)
179
+ && (!closing || (!slashFirst && whitespaceEnd === rest.length))
180
+ && (!slashFirst || whitespaceEnd === rest.length)
181
+ // Malformed dropped openers still suppress their bodies; malformed closers cannot end a dropped body.
182
+ if (!validHead && (closing || !DROP_CONTENT.hasOwnProperty(name)))
183
+ name = ""
184
+ var attrs = scanAttributes(rest)
185
+ return { name: name, closing: closing, rest: rest, selfClose: validHead && attrs.valid && attrs.selfClose,
186
+ attributes: attrs.attributes, validAttrs: attrs.valid }
187
+ }
188
+
189
+ // Sample input: " \thttps://a.example/x\n " strips URL padding and embedded tab, CR and LF.
190
+ function normalizedTarget(value) {
191
+ return MdUrl.strippedTarget(value)
192
+ }
193
+
194
+ // One attribute value with entities decoded for the safety checks below.
195
+ function attrKept(name, value, tagName) {
196
+ var seen = normalizedTarget(MdUrl.canonicalUrl(value)).toLowerCase()
197
+ // CSS url() in any attribute loads, so the attribute goes.
198
+ if (/url\s*\(/i.test(seen))
199
+ return false
200
+ if (name === "href") {
201
+ if (tagName !== "a")
202
+ return false
203
+ // Links never fetch: http, https, mailto, relative and #anchor stay, through every decoding.
204
+ return MdUrl.targetAllowed(value)
205
+ }
206
+ if (name === "src")
207
+ return tagName === "img" || tagName === "source"
208
+ if (name === "color")
209
+ return tagName === "font"
210
+ return GLOBAL_ATTRS.hasOwnProperty(name)
211
+ }
212
+
213
+ // The opening of an inline code chip; an unusable chrome leaves a plain code tag.
214
+ function chipOpen(chrome) {
215
+ return CHROME_PATTERN.test(String(chrome || "")) ? '<code style="background-color:' + chrome + '">' + MdEscape.chipPad() : "<code>"
216
+ }
217
+ function chipClose(chrome) {
218
+ return CHROME_PATTERN.test(String(chrome || "")) ? MdEscape.chipPad() + "</code>" : "</code>"
219
+ }
220
+
221
+ function escapeAttr(value) {
222
+ return String(value).replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/</g, "&#60;")
223
+ }
224
+
225
+ // Sanitize one tag into {emit, drop}; held image tokens carry resolved URLs, and drop names content to skip. chrome fills the key cap, ink colours a link, inked.open counts the links wearing it.
226
+ function sanitizeTag(tag, dir, tokens, chrome, ink, inked) {
227
+ function hold(html) {
228
+ return holdToken(tokens, html)
229
+ }
230
+ var head = tagHead(tag)
231
+ var name = STRIKE_AS.hasOwnProperty(head.name) ? STRIKE_AS[head.name] : head.name
232
+ if (name.length === 0)
233
+ return { emit: "&#60;", drop: null }
234
+ if (DROP_CONTENT.hasOwnProperty(name))
235
+ return { emit: "", drop: head.closing || head.selfClose ? null : name }
236
+ if (!ALLOWED.hasOwnProperty(name))
237
+ return { emit: "", drop: null }
238
+ // details is drawn open: its summary is a bold line led by the open disclosure mark, and its body follows.
239
+ if (name === "details")
240
+ return { emit: "", drop: null }
241
+ if (name === "summary")
242
+ return { emit: head.closing ? "</b>" : "<b>" + DISCLOSURE_OPEN + " ", drop: null }
243
+ // kbd and code are the inline code chip, never a bare tag.
244
+ if (name === "kbd" || name === "code")
245
+ return { emit: head.closing ? chipClose(chrome) : chipOpen(chrome), drop: null }
246
+ var wear = name === "a" ? MdInline.linkInk(ink) : null
247
+ // A closer takes off only ink its own opener put on, so a refused, self-closed or missing opener never ends an enclosing font.
248
+ if (head.closing) {
249
+ var worn = wear !== null && inked.open > 0
250
+ if (worn)
251
+ inked.open--
252
+ return { emit: (worn ? wear.close : "") + "</" + name + ">", drop: null }
253
+ }
254
+ if (!head.validAttrs)
255
+ return { emit: "", drop: null }
256
+ var kept = ""
257
+ var srcSeen = null
258
+ var srcsetSeen = null
259
+ var altSeen = null
260
+ for (var i = 0; i < head.attributes.length; i++) {
261
+ var aname = head.attributes[i].name
262
+ var value = head.attributes[i].value
263
+ // Every style, class, id, background, srcset, poster, data-* and on* attribute is dropped, whatever its value.
264
+ if (aname === "style" || aname === "class" || aname === "id"
265
+ || aname === "background" || aname === "poster"
266
+ || aname.indexOf("data-") === 0 || aname.indexOf("on") === 0)
267
+ continue
268
+ if (aname === "srcset") {
269
+ if (srcsetSeen === null)
270
+ srcsetSeen = value === null ? "" : value
271
+ continue
272
+ }
273
+ if (aname === "src" && (name === "img" || name === "source")) {
274
+ if (srcSeen === null)
275
+ srcSeen = value === null ? "" : value
276
+ continue
277
+ }
278
+ if (aname === "alt") {
279
+ if (altSeen !== null)
280
+ continue
281
+ altSeen = value === null ? "" : value
282
+ }
283
+ if (aname === "href" && value !== null)
284
+ value = normalizedTarget(value)
285
+ if (value === null || attrKept(aname, value, name))
286
+ kept += " " + aname + (value === null ? "" : '="' + escapeAttr(value) + '"')
287
+ }
288
+ if (name === "img" || name === "source") {
289
+ var picked = null
290
+ if (srcSeen !== null)
291
+ picked = MdUrl.classifyImage(srcSeen, dir)
292
+ else if (srcsetSeen !== null)
293
+ picked = MdUrl.srcsetPick(srcsetSeen, dir)
294
+ // The importer drops everything after a raw img tag, so a local picture reaches it as a Markdown image.
295
+ if (picked !== null && picked.kind === "local")
296
+ return { emit: hold("![" + MdEscape.escapeText(altSeen === null ? "" : altSeen) + "]("
297
+ + picked.url.replace(/\(/g, "%28").replace(/\)/g, "%29") + ")"), drop: null }
298
+ if (picked !== null && picked.kind === "remote")
299
+ return { emit: "\n\n" + MdUrl.placeholder(MdEscape.escapeText(picked.host)) + "\n\n", drop: null }
300
+ return { emit: MdUrl.canonicalUrl(altSeen).length > 0 ? MdEscape.escapeText(altSeen) : "", drop: null }
301
+ }
302
+ var close = (head.selfClose || VOID.hasOwnProperty(name)) ? " /" : ""
303
+ var wears = wear !== null && close === ""
304
+ if (wears)
305
+ inked.open++
306
+ return { emit: "<" + name + kept + close + ">" + (wears ? wear.open : ""), drop: null }
307
+ }
@@ -0,0 +1,290 @@
1
+ .pragma library
2
+
3
+ // MdHtmlBlock: images leave an HTML block as image blocks, and top-level HTML blocks start their own lines.
4
+ .import "MdHtml.js" as MdHtml
5
+ .import "MdHtmlImage.js" as HtmlImage
6
+
7
+ // The names CommonMark starts an HTML block with, and one complete tag alone on its line, which starts one only outside a paragraph.
8
+ var BLOCK_NAMES = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul"
9
+ // Sample input: '<div align="center">' and ' </table>' start an HTML block; '<span>x</span>' and 'text <div>' do not.
10
+ var BLOCK_START = new RegExp("^ {0,3}<\\/?(?:" + BLOCK_NAMES + ")(?:[\\s>]|\\/>|$)", "i")
11
+ // Sample input: '<a href="x">' and '</span>' alone on a line are complete tags; '<a href="x">text' is not.
12
+ var COMPLETE_TAG = /^ {0,3}(?:<[A-Za-z][A-Za-z0-9-]*(?:\s[^<>]*)?\/?>|<\/[A-Za-z][A-Za-z0-9-]*\s*>)\s*$/
13
+ // Sample input: 'x <a href="https://y">' ends with a link opener, which the text before an image holds when the image sits in a link.
14
+ var LINK_BEFORE = /<a\b[^<>]*>\s*$/i
15
+ // Sample input: '</a>' and '</A>' close the link around an image; the four characters after the image are tested against it.
16
+ var LINK_CLOSE = /^<\/a>$/i
17
+ var LINK_CLOSE_LENGTH = "</a>".length
18
+ // Sample input: 'A<IMG' holds the capital letters asciiLower lowers, by their distance from lower case.
19
+ var UPPER_ASCII = /[A-Z]/g
20
+ var CASE_OFFSET = "a".charCodeAt(0) - "A".charCodeAt(0)
21
+ // Sample input: '<p align="center"><b>x</b>' and '<center>' open a block that may centre; '<span>' and 'text' do not.
22
+ var CENTRED_OPEN = /^\s*<(?:p|div|center)\b[^<>]*>/i
23
+ // Sample input: 'a <div>b</div>' and '<h1 align="center">' hold a block tag that centres itself; '<b>x</b>' holds none.
24
+ var BLOCK_TAG = /<(?:p|div|h[1-6]|table|ul|ol|blockquote|pre)\b/i
25
+ // Sample input: '</p><p>' and '<div align="center">' open or close a block, so pictures either side of them sit on lines of their own; '<b>' and '</td><td>' do not.
26
+ var BLOCK_BOUNDARY = /<\/?(?:p|div|h[1-6]|table|tr|ul|ol|li|blockquote|pre)\b/i
27
+ // Sample input: '<br>' and '<BR />' break a line.
28
+ var BREAK_TAG = /<br\b[^<>]*>/i
29
+ // The most pictures one images block holds.
30
+ var ROW_IMAGE_CAP = 64
31
+ var CENTRED_WRAP = '<p align="center">'
32
+ // The elements that start their own line, and the ones that nest and so are counted open and closed.
33
+ // Sample input: '<h1 align="center">Flea</h1>' and ' <details open>' start a line of their own; '<b>x</b>' does not.
34
+ var LINE_OPENER = /^ {0,3}<(?:p|div|h[1-6]|details|summary|hr|table|ul|ol|blockquote|pre)(?=[\s>\/])/i
35
+ // Sample input: '<div class="x">' answers slash "" and '</div>' answers "/"; '<b>' and '<divider>' match nothing.
36
+ var NESTING_TAG = /<(\/?)(?:p|div|h[1-6]|details|summary|table|ul|ol|blockquote|pre)(?=[\s>\/])[^<>]*>/gi
37
+ // Sample input: '<b>' answers slash "" and name "b"; '</p>' answers "/" and "p"; text with no angle bracket matches nothing.
38
+ var ANY_TAG = /<(\/?)([A-Za-z][A-Za-z0-9]*)[^<>]*>/g
39
+
40
+ // Sample input: '<IMG SRC>' after a U+0130 answers '<img src>'; only A to Z change, so an index in the answer is an index in the text.
41
+ function asciiLower(text) {
42
+ return text.replace(UPPER_ASCII, function (letter) { return String.fromCharCode(letter.charCodeAt(0) + CASE_OFFSET) })
43
+ }
44
+
45
+ // Sample input: '<td><img src="a.png"></td>' from 0 answers { start: 4, end: 24, block }; remote and unreadable images answer null.
46
+ // lower is the line in asciiLower form and dead its tag cache, made once per line, so a row of many images costs one pass.
47
+ function findImage(line, lower, from, dead, dir) {
48
+ var at = lower.indexOf("<img", from)
49
+ while (at >= 0) {
50
+ var tag = MdHtml.readTag(line, at, dead)
51
+ var block = tag === null ? null : HtmlImage.rawImage(tag.tag, dir)
52
+ if (block !== null && block.type === "image")
53
+ return { start: at, end: tag.end, block: block }
54
+ at = lower.indexOf("<img", at + 1)
55
+ }
56
+ return null
57
+ }
58
+
59
+ // Sample input: '<td>a</p>' drops the closer no opener in the text matches; text with its own pairs is unchanged.
60
+ function withoutStrayClosers(text) {
61
+ var open = {}
62
+ return text.replace(ANY_TAG, function (tag, slash, name) {
63
+ var key = name.toLowerCase()
64
+ if (slash === "") {
65
+ open[key] = (open[key] || 0) + 1
66
+ return tag
67
+ }
68
+ if (open[key] > 0) {
69
+ open[key]--
70
+ return tag
71
+ }
72
+ return ""
73
+ })
74
+ }
75
+
76
+ // What stays of the lines around an extracted image: lines with visible text, their stray closers gone, centred when its block was.
77
+ function remainder(kept, centred) {
78
+ var split = withoutStrayClosers(kept.join("\n")).split("\n")
79
+ var lines = []
80
+ // A line that holds a block tag of its own centres itself; wrapping it would nest the paragraphs.
81
+ var nests = false
82
+ for (var i = 0; i < split.length; i++) {
83
+ // A line holding an image the splitter did not take (a remote one) draws its placeholder, so it stays.
84
+ if (split[i].replace(ANY_TAG, "").trim().length === 0 && !/<(?:hr|img)\b/i.test(split[i]))
85
+ continue
86
+ lines.push(split[i])
87
+ nests = nests || BLOCK_TAG.test(split[i])
88
+ }
89
+ if (lines.length > 0)
90
+ lines[0] = lines[0].replace(HtmlImage.LEADING_BREAK, "")
91
+ return lines.length === 0 ? [] : centred && !nests ? [CENTRED_WRAP + lines.join("\n") + "</p>"] : lines
92
+ }
93
+
94
+ // Sample input: images a and b with nothing between them answer [{ block: { type: "images", items: [a, b] } }]; one image, text or a row break keeps them apart.
95
+ // A row longer than ROW_IMAGE_CAP continues in the next block, so no block builds an unbounded number of pictures at once.
96
+ function imageRows(parts) {
97
+ var out = []
98
+ var row = []
99
+ function close() {
100
+ for (var at = 0; at < row.length; at += ROW_IMAGE_CAP) {
101
+ var items = row.slice(at, at + ROW_IMAGE_CAP)
102
+ if (items.length === 1) {
103
+ out.push({ block: items[0] })
104
+ continue
105
+ }
106
+ var rows = { type: "images", items: items }
107
+ if (items[0].align !== undefined)
108
+ rows.align = items[0].align
109
+ for (var r = 0; r < items.length; r++)
110
+ delete items[r].align
111
+ out.push({ block: rows })
112
+ }
113
+ row = []
114
+ }
115
+ for (var i = 0; i < parts.length; i++) {
116
+ if (parts[i].block !== undefined) {
117
+ row.push(parts[i].block)
118
+ } else {
119
+ close()
120
+ if (parts[i].lines !== undefined)
121
+ out.push(parts[i])
122
+ }
123
+ }
124
+ close()
125
+ return out
126
+ }
127
+
128
+ // One HTML block's lines as parts, each a { lines } to parse or a { block } image; the block's wrappers do not outlive its image.
129
+ function splitBlock(group, dir) {
130
+ var centred = CENTRED_OPEN.test(group[0]) && (/^\s*<center\b/i.test(group[0]) || HtmlImage.isCentred(CENTRED_OPEN.exec(group[0])[0]))
131
+ var parts = []
132
+ var kept = []
133
+ var found = false
134
+ function flush() {
135
+ var lines = remainder(kept, centred)
136
+ // A line break or a block boundary between two images starts the next row.
137
+ var between = kept.join("\n")
138
+ var broke = BREAK_TAG.test(between) || BLOCK_BOUNDARY.test(between)
139
+ kept = []
140
+ if (lines.length > 0)
141
+ parts.push({ lines: lines })
142
+ else if (broke)
143
+ parts.push({ rowBreak: true })
144
+ }
145
+ for (var i = 0; i < group.length; i++) {
146
+ var line = group[i]
147
+ var lower = asciiLower(line)
148
+ var dead = { tagDead: -1 }
149
+ // The scan walks the line by position, so a line of many images is cut once, never once per image.
150
+ var from = 0
151
+ for (var hit = findImage(line, lower, from, dead, dir); hit !== null; hit = findImage(line, lower, from, dead, dir)) {
152
+ var before = line.slice(from, hit.start)
153
+ var wrap = LINK_BEFORE.exec(before)
154
+ // The link closer follows the image after optional whitespace.
155
+ var next = hit.end
156
+ while (next < line.length && /\s/.test(line.charAt(next)))
157
+ next++
158
+ from = hit.end
159
+ if (wrap !== null && LINK_CLOSE.test(line.slice(next, next + LINK_CLOSE_LENGTH))) {
160
+ if (HtmlImage.linkOf(wrap[0]) !== null)
161
+ hit.block.link = HtmlImage.linkOf(wrap[0])
162
+ before = before.slice(0, wrap.index)
163
+ from = next + LINK_CLOSE_LENGTH
164
+ }
165
+ kept.push(before)
166
+ flush()
167
+ if (centred)
168
+ hit.block.align = "center"
169
+ parts.push({ block: hit.block })
170
+ found = true
171
+ }
172
+ kept.push(line.slice(from))
173
+ }
174
+ flush()
175
+ return found ? imageRows(parts) : [{ lines: group }]
176
+ }
177
+
178
+ // Sample input: ['<table><tr><td><img src="a.png"></td></tr></table>'] answers [{ block }]; a paragraph's inline image stays in its lines.
179
+ // The importer draws no Markdown inside an HTML block and drops a raw img with all that follows it, so a block's images leave it.
180
+ function splitHtmlImages(lines, dir) {
181
+ var parts = []
182
+ var text = []
183
+ var group = null
184
+ var paragraph = false
185
+ function closeGroup() {
186
+ if (group !== null) {
187
+ var split = splitBlock(group, dir)
188
+ for (var s = 0; s < split.length; s++)
189
+ parts.push(split[s])
190
+ }
191
+ group = null
192
+ }
193
+ function closeText() {
194
+ if (text.length > 0)
195
+ parts.push({ lines: text })
196
+ text = []
197
+ }
198
+ for (var i = 0; i < lines.length; i++) {
199
+ var line = lines[i]
200
+ if (line.trim().length === 0) {
201
+ closeGroup()
202
+ text.push(line)
203
+ paragraph = false
204
+ } else if (group !== null) {
205
+ group.push(line)
206
+ } else if (BLOCK_START.test(line) || (!paragraph && COMPLETE_TAG.test(line))) {
207
+ closeText()
208
+ group = [line]
209
+ } else {
210
+ paragraph = true
211
+ text.push(line)
212
+ }
213
+ }
214
+ closeGroup()
215
+ closeText()
216
+ // Lines the split left alone stay one run, as the importer joins an HTML block with the paragraph after it.
217
+ var merged = []
218
+ for (var k = 0; k < parts.length; k++) {
219
+ var last = merged.length - 1
220
+ if (last >= 0 && merged[last].lines !== undefined && parts[k].lines !== undefined) {
221
+ for (var m = 0; m < parts[k].lines.length; m++)
222
+ merged[last].lines.push(parts[k].lines[m])
223
+ } else {
224
+ merged.push(parts[k].lines === undefined ? parts[k] : { lines: parts[k].lines.slice(0) })
225
+ }
226
+ }
227
+ return merged
228
+ }
229
+
230
+ // Sample input: ['<h1>A</h1>', '<p>B</p>'] answers ['<h1>A</h1>', '', '<p>B</p>']; a block nested in an open one stays on its line.
231
+ // The importer draws adjacent HTML block lines as one line, so each top-level block starts after a blank line.
232
+ function separateBlocks(lines) {
233
+ var out = []
234
+ var depth = 0
235
+ for (var i = 0; i < lines.length; i++) {
236
+ var line = lines[i]
237
+ if (line.trim().length === 0)
238
+ depth = 0
239
+ else if (depth === 0 && out.length > 0 && out[out.length - 1].trim().length > 0 && LINE_OPENER.test(line))
240
+ out.push("")
241
+ out.push(line)
242
+ line.replace(NESTING_TAG, function (tag, slash) {
243
+ depth = slash === "/" ? Math.max(0, depth - 1) : depth + 1
244
+ return tag
245
+ })
246
+ }
247
+ return out
248
+ }
249
+
250
+ // The six heading levels by tag name, so an HTML heading maps to its Markdown level.
251
+ var HEADING_LEVEL = { h1: 1, h2: 2, h3: 3, h4: 4, h5: 5, h6: 6 }
252
+ // The shortest heading line that holds text, "<h1>x</h1>": anything shorter is never one.
253
+ var HEADING_SHORTEST = 10
254
+ // Sample input: '<h1 align="center">Flea</h1>' answers level 1 with centre and inner Flea; '<h2>x</h2> tail' answers null.
255
+ function htmlHeading(line) {
256
+ var text = String(line).trim()
257
+ if (text.length < HEADING_SHORTEST)
258
+ return null
259
+ var open = MdHtml.readTag(text, 0, null)
260
+ if (open === null || open.end <= 0)
261
+ return null
262
+ var head = MdHtml.tagHead(open.tag)
263
+ var level = HEADING_LEVEL[head.name]
264
+ if (level === undefined || head.closing)
265
+ return null
266
+ var rest = text.slice(open.end)
267
+ var lower = asciiLower(rest)
268
+ var closeName = "</h" + level
269
+ var closeAt = lower.indexOf(closeName)
270
+ if (closeAt < 0)
271
+ return null
272
+ var close = MdHtml.readTag(text, open.end + closeAt, null)
273
+ if (close === null || close.end !== text.length)
274
+ return null
275
+ var closeHead = MdHtml.tagHead(close.tag)
276
+ if (closeHead.name !== head.name || !closeHead.closing)
277
+ return null
278
+ var inner = rest.slice(0, closeAt)
279
+ var align = null
280
+ var aligned = false
281
+ for (var i = 0; i < head.attributes.length; i++) {
282
+ if (head.attributes[i].name === "align" && head.attributes[i].value !== null) {
283
+ aligned = true
284
+ var seen = head.attributes[i].value.toLowerCase()
285
+ if (seen === "center" || seen === "right")
286
+ align = seen
287
+ }
288
+ }
289
+ return { level: level, align: align, aligned: aligned, inner: inner }
290
+ }
@@ -0,0 +1,53 @@
1
+ .pragma library
2
+
3
+ // MdHtmlHeading: an HTML heading inside a wrapper or opening with a picture, lifted whole so no wrapper is split and no picture sits in a text line.
4
+ .import "MdHtml.js" as MdHtml
5
+ .import "MdHtmlImage.js" as HtmlImage
6
+ .import "MdHtmlBlock.js" as HtmlBlock
7
+
8
+ // Sample input: drawn heading text '![](file:///d/logo.png)Flea' or '<img src="a.png">' holds a picture; 'Flea' and 'Wow!\[beta]' hold none.
9
+ var DRAWN_PICTURE = /<img\b|!\[(?:\\.|[^\]\\])*\]\(/i
10
+
11
+ // Sample input: ['<div align="center">', '<h1>Flea</h1>', '<p>x</p>', '</div>'] at 0 answers { head, end: 3, wrapper: ['<div align="center"><p>x</p></div>'] }; a heading with no lone wrapper before it, or a wrapper that cannot be matched, answers null.
12
+ // The heading lifts out with its own align, else the wrapper's centre; what the wrapper held after it is drawn centred as it was.
13
+ function headingUnit(lines, at) {
14
+ var open = String(lines[at]).trim()
15
+ if (!HtmlImage.WRAPPER_OPEN.test(open) || at + 1 >= lines.length)
16
+ return null
17
+ var head = HtmlBlock.htmlHeading(lines[at + 1])
18
+ if (head === null)
19
+ return null
20
+ var name = MdHtml.tagHead(open).name
21
+ var tail = HtmlImage.wrapperTail(lines, at + 2, name)
22
+ if (tail === null)
23
+ return null
24
+ if (!head.aligned && HtmlImage.isCentred(open))
25
+ head.align = "center"
26
+ var shown = tail.rest.filter(function (line) { return line.length > 0 })
27
+ return { head: head, end: tail.end, wrapper: shown.length === 0 ? [] : [open + shown.join("\n") + "</" + name + ">"] }
28
+ }
29
+
30
+ // Sample input: ('<div>', 0) answers 1 and ('</div>', 1) answers 0; a line with no block tag leaves the depth as it was.
31
+ // The open block HTML a run holds after a line, so a heading is judged inside open HTML by what the lines before it left open.
32
+ function nestDepth(line, depth) {
33
+ line.replace(HtmlBlock.NESTING_TAG, function (tag, slash) {
34
+ depth = slash === "/" ? Math.max(0, depth - 1) : depth + 1
35
+ return tag
36
+ })
37
+ return depth
38
+ }
39
+
40
+ // Sample input: '<a href="https://x/"><img src="logo.png" width="120"></a><br>Flea' answers { block: the linked image, rest: 'Flea' }; text first answers null.
41
+ var HEADING_PICTURE = /^\s*(<a\b[^<>]*>)?\s*(<img\b[^<>]*>)\s*(<\/a>)?\s*(?:<br\s*\/?>\s*)*/i
42
+ // A picture opening a heading's text draws through the picture path, so it is sized and fetched there and never sits in a text line.
43
+ function headingPicture(inner, dir) {
44
+ var parts = HEADING_PICTURE.exec(inner)
45
+ if (parts === null || (parts[1] === undefined) !== (parts[3] === undefined))
46
+ return null
47
+ var block = HtmlImage.rawImage(parts[2], dir)
48
+ if (block === null)
49
+ return null
50
+ if (parts[1] !== undefined && block.type === "image" && HtmlImage.linkOf(parts[1]) !== null)
51
+ block.link = HtmlImage.linkOf(parts[1])
52
+ return { block: block, rest: inner.slice(parts[0].length) }
53
+ }