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,139 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Lists.js" as Lists
|
|
4
|
+
.import "Kinds.js" as Kinds
|
|
5
|
+
.import "ExtThumbs.js" as ExtThumbs
|
|
6
|
+
.import "Contrast.js" as Contrast
|
|
7
|
+
.import "Format.js" as Format
|
|
8
|
+
|
|
9
|
+
// The one parsed Markdown document Quick Look takes without parsing, keyed by its text so an edited file misses and one past MAX_BYTES is never held.
|
|
10
|
+
var entry = null
|
|
11
|
+
var MAX_BYTES = 65536
|
|
12
|
+
|
|
13
|
+
// Sample input: the row { n: "a.md", d: false } answers true; { n: "a.md", d: true }, { n: "a.txt", d: false } and null answer false.
|
|
14
|
+
// Whether the cursor row is a Markdown file by name, the one trigger Quick Look's warm and its ahead-of-Space build share.
|
|
15
|
+
function isMarkdownRow(row) {
|
|
16
|
+
return row !== null && row !== undefined && !row.d && Kinds.isMarkdown(row.n)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Sample input: a 900 byte regular "a.md" row on class "" with the class known answers true; a named pipe row, class "network" or an unknown class answers false.
|
|
20
|
+
// Only a regular local file under MAX_BYTES in a folder whose class has landed is read ahead or inside the key; cifs, nfs and listed FUSE shares classify "network" in extclass.rs.
|
|
21
|
+
function readsInline(row, storageClass, storageKnown) {
|
|
22
|
+
if (!row || row.d || !storageKnown || ExtThumbs.present(storageClass) || !Kinds.isMarkdown(row.n))
|
|
23
|
+
return false
|
|
24
|
+
return (row.p & Format.S_IFMT) === Format.S_IFREG && row.s > 0 && row.s <= MAX_BYTES
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// A picture at most this big is decoded ahead of the open, and a document is asked about at most this many.
|
|
28
|
+
var PICTURE_MAX_BYTES = 262144
|
|
29
|
+
var PICTURE_LIMIT = 8
|
|
30
|
+
var FILE_SCHEME_LENGTH = 7
|
|
31
|
+
// The stat child that sizes the pictures is dropped after this long, so a hung mount holds nothing past it.
|
|
32
|
+
var PICTURE_SIZE_DEADLINE_MS = 1500
|
|
33
|
+
|
|
34
|
+
// Sample input: "file:///d/b%20c.png" answers "/d/b c.png"; "file:///d/100%.png" (a stray percent) answers "".
|
|
35
|
+
function pathOfUrl(url) {
|
|
36
|
+
try {
|
|
37
|
+
return decodeURIComponent(String(url).slice(FILE_SCHEME_LENGTH))
|
|
38
|
+
} catch (e) {
|
|
39
|
+
return ""
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Sample input: path "/d/img/a.png" in dir "/d" answers true; "/mnt/nas/a.png" and "/d/../e/a.png" answer false.
|
|
44
|
+
// Only a picture under the document's folder shares the storage class readsInline cleared, so a stat never reaches another mount.
|
|
45
|
+
function insideDir(path, dir) {
|
|
46
|
+
return dir !== "" && path.indexOf(dir + "/") === 0 && path.split("/").indexOf("..") < 0
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Sample input: blocks [{ type: "image", url: "file:///d/a.png" }, { type: "images", items: [{ url: "file:///d/b%20c.png" }, { url: "file:///d/a.png" }] }, { type: "run" }] in dir "/d" answer ["file:///d/a.png", "file:///d/b%20c.png"].
|
|
50
|
+
// The local pictures a parsed document draws at its top level under its own folder, each once, in reading order, at most limit of them.
|
|
51
|
+
function pictureUrls(blocks, limit, dir) {
|
|
52
|
+
var urls = []
|
|
53
|
+
function add(url) {
|
|
54
|
+
if (typeof url === "string" && url.indexOf("file://") === 0 && urls.length < limit && urls.indexOf(url) < 0
|
|
55
|
+
&& insideDir(pathOfUrl(url), dir))
|
|
56
|
+
urls.push(url)
|
|
57
|
+
}
|
|
58
|
+
for (var i = 0; i < blocks.length; i++) {
|
|
59
|
+
var b = blocks[i]
|
|
60
|
+
if (b.type === "image") {
|
|
61
|
+
add(b.url)
|
|
62
|
+
} else if (b.type === "images" && b.items !== undefined) {
|
|
63
|
+
for (var j = 0; j < b.items.length; j++)
|
|
64
|
+
add(b.items[j].url)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return urls
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Sample input: urls ["file:///d/a.png", "file:///d/big.png", "file:///d/gone.png"] with the stat text "2048\t/d/a.png\n900000\t/d/big.png\n" answer ["file:///d/a.png"].
|
|
71
|
+
// The pictures stat sized at PICTURE_MAX_BYTES or less; a name stat did not print (a missing file) or a bigger one keeps the open's own load.
|
|
72
|
+
function smallPictures(urls, statText) {
|
|
73
|
+
var sizes = {}
|
|
74
|
+
var lines = String(statText).split("\n")
|
|
75
|
+
for (var i = 0; i < lines.length; i++) {
|
|
76
|
+
var tab = lines[i].indexOf("\t")
|
|
77
|
+
if (tab > 0)
|
|
78
|
+
sizes[lines[i].slice(tab + 1)] = Number(lines[i].slice(0, tab))
|
|
79
|
+
}
|
|
80
|
+
return urls.filter(function (url) {
|
|
81
|
+
var size = sizes[pathOfUrl(url)]
|
|
82
|
+
return size !== undefined && size > 0 && size <= PICTURE_MAX_BYTES
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// The most formulas a rested document typesets ahead, so a document full of them never queues a render per rest.
|
|
87
|
+
var FORMULA_LIMIT = 8
|
|
88
|
+
|
|
89
|
+
// Sample input: [{ type: "run", maths: ["x", "x"] }, { type: "figure", kind: "math", source: "y" }, { type: "quote", parts: [{ type: "run", maths: ["z"] }] }] answer [{ source: "x", display: false }, { source: "y", display: true }, { source: "z", display: false }].
|
|
90
|
+
// The distinct maths a prepared document draws, in reading order and at most limit of them: inline formulas and display figures, a quote's or a list item's parts included.
|
|
91
|
+
function formulasIn(blocks, limit) {
|
|
92
|
+
var out = []
|
|
93
|
+
var seen = {}
|
|
94
|
+
function add(source, display) {
|
|
95
|
+
var key = (display ? "d" : "i") + source
|
|
96
|
+
if (out.length < limit && seen[key] === undefined) {
|
|
97
|
+
seen[key] = true
|
|
98
|
+
out.push({ source: source, display: display })
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function walk(list) {
|
|
102
|
+
for (var i = 0; i < list.length; i++) {
|
|
103
|
+
var b = list[i]
|
|
104
|
+
if (!b)
|
|
105
|
+
continue
|
|
106
|
+
if (Lists.isList(b)) {
|
|
107
|
+
walk(b)
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
if (b.type === "figure" && b.kind === "math")
|
|
111
|
+
add(b.source, true)
|
|
112
|
+
for (var k = 0; b.maths !== undefined && k < b.maths.length; k++)
|
|
113
|
+
add(b.maths[k], false)
|
|
114
|
+
if (b.parts !== undefined)
|
|
115
|
+
walk(b.parts)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
walk(blocks)
|
|
119
|
+
return out
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// QML color components read 0..1, so the hex a style attribute needs is assembled from them, never coerced from the colour.
|
|
123
|
+
// Sample input: a colour with r 0.0627, g 0.0745, b 0.0745 answers "#101313".
|
|
124
|
+
function hexOf(c) {
|
|
125
|
+
return Contrast.hexOf([c.r, c.g, c.b])
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function store(path, text, dir, chrome, ink, blocks) {
|
|
129
|
+
if (text.length > MAX_BYTES) return
|
|
130
|
+
entry = { path: path, text: text, dir: dir, chrome: chrome, ink: ink, blocks: blocks }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The blocks parsed from exactly this text with exactly these inputs, or null.
|
|
134
|
+
function take(path, text, dir, chrome, ink) {
|
|
135
|
+
var e = entry
|
|
136
|
+
if (e === null || e.path !== path || e.dir !== dir || e.chrome !== chrome || e.ink !== ink || e.text !== text)
|
|
137
|
+
return null
|
|
138
|
+
return e.blocks
|
|
139
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
// MarkdownTableFit: how a table shares the width its block gives it, a pure function of column widths in pixels.
|
|
4
|
+
|
|
5
|
+
// Sample input: fit([100, 400], [50, 100], 300, 10) is [71, 228]: each column keeps its longest word, the rest goes by want.
|
|
6
|
+
// A table that fits keeps its natural widths; past that no column falls under its longest word or least (one narrower keeps its natural), so a hopeless one is wider than avail.
|
|
7
|
+
function fit(natural, minimum, avail, least) {
|
|
8
|
+
function heldAt(c) {
|
|
9
|
+
return natural[c] < least ? natural[c] : Math.max(least, Math.min(minimum[c], natural[c]))
|
|
10
|
+
}
|
|
11
|
+
function capped(w, c) {
|
|
12
|
+
return Math.max(Math.min(least, natural[c]), Math.floor(w))
|
|
13
|
+
}
|
|
14
|
+
var total = 0
|
|
15
|
+
var floor = 0
|
|
16
|
+
for (var i = 0; i < natural.length; i++) {
|
|
17
|
+
total += natural[i]
|
|
18
|
+
floor += heldAt(i)
|
|
19
|
+
}
|
|
20
|
+
if (total <= avail)
|
|
21
|
+
return natural.slice()
|
|
22
|
+
var widths = []
|
|
23
|
+
if (floor <= avail) {
|
|
24
|
+
for (var c = 0; c < natural.length; c++) {
|
|
25
|
+
var held = heldAt(c)
|
|
26
|
+
widths.push(held + (avail - floor) * (natural[c] - held) / (total - floor))
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
// Even the longest words do not fit: every column holds its longest word whole and the table scrolls sideways.
|
|
30
|
+
for (var h = 0; h < natural.length; h++)
|
|
31
|
+
widths.push(heldAt(h))
|
|
32
|
+
}
|
|
33
|
+
return widths.map(capped)
|
|
34
|
+
}
|
package/ui/js/Marks.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
.import "Filter.js" as Filter
|
|
4
|
+
|
|
5
|
+
// Marking rows: ctrl+A, the shift range in both its keyboard and its pointer form, and ctrl+click.
|
|
6
|
+
// Split out of ui/js/Filter.js, which narrows the listing; these move the cursor and the marks over
|
|
7
|
+
// whatever that narrowing left drawn, which is why every one of them reads through it.
|
|
8
|
+
|
|
9
|
+
// Ctrl+A takes what is drawn, never what is listed: under a filter that is the matches alone.
|
|
10
|
+
function selectAll(pane) {
|
|
11
|
+
if (pane.shown === null) {
|
|
12
|
+
pane.selection.all(pane.total)
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
pane.selection.clear()
|
|
16
|
+
for (var i = 0; i < pane.shown.length; i++) {
|
|
17
|
+
pane.selection.toggle(pane.shown[i])
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// A gesture continues while nothing else moved the cursor since the last extend left it;
|
|
22
|
+
// any other cursor move, and any mark made outside the gesture, ends it through shiftState.
|
|
23
|
+
function continuing(pane) {
|
|
24
|
+
var state = pane.selection.shiftState()
|
|
25
|
+
return state !== null && pane.cursorIndex === state.last && (pane.cursorSeq || 0) === (state.seq || 0)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Invert flips the drawn marks; a row no filter draws is never selected.
|
|
29
|
+
function inverted(total, shown, selected) {
|
|
30
|
+
var drawn = shown === null ? range(total) : shown.slice()
|
|
31
|
+
var has = {}
|
|
32
|
+
for (var s = 0; s < selected.length; s++)
|
|
33
|
+
has[selected[s]] = true
|
|
34
|
+
var out = []
|
|
35
|
+
for (var i = 0; i < drawn.length; i++) {
|
|
36
|
+
if (has[drawn[i]] !== true)
|
|
37
|
+
out.push(drawn[i])
|
|
38
|
+
}
|
|
39
|
+
return out
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function range(total) {
|
|
43
|
+
var out = []
|
|
44
|
+
for (var r = 0; r < total; r++)
|
|
45
|
+
out.push(r)
|
|
46
|
+
return out
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The pane's own invert, through the same drawn set selectAll reads.
|
|
50
|
+
function invert(pane) {
|
|
51
|
+
var next = inverted(pane.total, pane.shown, pane.selectedIndices())
|
|
52
|
+
pane.selection.clear()
|
|
53
|
+
for (var i = 0; i < next.length; i++)
|
|
54
|
+
pane.selection.toggle(next[i])
|
|
55
|
+
pane.selectionVersion += 1
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A range starts at the cursor, or where it stood before the wheel pulled it onto the viewport.
|
|
59
|
+
function latchAnchor(pane) {
|
|
60
|
+
var from = Filter.pulledFrom(pane)
|
|
61
|
+
pane.selectionAnchor = from >= 0 ? from : pane.cursorIndex
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Shift+J and Shift+K, the whole gesture: the cursor moves through what is drawn and the selection
|
|
65
|
+
// is the base the gesture started from plus the drawn rows between the anchor and the cursor, so
|
|
66
|
+
// several blocks can be marked and the gesture's own range still grows and shrinks.
|
|
67
|
+
function extend(pane, delta) {
|
|
68
|
+
if (!continuing(pane)) {
|
|
69
|
+
pane.selection.shiftBegin(pane.selectedIndices(), pane.cursorIndex, pane.cursorSeq || 0)
|
|
70
|
+
latchAnchor(pane)
|
|
71
|
+
}
|
|
72
|
+
Filter.moveCursor(pane, delta)
|
|
73
|
+
extendTo(pane, pane.selectionAnchor)
|
|
74
|
+
pane.selection.shiftMoved(pane.cursorIndex, pane.cursorSeq || 0)
|
|
75
|
+
pane.selectionVersion += 1
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Shift+click, the absolute twin of extend() above: the anchor latches through latchAnchor before the
|
|
79
|
+
// click, which a plain click or ctrl+click already sets, and consecutive shift+clicks share one base.
|
|
80
|
+
// A click carries context 0 so the list never moves under the pointer.
|
|
81
|
+
function extendToRow(pane, index) {
|
|
82
|
+
if (!continuing(pane)) {
|
|
83
|
+
pane.selection.shiftBegin(pane.selectedIndices(), pane.cursorIndex, pane.cursorSeq || 0)
|
|
84
|
+
latchAnchor(pane)
|
|
85
|
+
}
|
|
86
|
+
Filter.setCursor(pane, index, 0)
|
|
87
|
+
extendTo(pane, pane.selectionAnchor)
|
|
88
|
+
pane.selection.shiftMoved(pane.cursorIndex, pane.cursorSeq || 0)
|
|
89
|
+
pane.selectionVersion += 1
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Ctrl+click, v's mouse twin. An empty set means the cursor row is selected, so it joins first.
|
|
93
|
+
// A click carries context 0 so the list never moves under the pointer.
|
|
94
|
+
function toggleRow(pane, index) {
|
|
95
|
+
if (pane.selection.count() === 0 && pane.cursorIndex !== index) {
|
|
96
|
+
pane.selection.toggle(pane.cursorIndex)
|
|
97
|
+
}
|
|
98
|
+
Filter.setCursor(pane, index, 0)
|
|
99
|
+
pane.selection.toggle(index)
|
|
100
|
+
pane.selectionAnchor = index
|
|
101
|
+
pane.selectionVersion += 1
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// A lone selection follows a plain move so delete takes the cursor row; deliberate marks drop lone.
|
|
105
|
+
function follow(pane) {
|
|
106
|
+
if (!pane.selection.follows() || pane.cursorIndex === pane.selectedIndices()[0])
|
|
107
|
+
return
|
|
108
|
+
var keep = pane.selection.isLanded ? pane.selection.isLanded() : false
|
|
109
|
+
pane.selection.only(pane.cursorIndex, keep)
|
|
110
|
+
pane.selectionAnchor = pane.cursorIndex
|
|
111
|
+
pane.selectionVersion += 1
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// v on a lone following row keeps it as a deliberate mark instead of toggling it off.
|
|
115
|
+
function toggleSelect(pane) {
|
|
116
|
+
if (!pane.selection.promote(pane.cursorIndex)) pane.selection.toggle(pane.cursorIndex)
|
|
117
|
+
pane.selectionAnchor = pane.cursorIndex
|
|
118
|
+
pane.selectionVersion += 1
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// The drawn rows between cursor and anchor; a shrinking gesture keeps its base.
|
|
122
|
+
function extendTo(pane, anchor) {
|
|
123
|
+
var state = pane.selection.shiftState()
|
|
124
|
+
if (state === null) {
|
|
125
|
+
if (pane.shown === null) {
|
|
126
|
+
pane.selection.extendTo(pane.cursorIndex, anchor)
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
pane.selection.clear()
|
|
130
|
+
var single = Filter.between(pane.shown, pane.cursorIndex, anchor)
|
|
131
|
+
for (var i = 0; i < single.length; i++) {
|
|
132
|
+
pane.selection.toggle(single[i])
|
|
133
|
+
}
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
var range
|
|
137
|
+
if (pane.shown === null) {
|
|
138
|
+
range = []
|
|
139
|
+
var lo = Math.min(pane.cursorIndex, anchor)
|
|
140
|
+
var hi = Math.max(pane.cursorIndex, anchor)
|
|
141
|
+
for (var r = lo; r <= hi; r++) {
|
|
142
|
+
range.push(r)
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
range = Filter.between(pane.shown, pane.cursorIndex, anchor)
|
|
146
|
+
}
|
|
147
|
+
pane.selection.shiftApply(range)
|
|
148
|
+
}
|
package/ui/js/Marquee.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
.import "Selection.js" as Selection
|
|
3
|
+
|
|
4
|
+
// Cell coordinates avoid inspecting or instantiating delegates outside the viewport.
|
|
5
|
+
function cells(x1, y1, x2, y2, width, height, columns, count) {
|
|
6
|
+
var left = Math.min(x1, x2), right = Math.max(x1, x2)
|
|
7
|
+
var top = Math.min(y1, y2), bottom = Math.max(y1, y2)
|
|
8
|
+
if (width <= 0 || height <= 0 || count <= 0 || left === right || top === bottom
|
|
9
|
+
|| right <= 0 || bottom <= 0 || left >= columns * width)
|
|
10
|
+
return null
|
|
11
|
+
var box = { left: Math.max(0, Math.floor(left / width)),
|
|
12
|
+
right: Math.min(columns - 1, Math.ceil(right / width) - 1),
|
|
13
|
+
top: Math.max(0, Math.floor(top / height)),
|
|
14
|
+
bottom: Math.min(Math.ceil(count / columns) - 1, Math.ceil(bottom / height) - 1) }
|
|
15
|
+
return box.top <= box.bottom ? box : null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function same(a, b) {
|
|
19
|
+
return a === b || (a !== null && b !== null && a.left === b.left && a.right === b.right
|
|
20
|
+
&& a.top === b.top && a.bottom === b.bottom)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Visit only strips entering or leaving the rectangle; a one-row move never scans all old marks.
|
|
24
|
+
function difference(box, other, columns, count, backwardsX, backwardsY, visit) {
|
|
25
|
+
if (box === null) return
|
|
26
|
+
var strips = [box]
|
|
27
|
+
if (other !== null && other.left <= box.right && other.right >= box.left
|
|
28
|
+
&& other.top <= box.bottom && other.bottom >= box.top) {
|
|
29
|
+
var top = Math.max(box.top, other.top), bottom = Math.min(box.bottom, other.bottom)
|
|
30
|
+
strips = [
|
|
31
|
+
{left: box.left, right: box.right, top: box.top, bottom: top - 1},
|
|
32
|
+
{left: box.left, right: Math.min(box.right, other.left - 1), top: top, bottom: bottom},
|
|
33
|
+
{left: Math.max(box.left, other.right + 1), right: box.right, top: top, bottom: bottom},
|
|
34
|
+
{left: box.left, right: box.right, top: bottom + 1, bottom: box.bottom}
|
|
35
|
+
]
|
|
36
|
+
strips.sort(function (a, b) {
|
|
37
|
+
return (backwardsY ? b.bottom - a.bottom : a.top - b.top)
|
|
38
|
+
|| (backwardsX ? b.right - a.right : a.left - b.left)
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
var rowStep = backwardsY ? -1 : 1
|
|
42
|
+
var columnStep = backwardsX ? -1 : 1
|
|
43
|
+
for (var s = 0; s < strips.length; s++) {
|
|
44
|
+
var strip = strips[s]
|
|
45
|
+
if (strip.left > strip.right) continue
|
|
46
|
+
for (var row = backwardsY ? strip.bottom : strip.top;
|
|
47
|
+
row >= strip.top && row <= strip.bottom; row += rowStep) {
|
|
48
|
+
for (var column = backwardsX ? strip.right : strip.left;
|
|
49
|
+
column >= strip.left && column <= strip.right; column += columnStep) {
|
|
50
|
+
var index = row * columns + column
|
|
51
|
+
if (index < count) visit(index)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function begin(pane, additive) {
|
|
58
|
+
var selection = Selection.create()
|
|
59
|
+
if (additive) {
|
|
60
|
+
var saved = pane.selectedIndices()
|
|
61
|
+
for (var i = 0; i < saved.length; i++) selection.toggle(saved[i])
|
|
62
|
+
}
|
|
63
|
+
var state = { before: pane.selection, cursor: pane.cursorIndex, anchor: pane.selectionAnchor,
|
|
64
|
+
additive: additive, box: null, last: -1 }
|
|
65
|
+
pane.selection = selection
|
|
66
|
+
pane.selectionVersion++
|
|
67
|
+
return state
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function update(pane, state, box, columns, count, backwardsX, backwardsY, listingIndex) {
|
|
71
|
+
if (same(state.box, box)) return
|
|
72
|
+
difference(state.box, box, columns, count, false, false, function (viewIndex) {
|
|
73
|
+
var index = listingIndex(viewIndex)
|
|
74
|
+
if (index >= 0 && !(state.additive && state.before.has(index))) pane.selection.toggle(index)
|
|
75
|
+
})
|
|
76
|
+
difference(box, state.box, columns, count, backwardsX, backwardsY, function (viewIndex) {
|
|
77
|
+
var index = listingIndex(viewIndex)
|
|
78
|
+
if (index < 0) return
|
|
79
|
+
if (!pane.selection.has(index)) pane.selection.toggle(index)
|
|
80
|
+
state.last = index
|
|
81
|
+
})
|
|
82
|
+
state.box = box
|
|
83
|
+
pane.selectionVersion++
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function finish(pane, state, cancelled) {
|
|
87
|
+
if (cancelled) {
|
|
88
|
+
pane.selection = state.before
|
|
89
|
+
pane.cursorIndex = state.cursor
|
|
90
|
+
pane.selectionAnchor = state.anchor
|
|
91
|
+
pane.selectionVersion++
|
|
92
|
+
} else if (state.last >= 0) {
|
|
93
|
+
pane.setCursor(state.last, 0)
|
|
94
|
+
pane.selectionAnchor = state.last
|
|
95
|
+
}
|
|
96
|
+
}
|
package/ui/js/Match.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
// A search row's name is its path relative to the search root, so the display splits it here and
|
|
4
|
+
// the wire never carries a second shape; see docs/protocol.md "search".
|
|
5
|
+
function base(path) {
|
|
6
|
+
var i = String(path).lastIndexOf("/")
|
|
7
|
+
return i < 0 ? String(path) : String(path).substring(i + 1)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// A Trash row's storage name is an IO identity, never its visible caption.
|
|
11
|
+
function rowName(row, locating) {
|
|
12
|
+
if (!row) return ""
|
|
13
|
+
if (row.trash) return row.trash.name !== undefined ? String(row.trash.name) : base(row.trash.original || row.n)
|
|
14
|
+
return locating ? base(row.n) : row.n
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// The location column: the parent path relative to the scope, empty for a match in the root itself.
|
|
18
|
+
function location(path) {
|
|
19
|
+
var i = String(path).lastIndexOf("/")
|
|
20
|
+
return i < 0 ? "" : String(path).substring(0, i)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Where to paint the accent run inside a name, mirroring the backend's own case-insensitive match.
|
|
24
|
+
// corner: a character whose lowercase form is a different length (Turkish dotted capital I) can
|
|
25
|
+
// shift the run by one; the name still renders whole, and the backend alone decides what matched.
|
|
26
|
+
function run(hay, needle) {
|
|
27
|
+
var h = String(hay)
|
|
28
|
+
var n = String(needle)
|
|
29
|
+
if (n.length === 0) {
|
|
30
|
+
return { start: -1, length: 0 }
|
|
31
|
+
}
|
|
32
|
+
// flea-qml: a query with a glob character is a shell glob over the whole name, so `*.js` is the
|
|
33
|
+
// names ending in .js; the run is then the whole name. Plain text stays a substring, as upstream.
|
|
34
|
+
var glob = globPattern(n)
|
|
35
|
+
if (glob !== null)
|
|
36
|
+
return glob.test(h) ? { start: 0, length: h.length } : { start: -1, length: 0 }
|
|
37
|
+
var at = h.toLowerCase().indexOf(n.toLowerCase())
|
|
38
|
+
return at < 0 ? { start: -1, length: 0 } : { start: at, length: n.length }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// flea-qml: `*` any run, `?` one character, `[abc]` `[a-z]` `[!a]` `[^a]` a class, `{js,ts}` one of
|
|
42
|
+
// the words, and `\` takes the next character literally; letter case is ignored, as the plain
|
|
43
|
+
// filter ignores it. A `[` or `{` with no close is that character itself. Null for a query with no
|
|
44
|
+
// glob character. Sample input: "*.{js,ts}" matches "app.js" and "types.ts", not "app.json".
|
|
45
|
+
var globCache = { source: null, regex: null }
|
|
46
|
+
function globPattern(query) {
|
|
47
|
+
if (!/[*?[{]/.test(query))
|
|
48
|
+
return null
|
|
49
|
+
if (globCache.source === query)
|
|
50
|
+
return globCache.regex
|
|
51
|
+
var out = "", depth = 0
|
|
52
|
+
for (var i = 0; i < query.length; i++) {
|
|
53
|
+
var c = query.charAt(i)
|
|
54
|
+
if (c === "\\" && i + 1 < query.length) {
|
|
55
|
+
out += escapeRegex(query.charAt(++i))
|
|
56
|
+
} else if (c === "*") {
|
|
57
|
+
out += ".*"
|
|
58
|
+
} else if (c === "?") {
|
|
59
|
+
out += "."
|
|
60
|
+
} else if (c === "[") {
|
|
61
|
+
var close = query.indexOf("]", i + 2)
|
|
62
|
+
if (close < 0) { out += "\\["; continue }
|
|
63
|
+
var body = query.substring(i + 1, close)
|
|
64
|
+
var negate = body.charAt(0) === "!" || body.charAt(0) === "^"
|
|
65
|
+
if (negate) body = body.substring(1)
|
|
66
|
+
out += "[" + (negate ? "^" : "") + body.replace(/[\\\]]/g, "\\$&") + "]"
|
|
67
|
+
i = close
|
|
68
|
+
} else if (c === "{" && query.indexOf("}", i) > i) {
|
|
69
|
+
out += "(?:"
|
|
70
|
+
depth++
|
|
71
|
+
} else if (c === "," && depth > 0) {
|
|
72
|
+
out += "|"
|
|
73
|
+
} else if (c === "}" && depth > 0) {
|
|
74
|
+
out += ")"
|
|
75
|
+
depth--
|
|
76
|
+
} else {
|
|
77
|
+
out += escapeRegex(c)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
var regex = null
|
|
81
|
+
try {
|
|
82
|
+
regex = new RegExp("^" + out + "$", "i")
|
|
83
|
+
} catch (e) {
|
|
84
|
+
// A pattern the engine refuses matches nothing rather than everything.
|
|
85
|
+
regex = /(?!)/
|
|
86
|
+
}
|
|
87
|
+
globCache = { source: query, regex: regex }
|
|
88
|
+
return regex
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function escapeRegex(c) {
|
|
92
|
+
return /[.*+?^${}()|[\]\\\/]/.test(c) ? "\\" + c : c
|
|
93
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
.import "Contrast.js" as Contrast
|
|
3
|
+
|
|
4
|
+
// Omarchy Glassy dims its blurred backdrop to 0.75; channels and alpha use whole 8-bit steps.
|
|
5
|
+
var STEPS = 255
|
|
6
|
+
var MIN_ALPHA = Math.ceil(0.75 * STEPS)
|
|
7
|
+
var INK_STEP = 1.25
|
|
8
|
+
// Twenty bisections resolve lightness more finely than one 8-bit colour channel.
|
|
9
|
+
var LIGHTNESS_SEARCH_STEPS = 20
|
|
10
|
+
// Half an 8-bit channel step repairs rounding without skipping the first passing colour.
|
|
11
|
+
var ROUNDING_REPAIR_STEPS = 512
|
|
12
|
+
|
|
13
|
+
function ground(plane, a, backdrop) {
|
|
14
|
+
return Contrast.hexOf(Contrast.over(String(plane), a / STEPS, backdrop))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function worst(ink, c, a, planes) {
|
|
18
|
+
var least = Infinity
|
|
19
|
+
var grounds = planes || [c.background, c.surface]
|
|
20
|
+
var brightness = c.blurBrightness === undefined ? 0.75 : c.blurBrightness
|
|
21
|
+
var white = Contrast.hexOf([brightness, brightness, brightness])
|
|
22
|
+
var backdrops = [white, "#000000"]
|
|
23
|
+
for (var p = 0; p < grounds.length; p++)
|
|
24
|
+
for (var b = 0; b < backdrops.length; b++)
|
|
25
|
+
least = Math.min(least, Contrast.ratio(String(ink), ground(grounds[p], a, backdrops[b])))
|
|
26
|
+
return least
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function direction(c) {
|
|
30
|
+
var fg = Contrast.parse(String(c.foreground)), bg = Contrast.parse(String(c.background))
|
|
31
|
+
return Contrast.luminance(fg[0], fg[1], fg[2]) > Contrast.luminance(bg[0], bg[1], bg[2]) ? [1, 1, 1] : [0, 0, 0]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The R3 lightness walk, including its rounding repair, applied to the live palette rather than a theme-name table.
|
|
35
|
+
function inkHolds(ink, c, a, need, quiet) {
|
|
36
|
+
if (worst(ink, c, a) < need) return false
|
|
37
|
+
if (quiet === undefined) return true
|
|
38
|
+
var x = Contrast.parse(String(ink)), q = Contrast.parse(String(quiet))
|
|
39
|
+
var lx = Contrast.luminance(x[0], x[1], x[2]), lq = Contrast.luminance(q[0], q[1], q[2])
|
|
40
|
+
return direction(c)[0] === 1 ? lx >= lq : lx <= lq
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function liftInk(ink, c, a, need, quiet) {
|
|
44
|
+
if (inkHolds(ink, c, a, need, quiet)) return String(ink)
|
|
45
|
+
var from = Contrast.parse(String(ink)), to = direction(c), lo = 0, hi = 1
|
|
46
|
+
for (var i = 0; i < LIGHTNESS_SEARCH_STEPS; i++) {
|
|
47
|
+
var mid = (lo + hi) / 2
|
|
48
|
+
if (inkHolds(Contrast.hexOf(Contrast.mix(from, to, mid)), c, a, need, quiet)) hi = mid
|
|
49
|
+
else lo = mid
|
|
50
|
+
}
|
|
51
|
+
for (var t = hi; t <= 1; t += 1 / ROUNDING_REPAIR_STEPS) {
|
|
52
|
+
var hex = Contrast.hexOf(Contrast.mix(from, to, t))
|
|
53
|
+
if (inkHolds(hex, c, a, need, quiet)) return hex
|
|
54
|
+
}
|
|
55
|
+
return Contrast.hexOf(to)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function quieter(ink, primary, c) {
|
|
59
|
+
var x = Contrast.parse(String(ink)), fg = Contrast.parse(String(primary))
|
|
60
|
+
var lx = Contrast.luminance(x[0], x[1], x[2]), lf = Contrast.luminance(fg[0], fg[1], fg[2])
|
|
61
|
+
return (direction(c)[0] === 1 ? lx < lf : lx > lf) && Contrast.ratio(String(ink), String(primary)) >= INK_STEP
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function primaryHolds(primary, c, a, need, muted, metadata) {
|
|
65
|
+
return worst(primary, c, a) >= need && quieter(muted, primary, c) && quieter(metadata, primary, c)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// A mode may lift primary ink too, so legible secondary ink never becomes the primary rung.
|
|
69
|
+
function primaryInk(c, a, need, muted, metadata) {
|
|
70
|
+
if (primaryHolds(c.foreground, c, a, need, muted, metadata)) return String(c.foreground)
|
|
71
|
+
var from = Contrast.parse(String(c.foreground)), to = direction(c), lo = 0, hi = 1
|
|
72
|
+
for (var i = 0; i < LIGHTNESS_SEARCH_STEPS; i++) {
|
|
73
|
+
var mid = (lo + hi) / 2
|
|
74
|
+
if (primaryHolds(Contrast.hexOf(Contrast.mix(from, to, mid)), c, a, need, muted, metadata)) hi = mid
|
|
75
|
+
else lo = mid
|
|
76
|
+
}
|
|
77
|
+
for (var t = hi; t <= 1; t += 1 / ROUNDING_REPAIR_STEPS) {
|
|
78
|
+
var hex = Contrast.hexOf(Contrast.mix(from, to, t))
|
|
79
|
+
if (primaryHolds(hex, c, a, need, muted, metadata)) return hex
|
|
80
|
+
}
|
|
81
|
+
return Contrast.hexOf(to)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function inks(c, a, need) {
|
|
85
|
+
var muted = liftInk(c.muted, c, a, need), metadata = liftInk(c.metadata, c, a, need)
|
|
86
|
+
var meta = Contrast.parse(metadata), fg = Contrast.parse(String(c.foreground))
|
|
87
|
+
var lm = Contrast.luminance(meta[0], meta[1], meta[2]), lf = Contrast.luminance(fg[0], fg[1], fg[2])
|
|
88
|
+
// Darkening a light palette's foreground put metadata beyond primary, or on it in White; reuse its muted rung.
|
|
89
|
+
if (direction(c)[0] === 1 ? lm >= lf : lm <= lf) metadata = muted
|
|
90
|
+
var primary = primaryInk(c, a, need, muted, metadata)
|
|
91
|
+
return {foreground: primary, muted: muted, metadata: metadata}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// One alpha for every main plane in A, raised only if its ink cannot hold the two text rungs.
|
|
95
|
+
function floor(c, need) {
|
|
96
|
+
for (var a = MIN_ALPHA; a < STEPS; a++) {
|
|
97
|
+
var ink = inks(c, a, need)
|
|
98
|
+
if (primaryHolds(ink.foreground, c, a, need, ink.muted, ink.metadata)
|
|
99
|
+
&& worst(ink.muted, c, a) >= need && worst(ink.metadata, c, a) >= need) return a
|
|
100
|
+
}
|
|
101
|
+
return STEPS
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// B keeps the unlifted listing text legible on its own background plane, never thinner than A.
|
|
105
|
+
function listFloor(c, need) {
|
|
106
|
+
var a = STEPS
|
|
107
|
+
while (a > 0 && Math.min(worst(c.muted, c, a - 1, [c.background]), worst(c.metadata, c, a - 1, [c.background])) >= need) a--
|
|
108
|
+
return a
|
|
109
|
+
}
|