flea-qml 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +511 -2
- package/THIRD-PARTY-NOTICES.md +29 -0
- package/demos/App.java +5 -0
- package/demos/Dockerfile +4 -0
- package/demos/Main.kt +3 -0
- package/demos/Program.cs +1 -0
- package/demos/README.md +12 -0
- package/demos/app.dart +3 -0
- package/demos/app.deb +0 -0
- package/demos/app.js +1 -0
- package/demos/backup.tar +0 -0
- package/demos/budget.xlsx +0 -0
- package/demos/build.sh +2 -0
- package/demos/bundle.zip +0 -0
- package/demos/clip.mp4 +0 -0
- package/demos/data.sqlite +0 -0
- package/demos/disk.iso +0 -0
- package/demos/engine.cpp +5 -0
- package/demos/firmware.bin +0 -0
- package/demos/flake.nix +4 -0
- package/demos/folder/inside.txt +1 -0
- package/demos/font.ttf +0 -0
- package/demos/index.html +5 -0
- package/demos/index.php +2 -0
- package/demos/init.lua +1 -0
- package/demos/letter.docx +0 -0
- package/demos/lib.rs +3 -0
- package/demos/main.c +6 -0
- package/demos/main.h +3 -0
- package/demos/math-and-diagrams.md +200 -0
- package/demos/notes.tar.gz +0 -0
- package/demos/notes.txt +3 -0
- package/demos/photo.png +0 -0
- package/demos/program +2 -0
- package/demos/report.pdf +32 -0
- package/demos/script.py +1 -0
- package/demos/server.go +7 -0
- package/demos/settings.json +4 -0
- package/demos/slides.pptx +0 -0
- package/demos/song.mp3 +0 -0
- package/demos/style.css +4 -0
- package/demos/tool.rb +1 -0
- package/demos/types.ts +2 -0
- package/docs/pele.md +23 -0
- package/docs/protocol.md +3420 -0
- package/docs/temml.md +63 -0
- package/index.js +107 -0
- package/package.json +34 -4
- package/src/archive.js +407 -0
- package/src/archiveops.js +728 -0
- package/src/backend.js +369 -0
- package/src/bulkrename.js +95 -0
- package/src/clip-host.js +76 -0
- package/src/clip.js +462 -0
- package/src/code.js +168 -0
- package/src/compare.js +74 -0
- package/src/create.js +128 -0
- package/src/dirsize.js +147 -0
- package/src/figure-svg.js +530 -0
- package/src/figure-thread.js +23 -0
- package/src/figure.js +132 -0
- package/src/find.js +55 -0
- package/src/flea.js +39 -0
- package/src/fsinfo.js +39 -0
- package/src/highlight.js +141 -0
- package/src/html.js +52 -0
- package/src/kinds.js +89 -0
- package/src/listing.js +130 -0
- package/src/markdown-html.js +317 -0
- package/src/mathml.js +186 -0
- package/src/menu.js +180 -0
- package/src/meta.js +135 -0
- package/src/office.js +810 -0
- package/src/order.js +100 -0
- package/src/peek.js +49 -0
- package/src/pele-wrapper.js +695 -0
- package/src/permissions.js +180 -0
- package/src/places.js +313 -0
- package/src/preview-language.js +10 -0
- package/src/terminal-server.js +95 -0
- package/src/terminal-shell.js +26 -0
- package/src/transfer.js +669 -0
- package/src/trash-record.js +41 -0
- package/src/trash.js +210 -0
- package/src/trashbrowse.js +327 -0
- package/src/uistate.js +393 -0
- package/src/uistore.js +168 -0
- package/src/vendor/LICENSES/Apache-2.0.txt +202 -0
- package/src/vendor/LICENSES/MIT-katex-2015.txt +27 -0
- package/src/vendor/LICENSES/MIT-katex.txt +21 -0
- package/src/vendor/LICENSES/MIT-mermaid.txt +21 -0
- package/src/vendor/LICENSES/MIT-pele.txt +40 -0
- package/src/vendor/LICENSES/MIT-perseus.txt +18 -0
- package/src/vendor/LICENSES/MIT-temml.txt +21 -0
- package/src/vendor/pele.js +145 -0
- package/src/vendor/temml.mjs +14708 -0
- package/src/watch.js +98 -0
- package/src/wayland/client.js +109 -0
- package/src/wayland/protocol.js +55 -0
- package/src/wayland/protocols/ext-data-control-v1.xml +276 -0
- package/src/wayland/protocols/wayland.xml +3248 -0
- package/src/wayland/protocols/wlr-data-control-unstable-v1.xml +278 -0
- package/src/wayland/resource-io.js +6 -0
- package/src/wayland/socket-discovery.js +26 -0
- package/src/wayland/transport-posix.js +120 -0
- package/src/wayland/transport-win32.js +11 -0
- package/src/wayland/transport.js +3 -0
- package/src/wayland/win32-resources.js +80 -0
- package/src/wayland/win32-wire.js +62 -0
- package/test/archive.test.js +80 -0
- package/test/bench-markdown-scroll.mjs +190 -0
- package/test/clip-host.test.js +113 -0
- package/test/code-preview.test.js +35 -0
- package/test/compare-ui-paths.test.js +24 -0
- package/test/compare.test.js +54 -0
- package/test/delete-trash.test.js +67 -0
- package/test/dirsize.test.js +138 -0
- package/test/file-ops.test.js +307 -0
- package/test/file-url.test.js +24 -0
- package/test/find-contents.test.js +161 -0
- package/test/find-input.test.js +66 -0
- package/test/fixtures/pele-parity.json +1006 -0
- package/test/highlight-launcher.test.js +35 -0
- package/test/html-preview.test.js +22 -0
- package/test/input.test.js +15 -0
- package/test/keymap.test.js +26 -0
- package/test/language-icons.test.js +36 -0
- package/test/launcher.test.js +51 -0
- package/test/manual-archive-here-ui.mjs +47 -0
- package/test/manual-code-scroll.mjs +28 -0
- package/test/manual-column-scroll.mjs +24 -0
- package/test/manual-compare-ui.mjs +20 -0
- package/test/manual-find-status.mjs +37 -0
- package/test/manual-folder-focus.mjs +63 -0
- package/test/manual-html-security.mjs +23 -0
- package/test/manual-html-ui.mjs +30 -0
- package/test/manual-syntax-preview.mjs +26 -0
- package/test/manual-terminal-lifecycle.mjs +42 -0
- package/test/manual-terminal-navigation.mjs +48 -0
- package/test/manual-terminal-ui.mjs +47 -0
- package/test/manual-trash-ui.mjs +86 -0
- package/test/markdown-diagrams.test.js +93 -0
- package/test/markdown-html.test.js +105 -0
- package/test/mathml.test.js +92 -0
- package/test/menu-transfer.test.js +57 -0
- package/test/office-preview.test.js +154 -0
- package/test/pele-parity.test.js +28 -0
- package/test/places.test.js +134 -0
- package/test/preview-keys.test.js +60 -0
- package/test/preview-language.test.js +22 -0
- package/test/status-filename.test.js +20 -0
- package/test/transfer-replace-merge.test.js +187 -0
- package/test/trash-address.test.js +23 -0
- package/test/trash-view.test.js +37 -0
- package/test/trashbrowse.test.js +135 -0
- package/ui/AboutFacts.qml +78 -0
- package/ui/ArchiveCards.qml +95 -0
- package/ui/ArchiveCompressDialog.qml +378 -0
- package/ui/ArchiveHereConfirm.qml +127 -0
- package/ui/ArchivePasswordDialog.qml +257 -0
- package/ui/Backend.qml +775 -0
- package/ui/BulkOldNames.qml +47 -0
- package/ui/BulkRenameDialog.qml +380 -0
- package/ui/CardFrame.qml +67 -0
- package/ui/CardScroll.qml +79 -0
- package/ui/CheckBox.qml +73 -0
- package/ui/ChromeBar.qml +360 -0
- package/ui/ChromeButton.qml +131 -0
- package/ui/ChromeModes.qml +43 -0
- package/ui/CodeLines.qml +256 -0
- package/ui/CodeRefusal.qml +52 -0
- package/ui/CollideConfirm.qml +147 -0
- package/ui/CollideHost.qml +167 -0
- package/ui/ColumnPane.qml +525 -0
- package/ui/ColumnRow.qml +380 -0
- package/ui/ColumnsArea.qml +594 -0
- package/ui/ColumnsLanding.qml +147 -0
- package/ui/CompareView.qml +321 -0
- package/ui/ContextMenu.qml +743 -0
- package/ui/ConvertDialog.qml +456 -0
- package/ui/CountedWorker.qml +7 -0
- package/ui/Crumb.qml +64 -0
- package/ui/CrumbDrop.qml +25 -0
- package/ui/CsvTable.qml +394 -0
- package/ui/CursorMark.qml +41 -0
- package/ui/DefaultClaim.qml +130 -0
- package/ui/DeviceLock.qml +47 -0
- package/ui/DeviceMounts.qml +540 -0
- package/ui/DialogButton.qml +150 -0
- package/ui/DialogField.qml +147 -0
- package/ui/DialogHeader.qml +31 -0
- package/ui/DialogScrim.qml +20 -0
- package/ui/DialogTitle.qml +37 -0
- package/ui/Divider.qml +9 -0
- package/ui/DropInto.qml +126 -0
- package/ui/DropTarget.qml +35 -0
- package/ui/DropboxMark.qml +60 -0
- package/ui/EmptyState.qml +150 -0
- package/ui/EscapeHint.qml +11 -0
- package/ui/FactsTable.qml +54 -0
- package/ui/FastScrollHandler.qml +476 -0
- package/ui/FatNamesConfirm.qml +157 -0
- package/ui/Favourites.qml +143 -0
- package/ui/FigureService.qml +120 -0
- package/ui/FileDrag.qml +267 -0
- package/ui/FilterStrip.qml +133 -0
- package/ui/FitMetrics.qml +22 -0
- package/ui/FlashDriveRows.qml +137 -0
- package/ui/FlashHost.qml +72 -0
- package/ui/FlashImageRow.qml +104 -0
- package/ui/FlashRunner.qml +119 -0
- package/ui/FlashStepRow.qml +172 -0
- package/ui/FlashStrip.qml +38 -0
- package/ui/FlashView.qml +397 -0
- package/ui/FleaMark.qml +88 -0
- package/ui/FlyoutFade.qml +23 -0
- package/ui/FontPane.qml +170 -0
- package/ui/Glass.qml +114 -0
- package/ui/GlassTagger.qml +59 -0
- package/ui/Glyph.qml +64 -0
- package/ui/GlyphSolid.qml +22 -0
- package/ui/GridArea.qml +664 -0
- package/ui/GridTile.qml +325 -0
- package/ui/GvfsBridge.qml +164 -0
- package/ui/Header.qml +433 -0
- package/ui/HoverTimers.qml +39 -0
- package/ui/HtmlClip.qml +30 -0
- package/ui/HtmlPane.qml +63 -0
- package/ui/HyprlandMark.qml +45 -0
- package/ui/Ipc.qml +1005 -0
- package/ui/IpcControls.qml +7 -0
- package/ui/IpcMenuState.qml +48 -0
- package/ui/IpcPreviewState.qml +185 -0
- package/ui/JumpPath.qml +51 -0
- package/ui/KeymapSheet.qml +561 -0
- package/ui/KeymapSheetResult.qml +89 -0
- package/ui/KindStack.qml +40 -0
- package/ui/LangMark.qml +51 -0
- package/ui/LangMarkLoader.qml +26 -0
- package/ui/List.qml +480 -0
- package/ui/LoadingState.qml +54 -0
- package/ui/LocalSend.qml +56 -0
- package/ui/LocalSendMark.qml +73 -0
- package/ui/MarkdownBlockView.qml +311 -0
- package/ui/MarkdownBlocks.qml +35 -0
- package/ui/MarkdownFigure.qml +254 -0
- package/ui/MarkdownImages.qml +72 -0
- package/ui/MarkdownList.qml +81 -0
- package/ui/MarkdownMathsText.qml +97 -0
- package/ui/MarkdownPane.qml +83 -0
- package/ui/MarkdownPictures.qml +41 -0
- package/ui/MarkdownQuote.qml +52 -0
- package/ui/MarkdownRemote.qml +82 -0
- package/ui/MarkdownSource.qml +155 -0
- package/ui/MarkdownTable.qml +222 -0
- package/ui/MarkdownTableScroll.qml +64 -0
- package/ui/MarkdownTableWheel.qml +126 -0
- package/ui/MarkdownText.qml +87 -0
- package/ui/MarkdownWorker.js +132 -0
- package/ui/MatchText.qml +99 -0
- package/ui/MediaSession.qml +38 -0
- package/ui/MediaSound.qml +26 -0
- package/ui/MediaStrip.qml +191 -0
- package/ui/MediaTrack.qml +36 -0
- package/ui/MediaVolume.qml +54 -0
- package/ui/MenuActionDialog.qml +396 -0
- package/ui/MenuEdgeFade.qml +24 -0
- package/ui/MenuHost.qml +227 -0
- package/ui/MenuRow.qml +351 -0
- package/ui/MountListing.qml +100 -0
- package/ui/NetworkDialog.qml +435 -0
- package/ui/NetworkForm.qml +426 -0
- package/ui/NetworkMounts.qml +913 -0
- package/ui/NetworkPlaces.qml +127 -0
- package/ui/OpenWithDialog.qml +613 -0
- package/ui/Opener.qml +95 -0
- package/ui/Pane.qml +1320 -0
- package/ui/PaneMenuActions.qml +527 -0
- package/ui/PanePath.qml +90 -0
- package/ui/PaneRail.qml +268 -0
- package/ui/PaneStates.qml +88 -0
- package/ui/PaneSwap.qml +339 -0
- package/ui/PaneWire.qml +601 -0
- package/ui/ParkedWait.qml +9 -0
- package/ui/PathEntry.qml +186 -0
- package/ui/PathJump.qml +400 -0
- package/ui/PdfViewer.qml +297 -0
- package/ui/PermissionsDialog.qml +658 -0
- package/ui/PermissionsHeadings.qml +31 -0
- package/ui/PhoneMounts.qml +67 -0
- package/ui/PickerAnswers.qml +75 -0
- package/ui/PickerBox.qml +26 -0
- package/ui/PickerChrome.qml +295 -0
- package/ui/PickerFilter.qml +97 -0
- package/ui/PickerGrid.qml +308 -0
- package/ui/PickerHeader.qml +28 -0
- package/ui/PickerLifecycle.qml +27 -0
- package/ui/PickerList.qml +218 -0
- package/ui/PickerListing.qml +149 -0
- package/ui/PickerPathBar.qml +127 -0
- package/ui/PickerPlaces.qml +189 -0
- package/ui/PickerRecent.qml +92 -0
- package/ui/PickerSave.qml +101 -0
- package/ui/PickerSelection.qml +155 -0
- package/ui/PickerWindow.qml +846 -0
- package/ui/PowerSectorsReader.qml +10 -0
- package/ui/PrebuildDriver.qml +146 -0
- package/ui/Preview.qml +1005 -0
- package/ui/PreviewAnimation.qml +24 -0
- package/ui/PreviewArchive.qml +91 -0
- package/ui/PreviewColumn.qml +553 -0
- package/ui/PreviewEdge.qml +63 -0
- package/ui/PreviewFacts.qml +30 -0
- package/ui/PreviewFactsLine.qml +34 -0
- package/ui/PreviewHtml.qml +233 -0
- package/ui/PreviewImage.qml +253 -0
- package/ui/PreviewImagePan.qml +13 -0
- package/ui/PreviewImageSharp.qml +32 -0
- package/ui/PreviewLines.qml +106 -0
- package/ui/PreviewMarkdown.qml +706 -0
- package/ui/PreviewMedia.qml +250 -0
- package/ui/PreviewPdf.qml +482 -0
- package/ui/PreviewScroll.qml +201 -0
- package/ui/PreviewSwap.qml +335 -0
- package/ui/PreviewText.qml +149 -0
- package/ui/ProtocolChip.qml +18 -0
- package/ui/QuickLookArchive.qml +41 -0
- package/ui/QuickLookBar.qml +103 -0
- package/ui/QuickLookPrepare.qml +355 -0
- package/ui/QuickLookSwap.qml +10 -0
- package/ui/QuickLookWarm.qml +65 -0
- package/ui/RailDrop.qml +155 -0
- package/ui/RailHeading.qml +19 -0
- package/ui/RailPlaces.qml +38 -0
- package/ui/RailTrashRow.qml +67 -0
- package/ui/RenameField.qml +353 -0
- package/ui/RendererRetry.qml +11 -0
- package/ui/ResizeHandle.qml +52 -0
- package/ui/Reveal.qml +54 -0
- package/ui/Row.qml +476 -0
- package/ui/RowDrag.qml +213 -0
- package/ui/RowDropTarget.qml +27 -0
- package/ui/RunCard.qml +286 -0
- package/ui/Scripts.qml +65 -0
- package/ui/SearchStrip.qml +232 -0
- package/ui/SelectionBand.qml +140 -0
- package/ui/SelectionPreview.qml +370 -0
- package/ui/SettingsFavourite.qml +122 -0
- package/ui/SettingsGroup.qml +96 -0
- package/ui/SettingsHint.qml +12 -0
- package/ui/SettingsMetrics.qml +29 -0
- package/ui/SettingsPane.qml +178 -0
- package/ui/SettingsPanel.qml +547 -0
- package/ui/SettingsRail.qml +128 -0
- package/ui/SettingsRow.qml +409 -0
- package/ui/SettingsRuler.qml +85 -0
- package/ui/SettingsSegment.qml +85 -0
- package/ui/ShareBrowser.qml +113 -0
- package/ui/ShareLink.qml +67 -0
- package/ui/ShelfPins.qml +101 -0
- package/ui/Sidebar.qml +728 -0
- package/ui/SidebarRow.qml +358 -0
- package/ui/Spinner.qml +60 -0
- package/ui/StableModel.qml +89 -0
- package/ui/StateMessage.qml +84 -0
- package/ui/StatusBar.qml +512 -0
- package/ui/StatusFileName.qml +27 -0
- package/ui/TabBar.qml +673 -0
- package/ui/TabDragGeometry.qml +60 -0
- package/ui/TagMenuMark.qml +52 -0
- package/ui/TagRailSection.qml +53 -0
- package/ui/TagSlot.qml +40 -0
- package/ui/TagState.qml +150 -0
- package/ui/TagSwatch.qml +28 -0
- package/ui/Taildrop.qml +86 -0
- package/ui/TailscaleMark.qml +50 -0
- package/ui/TerminalService.qml +69 -0
- package/ui/TerminalTab.qml +48 -0
- package/ui/TerminalTabs.qml +27 -0
- package/ui/Theme.qml +460 -0
- package/ui/ThemeColors.qml +43 -0
- package/ui/TransferCard.qml +239 -0
- package/ui/TrashConfirm.qml +129 -0
- package/ui/TrashDropHandler.qml +11 -0
- package/ui/TrashHost.qml +202 -0
- package/ui/TrashMonitor.qml +30 -0
- package/ui/TrashToolbar.qml +19 -0
- package/ui/TrashView.qml +492 -0
- package/ui/UnlockDialog.qml +450 -0
- package/ui/UnlockHost.qml +206 -0
- package/ui/UpdateCheck.qml +97 -0
- package/ui/UserDirs.qml +25 -0
- package/ui/ViewState.qml +565 -0
- package/ui/ViewportScrollBar.qml +195 -0
- package/ui/ViewportScrollBars.qml +25 -0
- package/ui/WebPreview.qml +33 -0
- package/ui/WebPreviewView.qml +26 -0
- package/ui/WindowBody.qml +829 -0
- package/ui/WindowDrag.qml +35 -0
- package/ui/boot/Commons/AudioNodes.qml +50 -0
- package/ui/boot/Commons/AudioNodesModel.js +96 -0
- package/ui/boot/Commons/Border.qml +243 -0
- package/ui/boot/Commons/BorderGeometry.js +373 -0
- package/ui/boot/Commons/Color.qml +258 -0
- package/ui/boot/Commons/I18n.qml +118 -0
- package/ui/boot/Commons/InputDevices.qml +112 -0
- package/ui/boot/Commons/InputMethodState.qml +38 -0
- package/ui/boot/Commons/IpcRegistry.qml +77 -0
- package/ui/boot/Commons/Numbers.js +19 -0
- package/ui/boot/Commons/Plural.js +91 -0
- package/ui/boot/Commons/ShellIpc.qml +12 -0
- package/ui/boot/Commons/Style.qml +561 -0
- package/ui/boot/Commons/Translations.qml +100 -0
- package/ui/boot/Commons/UntypedInput.qml +152 -0
- package/ui/boot/Commons/Util.qml +188 -0
- package/ui/boot/Commons/qmldir +13 -0
- package/ui/boot/LICENSE-omarchy +20 -0
- package/ui/boot/Ui/BackgroundMedia.qml +49 -0
- package/ui/boot/Ui/BarIconButton.qml +106 -0
- package/ui/boot/Ui/BarIconContent.qml +38 -0
- package/ui/boot/Ui/BarIndicator.qml +53 -0
- package/ui/boot/Ui/BarWidget.qml +50 -0
- package/ui/boot/Ui/BorderOverlay.qml +54 -0
- package/ui/boot/Ui/BorderSurface.qml +40 -0
- package/ui/boot/Ui/Button.qml +224 -0
- package/ui/boot/Ui/ButtonGroup.qml +131 -0
- package/ui/boot/Ui/ConfirmDialog.qml +134 -0
- package/ui/boot/Ui/CursorSurface.qml +42 -0
- package/ui/boot/Ui/Dropdown.qml +245 -0
- package/ui/boot/Ui/FilterInput.qml +26 -0
- package/ui/boot/Ui/IconContentBounds.qml +141 -0
- package/ui/boot/Ui/KeyboardPanel.qml +453 -0
- package/ui/boot/Ui/MultiSelect.qml +624 -0
- package/ui/boot/Ui/NumberField.qml +86 -0
- package/ui/boot/Ui/OpticalGlyph.qml +68 -0
- package/ui/boot/Ui/OverlayWindow.qml +102 -0
- package/ui/boot/Ui/Panel.qml +60 -0
- package/ui/boot/Ui/PanelActionButton.qml +105 -0
- package/ui/boot/Ui/PanelController.qml +16 -0
- package/ui/boot/Ui/PanelHero.qml +112 -0
- package/ui/boot/Ui/PanelKeyCatcher.qml +100 -0
- package/ui/boot/Ui/PanelSectionHeader.qml +31 -0
- package/ui/boot/Ui/PanelSeparator.qml +19 -0
- package/ui/boot/Ui/PanelSlider.qml +156 -0
- package/ui/boot/Ui/PanelToolTip.qml +50 -0
- package/ui/boot/Ui/PluginBarApi.qml +89 -0
- package/ui/boot/Ui/PointerMoveGate.qml +54 -0
- package/ui/boot/Ui/PopupCard.qml +181 -0
- package/ui/boot/Ui/ScreenMoveRemap.qml +43 -0
- package/ui/boot/Ui/SearchableDropdown.qml +354 -0
- package/ui/boot/Ui/SizedImage.qml +125 -0
- package/ui/boot/Ui/SpeedTestOverlay.qml +412 -0
- package/ui/boot/Ui/TextField.qml +58 -0
- package/ui/boot/Ui/Toggle.qml +118 -0
- package/ui/boot/Ui/ToggleSwitch.qml +115 -0
- package/ui/boot/Ui/WidgetButton.qml +172 -0
- package/ui/boot/Ui/qmldir +41 -0
- package/ui/boot/fleatab.qml +50 -0
- package/ui/boot/picker.qml +39 -0
- package/ui/boot/shell.qml +131 -0
- package/ui/boot/tabtearoff.qml +51 -0
- package/ui/js/Anchor.js +379 -0
- package/ui/js/AnchorHold.js +162 -0
- package/ui/js/Archive.js +157 -0
- package/ui/js/ArchiveCard.js +44 -0
- package/ui/js/ArchiveOps.js +44 -0
- package/ui/js/BackReturn.js +118 -0
- package/ui/js/BulkRename.js +100 -0
- package/ui/js/Buttons.js +54 -0
- package/ui/js/ChromeKeys.js +116 -0
- package/ui/js/ClipMarks.js +73 -0
- package/ui/js/ClipSelection.js +67 -0
- package/ui/js/Clipboard.js +179 -0
- package/ui/js/Cloud.js +97 -0
- package/ui/js/CodeRuns.js +72 -0
- package/ui/js/Collide.js +212 -0
- package/ui/js/ColumnFit.js +28 -0
- package/ui/js/ColumnMenu.js +111 -0
- package/ui/js/Columns.js +298 -0
- package/ui/js/ColumnsCarry.js +103 -0
- package/ui/js/Compare.js +74 -0
- package/ui/js/Contrast.js +157 -0
- package/ui/js/ControlReader.js +42 -0
- package/ui/js/Convert.js +52 -0
- package/ui/js/CopyAs.js +52 -0
- package/ui/js/Crumbs.js +178 -0
- package/ui/js/Csv.js +231 -0
- package/ui/js/Density.js +44 -0
- package/ui/js/Devices.js +440 -0
- package/ui/js/DirSizes.js +180 -0
- package/ui/js/Drag.js +360 -0
- package/ui/js/DragOut.js +166 -0
- package/ui/js/DropDev.js +52 -0
- package/ui/js/Dropbox.js +41 -0
- package/ui/js/Eject.js +217 -0
- package/ui/js/Errors.js +188 -0
- package/ui/js/ExtThumbs.js +115 -0
- package/ui/js/Facts.js +402 -0
- package/ui/js/FigureDate.js +14 -0
- package/ui/js/Filter.js +285 -0
- package/ui/js/Find.js +46 -0
- package/ui/js/Flash.js +184 -0
- package/ui/js/FlashCard.js +79 -0
- package/ui/js/FlashEndings.js +125 -0
- package/ui/js/FlashPane.js +116 -0
- package/ui/js/FleaBin.js +12 -0
- package/ui/js/Focus.js +504 -0
- package/ui/js/FolderSorts.js +108 -0
- package/ui/js/FolderViews.js +44 -0
- package/ui/js/Format.js +314 -0
- package/ui/js/Fuzzy.js +141 -0
- package/ui/js/GlassTag.js +72 -0
- package/ui/js/Grid.js +33 -0
- package/ui/js/GridGeometry.js +90 -0
- package/ui/js/GridNames.js +153 -0
- package/ui/js/GvfsBridge.js +200 -0
- package/ui/js/HostClipboard.js +29 -0
- package/ui/js/Icons.js +218 -0
- package/ui/js/Input.js +50 -0
- package/ui/js/Jump.js +200 -0
- package/ui/js/KeyName.js +64 -0
- package/ui/js/Keymap.js +401 -0
- package/ui/js/Kinds.js +164 -0
- package/ui/js/LICENSES/ISC-lucide.txt +43 -0
- package/ui/js/LangMarkPaths.js +47 -0
- package/ui/js/LangMarks.js +120 -0
- package/ui/js/Lists.js +11 -0
- package/ui/js/LocalSend.js +39 -0
- package/ui/js/LockedMenu.js +63 -0
- package/ui/js/MakeDefault.js +186 -0
- package/ui/js/MarkBox.js +7 -0
- package/ui/js/Markdown.js +119 -0
- package/ui/js/MarkdownLists.js +86 -0
- package/ui/js/MarkdownMaths.js +58 -0
- package/ui/js/MarkdownPictures.js +32 -0
- package/ui/js/MarkdownPrepared.js +139 -0
- package/ui/js/MarkdownTableFit.js +34 -0
- package/ui/js/Marks.js +148 -0
- package/ui/js/Marquee.js +96 -0
- package/ui/js/Match.js +93 -0
- package/ui/js/Material.js +109 -0
- package/ui/js/MdBlocks.js +437 -0
- package/ui/js/MdBreak.js +71 -0
- package/ui/js/MdChunks.js +70 -0
- package/ui/js/MdContainer.js +137 -0
- package/ui/js/MdDocument.js +337 -0
- package/ui/js/MdEmph.js +97 -0
- package/ui/js/MdEntity.js +108 -0
- package/ui/js/MdEntityTable.js +223 -0
- package/ui/js/MdEscape.js +59 -0
- package/ui/js/MdFront.js +37 -0
- package/ui/js/MdHold.js +32 -0
- package/ui/js/MdHtml.js +307 -0
- package/ui/js/MdHtmlBlock.js +290 -0
- package/ui/js/MdHtmlHeading.js +53 -0
- package/ui/js/MdHtmlImage.js +179 -0
- package/ui/js/MdInline.js +154 -0
- package/ui/js/MdItems.js +212 -0
- package/ui/js/MdLeaf.js +309 -0
- package/ui/js/MdLink.js +196 -0
- package/ui/js/MdMath.js +67 -0
- package/ui/js/MdParagraphs.js +138 -0
- package/ui/js/MdRefs.js +232 -0
- package/ui/js/MdResolve.js +226 -0
- package/ui/js/MdRun.js +300 -0
- package/ui/js/MdUrl.js +226 -0
- package/ui/js/Menu.js +514 -0
- package/ui/js/MenuContext.js +85 -0
- package/ui/js/MenuFit.js +13 -0
- package/ui/js/MenuRefresh.js +74 -0
- package/ui/js/MenuWheel.js +35 -0
- package/ui/js/Messages.js +186 -0
- package/ui/js/Motion.js +16 -0
- package/ui/js/Mounts.js +320 -0
- package/ui/js/MouseNav.js +13 -0
- package/ui/js/Nav.js +329 -0
- package/ui/js/NetFs.js +26 -0
- package/ui/js/OpenWith.js +83 -0
- package/ui/js/Ops.js +585 -0
- package/ui/js/Palette.js +33 -0
- package/ui/js/PathBar.js +260 -0
- package/ui/js/Permissions.js +179 -0
- package/ui/js/Phones.js +112 -0
- package/ui/js/Picker.js +353 -0
- package/ui/js/PlaceMenu.js +96 -0
- package/ui/js/Places.js +265 -0
- package/ui/js/PreviewAsk.js +21 -0
- package/ui/js/PreviewKeys.js +155 -0
- package/ui/js/PreviewSettle.js +29 -0
- package/ui/js/PreviewSwap.js +101 -0
- package/ui/js/PropertyFacts.js +144 -0
- package/ui/js/Protocols.js +296 -0
- package/ui/js/QuickLookKinds.js +27 -0
- package/ui/js/QuickLookRect.js +24 -0
- package/ui/js/RailDrop.js +51 -0
- package/ui/js/RailKeys.js +87 -0
- package/ui/js/RailMenu.js +133 -0
- package/ui/js/Recent.js +135 -0
- package/ui/js/RecentMode.js +156 -0
- package/ui/js/Reload.js +60 -0
- package/ui/js/Renderer.js +9 -0
- package/ui/js/RunFile.js +143 -0
- package/ui/js/Scripts.js +28 -0
- package/ui/js/Scroll.js +304 -0
- package/ui/js/ScrollOff.js +69 -0
- package/ui/js/Search.js +478 -0
- package/ui/js/Selection.js +97 -0
- package/ui/js/Settings.js +476 -0
- package/ui/js/SettingsAbout.js +97 -0
- package/ui/js/SettingsShelf.js +52 -0
- package/ui/js/SheetKeys.js +42 -0
- package/ui/js/SheetQuery.js +281 -0
- package/ui/js/ShelfPile.js +27 -0
- package/ui/js/SlowClick.js +53 -0
- package/ui/js/SlowOp.js +6 -0
- package/ui/js/Sort.js +134 -0
- package/ui/js/Startup.js +63 -0
- package/ui/js/StateWords.js +17 -0
- package/ui/js/Status.js +238 -0
- package/ui/js/Swap.js +166 -0
- package/ui/js/TabMove.js +39 -0
- package/ui/js/Tabs.js +751 -0
- package/ui/js/Tags.js +134 -0
- package/ui/js/Taildrop.js +128 -0
- package/ui/js/Tap.js +180 -0
- package/ui/js/TextSize.js +107 -0
- package/ui/js/Thumbs.js +158 -0
- package/ui/js/Transfer.js +172 -0
- package/ui/js/Trash.js +84 -0
- package/ui/js/TrashDates.js +47 -0
- package/ui/js/TrashDrop.js +64 -0
- package/ui/js/UiState.js +438 -0
- package/ui/js/Unlock.js +152 -0
- package/ui/js/Update.js +130 -0
- package/ui/js/UserDirs.js +56 -0
- package/ui/qmldir +230 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Search.js" as Search
|
|
4
|
+
|
|
5
|
+
// The mark follows the pane's own clipboard, so spending a cut clears every mark at once.
|
|
6
|
+
|
|
7
|
+
// Sample input: { paths: ["/home/gm/Pictures/phone/IMG_4121.jpg"], moving: true }
|
|
8
|
+
var _cached = null
|
|
9
|
+
var _marks = {}
|
|
10
|
+
// Counts rows reaching the library; production ignores it, tests/listcost.qml asserts on it.
|
|
11
|
+
var markCalls = 0
|
|
12
|
+
|
|
13
|
+
// One keyed lookup per clipboard, rebuilt when the clipboard object changes; every row after that is a single key read.
|
|
14
|
+
function setFor(clipboard) {
|
|
15
|
+
if (clipboard === _cached)
|
|
16
|
+
return _marks
|
|
17
|
+
_cached = clipboard
|
|
18
|
+
_marks = {}
|
|
19
|
+
var paths = (clipboard && clipboard.paths) || []
|
|
20
|
+
for (var i = 0; i < paths.length; i++)
|
|
21
|
+
_marks[paths[i]] = true
|
|
22
|
+
return _marks
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// An emptied clipboard drops its lookup once, so a cut of a large directory frees it and later rows allocate nothing.
|
|
26
|
+
function release() {
|
|
27
|
+
if (_cached === null) return
|
|
28
|
+
_cached = null
|
|
29
|
+
_marks = {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Sample input: { paths: [], moving: false } is empty, null is empty.
|
|
33
|
+
function isEmpty(clipboard) {
|
|
34
|
+
return !clipboard || !clipboard.paths || clipboard.paths.length === 0
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function markFor(path, clipboard) {
|
|
38
|
+
if (isEmpty(clipboard)) {
|
|
39
|
+
release()
|
|
40
|
+
return ""
|
|
41
|
+
}
|
|
42
|
+
return setFor(clipboard)[path] === true ? (clipboard.moving ? "scissors" : "copy") : ""
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// An empty clipboard costs nothing: its paths are never joined or searched.
|
|
46
|
+
function markForRow(pane, name, clipboard) {
|
|
47
|
+
markCalls += 1
|
|
48
|
+
if (isEmpty(clipboard)) {
|
|
49
|
+
release()
|
|
50
|
+
return ""
|
|
51
|
+
}
|
|
52
|
+
if (!name) {
|
|
53
|
+
return ""
|
|
54
|
+
}
|
|
55
|
+
return markFor(rowPath(pane, name), clipboard)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The pane's own join under the listing's base, so a search result resolves against the scope its search walked.
|
|
59
|
+
// Sample input: pane { path: "/home/gm/Pictures/phone" }, name "IMG_4121.jpg".
|
|
60
|
+
function rowPath(pane, name) {
|
|
61
|
+
if (!name) {
|
|
62
|
+
return ""
|
|
63
|
+
}
|
|
64
|
+
return pane.join(Search.baseOf(pane), name)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// A sent cut empties a cut clipboard, so the marks go with it; anything else keeps it. ui/CollideHost.qml decides through this.
|
|
68
|
+
function spent(clipboard, spendsCut) {
|
|
69
|
+
if (spendsCut === true && clipboard && clipboard.moving === true) {
|
|
70
|
+
return { paths: [], moving: false }
|
|
71
|
+
}
|
|
72
|
+
return clipboard
|
|
73
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Clipboard.js" as Clipboard
|
|
4
|
+
|
|
5
|
+
function publish(pane, request, copied) {
|
|
6
|
+
if (request.sequence !== pane.clipSequence) return
|
|
7
|
+
Clipboard.set(pane, request.paths, request.moving)
|
|
8
|
+
pane.message(copied(request.paths.length, request.moving), false)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Untagged paths replies resolve one queued request at a time; only the newest choice publishes.
|
|
12
|
+
function drain(pane) {
|
|
13
|
+
if (pane.clipPending !== null) return
|
|
14
|
+
var queue = (pane.clipQueue || []).slice()
|
|
15
|
+
while (queue.length) {
|
|
16
|
+
var request = queue[0]
|
|
17
|
+
if (request.paths !== null || request.sequence !== pane.clipSequence) {
|
|
18
|
+
queue.shift()
|
|
19
|
+
continue
|
|
20
|
+
}
|
|
21
|
+
if (request.path !== pane.path || request.listing !== pane.backend.heldListing || pane.listInFlight) {
|
|
22
|
+
queue.shift()
|
|
23
|
+
pane.message("Selected items changed; copy or cut again.", false)
|
|
24
|
+
continue
|
|
25
|
+
}
|
|
26
|
+
pane.clipQueue = queue
|
|
27
|
+
pane.clipPending = request
|
|
28
|
+
pane.backend.askPaths(request.rows)
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
pane.clipQueue = queue
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function take(pane, moving, paths, indices, copied) {
|
|
35
|
+
pane.clipSequence = (pane.clipSequence || 0) + 1
|
|
36
|
+
var request = { sequence: pane.clipSequence, moving: moving, paths: paths ? paths.slice() : null,
|
|
37
|
+
rows: paths ? null : indices.slice(), path: pane.path, listing: pane.backend.heldListing }
|
|
38
|
+
pane.clipQueue = (pane.clipQueue || []).concat([request])
|
|
39
|
+
if (request.paths !== null) publish(pane, request, copied)
|
|
40
|
+
drain(pane)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function resolved(pane, list, copied) {
|
|
44
|
+
if (pane.clipPending === null) return
|
|
45
|
+
var sequence = pane.clipPending.sequence
|
|
46
|
+
var queue = (pane.clipQueue || []).slice()
|
|
47
|
+
for (var i = 0; i < queue.length; i++) {
|
|
48
|
+
if (queue[i].sequence !== sequence) continue
|
|
49
|
+
var request = Object.assign({}, queue[i], { paths: list.slice() })
|
|
50
|
+
queue[i] = request
|
|
51
|
+
publish(pane, request, copied)
|
|
52
|
+
break
|
|
53
|
+
}
|
|
54
|
+
pane.clipQueue = queue
|
|
55
|
+
pane.clipPending = null
|
|
56
|
+
drain(pane)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function failed(pane) {
|
|
60
|
+
if (pane.clipPending === null) return
|
|
61
|
+
var sequence = pane.clipPending.sequence
|
|
62
|
+
pane.clipQueue = (pane.clipQueue || []).filter(function (request) {
|
|
63
|
+
return request.sequence !== sequence
|
|
64
|
+
})
|
|
65
|
+
pane.clipPending = null
|
|
66
|
+
drain(pane)
|
|
67
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "ClipMarks.js" as ClipMarks
|
|
4
|
+
.import "Menu.js" as Menu
|
|
5
|
+
.import "Format.js" as Format
|
|
6
|
+
|
|
7
|
+
// Whole sentences with "%1" for a value, filled by fill so each translates as one.
|
|
8
|
+
var WORDS = {
|
|
9
|
+
setFailed: "Copied in this window only: %1",
|
|
10
|
+
clearFailed: "Could not clear the system clipboard: %1"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function empty() { return { paths: [], moving: false, token: "" } }
|
|
14
|
+
function state() {
|
|
15
|
+
return { sets: [], ownTokens: Object.create(null), generation: 0, failed: [], gets: [], deferred: null,
|
|
16
|
+
getSequence: 0, acceptedGetSequence: 0 }
|
|
17
|
+
}
|
|
18
|
+
function session(pane) {
|
|
19
|
+
if (!pane.clipboardState) pane.clipboardState = state()
|
|
20
|
+
return pane.clipboardState
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function set(pane, paths, moving) {
|
|
24
|
+
var s = session(pane)
|
|
25
|
+
s.generation += 1
|
|
26
|
+
s.deferred = null
|
|
27
|
+
var clip = { paths: paths, moving: moving, token: "" }
|
|
28
|
+
pane.clipboard = clip
|
|
29
|
+
s.sets.push({ pane: pane, backend: pane.backend, clip: clip })
|
|
30
|
+
pane.backend.send({ c: "clipSet", op: moving ? "cut" : "copy", paths: paths })
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function take(queue, backend) {
|
|
34
|
+
for (var i = 0; i < queue.length; i++) {
|
|
35
|
+
if (queue[i].backend === backend) return queue.splice(i, 1)[0]
|
|
36
|
+
}
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function replace(pane, message) {
|
|
41
|
+
pane.clipboard = message.clip === "copy" || message.clip === "cut"
|
|
42
|
+
? { paths: message.paths || [], moving: message.clip === "cut", token: message.token || "" }
|
|
43
|
+
: empty()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function pendingEcho(s, message) {
|
|
47
|
+
if (!message.token) return false
|
|
48
|
+
var paths = message.paths || []
|
|
49
|
+
for (var i = 0; i < s.sets.length; i++) {
|
|
50
|
+
var clip = s.sets[i].clip
|
|
51
|
+
if (clip.moving !== (message.clip === "cut") || clip.paths.length !== paths.length) continue
|
|
52
|
+
var equal = true
|
|
53
|
+
for (var j = 0; j < clip.paths.length; j++) {
|
|
54
|
+
if (clip.paths[j] !== paths[j]) {
|
|
55
|
+
equal = false
|
|
56
|
+
break
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (equal) return true
|
|
60
|
+
}
|
|
61
|
+
return false
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function selection(pane, message, s) {
|
|
65
|
+
s.deferred = null
|
|
66
|
+
if (message.token && s.ownTokens[message.token]) return
|
|
67
|
+
// A watcher can see our owner before set answers with its token.
|
|
68
|
+
if (pendingEcho(s, message)) { s.deferred = {pane: pane, message: message}; return }
|
|
69
|
+
s.generation += 1
|
|
70
|
+
replace(pane, message)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function receive(pane, message) {
|
|
74
|
+
var s = session(pane)
|
|
75
|
+
if (message.op === "set") {
|
|
76
|
+
var entry = take(s.sets, pane.backend)
|
|
77
|
+
if (!entry) return
|
|
78
|
+
if (!message.ok) {
|
|
79
|
+
// The copy itself worked, inside this window: a notice, so the paste's own result line is not held under it.
|
|
80
|
+
entry.pane.message(Format.fill(WORDS.setFailed, message.error), false)
|
|
81
|
+
} else {
|
|
82
|
+
// Both panes can echo any earlier owner after a later set has answered.
|
|
83
|
+
if (message.token) s.ownTokens[message.token] = true
|
|
84
|
+
// The collision card may already hold this cut, so its snapshot keeps the token too.
|
|
85
|
+
entry.clip.token = message.token
|
|
86
|
+
if (pane.clipboard === entry.clip)
|
|
87
|
+
pane.clipboard = { paths: entry.clip.paths, moving: entry.clip.moving, token: message.token }
|
|
88
|
+
}
|
|
89
|
+
var deferred = s.deferred
|
|
90
|
+
if (deferred) {
|
|
91
|
+
s.deferred = null
|
|
92
|
+
selection(deferred.pane, deferred.message, s)
|
|
93
|
+
}
|
|
94
|
+
} else if (message.op === "changed") {
|
|
95
|
+
var index = s.failed.indexOf(pane.backend)
|
|
96
|
+
pane.clipboardWatchFailed = !!message.error
|
|
97
|
+
if (message.error) {
|
|
98
|
+
if (index < 0) s.failed.push(pane.backend)
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
if (index >= 0) s.failed.splice(index, 1)
|
|
102
|
+
selection(pane, message, s)
|
|
103
|
+
} else if (message.op === "get") {
|
|
104
|
+
var waiting = take(s.gets, pane.backend)
|
|
105
|
+
if (!waiting) return
|
|
106
|
+
// A local set, newer watcher selection or later accepted read outranks this reply.
|
|
107
|
+
if (message.ok && s.sets.length === 0 && waiting.generation === s.generation
|
|
108
|
+
&& waiting.sequence > s.acceptedGetSequence) {
|
|
109
|
+
s.acceptedGetSequence = waiting.sequence
|
|
110
|
+
replace(pane, message)
|
|
111
|
+
}
|
|
112
|
+
waiting.ready()
|
|
113
|
+
} else if (message.op === "clear" && message.ok === false) {
|
|
114
|
+
pane.message(Format.fill(WORDS.clearFailed, message.error), true)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function read(pane, ready) {
|
|
119
|
+
var s = session(pane)
|
|
120
|
+
if (s.sets.length > 0 || s.failed.indexOf(pane.backend) < 0) {
|
|
121
|
+
ready()
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
for (var i = 0; i < s.gets.length; i++) {
|
|
125
|
+
if (s.gets[i].backend === pane.backend) {
|
|
126
|
+
pane.message("Still reading the clipboard; try again.", false)
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
s.getSequence += 1
|
|
131
|
+
s.gets.push({ backend: pane.backend, ready: ready, generation: s.generation, sequence: s.getSequence })
|
|
132
|
+
pane.backend.send({ c: "clipGet" })
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var IMAGE_NAME = "Pasted image %1 at %2.png"
|
|
136
|
+
function two(n) {
|
|
137
|
+
return (n < 10 ? "0" : "") + n
|
|
138
|
+
}
|
|
139
|
+
// Sample input: new Date(2026, 8, 23, 10, 14, 32) -> "Pasted image 2026-09-23 at 10.14.32.png".
|
|
140
|
+
function imageName(at) {
|
|
141
|
+
var date = at.getFullYear() + "-" + two(at.getMonth() + 1) + "-" + two(at.getDate())
|
|
142
|
+
var time = two(at.getHours()) + "." + two(at.getMinutes()) + "." + two(at.getSeconds())
|
|
143
|
+
return IMAGE_NAME.replace("%1", date).replace("%2", time)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// All paste verbs read the same file selection, including the no-watcher fallback.
|
|
147
|
+
function paste(pane, linkKind, forceMove) {
|
|
148
|
+
var dest = pane.path
|
|
149
|
+
function ready() {
|
|
150
|
+
if (pane.path !== dest || pane.listInFlight || pane.recentMode) {
|
|
151
|
+
pane.message("The paste destination changed; try again.", false)
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
var clip = pane.clipboard
|
|
155
|
+
var sources = clip.paths
|
|
156
|
+
if (sources.length === 0 && !linkKind) {
|
|
157
|
+
// No paths: the backend pastes an image as a stamped file, or answers its own sentence.
|
|
158
|
+
pane.backend.send({ c: "pasteimage", dest: dest, name: imageName(new Date()) })
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
if (sources.length === 0) {
|
|
162
|
+
pane.message(Menu.EMPTY_CLIPBOARD, false)
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
pane.asks().ask({ c: linkKind ? "link" : "transfer",
|
|
166
|
+
op: linkKind || (forceMove || clip.moving ? "move" : "copy"), paths: sources, dest: dest },
|
|
167
|
+
null, !linkKind && clip.moving)
|
|
168
|
+
}
|
|
169
|
+
read(pane, ready)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Clear only the cut captured by this transfer, never a newer selection on the card.
|
|
173
|
+
function spent(pane, clip, spendsCut) {
|
|
174
|
+
if (ClipMarks.spent(clip, spendsCut) === clip) return
|
|
175
|
+
pane.backend.send(clip.token ? { c: "clipClear", token: clip.token }
|
|
176
|
+
: { c: "clipClear", cut: clip.paths })
|
|
177
|
+
if (pane.clipboard === clip || (pane.clipboard.paths === clip.paths && pane.clipboard.token === clip.token))
|
|
178
|
+
pane.clipboard = empty()
|
|
179
|
+
}
|
package/ui/js/Cloud.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "NetFs.js" as NetFs
|
|
4
|
+
|
|
5
|
+
// Cloud rows: non-network FUSE mounts inside home, read off the rail's own poll; nothing new runs.
|
|
6
|
+
|
|
7
|
+
// Sample input, /proc/self/mountinfo lines (id parent maj:min root mountpoint options,
|
|
8
|
+
// then fstype source superoptions):
|
|
9
|
+
// 23 1 8:1 / /home/u/gdrive rw,nosuid,nodev - fuse.rclone remote: rw,user_id=1000,group_id=1000
|
|
10
|
+
// 24 1 8:1 / /home/u/My\040Drive rw,nosuid,nodev - fuse.mergerfs merge: rw,user_id=1000,group_id=1000
|
|
11
|
+
// 31 1 0:27 / /home/u/ProtonDrive rw,nosuid,nodev - fuse.protondrive proton: rw,user_id=1000
|
|
12
|
+
// 18 1 8:1 / /home/u rw,nosuid,nodev - btrfs /dev/sda1 rw
|
|
13
|
+
// 40 1 0:40 / /run/user/1000/gvfs rw,nosuid,nodev - fuse.gvfsd-fuse gvfsd-fuse rw,user_id=1000
|
|
14
|
+
// Only the mergerfs line is a cloud row (network fstypes are share rows; home and gvfs are not); a stacked mountpoint keeps the later line.
|
|
15
|
+
function parseCloudMounts(body, home) {
|
|
16
|
+
var root = String(home || "")
|
|
17
|
+
if (root.length === 0)
|
|
18
|
+
return []
|
|
19
|
+
var prefix = root.charAt(root.length - 1) === "/" ? root : root + "/"
|
|
20
|
+
var out = []
|
|
21
|
+
var at = {}
|
|
22
|
+
var lines = String(body || "").split("\n")
|
|
23
|
+
for (var i = 0; i < lines.length; i++) {
|
|
24
|
+
var parsed = parseMountinfoLine(lines[i])
|
|
25
|
+
if (!parsed || !isCloudFstype(parsed.fstype))
|
|
26
|
+
continue
|
|
27
|
+
if (NetFs.isNetworkFstype(parsed.fstype))
|
|
28
|
+
continue // A network fstype is a share row wherever it is mounted.
|
|
29
|
+
// Strictly inside: the home directory itself mounts whatever the box is made of.
|
|
30
|
+
if (parsed.path.length <= root.length || parsed.path.indexOf(prefix) !== 0)
|
|
31
|
+
continue
|
|
32
|
+
if (at[parsed.path] === undefined)
|
|
33
|
+
at[parsed.path] = out.length
|
|
34
|
+
out[at[parsed.path]] = parsed
|
|
35
|
+
}
|
|
36
|
+
return out
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Any FUSE mount is a cloud candidate; the home-folder containment above is what keeps
|
|
40
|
+
// gvfs, portals and the box's own mounts out, because none of them lives under it.
|
|
41
|
+
function isCloudFstype(fstype) {
|
|
42
|
+
var lower = String(fstype || "").toLowerCase()
|
|
43
|
+
return lower === "fuse" || lower.indexOf("fuse.") === 0
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Every network-fstype mountinfo line outside the box's plumbing is a NETWORK row, home or not.
|
|
47
|
+
// Sample input: "31 1 0:45 / /mnt/nas rw - nfs nas:/share rw" becomes one row.
|
|
48
|
+
function parseNetworkMounts(body) {
|
|
49
|
+
var out = []
|
|
50
|
+
var at = {}
|
|
51
|
+
var lines = String(body || "").split("\n")
|
|
52
|
+
for (var i = 0; i < lines.length; i++) {
|
|
53
|
+
var parsed = parseMountinfoLine(lines[i])
|
|
54
|
+
if (!parsed || !NetFs.isNetworkFstype(parsed.fstype))
|
|
55
|
+
continue
|
|
56
|
+
if (parsed.path === "/" || isSystemMountPath(parsed.path))
|
|
57
|
+
continue // The box's own plumbing is never a network row.
|
|
58
|
+
if (at[parsed.path] === undefined)
|
|
59
|
+
at[parsed.path] = out.length
|
|
60
|
+
out[at[parsed.path]] = parsed
|
|
61
|
+
}
|
|
62
|
+
return out
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Sample input: "/run/user/1000/gvfs" trues, "/mnt/nas" falses; read without a per-row stat.
|
|
66
|
+
function isSystemMountPath(p) {
|
|
67
|
+
if (p.indexOf("/proc/") === 0 || p === "/proc")
|
|
68
|
+
return true
|
|
69
|
+
if (p.indexOf("/sys/") === 0 || p === "/sys")
|
|
70
|
+
return true
|
|
71
|
+
if (p.indexOf("/dev/") === 0 || p === "/dev")
|
|
72
|
+
return true
|
|
73
|
+
if (p.indexOf("/run/") === 0)
|
|
74
|
+
return true
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// One mountinfo line into its mountpoint and fstype, or null: the mountpoint is field five
|
|
79
|
+
// of the left half and the fstype is the first field of the right half, split on " - ".
|
|
80
|
+
function parseMountinfoLine(line) {
|
|
81
|
+
var halves = String(line || "").split(" - ")
|
|
82
|
+
if (halves.length < 2)
|
|
83
|
+
return null
|
|
84
|
+
var left = halves[0].split(/\s+/)
|
|
85
|
+
var right = halves[1].split(/\s+/)
|
|
86
|
+
if (left.length < 5 || right.length < 1 || left[4].length === 0 || right[0].length === 0)
|
|
87
|
+
return null
|
|
88
|
+
return { path: unescapeOctal(left[4]), fstype: right[0] }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Sample input: "/home/u/My\040Drive" answers "/home/u/My Drive". A mountinfo escape is a
|
|
92
|
+
// backslash and three octal digits, and anything else is kept literally.
|
|
93
|
+
function unescapeOctal(field) {
|
|
94
|
+
return String(field).replace(/\\([0-7]{3})/g, function (match, digits) {
|
|
95
|
+
return String.fromCharCode(parseInt(digits, 8))
|
|
96
|
+
})
|
|
97
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Contrast.js" as Contrast
|
|
4
|
+
.import "Palette.js" as Palette
|
|
5
|
+
|
|
6
|
+
// The ink names after the foreground, in the order the code reply numbers its roles: 1 to 6 are bat's SGR 31 to 36.
|
|
7
|
+
var INKS = ["red", "green", "yellow", "blue", "magenta", "cyan"]
|
|
8
|
+
// The inks a theme without that colour draws in.
|
|
9
|
+
var FALLBACK = { red: "#f38ba8", green: "#a6e3a1", yellow: "#f9e2af", blue: "#89b4fa", magenta: "#cba6f7", cyan: "#94e2d5" }
|
|
10
|
+
// A tab fills to the next multiple of this many columns.
|
|
11
|
+
var TAB = 8
|
|
12
|
+
|
|
13
|
+
// The foreground, then bat's six colours, each the palette's own (its ANSI slot when unnamed) lifted to 4.5:1 on the background or surface it contrasts less with.
|
|
14
|
+
function inks(found, fallback, foreground) {
|
|
15
|
+
var bg = Palette.pick(found, ["background"], fallback.background)
|
|
16
|
+
var surface = Palette.pick(found, Palette.SURFACE_KEYS, fallback.surface)
|
|
17
|
+
var out = [foreground]
|
|
18
|
+
for (var i = 0; i < INKS.length; i++) {
|
|
19
|
+
var ink = Palette.pick(found, [INKS[i], "color" + (i + 1)], FALLBACK[INKS[i]])
|
|
20
|
+
out.push(Contrast.ensureRatio(ink, Contrast.ratio(ink, bg) < Contrast.ratio(ink, surface) ? bg : surface, 4.5))
|
|
21
|
+
}
|
|
22
|
+
return out
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function roleName(role) {
|
|
26
|
+
return role >= 1 && role <= INKS.length ? INKS[role - 1] : "foreground"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function escape(text) {
|
|
30
|
+
return String(text).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// The reply's flat [role, text, role, text, ...] as [role, text] pairs with every tab filled to its stop, since a rich text folds a tab into one space.
|
|
34
|
+
// Sample input: [5, "ab", 0, "\tx"] answers [[5, "ab"], [0, " x"]].
|
|
35
|
+
function pairs(runs) {
|
|
36
|
+
var out = []
|
|
37
|
+
var column = 0
|
|
38
|
+
for (var i = 0; i + 1 < runs.length; i += 2) {
|
|
39
|
+
var text = ""
|
|
40
|
+
var raw = String(runs[i + 1])
|
|
41
|
+
for (var j = 0; j < raw.length; j++) {
|
|
42
|
+
var fill = raw.charAt(j) === "\t" ? TAB - column % TAB : 1
|
|
43
|
+
text += raw.charAt(j) === "\t" ? " ".repeat(fill) : raw.charAt(j)
|
|
44
|
+
column += fill
|
|
45
|
+
}
|
|
46
|
+
out.push([runs[i], text])
|
|
47
|
+
}
|
|
48
|
+
return out
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function plain(runs) {
|
|
52
|
+
return pairs(runs).map(function (pair) { return pair[1] }).join("")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// One line as StyledText: every run escaped, a coloured run in one font tag, and each space kept as a non-breaking space unless it is a single space between two characters, which a rich text keeps and may wrap at.
|
|
56
|
+
// Sample input: [5, "fn", 0, " x <b>"] answers <font color="#cba6f7">fn</font> x <b> with the magenta ink.
|
|
57
|
+
function styled(runs, colors) {
|
|
58
|
+
var parts = pairs(runs)
|
|
59
|
+
var line = parts.map(function (pair) { return pair[1] }).join("")
|
|
60
|
+
var out = ""
|
|
61
|
+
var at = 0
|
|
62
|
+
for (var i = 0; i < parts.length; i++) {
|
|
63
|
+
var body = ""
|
|
64
|
+
for (var j = 0; j < parts[i][1].length; j++, at++) {
|
|
65
|
+
var c = parts[i][1].charAt(j)
|
|
66
|
+
var kept = c === " " && at > 0 && at < line.length - 1 && line.charAt(at - 1) !== " " && line.charAt(at + 1) !== " "
|
|
67
|
+
body += c === " " ? (kept ? " " : " ") : escape(c)
|
|
68
|
+
}
|
|
69
|
+
out += parts[i][0] > 0 ? "<font color=\"" + colors[parts[i][0]] + "\">" + body + "</font>" : body
|
|
70
|
+
}
|
|
71
|
+
return out
|
|
72
|
+
}
|