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
package/ui/js/Picker.js
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Format.js" as Format
|
|
4
|
+
.import "Thumbs.js" as Thumbs
|
|
5
|
+
|
|
6
|
+
// Whole sentences with "%1" for a value, filled by fill so each translates as one.
|
|
7
|
+
var WORDS = {
|
|
8
|
+
requestedBy: "Requested by %1",
|
|
9
|
+
selectedWithSize: "%1 selected · %2",
|
|
10
|
+
hintsEsc: "%1 · Esc cancel"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// The portal request tools/flea-portal puts in FLEA_PICKER, and the answer ui/picker.qml writes
|
|
14
|
+
// back. Everything here is pure so tests/js/picker.js can drive it without a window.
|
|
15
|
+
|
|
16
|
+
// The portal's own response codes, mirrored from tools/flea-portal: 1 is the user's no, and this
|
|
17
|
+
// front end never sends 2, because a window that opened at all can only pick or refuse.
|
|
18
|
+
var RESPONSE_OK = 0
|
|
19
|
+
var RESPONSE_CANCELLED = 1
|
|
20
|
+
|
|
21
|
+
var ALL_FILES = "All files"
|
|
22
|
+
|
|
23
|
+
// The rail's Recent row is a location and not a directory, so it is named by a token no listing
|
|
24
|
+
// path can equal: every path this window holds is absolute, and this one does not start with "/".
|
|
25
|
+
// SendPicker.html draws it first in the rail and draws this word where the path would be.
|
|
26
|
+
var RECENT = "flea:recent"
|
|
27
|
+
var RECENT_LABEL = "Recent"
|
|
28
|
+
|
|
29
|
+
function isRecent(location) {
|
|
30
|
+
return location === RECENT
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// SendPicker.html draws a chooser row as the name, a 70px size and an 80px date, so the two columns
|
|
34
|
+
// the window's rows also carry are hidden here at every width rather than at some of them.
|
|
35
|
+
var HIDDEN_COLS = ["mode", "kind"]
|
|
36
|
+
|
|
37
|
+
// The chooser's s-step order: only columns it draws, since an order no header can mark has no feedback.
|
|
38
|
+
var SORT_ORDERS = ["name", "size", "mtime"]
|
|
39
|
+
|
|
40
|
+
// Every field defaulted, because a request that arrived short must still open a window.
|
|
41
|
+
function request(text) {
|
|
42
|
+
var read = {}
|
|
43
|
+
try {
|
|
44
|
+
read = JSON.parse(String(text || "{}")) || {}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
read = {}
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
mode: read.mode === "save" || read.mode === "savefiles" ? read.mode : "open",
|
|
50
|
+
title: String(read.title || ""),
|
|
51
|
+
app: String(read.app || ""),
|
|
52
|
+
accept: String(read.accept || ""),
|
|
53
|
+
multiple: read.multiple === true,
|
|
54
|
+
directory: read.directory === true,
|
|
55
|
+
hidden: typeof read.hidden === "boolean" ? read.hidden : undefined,
|
|
56
|
+
folder: String(read.folder || ""),
|
|
57
|
+
file: String(read.file || ""),
|
|
58
|
+
name: String(read.name || ""),
|
|
59
|
+
files: Array.isArray(read.files) ? read.files : [],
|
|
60
|
+
filters: Array.isArray(read.filters) ? read.filters : [],
|
|
61
|
+
current: String(read.current || ""),
|
|
62
|
+
currentIndex: typeof read.currentIndex === "number" ? read.currentIndex : -1
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The caller's own title wins; the fallback says what the window is for rather than naming Flea.
|
|
67
|
+
function title(req) {
|
|
68
|
+
if (req.title.length > 0) {
|
|
69
|
+
return req.title
|
|
70
|
+
}
|
|
71
|
+
if (req.mode === "save" || req.mode === "savefiles") {
|
|
72
|
+
return "Save file"
|
|
73
|
+
}
|
|
74
|
+
return req.directory ? "Choose folder" : "Choose file"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Only a portal identity is ever shown here. A host application has none, and inventing one from
|
|
78
|
+
// the window title would put a name the desktop never vouched for under a trusted-looking label.
|
|
79
|
+
function subtitle(req) {
|
|
80
|
+
return req.app.length > 0 ? Format.fill(WORDS.requestedBy, req.app) : ""
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// The primary button. The count rides on it in the multiple case, which is the board's "Send 3".
|
|
84
|
+
function acceptLabel(req, count) {
|
|
85
|
+
var base = req.accept.length > 0 ? req.accept : defaultAccept(req)
|
|
86
|
+
// The count goes in first and the caller's own text last, so a placeholder in it is never filled in.
|
|
87
|
+
if (req.multiple && count > 1) {
|
|
88
|
+
return "%2 %1".arg(Format.count(count)).arg(base)
|
|
89
|
+
}
|
|
90
|
+
return base
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function defaultAccept(req) {
|
|
94
|
+
if (req.mode === "save") {
|
|
95
|
+
return "Save"
|
|
96
|
+
}
|
|
97
|
+
if (req.mode === "savefiles" || req.directory) {
|
|
98
|
+
return "Choose folder"
|
|
99
|
+
}
|
|
100
|
+
return "Open"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The footer's left half: what is checked, and what it weighs.
|
|
104
|
+
function statusLine(count, bytes) {
|
|
105
|
+
if (count === 0) {
|
|
106
|
+
return "0 selected"
|
|
107
|
+
}
|
|
108
|
+
return Format.fill(WORDS.selectedWithSize, Format.count(count), Format.size(bytes))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// The footer's right half, which says only the keys this mode actually answers.
|
|
112
|
+
function hints(req) {
|
|
113
|
+
if (req.mode === "save") {
|
|
114
|
+
return "Enter save · Esc cancel"
|
|
115
|
+
}
|
|
116
|
+
var pick = req.multiple ? (req.directory ? "Enter open · Space mark folder" : "Space select · Enter open/send") : "Enter open"
|
|
117
|
+
return Format.fill(WORDS.hintsEsc, pick)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// The collision review's error line, one template so a placeholder inside the name is never filled in.
|
|
121
|
+
function collisionLine(name) {
|
|
122
|
+
return "%1 already exists here.".arg(name)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Where a name's stem ends: at its last dot, and a leading dot belongs to the stem.
|
|
126
|
+
function stemEnd(name) {
|
|
127
|
+
var dot = String(name).lastIndexOf(".")
|
|
128
|
+
return dot > 0 ? dot : String(name).length
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Callout 12: Back, Up, the rail, the list, Filename, the filter, Cancel and the answer; a hidden or disabled stop is skipped.
|
|
132
|
+
function tabOrder(stops) {
|
|
133
|
+
return [].concat(stops.chrome, [stops.rail, stops.view], stops.save, stops.answers)
|
|
134
|
+
.filter(function(item) { return item.visible && item.enabled && item.activeFocusOnTab })
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// The filter menu's rows: the caller's filters, then All files, which is always explicit. No filters is no
|
|
138
|
+
// dropdown at all, because a chooser with one filter is a chooser with nothing to choose between.
|
|
139
|
+
function chips(req) {
|
|
140
|
+
if (req.filters.length === 0) {
|
|
141
|
+
return []
|
|
142
|
+
}
|
|
143
|
+
var out = []
|
|
144
|
+
for (var i = 0; i < req.filters.length; i++) {
|
|
145
|
+
out.push({ label: String(req.filters[i].label || ""), index: i })
|
|
146
|
+
}
|
|
147
|
+
out.push({ label: ALL_FILES, index: -1 })
|
|
148
|
+
return out
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Which filter starts current: the caller's current_filter when it names one of them, else the first.
|
|
152
|
+
function currentChip(req) {
|
|
153
|
+
if (req.filters.length === 0) {
|
|
154
|
+
return -1
|
|
155
|
+
}
|
|
156
|
+
if (req.currentIndex >= 0 && req.currentIndex < req.filters.length) return req.currentIndex
|
|
157
|
+
for (var i = 0; i < req.filters.length; i++) {
|
|
158
|
+
if (String(req.filters[i].label || "") === req.current) {
|
|
159
|
+
return i
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return 0
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// A mark is a path, never a row number: the board's rule is that a checked identity survives Back
|
|
166
|
+
// and Parent, and a row number rebinds to whatever else lands in that position.
|
|
167
|
+
function marked(marks, path) {
|
|
168
|
+
for (var i = 0; i < marks.length; i++) {
|
|
169
|
+
if (marks[i].path === path) {
|
|
170
|
+
return true
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return false
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function totalBytes(marks) {
|
|
177
|
+
var sum = 0
|
|
178
|
+
for (var i = 0; i < marks.length; i++) {
|
|
179
|
+
sum += marks[i].bytes
|
|
180
|
+
}
|
|
181
|
+
return sum
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function paths(marks) {
|
|
185
|
+
var out = []
|
|
186
|
+
for (var i = 0; i < marks.length; i++) {
|
|
187
|
+
out.push(marks[i].path)
|
|
188
|
+
}
|
|
189
|
+
return out
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function reviewedMarks(previous, reviewed) {
|
|
193
|
+
return reviewed.map(function(item) {
|
|
194
|
+
var old = previous.find(function(mark) { return mark.path === item.path })
|
|
195
|
+
return {path: item.path, bytes: item.bytes, uri: old && old.uri ? old.uri : Format.fileUri(item.path)}
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// The save name is the one filename a client hands this window, so it is a trust boundary and it
|
|
200
|
+
// gets the rule the rest of the product already applies. Mirrored from src/backend/ops.rs
|
|
201
|
+
// valid_name() and kept identical to it, character for character, so the two cannot drift.
|
|
202
|
+
function validName(name) {
|
|
203
|
+
var text = String(name)
|
|
204
|
+
return text.length > 0 && text !== "." && text !== ".."
|
|
205
|
+
&& text.indexOf("/") < 0 && text.indexOf("\0") < 0
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// What both the strip and the status line say about a name validName() refuses, in ops.rs's words.
|
|
209
|
+
var NAME_REFUSED = "a name cannot be empty, . or .., or contain /"
|
|
210
|
+
// Status lines are whole sentences with placeholders, filled by Format.fill.
|
|
211
|
+
var SAVE_REFUSED = "%1 cannot be used: %2"
|
|
212
|
+
var SAVE_EXISTS = "%1 already exists here. Review it before you continue."
|
|
213
|
+
|
|
214
|
+
// Whole sentences for the selection check, filled by Format.fill; singular and plural are two sentences.
|
|
215
|
+
var NOTES = {
|
|
216
|
+
skippedOne: "Selected %1 of %2. 1 was left out: %3 (%4).",
|
|
217
|
+
skippedMany: "Selected %1 of %2. %3 were left out: %4 (%5) and %6 more."
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// A name is one token to the wrapper, so its segment joints carry zero-width breaks; zero width keeps one-line draws identical.
|
|
221
|
+
function jointName(name) {
|
|
222
|
+
return String(name).replace(/([._-])/g, "$1\u200b")
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
var DOUBLE_OPEN = "open"
|
|
226
|
+
var DOUBLE_MARK = "mark"
|
|
227
|
+
var DOUBLE_ACCEPT = "accept"
|
|
228
|
+
var DOUBLE_MARK_ACCEPT = "markAccept"
|
|
229
|
+
var DOUBLE_NONE = "none"
|
|
230
|
+
|
|
231
|
+
// Sample input: sameTap("/a/b.txt", "/a/b.txt") answers true, sameTap("/a/b.txt", "/a/c.txt") answers false.
|
|
232
|
+
function sameTap(firstPath, rowPath) {
|
|
233
|
+
return !!rowPath && rowPath === firstPath
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Sample input: doubleAction({mode:"open",multiple:false}, {d:false}, "/a/b.txt", "/a/b.txt", []) answers "markAccept"; multiple:true answers "mark" for either mark state.
|
|
237
|
+
function doubleAction(req, row, rowPath, firstPath, marks) {
|
|
238
|
+
if (!row) {
|
|
239
|
+
return DOUBLE_NONE
|
|
240
|
+
}
|
|
241
|
+
if (directory(row)) {
|
|
242
|
+
return DOUBLE_OPEN
|
|
243
|
+
}
|
|
244
|
+
// Save mode and folder requests keep their own rules, so a file double click changes nothing there.
|
|
245
|
+
if (req.mode === "save" || req.directory || req.mode === "savefiles") {
|
|
246
|
+
return DOUBLE_NONE
|
|
247
|
+
}
|
|
248
|
+
// The row path names the file, so a list rebuilt between the taps never marks or sends another row.
|
|
249
|
+
if (!sameTap(firstPath, rowPath)) {
|
|
250
|
+
return DOUBLE_NONE
|
|
251
|
+
}
|
|
252
|
+
return req.multiple ? DOUBLE_MARK : marked(marks, rowPath) ? DOUBLE_ACCEPT : DOUBLE_MARK_ACCEPT
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// The picker never renames, so Return/Enter still activates and other rename keys stay unhandled.
|
|
256
|
+
function activates(action, key) {
|
|
257
|
+
if (action === "open" || action === "pageForward") {
|
|
258
|
+
return true
|
|
259
|
+
}
|
|
260
|
+
if (action !== "rename") {
|
|
261
|
+
return false
|
|
262
|
+
}
|
|
263
|
+
return key === Qt.Key_Return || key === Qt.Key_Enter
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function join(dir, name) {
|
|
267
|
+
return dir === "/" ? "/" + name : dir + "/" + name
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// A row's own identity, which is what a mark holds and what the caller is answered with. A Recent
|
|
271
|
+
// listing's base is "/" and its rows are named by their path under it, so the row's path is that
|
|
272
|
+
// name and never a join onto the location token; see docs/protocol.md "listpaths".
|
|
273
|
+
function rowPath(location, name) {
|
|
274
|
+
return isRecent(location) ? "/" + name : join(location, name)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function directory(row) {
|
|
278
|
+
return !!row && (row.d === true || (Format.isSymlink(row.p) && row.i === "folder"))
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// A launch opens only a view the picker draws; anything else opens the list.
|
|
282
|
+
function rememberedView(stored) {
|
|
283
|
+
return stored === "grid" ? "grid" : "list"
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Only a switch that moves the view owes the state file a write.
|
|
287
|
+
function viewSwitch(current, next) {
|
|
288
|
+
return (next === "list" || next === "grid") && next !== current ? next : ""
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Visible tiles as listing rows, the same multiplication GridArea.visibleRange does.
|
|
292
|
+
function tileRange(contentY, cellH, tileRows, columns, total) {
|
|
293
|
+
var view = Thumbs.viewport(contentY, cellH, tileRows, Math.max(1, Math.ceil(total / Math.max(1, columns))))
|
|
294
|
+
return {
|
|
295
|
+
first: view.first * columns,
|
|
296
|
+
last: Math.min(total - 1, (view.last + 1) * columns - 1)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// One grid step keeps the main grid's edge rule: off its row or past an end stays.
|
|
301
|
+
function gridTarget(index, delta, columns, total) {
|
|
302
|
+
var next = index + delta
|
|
303
|
+
if (next < 0 || next >= total) {
|
|
304
|
+
return Math.max(0, Math.min(total - 1, index))
|
|
305
|
+
}
|
|
306
|
+
if ((delta === -1 && index % columns === 0) || (delta === 1 && next % columns === 0)) {
|
|
307
|
+
return index
|
|
308
|
+
}
|
|
309
|
+
return next
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Page steps clamp to the nearer end; single steps refuse instead, see gridTarget.
|
|
313
|
+
function pageTarget(index, delta, total) {
|
|
314
|
+
return Math.max(0, Math.min(total - 1, index + delta))
|
|
315
|
+
}
|
|
316
|
+
// Twice the wider view's screen plus slack, so the screen still fits after the quarter lead.
|
|
317
|
+
var WINDOW_COVER = 2
|
|
318
|
+
var WINDOW_SLACK = 60
|
|
319
|
+
// Sample input: windowSize(10, 4, 5) is 100, windowSize(30, 2, 5) is 120.
|
|
320
|
+
function windowSize(listRows, tileRows, columns) {
|
|
321
|
+
var tiles = Math.max(1, tileRows) * Math.max(1, columns)
|
|
322
|
+
return WINDOW_COVER * Math.max(listRows, tiles) + WINDOW_SLACK
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function parentOf(path) {
|
|
326
|
+
var cut = String(path).lastIndexOf("/")
|
|
327
|
+
if (cut <= 0) {
|
|
328
|
+
return "/"
|
|
329
|
+
}
|
|
330
|
+
return String(path).substring(0, cut)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// The one place a path becomes a URI: xdg-desktop-portal drops anything that is not file://, and
|
|
334
|
+
// omarchy-file-select turns what comes back into a path with GLib, which refuses a bad encoding.
|
|
335
|
+
function uris(list) {
|
|
336
|
+
var out = []
|
|
337
|
+
for (var i = 0; i < list.length; i++) {
|
|
338
|
+
out.push(Format.fileUri(list[i]))
|
|
339
|
+
}
|
|
340
|
+
return out
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// What tools/flea-portal reads out of the reply file. A refusal carries no URI at all.
|
|
344
|
+
function reply(response, list, filterIndex) {
|
|
345
|
+
if (response !== RESPONSE_OK) {
|
|
346
|
+
return JSON.stringify({ response: response })
|
|
347
|
+
}
|
|
348
|
+
var answer = { response: RESPONSE_OK, uris: list.map(function(item) {
|
|
349
|
+
return typeof item === "string" ? Format.fileUri(item) : item.uri
|
|
350
|
+
}) }
|
|
351
|
+
if (typeof filterIndex === "number") answer.filter = filterIndex
|
|
352
|
+
return JSON.stringify(answer)
|
|
353
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Format.js" as Format
|
|
4
|
+
.import "Menu.js" as Menu
|
|
5
|
+
.import "Nav.js" as Nav
|
|
6
|
+
.import "RailKeys.js" as RailKeys
|
|
7
|
+
.import "Places.js" as Places
|
|
8
|
+
.import "Tabs.js" as Tabs
|
|
9
|
+
|
|
10
|
+
// The sentence a remote favourite answers a new-tab open with, filled by Format.fill.
|
|
11
|
+
var WORDS = {
|
|
12
|
+
opensHere: "%1 opens in this tab only"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// MenuAdditions rule 3: the folder menu, opened from a Places or Favorites row and acting on that
|
|
16
|
+
// row's own path. The key carries the path because the rail rebuilds on a five second poll and an
|
|
17
|
+
// index taken when the menu opened can name another row by the time a row inside it is chosen, the
|
|
18
|
+
// same reason ui/js/Mounts.js keys a share's menu by its uri.
|
|
19
|
+
function key(entry, favouriteIndex) {
|
|
20
|
+
return "place:" + favouriteIndex + ":" + entry.path
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// The hidden list is ui/ViewState.qml "menuHidden", handed in by the caller: it is the one reader
|
|
24
|
+
// that falls back to the shipped defaults, and a list derived any other way is empty before the
|
|
25
|
+
// state file lands, which switched this menu on in a fresh home. Anything else fails closed.
|
|
26
|
+
function entries(entry, favouriteIndex, hidden) {
|
|
27
|
+
if (!Array.isArray(hidden))
|
|
28
|
+
return []
|
|
29
|
+
return Menu.placeEntries({ hiddenActions: hidden, hasRow: true, placeFavourite: favouriteIndex >= 0 })
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Every row here takes the path the key carries. Properties is not among them: the dialog snapshots
|
|
33
|
+
// row indices through the backend's own menuaction op, which a place has none of, so the board's
|
|
34
|
+
// sixth row waits for that protocol rather than being faked from the listing's cursor.
|
|
35
|
+
function perform(action, key, sidebar, favourites) {
|
|
36
|
+
// The rail's older key, which only ever carried Remove: kept exactly, identity check included,
|
|
37
|
+
// because it is what a favourite's menu still is while the Places row menu is switched off.
|
|
38
|
+
if (key.indexOf("favourite:") === 0) {
|
|
39
|
+
var end = key.indexOf(":", 10)
|
|
40
|
+
var at = Number(key.substring(10, end))
|
|
41
|
+
if (action !== "removeFavourite") return
|
|
42
|
+
if (JSON.stringify(favourites.records[at]) === key.substring(end + 1)) favourites.remove(at)
|
|
43
|
+
else sidebar.message("Favorites changed; reopen the menu before removing this row.", true)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
var rest = key.substring("place:".length)
|
|
47
|
+
var cut = rest.indexOf(":")
|
|
48
|
+
var index = Number(rest.substring(0, cut))
|
|
49
|
+
var path = rest.substring(cut + 1)
|
|
50
|
+
var pane = sidebar.navigationPane
|
|
51
|
+
if (!pane || path.length === 0)
|
|
52
|
+
return
|
|
53
|
+
if (action === "open") { openPath(path, sidebar, pane); return }
|
|
54
|
+
else if (action === "openTab") Tabs.openNew(pane, path)
|
|
55
|
+
else if (action === "openTerminal") pane.openTerminal(path)
|
|
56
|
+
// The Places row's Copy path row acts on its own path, the way the Locked
|
|
57
|
+
// tile's does: MenuAdditions040 replaced the file menu's row, not this one.
|
|
58
|
+
else if (action === "copypath") pane.performMenu("copypath", 0, [path])
|
|
59
|
+
else if (action === "addFavourite") favourites.add(path, leaf(path))
|
|
60
|
+
else if (action === "removeFavourite") removeAt(sidebar, favourites, index, path)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Open reuses the rail's own activation handoff: focus follows a ready folder or a started listing, and a refused busy open stays on the rail.
|
|
64
|
+
function openPath(path, sidebar, pane) {
|
|
65
|
+
if (pane.listInFlight === true) { Nav.openPlace(pane, path); return }
|
|
66
|
+
sidebar.focusOnOpen = true
|
|
67
|
+
RailKeys.openFrom(pane, path, sidebar)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// A favourite is removed by index, so the index is checked against the path the menu was opened on:
|
|
71
|
+
// the rail rebuilds on a five second poll and Favourites can be rewritten by the other front end.
|
|
72
|
+
function removeAt(sidebar, favourites, index, path) {
|
|
73
|
+
var record = favourites.records[index]
|
|
74
|
+
if (record && String(record.path) === path) favourites.remove(index)
|
|
75
|
+
else sidebar.message("Favorites changed; reopen the menu before removing this row.", true)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function leaf(path) {
|
|
79
|
+
var cut = String(path).replace(/\/+$/, "").lastIndexOf("/")
|
|
80
|
+
return cut < 0 ? path : path.substring(cut + 1)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// A middle click on a Places or Favorites row: its folder in a new tab, the listing's own middle click
|
|
84
|
+
// (ui/js/Tap.js tappedTab). A favourite resolves as ui/Sidebar.qml openFavourite does, and a remote
|
|
85
|
+
// one, which has to mount before it has a path, says so rather than opening somewhere else.
|
|
86
|
+
function openTabAt(sidebar, index) {
|
|
87
|
+
var entry = sidebar.entries[index]
|
|
88
|
+
var pane = sidebar.navigationPane
|
|
89
|
+
if (!entry || !pane || (entry.kind !== "home" && entry.kind !== "favourite"))
|
|
90
|
+
return
|
|
91
|
+
// Places.openEntry with a new-tab port: same record check, message and file:// decode; a remote entry answers through the network port.
|
|
92
|
+
Places.openEntry(entry, { pane: pane,
|
|
93
|
+
opened: function (path) { Tabs.openNew(pane, path) },
|
|
94
|
+
networkHost: function () { sidebar.message(Format.fill(WORDS.opensHere, entry.label), false); return null },
|
|
95
|
+
message: sidebar.message })
|
|
96
|
+
}
|