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/MdLeaf.js
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
// MdLeaf: leaf-block readers over MdRun (tasks, fences, breaks, tables, images, alerts), each a pure function of its lines.
|
|
4
|
+
.import "MdUrl.js" as MdUrl
|
|
5
|
+
.import "MdHtml.js" as MdHtml
|
|
6
|
+
.import "MdInline.js" as Md
|
|
7
|
+
.import "MdHtmlImage.js" as HtmlImage
|
|
8
|
+
.import "MdLink.js" as Link
|
|
9
|
+
|
|
10
|
+
// The limits MdContainer names for list markers; the worker bundle shares only functions between files, so each holds its own.
|
|
11
|
+
var MAX_MARKER_INDENT = 3
|
|
12
|
+
var MAX_MARKER_DIGITS = 9
|
|
13
|
+
var MAX_HEADING_LEVEL = 6
|
|
14
|
+
var hasOwn = Object.prototype.hasOwnProperty
|
|
15
|
+
var ORDERED_MARKER = new RegExp("^(\\d{1," + MAX_MARKER_DIGITS + "})([.)])(?=[ \\t]|$)")
|
|
16
|
+
var HEADING_MARKER = new RegExp("^(?:[-+*](?:[ \\t]|$)|>|#{1," + MAX_HEADING_LEVEL + "}(?:[ \\t]|$)|```|~~~)")
|
|
17
|
+
|
|
18
|
+
// A family that holds both box glyphs, so the open and the done box draw from one text font and neither falls back to a colour emoji font.
|
|
19
|
+
var TASK_BOX_FACE = "Noto Sans Symbols 2"
|
|
20
|
+
var TASK_BOX_LEAD = /^([\u2610\u2611]) /
|
|
21
|
+
|
|
22
|
+
// Sample input: "[x] done" draws U+2611 and "[ ] pending" draws U+2610; pinTaskBox then sets the box in TASK_BOX_FACE.
|
|
23
|
+
function taskText(text) {
|
|
24
|
+
var m = /^\[([ xX])\] (.*)$/.exec(String(text))
|
|
25
|
+
if (m === null)
|
|
26
|
+
return text
|
|
27
|
+
return (m[1] === " " ? "\u2610 " : "\u2611 ") + m[2]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Sample input: "\u2611 done" answers '<font face="Noto Sans Symbols 2">\u2611</font> done'; a font tag with no colour survives Text.MarkdownText and keeps the row ink.
|
|
31
|
+
function pinTaskBox(text) {
|
|
32
|
+
var m = TASK_BOX_LEAD.exec(String(text))
|
|
33
|
+
return m === null ? text : '<font face="' + TASK_BOX_FACE + '">' + m[1] + "</font>" + text.slice(1)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Sample input: " * * *" is a thematic break.
|
|
37
|
+
function isThematic(line) {
|
|
38
|
+
return /^ {0,3}([*_-])(?:[ \t]*\1){2,}[ \t]*$/.test(String(line))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Sample input: "## Second level ##" answers { level: 2, text: "Second level" }; "#hashtag" answers null.
|
|
42
|
+
function atxHeading(line) {
|
|
43
|
+
var s = String(line)
|
|
44
|
+
var i = 0
|
|
45
|
+
while (i < MAX_MARKER_INDENT && s.charAt(i) === " ")
|
|
46
|
+
i++
|
|
47
|
+
var from = i
|
|
48
|
+
while (i < s.length && s.charAt(i) === "#")
|
|
49
|
+
i++
|
|
50
|
+
var level = i - from
|
|
51
|
+
if (level < 1 || level > MAX_HEADING_LEVEL || (i < s.length && s.charAt(i) !== " " && s.charAt(i) !== "\t"))
|
|
52
|
+
return null
|
|
53
|
+
var end = s.length
|
|
54
|
+
while (end > i && (s.charAt(end - 1) === " " || s.charAt(end - 1) === "\t"))
|
|
55
|
+
end--
|
|
56
|
+
var close = end
|
|
57
|
+
while (close > i && s.charAt(close - 1) === "#")
|
|
58
|
+
close--
|
|
59
|
+
if (close < end && (close === i || s.charAt(close - 1) === " " || s.charAt(close - 1) === "\t"))
|
|
60
|
+
end = close
|
|
61
|
+
while (end > i && (s.charAt(end - 1) === " " || s.charAt(end - 1) === "\t"))
|
|
62
|
+
end--
|
|
63
|
+
while (i < end && (s.charAt(i) === " " || s.charAt(i) === "\t"))
|
|
64
|
+
i++
|
|
65
|
+
return { level: level, text: s.slice(i, end) }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Sample input: 1. Intro answers 1\. Intro; - item answers \- item; _Plain_ is unchanged.
|
|
69
|
+
function headingSafe(text) {
|
|
70
|
+
var t = String(text)
|
|
71
|
+
var ordered = ORDERED_MARKER.exec(t)
|
|
72
|
+
if (ordered !== null)
|
|
73
|
+
return ordered[1] + "\\" + t.slice(ordered[1].length)
|
|
74
|
+
var block = HEADING_MARKER.test(t)
|
|
75
|
+
return block || isThematic(t) ? "\\" + t : t
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Sample: "Title\n=" or "Title\n--" closes a paragraph with a setext underline.
|
|
79
|
+
function isSetext(line) {
|
|
80
|
+
return /^ {0,3}(?:=+|-+)[ \t]*$/.test(String(line))
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Sample input: "===" underlines a level 1 heading, "---" and "--" a level 2.
|
|
84
|
+
function setextLevel(line) {
|
|
85
|
+
return String(line).trim().charAt(0) === "=" ? 1 : 2
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Sample input: "```js" opens a backtick fence with info "js".
|
|
89
|
+
function fenceOpen(line) {
|
|
90
|
+
var m = /^( {0,3})(```+|~~~+) *(.*)$/.exec(String(line))
|
|
91
|
+
if (m === null)
|
|
92
|
+
return null
|
|
93
|
+
if (m[2].charAt(0) === "`" && m[3].indexOf("`") >= 0)
|
|
94
|
+
return null
|
|
95
|
+
return { tick: m[2].charAt(0), len: m[2].length, indent: m[1].length, info: m[3].replace(/\s+$/, "") }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Sample input: "| :--- | ---: |"; dashes with optional edge colons carry the alignment, anything else is not a table.
|
|
99
|
+
function delimAligns(line) {
|
|
100
|
+
var cells = String(line).trim().replace(/^\||\|$/g, "").split("|")
|
|
101
|
+
if (cells.length === 0)
|
|
102
|
+
return null
|
|
103
|
+
var aligns = []
|
|
104
|
+
for (var i = 0; i < cells.length; i++) {
|
|
105
|
+
var m = cells[i].match(/^\s*(:?)-+(:?)\s*$/)
|
|
106
|
+
if (!m)
|
|
107
|
+
return null
|
|
108
|
+
aligns.push(m[1] && m[2] ? "center" : m[2] ? "right" : "left")
|
|
109
|
+
}
|
|
110
|
+
return aligns
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Sample input: "| a | b \|" keeps the final pipe as cell text; other backslash pairs reach the inline scanner.
|
|
114
|
+
function splitRow(line) {
|
|
115
|
+
var text = String(line).trim().replace(/^\|/, "")
|
|
116
|
+
var cells = []
|
|
117
|
+
var cell = ""
|
|
118
|
+
for (var i = 0; i < text.length; i++) {
|
|
119
|
+
var ch = text.charAt(i)
|
|
120
|
+
if (ch === "\\" && i + 1 < text.length && /[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]/.test(text.charAt(i + 1))) {
|
|
121
|
+
cell += text.charAt(i + 1) === "|" ? "|" : ch + text.charAt(i + 1)
|
|
122
|
+
i++
|
|
123
|
+
} else if (ch === "|") {
|
|
124
|
+
if (i + 1 === text.length)
|
|
125
|
+
break
|
|
126
|
+
cells.push(cell)
|
|
127
|
+
cell = ""
|
|
128
|
+
} else {
|
|
129
|
+
cell += ch
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
cells.push(cell)
|
|
133
|
+
for (var j = 0; j < cells.length; j++)
|
|
134
|
+
cells[j] = cells[j].trim()
|
|
135
|
+
return cells
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Rows per table chunk and items per list chunk: a longer container is emitted as consecutive blocks the outer ListView draws lazily.
|
|
139
|
+
var TABLE_CHUNK_ROWS = 24
|
|
140
|
+
var LIST_CHUNK_ITEMS = 32
|
|
141
|
+
|
|
142
|
+
// Columns an image holds in a cell's measure; its true width is only known once Qt decodes it.
|
|
143
|
+
var IMAGE_COLUMNS = 8
|
|
144
|
+
// One image, as the cell's Markdown or a raw tag; the private-use character stands for it while the text is counted.
|
|
145
|
+
var CELL_IMAGE = /!\[[^\]]*\]\([^)]*\)|<img\b[^>]*>/gi
|
|
146
|
+
// The chip pad span MdEscape.CHIP_PAD_HTML writes; a pad holds no column, and the worker bundle shares only functions between files.
|
|
147
|
+
var CHIP_PAD_CELL = /<span style="font-size:chippad"> <\/span>/g
|
|
148
|
+
var CELL_GLYPH = /[\ud800-\udbff][\udc00-\udfff]|[\s\S]/g
|
|
149
|
+
var WIDE_GLYPH = /[\u1100-\u115f\u2e80-\ua4cf\uac00-\ud7a3\uf900-\ufaff\ufe30-\ufe6f\uff00-\uff60\uffe0-\uffe6]/
|
|
150
|
+
|
|
151
|
+
// Sample input: 'a<br>**bb** ! ' draws lines "a" and "bb ! \ue000": 5 columns of text, 13 with the image, a longest word of 8.
|
|
152
|
+
// A wide glyph counts 2, a joiner, a variation selector and a chip's pad span 0, a break starts a line, and an image counts only in image.
|
|
153
|
+
function cellExtent(cell) {
|
|
154
|
+
var plain = String(cell).replace(CHIP_PAD_CELL, "").replace(/<br\s*\/?>/gi, "\n").replace(CELL_IMAGE, "\ue000").replace(/<[^>"]*("[^"]*"[^>"]*)*>/g, "").replace(/[*_~`]/g, "")
|
|
155
|
+
plain = plain.replace(/&#(\d+);/g, function (m, n) { return String.fromCharCode(parseInt(n, 10)) }).replace(/&(amp|lt|gt|quot);/g, "?")
|
|
156
|
+
var out = { text: 0, image: 0, word: 0 }
|
|
157
|
+
for (var l = 0, lines = plain.split("\n"); l < lines.length; l++) {
|
|
158
|
+
var text = 0, image = 0, word = 0, joined = false
|
|
159
|
+
var glyphs = lines[l].match(CELL_GLYPH) || []
|
|
160
|
+
for (var i = 0; i < glyphs.length; i++) {
|
|
161
|
+
var g = glyphs[i]
|
|
162
|
+
var space = /\s/.test(g)
|
|
163
|
+
var picture = g === "\ue000"
|
|
164
|
+
var cols = joined || g === "\u200d" || g === "\ufe0f" ? 0 : picture ? IMAGE_COLUMNS : space ? 1 : g.length > 1 || WIDE_GLYPH.test(g) ? 2 : 1
|
|
165
|
+
joined = g === "\u200d"
|
|
166
|
+
image += cols
|
|
167
|
+
text += picture ? 0 : cols
|
|
168
|
+
word = space ? 0 : word + cols
|
|
169
|
+
out.word = Math.max(out.word, word)
|
|
170
|
+
}
|
|
171
|
+
out.text = Math.max(out.text, text)
|
|
172
|
+
out.image = Math.max(out.image, image)
|
|
173
|
+
}
|
|
174
|
+
return out
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Sample input: widest(["ab", "cdef"], [{ text: 2 }, { text: 4 }], "text", false) is "cdef"; images only skips cells with no image.
|
|
178
|
+
function widest(cells, drawn, key, imagesOnly) {
|
|
179
|
+
var best = ""
|
|
180
|
+
var bestColumns = 0
|
|
181
|
+
for (var i = 0; i < cells.length; i++) {
|
|
182
|
+
if (drawn[i][key] > bestColumns && (!imagesOnly || drawn[i].image > drawn[i].text)) {
|
|
183
|
+
best = cells[i]
|
|
184
|
+
bestColumns = drawn[i][key]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return best
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// The board's table as data: measure is each column's widest cell so chunks share widths, pictures the widest image cell of unknown width, words the longest run.
|
|
191
|
+
function tableBlock(head, aligns, rows, inlineOf) {
|
|
192
|
+
var cols = head.length
|
|
193
|
+
var shownHead = head.map(inlineOf)
|
|
194
|
+
// GFM: a row's cells beyond the header's are dropped, and a short row is padded with empty cells.
|
|
195
|
+
var shownRows = rows.map(function (cells) {
|
|
196
|
+
var row = cells.slice(0, cols).map(inlineOf)
|
|
197
|
+
while (row.length < cols)
|
|
198
|
+
row.push("")
|
|
199
|
+
return row
|
|
200
|
+
})
|
|
201
|
+
var measure = []
|
|
202
|
+
var pictures = []
|
|
203
|
+
var weights = []
|
|
204
|
+
var words = []
|
|
205
|
+
for (var c = 0; c < cols; c++) {
|
|
206
|
+
var column = [c < shownHead.length ? shownHead[c] : ""]
|
|
207
|
+
for (var r = 0; r < shownRows.length; r++)
|
|
208
|
+
column.push(c < shownRows[r].length ? shownRows[r][c] : "")
|
|
209
|
+
var drawn = column.map(cellExtent)
|
|
210
|
+
measure.push(widest(column, drawn, "text", false))
|
|
211
|
+
pictures.push(widest(column, drawn, "image", true))
|
|
212
|
+
weights.push(cellExtent(measure[c]).text)
|
|
213
|
+
words.push(cellExtent(widest(column, drawn, "word", false)).word)
|
|
214
|
+
}
|
|
215
|
+
return { type: "table", head: shownHead, aligns: aligns, rows: shownRows, cols: cols, measure: measure, pictures: pictures, weights: weights, words: words }
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// The tables chunked so far, which numbers each one's chunks.
|
|
219
|
+
var chunkedTables = 0
|
|
220
|
+
|
|
221
|
+
// Splits a long table into consecutive blocks: the header stays on the first, the rest are marked joined.
|
|
222
|
+
function chunkTable(table) {
|
|
223
|
+
if (table.rows.length <= TABLE_CHUNK_ROWS)
|
|
224
|
+
return [table]
|
|
225
|
+
var chunks = []
|
|
226
|
+
// Every chunk of one table carries its key and whether it is the last, so they scroll sideways as one and the last holds the bar's lane.
|
|
227
|
+
var key = ++chunkedTables
|
|
228
|
+
for (var at = 0; at < table.rows.length; at += TABLE_CHUNK_ROWS)
|
|
229
|
+
chunks.push({ type: "table", head: at === 0 ? table.head : [], aligns: table.aligns,
|
|
230
|
+
rows: table.rows.slice(at, at + TABLE_CHUNK_ROWS), cols: table.cols, measure: table.measure, pictures: table.pictures,
|
|
231
|
+
weights: table.weights, words: table.words, joined: at > 0, tableKey: key, last: at + TABLE_CHUNK_ROWS >= table.rows.length })
|
|
232
|
+
return chunks
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Sample input: "", "![alt][ref]" or one raw <img> tag; balanced brackets nest, backslashes skip.
|
|
236
|
+
function standaloneImage(line, dir, defs) {
|
|
237
|
+
var text = String(line).trim()
|
|
238
|
+
var end = scanBalanced(text, 2)
|
|
239
|
+
if (text.charAt(0) === "!" && text.charAt(1) === "[" && end > 0) {
|
|
240
|
+
var alt = text.slice(2, end)
|
|
241
|
+
var after = end + 1
|
|
242
|
+
var target = null
|
|
243
|
+
if (text.charAt(after) === "(") {
|
|
244
|
+
var t = Link.readInlineTarget(text, after)
|
|
245
|
+
if (t === null || t.end !== text.length)
|
|
246
|
+
return null
|
|
247
|
+
target = t.url
|
|
248
|
+
} else if (text.charAt(after) === "[") {
|
|
249
|
+
var r = Link.readLabelRef(text, after)
|
|
250
|
+
if (r === null || r.end !== text.length)
|
|
251
|
+
return null
|
|
252
|
+
var key = Link.normalizeLabel(r.label.length > 0 ? r.label : alt)
|
|
253
|
+
if (!hasOwn.call(defs, key))
|
|
254
|
+
return null
|
|
255
|
+
target = defs[key]
|
|
256
|
+
} else if (after === text.length) {
|
|
257
|
+
var skey = Link.normalizeLabel(alt)
|
|
258
|
+
if (alt.length === 0 || !hasOwn.call(defs, skey))
|
|
259
|
+
return null
|
|
260
|
+
target = defs[skey]
|
|
261
|
+
} else {
|
|
262
|
+
return null
|
|
263
|
+
}
|
|
264
|
+
return imageBlock(alt, target, dir)
|
|
265
|
+
}
|
|
266
|
+
if (/^<img\b[^<>]*>$/i.test(text))
|
|
267
|
+
return HtmlImage.rawImage(text, dir)
|
|
268
|
+
return null
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Balanced ] scan from the [ at pos; backslash escapes skipped. -1 when open.
|
|
272
|
+
function scanBalanced(text, pos) {
|
|
273
|
+
var depth = 0
|
|
274
|
+
var i = pos
|
|
275
|
+
while (i < text.length) {
|
|
276
|
+
var c = text.charAt(i)
|
|
277
|
+
if (c === "\\") {
|
|
278
|
+
i += 2
|
|
279
|
+
continue
|
|
280
|
+
}
|
|
281
|
+
if (c === "[")
|
|
282
|
+
depth++
|
|
283
|
+
else if (c === "]") {
|
|
284
|
+
if (depth === 0)
|
|
285
|
+
return i
|
|
286
|
+
depth--
|
|
287
|
+
}
|
|
288
|
+
i++
|
|
289
|
+
}
|
|
290
|
+
return -1
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function imageBlock(alt, target, dir) {
|
|
294
|
+
var seen = MdUrl.classifyImage(target, dir)
|
|
295
|
+
if (seen.kind === "remote")
|
|
296
|
+
return { type: "remote", host: seen.host }
|
|
297
|
+
if (seen.kind === "local")
|
|
298
|
+
return { type: "image", url: seen.url, alt: alt }
|
|
299
|
+
return null
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Sample input: "[!NOTE] Remember this" names a GFM alert and its trailing text.
|
|
303
|
+
function alertTitle(line) {
|
|
304
|
+
var m = /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(.*)$/i.exec(String(line))
|
|
305
|
+
if (m === null)
|
|
306
|
+
return null
|
|
307
|
+
var title = m[1].charAt(0).toUpperCase() + m[1].slice(1).toLowerCase()
|
|
308
|
+
return "**" + title + "**" + (m[2].length > 0 ? " " + m[2] : "")
|
|
309
|
+
}
|
package/ui/js/MdLink.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
// MdLink: the readers of a link's pieces, a destination and title, a reference label, an autolink and a bare address.
|
|
4
|
+
.import "MdInline.js" as Md
|
|
5
|
+
|
|
6
|
+
var TARGET_SCAN_LIMIT = 8192
|
|
7
|
+
var LABEL_SCAN_LIMIT = 1000
|
|
8
|
+
var MIN_BARELINK_LENGTH = 9
|
|
9
|
+
var HTTP_PREFIX_LENGTH = 7
|
|
10
|
+
var HTTPS_PREFIX_LENGTH = 8
|
|
11
|
+
var WWW_PREFIX_LENGTH = 4
|
|
12
|
+
|
|
13
|
+
// Sample input: "\n x" read at 0 answers 4, past the line ending and the indent; "\n \n x" answers -1, a blank line.
|
|
14
|
+
function skipBlanks(text, j, cap) {
|
|
15
|
+
var ending = false
|
|
16
|
+
while (j < text.length && j < cap) {
|
|
17
|
+
var c = text.charAt(j)
|
|
18
|
+
if (c === "\r" && text.charAt(j + 1) === "\n")
|
|
19
|
+
j++
|
|
20
|
+
else if (c !== " " && c !== "\t" && c !== "\n" && c !== "\r")
|
|
21
|
+
break
|
|
22
|
+
if (c === "\n" || c === "\r") {
|
|
23
|
+
if (ending)
|
|
24
|
+
return -1
|
|
25
|
+
ending = true
|
|
26
|
+
}
|
|
27
|
+
j++
|
|
28
|
+
}
|
|
29
|
+
return j
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Sample input: `a\>b> c` read from 0 answers 4, the ">" that closes an angle destination; a line ending, even after a backslash, answers -1; strict refuses "<".
|
|
33
|
+
function angleClose(text, from, limit, strict) {
|
|
34
|
+
var j = from
|
|
35
|
+
while (j < text.length && j < limit) {
|
|
36
|
+
var c = text.charAt(j)
|
|
37
|
+
if (c === ">")
|
|
38
|
+
return j
|
|
39
|
+
if (c === "\n" || c === "\r" || (strict === true && c === "<"))
|
|
40
|
+
return -1
|
|
41
|
+
// A backslash before a line ending is no escape, so the destination ends there unclosed.
|
|
42
|
+
if (c === "\\" && (text.charAt(j + 1) === "\n" || text.charAt(j + 1) === "\r"))
|
|
43
|
+
return -1
|
|
44
|
+
j += c === "\\" ? 2 : 1
|
|
45
|
+
}
|
|
46
|
+
return -1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Sample input: (b "t") after a label's "]"; answers {url, end} past ")", or null; blanks, a line ending and the title may span lines.
|
|
50
|
+
function readInlineTarget(text, i) {
|
|
51
|
+
if (text.charAt(i) !== "(")
|
|
52
|
+
return null
|
|
53
|
+
// Targets past the scan limit read as literal text: no real target runs that long, and an unbounded walk is quadratic.
|
|
54
|
+
var cap = i + TARGET_SCAN_LIMIT
|
|
55
|
+
var j = skipBlanks(text, i + 1, cap)
|
|
56
|
+
if (j < 0)
|
|
57
|
+
return null
|
|
58
|
+
var url = ""
|
|
59
|
+
if (text.charAt(j) === "<") {
|
|
60
|
+
j++
|
|
61
|
+
var start = j
|
|
62
|
+
j = angleClose(text, j, cap, true)
|
|
63
|
+
if (j < 0)
|
|
64
|
+
return null
|
|
65
|
+
url = text.slice(start, j)
|
|
66
|
+
j++
|
|
67
|
+
} else {
|
|
68
|
+
var depth = 0
|
|
69
|
+
var begin = j
|
|
70
|
+
while (j < text.length && j < cap) {
|
|
71
|
+
var c = text.charAt(j)
|
|
72
|
+
if (c === "\n" || c === "\r" || ((c === " " || c === "\t") && depth === 0))
|
|
73
|
+
break
|
|
74
|
+
if (c === "\\") {
|
|
75
|
+
if (text.charAt(j + 1) === "\n" || text.charAt(j + 1) === "\r")
|
|
76
|
+
return null
|
|
77
|
+
j += 2
|
|
78
|
+
continue
|
|
79
|
+
}
|
|
80
|
+
if (c === "(")
|
|
81
|
+
depth++
|
|
82
|
+
else if (c === ")") {
|
|
83
|
+
if (depth === 0)
|
|
84
|
+
break
|
|
85
|
+
depth--
|
|
86
|
+
}
|
|
87
|
+
j++
|
|
88
|
+
}
|
|
89
|
+
if (j >= cap)
|
|
90
|
+
return null
|
|
91
|
+
url = text.slice(begin, j)
|
|
92
|
+
}
|
|
93
|
+
var gap = j
|
|
94
|
+
j = skipBlanks(text, j, cap)
|
|
95
|
+
if (j < 0)
|
|
96
|
+
return null
|
|
97
|
+
var opener = text.charAt(j)
|
|
98
|
+
if (j > gap && (opener === '"' || opener === "'" || opener === "(")) {
|
|
99
|
+
var qclose = opener === "(" ? ")" : opener
|
|
100
|
+
j++
|
|
101
|
+
while (j < text.length && j < cap) {
|
|
102
|
+
var titleChar = text.charAt(j)
|
|
103
|
+
if (titleChar === qclose)
|
|
104
|
+
break
|
|
105
|
+
if (titleChar === "\n" || titleChar === "\r") {
|
|
106
|
+
var next = skipBlanks(text, j, cap)
|
|
107
|
+
if (next < 0)
|
|
108
|
+
return null
|
|
109
|
+
j = next
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
var escaped = titleChar === "\\" && text.charAt(j + 1) !== "\n" && text.charAt(j + 1) !== "\r"
|
|
113
|
+
j += escaped ? 2 : 1
|
|
114
|
+
}
|
|
115
|
+
if (j >= text.length || j >= cap || text.charAt(j) !== qclose)
|
|
116
|
+
return null
|
|
117
|
+
j = skipBlanks(text, j + 1, cap)
|
|
118
|
+
if (j < 0)
|
|
119
|
+
return null
|
|
120
|
+
}
|
|
121
|
+
if (j >= cap || text.charAt(j) !== ")")
|
|
122
|
+
return null
|
|
123
|
+
return { url: url, end: j + 1 }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// A [label] or collapsed [label][]; answers {label, end} or null. Inline text has no blank line.
|
|
127
|
+
function readLabelRef(text, i) {
|
|
128
|
+
if (text.charAt(i) !== "[")
|
|
129
|
+
return null
|
|
130
|
+
var j = i + 1
|
|
131
|
+
while (j < text.length && j - i < LABEL_SCAN_LIMIT) {
|
|
132
|
+
var c = text.charAt(j)
|
|
133
|
+
if (c === "]")
|
|
134
|
+
break
|
|
135
|
+
if (c === "[")
|
|
136
|
+
return null
|
|
137
|
+
if (c === "\\") {
|
|
138
|
+
j += 2
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
j++
|
|
142
|
+
}
|
|
143
|
+
if (j >= text.length || j - i >= LABEL_SCAN_LIMIT)
|
|
144
|
+
return null
|
|
145
|
+
return { label: text.slice(i + 1, j), end: j + 1 }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Sample input: " My\tLabel " normalizes to "my label" for reference lookup; the case fold sends sharp s to "ss".
|
|
149
|
+
function normalizeLabel(label) {
|
|
150
|
+
return String(label).replace(/[\t\n ]+/g, " ").replace(/^ | $/g, "").toLowerCase().replace(/\u00df/g, "ss")
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// CommonMark's email address: its local part set and dot-separated host labels.
|
|
154
|
+
var MAIL_ADDRESS = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
|
|
155
|
+
|
|
156
|
+
// A <scheme:...> or <mail> autolink at text[i] === "<"; answers {url, href, end} or null, href gaining mailto: for an address.
|
|
157
|
+
function readAutolink(text, i) {
|
|
158
|
+
var j = i + 1
|
|
159
|
+
while (j < text.length && j - i < TARGET_SCAN_LIMIT && text.charAt(j) !== ">" && !Md.isSpace(text.charAt(j)))
|
|
160
|
+
j++
|
|
161
|
+
if (j >= text.length || j - i >= TARGET_SCAN_LIMIT || text.charAt(j) !== ">")
|
|
162
|
+
return null
|
|
163
|
+
var inner = text.slice(i + 1, j)
|
|
164
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]{1,31}:[^<>]*$/.test(inner))
|
|
165
|
+
return { url: inner, href: inner, end: j + 1 }
|
|
166
|
+
if (MAIL_ADDRESS.test(inner))
|
|
167
|
+
return { url: inner, href: "mailto:" + inner, end: j + 1 }
|
|
168
|
+
return null
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Sample input: see https://a.example/x. here; answers {url, href, end} or null; trailing punctuation is stripped, www. gains http://.
|
|
172
|
+
function readBarelink(text, i) {
|
|
173
|
+
var http = text.slice(i, i + HTTP_PREFIX_LENGTH) === "http://" || text.slice(i, i + HTTPS_PREFIX_LENGTH) === "https://"
|
|
174
|
+
if (!http) {
|
|
175
|
+
if (text.slice(i, i + WWW_PREFIX_LENGTH) !== "www.")
|
|
176
|
+
return null
|
|
177
|
+
var before = i > 0 ? text.charAt(i - 1) : " "
|
|
178
|
+
if (/[A-Za-z0-9_\/@]/.test(before))
|
|
179
|
+
return null
|
|
180
|
+
}
|
|
181
|
+
var j = i
|
|
182
|
+
while (j < text.length && !Md.isSpace(text.charAt(j)) && text.charAt(j) !== "<")
|
|
183
|
+
j++
|
|
184
|
+
var parens = 0
|
|
185
|
+
for (var at = i; at < j; at++)
|
|
186
|
+
parens += text.charAt(at) === "(" ? 1 : text.charAt(at) === ")" ? -1 : 0
|
|
187
|
+
while (j > i) {
|
|
188
|
+
var tail = text.charAt(j - 1)
|
|
189
|
+
if ("?!.,;:".indexOf(tail) < 0 && !(tail === ")" && parens < 0))
|
|
190
|
+
break
|
|
191
|
+
parens += tail === ")" ? 1 : 0
|
|
192
|
+
j--
|
|
193
|
+
}
|
|
194
|
+
var url = text.slice(i, j)
|
|
195
|
+
return url.length < MIN_BARELINK_LENGTH ? null : { url: url, href: http ? url : "http://" + url, end: j }
|
|
196
|
+
}
|
package/ui/js/MdMath.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
.pragma library
|
|
2
|
+
|
|
3
|
+
// MdMath: where a display formula starts and ends in the block reader's lines, and which formulas a paragraph holds.
|
|
4
|
+
.import "MdInline.js" as Md
|
|
5
|
+
var INLINE_DELIMITER_LENGTH = 1
|
|
6
|
+
var DISPLAY_DELIMITER_LENGTH = 2
|
|
7
|
+
|
|
8
|
+
// Sample input: "$$x^2$$ tail" answers { source: "x^2", tail: " tail", to: i }; a lone "$$" opener reads on to its closer line.
|
|
9
|
+
function displayAt(lines, i, text) {
|
|
10
|
+
var disp = /^ {0,3}\$\$(.*)$/.exec(text)
|
|
11
|
+
if (disp === null)
|
|
12
|
+
return null
|
|
13
|
+
var rest = disp[1]
|
|
14
|
+
var closeAt = rest.indexOf("$$")
|
|
15
|
+
var source = ""
|
|
16
|
+
var tail = ""
|
|
17
|
+
var to = i
|
|
18
|
+
if (closeAt >= 0) {
|
|
19
|
+
source = rest.slice(0, closeAt).trim()
|
|
20
|
+
tail = rest.slice(closeAt + DISPLAY_DELIMITER_LENGTH)
|
|
21
|
+
} else {
|
|
22
|
+
// The closer search stops at the paragraph's blank line, so no later opener scans these lines again.
|
|
23
|
+
var end = -1
|
|
24
|
+
for (var at = i + 1; end < 0 && at < lines.length && lines[at].trim().length > 0; at++) {
|
|
25
|
+
if (lines[at].indexOf("$$") >= 0)
|
|
26
|
+
end = at
|
|
27
|
+
}
|
|
28
|
+
if (end > i) {
|
|
29
|
+
var endAt = lines[end].indexOf("$$")
|
|
30
|
+
source = [rest].concat(lines.slice(i + 1, end), [lines[end].slice(0, endAt)]).join("\n").trim()
|
|
31
|
+
tail = lines[end].slice(endAt + DISPLAY_DELIMITER_LENGTH)
|
|
32
|
+
to = end
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return source.length > 0 ? { source: source, tail: tail, to: to } : null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Sample input: "a $$x$$ b" answers [{ text: "a " }, { math: "x" }, { text: " b" }]; text without a display pair answers null.
|
|
39
|
+
function splitDisplay(text) {
|
|
40
|
+
if (text.indexOf("$$") < 0)
|
|
41
|
+
return null
|
|
42
|
+
var spans = Md.spanIntervals(text)
|
|
43
|
+
var pieces = []
|
|
44
|
+
var at = 0
|
|
45
|
+
for (var k = 0; k < spans.length; k += Md.INTERVAL_STRIDE) {
|
|
46
|
+
if (spans[k + 3] !== Md.MATH_SPAN || spans[k + 2] !== DISPLAY_DELIMITER_LENGTH)
|
|
47
|
+
continue
|
|
48
|
+
pieces.push({ text: text.slice(at, spans[k]) })
|
|
49
|
+
pieces.push({ math: text.slice(spans[k] + DISPLAY_DELIMITER_LENGTH, spans[k + 1] - DISPLAY_DELIMITER_LENGTH).trim() })
|
|
50
|
+
at = spans[k + 1]
|
|
51
|
+
}
|
|
52
|
+
pieces.push({ text: text.slice(at) })
|
|
53
|
+
return pieces.length > 1 ? pieces : null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Sample input: "e $x^2$ and $y$" answers ["x^2", "y"]; display pairs and code spans hold none.
|
|
57
|
+
function inlineSources(text) {
|
|
58
|
+
var out = []
|
|
59
|
+
if (text.indexOf("$") < 0)
|
|
60
|
+
return out
|
|
61
|
+
var spans = Md.spanIntervals(text)
|
|
62
|
+
for (var k = 0; k < spans.length; k += Md.INTERVAL_STRIDE) {
|
|
63
|
+
if (spans[k + 3] === Md.MATH_SPAN && spans[k + 2] === INLINE_DELIMITER_LENGTH)
|
|
64
|
+
out.push(text.slice(spans[k] + INLINE_DELIMITER_LENGTH, spans[k + 1] - INLINE_DELIMITER_LENGTH).trim())
|
|
65
|
+
}
|
|
66
|
+
return out
|
|
67
|
+
}
|