@mudlet/mudlet-web 0.5.0 → 1.0.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/README.md +1 -1
- package/dist-lib/analytics.d.ts +27 -0
- package/dist-lib/assets/fonts/Vera.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
- package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
- package/dist-lib/backupImport-wt8r7JXI.js +233 -0
- package/dist-lib/branding.d.ts +111 -13
- package/dist-lib/db/sqliteClient.d.ts +195 -7
- package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
- package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
- package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
- package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
- package/dist-lib/import/applyMudletProfile.d.ts +35 -9
- package/dist-lib/import/backupImport.d.ts +118 -0
- package/dist-lib/import/collectProfileExport.d.ts +33 -2
- package/dist-lib/import/defaultPackages.d.ts +57 -14
- package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
- package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
- package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
- package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
- package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
- package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
- package/dist-lib/import/defaults/icesus-loader/icesus-loader.mpackage +0 -0
- package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
- package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
- package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
- package/dist-lib/import/mudletControlChars.d.ts +14 -0
- package/dist-lib/import/mudletHost.d.ts +73 -10
- package/dist-lib/import/mudletLink.d.ts +53 -2
- package/dist-lib/import/mudletProfileExport.d.ts +38 -5
- package/dist-lib/import/mudletProfileImport.d.ts +110 -12
- package/dist-lib/import/mudletVariables.d.ts +4 -3
- package/dist-lib/import/mudletWriteback.d.ts +15 -1
- package/dist-lib/import/mudletXmlImport.d.ts +46 -0
- package/dist-lib/import/packageFonts.d.ts +33 -0
- package/dist-lib/import/packageInstaller.d.ts +111 -7
- package/dist-lib/import/qtProfileData.d.ts +10 -0
- package/dist-lib/import/remotePackageInstall.d.ts +23 -7
- package/dist-lib/import/zipEntries.d.ts +45 -0
- package/dist-lib/index.d.ts +7 -3
- package/dist-lib/index.js +50508 -29836
- package/dist-lib/logging/SessionLogger.d.ts +75 -15
- package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
- package/dist-lib/map/MapStore.d.ts +387 -60
- package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
- package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
- package/dist-lib/map/areaGraph.d.ts +120 -0
- package/dist-lib/map/environmentKit.d.ts +36 -0
- package/dist-lib/map/labelPixmap.d.ts +90 -0
- package/dist-lib/map/mapImageExport.d.ts +36 -2
- package/dist-lib/map/mapStyle.d.ts +11 -0
- package/dist-lib/map/mapVersion.d.ts +66 -0
- package/dist-lib/map/pathfinding.d.ts +2 -2
- package/dist-lib/mud/CharLoginController.d.ts +230 -0
- package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
- package/dist-lib/mud/MudSession.d.ts +279 -22
- package/dist-lib/mud/PatternEngine.d.ts +153 -14
- package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
- package/dist-lib/mud/autoLogin.d.ts +59 -0
- package/dist-lib/mud/commandSplit.d.ts +9 -0
- package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
- package/dist-lib/mud/connection/MudClient.d.ts +291 -53
- package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
- package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
- package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
- package/dist-lib/mud/events.d.ts +102 -23
- package/dist-lib/mud/games/bundledGames.d.ts +12 -7
- package/dist-lib/mud/games/gameLinks.d.ts +40 -0
- package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
- package/dist-lib/mud/games/icons/3Scapes.png +0 -0
- package/dist-lib/mud/games/icons/achaea.png +0 -0
- package/dist-lib/mud/games/icons/aetolia.png +0 -0
- package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
- package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
- package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
- package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
- package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
- package/dist-lib/mud/games/icons/blackmud.png +0 -0
- package/dist-lib/mud/games/icons/carrionfields.png +0 -0
- package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
- package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
- package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
- package/dist-lib/mud/games/icons/imperian.png +0 -0
- package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
- package/dist-lib/mud/games/icons/lusternia.png +0 -0
- package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
- package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
- package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
- package/dist-lib/mud/games/icons/starmourn.png +0 -0
- package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
- package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
- package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
- package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
- package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
- package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
- package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
- package/dist-lib/mud/protocol/atcp.d.ts +19 -0
- package/dist-lib/mud/protocol/byteString.d.ts +24 -0
- package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
- package/dist-lib/mud/protocol/charset.d.ts +111 -46
- package/dist-lib/mud/protocol/codePages.d.ts +10 -0
- package/dist-lib/mud/protocol/constants.d.ts +17 -10
- package/dist-lib/mud/protocol/echo.d.ts +23 -27
- package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
- package/dist-lib/mud/protocol/index.d.ts +3 -2
- package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
- package/dist-lib/mud/protocol/mccp.d.ts +83 -1
- package/dist-lib/mud/protocol/mnes.d.ts +41 -58
- package/dist-lib/mud/protocol/msdp.d.ts +11 -4
- package/dist-lib/mud/protocol/msp.d.ts +3 -2
- package/dist-lib/mud/protocol/mssp.d.ts +9 -4
- package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
- package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
- package/dist-lib/mud/protocol/mxp.d.ts +193 -14
- package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
- package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
- package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
- package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
- package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
- package/dist-lib/mud/text/Console.d.ts +255 -49
- package/dist-lib/mud/text/FormatState.d.ts +137 -14
- package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
- package/dist-lib/mud/text/colorParsers.d.ts +14 -2
- package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
- package/dist-lib/mud/text/colors.d.ts +17 -10
- package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
- package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
- package/dist-lib/mud/text/lineBreak.d.ts +5 -0
- package/dist-lib/mud/text/serverWrap.d.ts +2 -2
- package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
- package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
- package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
- package/dist-lib/mud/text/wcwidth.d.ts +27 -22
- package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
- package/dist-lib/mud/timers/workerClock.d.ts +67 -0
- package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
- package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
- package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
- package/dist-lib/oauth-callback.html +94 -0
- package/dist-lib/pcre2Wasm.d.ts +54 -0
- package/dist-lib/pcre2Wasm.js +241 -0
- package/dist-lib/scripting/EngineHost.d.ts +45 -21
- package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
- package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
- package/dist-lib/scripting/ScriptingAPI.d.ts +1030 -213
- package/dist-lib/scripting/ScriptingEngine.d.ts +727 -106
- package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
- package/dist-lib/scripting/http/HttpService.d.ts +9 -1
- package/dist-lib/scripting/http/userUrl.d.ts +41 -0
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
- package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
- package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
- package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
- package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
- package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
- package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
- package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
- package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
- package/dist-lib/scripting/lua/rex.d.ts +4 -2
- package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
- package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
- package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
- package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
- package/dist-lib/scripting/lua/yajl.d.ts +43 -5
- package/dist-lib/scripting/profilesPresence.d.ts +20 -2
- package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
- package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
- package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
- package/dist-lib/storage/appStore.d.ts +24 -9
- package/dist-lib/storage/hooks.d.ts +5 -1
- package/dist-lib/storage/index.d.ts +2 -2
- package/dist-lib/storage/mapStorage.d.ts +2 -0
- package/dist-lib/storage/persistentStorage.d.ts +3 -1
- package/dist-lib/storage/profileStorage.d.ts +15 -0
- package/dist-lib/storage/profileVfsData.d.ts +3 -3
- package/dist-lib/storage/schema.d.ts +512 -40
- package/dist-lib/storage/storageMigration.d.ts +82 -0
- package/dist-lib/storage-g5V1b-c1.js +2039 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/ui/AboutModal.d.ts +1 -1
- package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
- package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
- package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
- package/dist-lib/ui/CommandBar.d.ts +8 -8
- package/dist-lib/ui/ConnectionFormModal.d.ts +20 -1
- package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
- package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
- package/dist-lib/ui/HelpModal.d.ts +5 -1
- package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
- package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
- package/dist-lib/ui/NotepadModal.d.ts +22 -0
- package/dist-lib/ui/ResizableModal.d.ts +16 -1
- package/dist-lib/ui/SettingsModal.d.ts +10 -1
- package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
- package/dist-lib/ui/Toolbar.d.ts +22 -1
- package/dist-lib/ui/VaultManageButton.d.ts +10 -5
- package/dist-lib/ui/VaultModal.d.ts +3 -0
- package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
- package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
- package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
- package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
- package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
- package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
- package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
- package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
- package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
- package/dist-lib/ui/codemirror/options.d.ts +33 -0
- package/dist-lib/ui/codemirror/theme.d.ts +29 -5
- package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
- package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
- package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
- package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
- package/dist-lib/ui/commands/keySequence.d.ts +57 -0
- package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
- package/dist-lib/ui/components/FontPicker.d.ts +5 -1
- package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
- package/dist-lib/ui/helpTopics.d.ts +15 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
- package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
- package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
- package/dist-lib/ui/labels/labelModel.d.ts +64 -0
- package/dist-lib/ui/labels/qColor.d.ts +13 -0
- package/dist-lib/ui/labels/qtCss.d.ts +12 -4
- package/dist-lib/ui/landmarks.d.ts +9 -0
- package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
- package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
- package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
- package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
- package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
- package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
- package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
- package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
- package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
- package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
- package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
- package/dist-lib/ui/menu/appMenus.d.ts +65 -0
- package/dist-lib/ui/menu/menuModel.d.ts +88 -0
- package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
- package/dist-lib/ui/notepad.d.ts +76 -0
- package/dist-lib/ui/openSignInPage.d.ts +14 -0
- package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
- package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
- package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
- package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
- package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
- package/dist-lib/ui/output/caretMode.d.ts +3 -2
- package/dist-lib/ui/output/clearSplit.d.ts +11 -0
- package/dist-lib/ui/output/outputCopy.d.ts +41 -2
- package/dist-lib/ui/output/outputRows.d.ts +43 -0
- package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
- package/dist-lib/ui/output/wordSelection.d.ts +33 -0
- package/dist-lib/ui/search/matcher.d.ts +14 -4
- package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
- package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
- package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
- package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
- package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
- package/dist-lib/ui/tabCompletion.d.ts +53 -0
- package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
- package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
- package/dist-lib/ui/video/VideoManager.d.ts +7 -0
- package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
- package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
- package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
- package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
- package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
- package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
- package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
- package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
- package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
- package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
- package/dist-lib/utils/appShellCache.d.ts +25 -0
- package/dist-lib/utils/fontFamilyName.d.ts +13 -0
- package/dist-lib/utils/fontLoader.d.ts +31 -0
- package/dist-lib/utils/formatBytes.d.ts +4 -0
- package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
- package/dist-lib/utils/profileLock.d.ts +1 -1
- package/dist-lib/utils/systemTheme.d.ts +24 -0
- package/dist-lib/utils/timeZone.d.ts +10 -0
- package/dist-lib/vault/CredentialVault.d.ts +51 -5
- package/dist-lib/vault/deviceUnlock.d.ts +47 -0
- package/dist-lib/vault/vaultAccess.d.ts +24 -2
- package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
- package/dist-lib/vault/vaultRecord.d.ts +33 -1
- package/dist-lib/vfs-sw.js +220 -11
- package/dist-lib/vite.d.ts +1 -1
- package/dist-lib/vite.js +66 -43
- package/package.json +22 -14
- package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
- package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
- package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
- package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
- package/dist-lib/ui/bufferWords.d.ts +0 -38
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
/** Where a script left the command line's caret: at the end with nothing
|
|
3
|
+
* selected (printCmdLine, appendCmdLine), or around all of it
|
|
4
|
+
* (selectCmdLineText, sendCmdLine). */
|
|
5
|
+
export type CmdLineSelection = 'end' | 'all';
|
|
6
|
+
/**
|
|
7
|
+
* Place a command line's caret or selection once the text a script put there
|
|
8
|
+
* has actually reached the input.
|
|
9
|
+
*
|
|
10
|
+
* A script's printCmdLine only reaches the input through React state, so the
|
|
11
|
+
* new value lands on the next commit — and writing a controlled input's value
|
|
12
|
+
* moves its caret to the end, wiping any selection made before it. Applying
|
|
13
|
+
* the selection straight away (or from a microtask, which runs before a
|
|
14
|
+
* render scheduled from a timer) is how `printCmdLine("ghi");
|
|
15
|
+
* selectCmdLineText()` left nothing selected, so the next keystroke appended
|
|
16
|
+
* instead of replacing (issue #284). Desktop applies both to the widget
|
|
17
|
+
* synchronously, so the later call always wins; here the latest request is
|
|
18
|
+
* held and applied in a layout effect after the commit that carries the text.
|
|
19
|
+
*
|
|
20
|
+
* `value` is the input's controlled value. The returned function records a
|
|
21
|
+
* request and forces a render, so a request with no text change still lands.
|
|
22
|
+
* A script's request also focuses the input; `focus: false` is for the
|
|
23
|
+
* client's own selection after a send, which must not pull focus back to an
|
|
24
|
+
* input the send just let go of (a phone's keyboard).
|
|
25
|
+
*/
|
|
26
|
+
export declare function useCmdLineSelection(inputRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>, value: string): (selection: CmdLineSelection | null, focus?: boolean) => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type MutableRefObject, type RefObject } from 'react';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import type { CmdLineHost, SubCommandLine } from './subCommandLine';
|
|
4
|
+
interface Options {
|
|
5
|
+
model: SubCommandLine;
|
|
6
|
+
host: () => CmdLineHost;
|
|
7
|
+
inputRef: RefObject<HTMLTextAreaElement | null>;
|
|
8
|
+
/** The line's live text (what getCmdLine reads), kept current by the caller. */
|
|
9
|
+
valueRef: MutableRefObject<string>;
|
|
10
|
+
setValue: (text: string) => void;
|
|
11
|
+
/** Hand one command (one line of the box) to the action, or the game. */
|
|
12
|
+
dispatch: (command: string) => void;
|
|
13
|
+
/** The text a script put on this line (printCmdLine and the like) while
|
|
14
|
+
* the commands ran, marking it applied; null when none did. */
|
|
15
|
+
takeScripted: () => string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Key handling for a named command line — the createCommandLine overlay and a
|
|
19
|
+
* miniconsole's / user window's own line — driving {@link SubCommandLine}, the
|
|
20
|
+
* port of desktop's TCommandLine. Returns the textarea's onKeyDown and
|
|
21
|
+
* onChange.
|
|
22
|
+
*
|
|
23
|
+
* The keys desktop's TCommandLine::event takes for itself are taken here too:
|
|
24
|
+
* Enter sends, Shift+Enter starts another line in the box, Up/Down walk the
|
|
25
|
+
* history, Tab and Shift+Tab complete, Escape selects everything. Only a Tab
|
|
26
|
+
* on an empty line, or after a space, is let through, as on the main command
|
|
27
|
+
* line, so the keyboard can still leave the box (WCAG 2.1.2).
|
|
28
|
+
*/
|
|
29
|
+
export declare function useSubCommandLineKeys({ model, host, inputRef, valueRef, setValue, dispatch, takeScripted }: Options): {
|
|
30
|
+
onKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
31
|
+
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
32
|
+
};
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mudlet's Editor option "Show Line/Paragraphs", as the checkbox is named:
|
|
3
|
+
* a visible mark where each line of the script ends.
|
|
4
|
+
*
|
|
5
|
+
* Desktop currently under-delivers on its own label. `slot_changeShowLineFeeds\
|
|
6
|
+
* AndParagraphs` (dlgProfilePreferences.cpp:4073) sets edbee's
|
|
7
|
+
* `useLineSeparator`, which rules a faint horizontal line under each row, and
|
|
8
|
+
* the method's comment says so: the marks the option is named for "may in the
|
|
9
|
+
* future" arrive. The tooltip in `profile_preferences.ui:1746` still promises
|
|
10
|
+
* them — "show line and paragraph ends with visible marks as well as
|
|
11
|
+
* whitespace" — so that is what this draws, next to `highlightWhitespace()`'s
|
|
12
|
+
* dots and arrows, which is where the tooltip puts it.
|
|
13
|
+
*
|
|
14
|
+
* CodeMirror has no built-in for this (`highlightWhitespace` covers spaces and
|
|
15
|
+
* tabs only), so it is a decoration: a zero-width widget at every line end,
|
|
16
|
+
* with the last line marked differently because it has no line feed after it.
|
|
17
|
+
*/
|
|
18
|
+
/** The extension behind the "Show Line/Paragraphs" toggle. */
|
|
19
|
+
export declare function showLineParagraphs(): import("@codemirror/state").Extension[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const luaHoverTheme: import("@codemirror/state").Extension;
|
|
2
|
+
/** Signature + description for the Mudlet function under the pointer. Shared by
|
|
3
|
+
* the script editor and by a `.lua` file opened from the file browser — the
|
|
4
|
+
* same code deserves the same tooltip whichever door you came in through. */
|
|
5
|
+
export declare const luaHover: import("@codemirror/state").Extension & {
|
|
6
|
+
active: import("@codemirror/state").StateField<readonly import("@codemirror/view").Tooltip[]>;
|
|
7
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Compartment, type Extension } from '@codemirror/state';
|
|
2
|
+
/** Mudlet's Editor preference page, which Mudlet Web had no equivalent of: the
|
|
3
|
+
* display options and autocomplete were hard-coded on. Held in a compartment
|
|
4
|
+
* so a change reconfigures the live editor instead of remounting it, which is
|
|
5
|
+
* what the theme swap alongside it already does.
|
|
6
|
+
*
|
|
7
|
+
* Every CodeMirror surface in the app shares these — the script editor and
|
|
8
|
+
* the file browser's editor and JSON viewer. "Show Spaces/Tabs" that only
|
|
9
|
+
* applied to one of the three would be a setting you have to remember the
|
|
10
|
+
* scope of; `useEditorSettings()` is the single source for all of them. */
|
|
11
|
+
export interface EditorOptions {
|
|
12
|
+
/** "Autocomplete Lua functions in code editor". */
|
|
13
|
+
autocomplete: boolean;
|
|
14
|
+
/** "Show Spaces/Tabs" — dots for runs of spaces, arrows for tabs. */
|
|
15
|
+
showWhitespace: boolean;
|
|
16
|
+
/** "Show Line/Paragraphs" — a ¶ where each line ends. */
|
|
17
|
+
showLineParagraphs: boolean;
|
|
18
|
+
/** "Show invisible Unicode control characters". */
|
|
19
|
+
showControlChars: boolean;
|
|
20
|
+
/** "Theme" — the editor palette, pinned or following the app's. */
|
|
21
|
+
theme: 'app' | 'dark' | 'light';
|
|
22
|
+
}
|
|
23
|
+
export declare const EDITOR_OPTION_DEFAULTS: EditorOptions;
|
|
24
|
+
export declare const optionsCompartment: Compartment;
|
|
25
|
+
/**
|
|
26
|
+
* The display options as extensions.
|
|
27
|
+
*
|
|
28
|
+
* @param lua whether to offer Lua completion — true for the script editor and
|
|
29
|
+
* for a `.lua` file opened from the file browser, false for the
|
|
30
|
+
* JSON, XML and plain-text documents the same editor also serves,
|
|
31
|
+
* where Mudlet's function list is noise.
|
|
32
|
+
*/
|
|
33
|
+
export declare function optionExtensions(opts: EditorOptions, lua: boolean): Extension[];
|
|
@@ -1,5 +1,29 @@
|
|
|
1
|
-
import { Compartment } from '@codemirror/state';
|
|
2
|
-
|
|
3
|
-
export declare const
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { Compartment, type Extension } from '@codemirror/state';
|
|
2
|
+
export declare const mudletCmTheme: Extension;
|
|
3
|
+
export declare const paletteCompartment: Compartment;
|
|
4
|
+
/**
|
|
5
|
+
* Mudlet's Editor → Theme, as far as it makes sense here. Desktop downloads a
|
|
6
|
+
* catalogue from colorsublime; Mudlet Web ships the two palettes it already has and
|
|
7
|
+
* lets you pin one, which is the part of that feature people actually use — a
|
|
8
|
+
* dark editor under a light app theme, or the reverse.
|
|
9
|
+
*
|
|
10
|
+
* `app` is the default and keeps the old behaviour exactly.
|
|
11
|
+
*/
|
|
12
|
+
export type EditorTheme = 'app' | 'dark' | 'light';
|
|
13
|
+
export declare const EDITOR_THEME_CHOICES: {
|
|
14
|
+
value: EditorTheme;
|
|
15
|
+
label: string;
|
|
16
|
+
}[];
|
|
17
|
+
/**
|
|
18
|
+
* The whole palette for one editor: syntax colours, plus — when the theme is
|
|
19
|
+
* pinned — the chrome that goes with them.
|
|
20
|
+
*
|
|
21
|
+
* Pinning means pinning: "Atom One Light" under a dark app theme is a light
|
|
22
|
+
* editor, background and all, not light syntax colours floating on a black
|
|
23
|
+
* page. `'app'` returns highlighting alone and leaves the chrome on whatever
|
|
24
|
+
* CSS vars the document carries, which is also what keeps a brand theme's own
|
|
25
|
+
* surface colours from being flattened into the stock two.
|
|
26
|
+
*
|
|
27
|
+
* @param theme the app theme, consulted only when `editorTheme` is 'app'.
|
|
28
|
+
*/
|
|
29
|
+
export declare function paletteFor(theme: string, editorTheme?: EditorTheme): Extension;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mudlet's addon command API — the commands a package places on the client's
|
|
3
|
+
* own surfaces (`addCommand`, `removeCommand`, `enableCommand`, …).
|
|
4
|
+
*
|
|
5
|
+
* This holds the state and the answers; the argument contract in front of it
|
|
6
|
+
* lives in Bridge.lua, because the refusals name the Lua type of what they were
|
|
7
|
+
* given ("surfaces has to be a list of surface names and this one holds a
|
|
8
|
+
* boolean") and a value's Lua type is exactly what does not survive the trip
|
|
9
|
+
* across wasmoon.
|
|
10
|
+
*
|
|
11
|
+
* What "reserved" means here is worth being straight about. On desktop Mudlet
|
|
12
|
+
* answers "is this key free?" by asking Qt what is currently wired to the
|
|
13
|
+
* window. There is no widget tree to ask in a browser tab, so the keys Mudlet
|
|
14
|
+
* itself holds are written down below instead — a mirror of another
|
|
15
|
+
* application's keyboard map, and it will need revisiting when Mudlet moves a
|
|
16
|
+
* shortcut. The alternative was to reserve nothing, which is technically true
|
|
17
|
+
* of a client with no menu bar and useless to a package author: a shortcut
|
|
18
|
+
* accepted here and refused on desktop is a bug report either way, and the
|
|
19
|
+
* quiet version (Qt disables BOTH bindings when two things claim one key) is
|
|
20
|
+
* the worse of the two to debug.
|
|
21
|
+
*/
|
|
22
|
+
/** Where a command can be placed. Absent means both, never neither. */
|
|
23
|
+
export type CommandSurface = 'menu' | 'toolbar' | 'both';
|
|
24
|
+
export interface AddonCommand {
|
|
25
|
+
id: number;
|
|
26
|
+
name: string;
|
|
27
|
+
icon: string;
|
|
28
|
+
tooltip: string;
|
|
29
|
+
menuPath: string;
|
|
30
|
+
shortcut: string;
|
|
31
|
+
surfaces: CommandSurface;
|
|
32
|
+
enabled: boolean;
|
|
33
|
+
checked: boolean;
|
|
34
|
+
/** Mudlet shows a pinned command in every profile's window, not just its
|
|
35
|
+
* own. A page here holds one profile, so this is kept and reported but
|
|
36
|
+
* there is no second window for it to appear in. */
|
|
37
|
+
pinned: boolean;
|
|
38
|
+
pulse: {
|
|
39
|
+
colour: string;
|
|
40
|
+
altColour: string;
|
|
41
|
+
intervalMs: number;
|
|
42
|
+
} | null;
|
|
43
|
+
/** The package or module whose code placed it, or '' for the profile's. */
|
|
44
|
+
owner: string;
|
|
45
|
+
}
|
|
46
|
+
/** A request as Bridge.lua hands it over, already type-checked there. */
|
|
47
|
+
export interface CommandRequest {
|
|
48
|
+
name: string;
|
|
49
|
+
icon?: string;
|
|
50
|
+
tooltip?: string;
|
|
51
|
+
menuPath?: string;
|
|
52
|
+
shortcut?: string;
|
|
53
|
+
surfaces?: CommandSurface;
|
|
54
|
+
owner?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Qt's QKeySequence holds four steps and silently drops the rest, so a longer
|
|
57
|
+
* sequence binds a key nobody asked for. */
|
|
58
|
+
export declare const MAX_SHORTCUT_STEPS = 4;
|
|
59
|
+
/** Normalised for comparison only — case and spacing carry no meaning in a Qt
|
|
60
|
+
* key sequence, so "Ctrl+Alt+L" and "ctrl+alt+l" are one key. */
|
|
61
|
+
export declare function normaliseShortcut(shortcut: string): string;
|
|
62
|
+
export declare class AddonCommandRegistry {
|
|
63
|
+
private readonly commands;
|
|
64
|
+
/** Monotonic and never reused: an id that has been removed must answer as
|
|
65
|
+
* unknown for good, not come back as a different command. */
|
|
66
|
+
private nextId;
|
|
67
|
+
private listeners;
|
|
68
|
+
/** Whether the buffer search currently holds its key. Pushed in rather than
|
|
69
|
+
* read out, so this file needs no store dependency. */
|
|
70
|
+
private searchActive;
|
|
71
|
+
/** Which platform's key map Mudlet would be answering from. Pushed in for
|
|
72
|
+
* the same reason. */
|
|
73
|
+
private reserved;
|
|
74
|
+
/**
|
|
75
|
+
* What the client's own commands hold right now, normalised key → the name
|
|
76
|
+
* to quote back. Separate from `reserved` because that one is a mirror of
|
|
77
|
+
* Mudlet's fixed map, while these move: the player can rebind any of them
|
|
78
|
+
* (see `appShortcuts.ts`), and a package asking about the key they moved it
|
|
79
|
+
* TO deserves the truth rather than "free".
|
|
80
|
+
*/
|
|
81
|
+
private clientKeys;
|
|
82
|
+
setPlatform(platform: string): void;
|
|
83
|
+
/** Told by the UI whenever the client's own bindings change: normalised key
|
|
84
|
+
* → the command's name. */
|
|
85
|
+
setClientShortcuts(keys: ReadonlyMap<string, string>): void;
|
|
86
|
+
subscribe(fn: () => void): () => void;
|
|
87
|
+
private notify;
|
|
88
|
+
list(): AddonCommand[];
|
|
89
|
+
get(id: number): AddonCommand | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Who holds `shortcut`, or null when it is free. `null` for an empty
|
|
92
|
+
* shortcut too — asking for no key is not a clash.
|
|
93
|
+
*
|
|
94
|
+
* A command of THIS profile is named outright; Mudlet's own keys answer
|
|
95
|
+
* with the reserved name. The spec tells the two apart deliberately: a
|
|
96
|
+
* package author can fix a clash with their own command, and needs to know
|
|
97
|
+
* when they cannot.
|
|
98
|
+
*/
|
|
99
|
+
holderOf(shortcut: string, ignoreId?: number): string | null;
|
|
100
|
+
/** Commands currently on `shortcut` — what the buffer search needs to know
|
|
101
|
+
* before it takes its key back. */
|
|
102
|
+
commandsOn(shortcut: string): AddonCommand[];
|
|
103
|
+
get searchHoldsItsKey(): boolean;
|
|
104
|
+
get searchShortcut(): string;
|
|
105
|
+
/** Told by the config layer, because the search is a preference rather than
|
|
106
|
+
* anything this registry owns. */
|
|
107
|
+
setSearchActive(active: boolean): void;
|
|
108
|
+
add(request: CommandRequest): number;
|
|
109
|
+
remove(id: number): boolean;
|
|
110
|
+
/** Take away every command the package or module `owner`'s code placed —
|
|
111
|
+
* once it is gone nothing knows their ids, and left behind they would
|
|
112
|
+
* stay on screen and hold their shortcuts against its own reinstall. */
|
|
113
|
+
removeOwnedBy(owner: string): void;
|
|
114
|
+
setEnabled(id: number, enabled: boolean): boolean;
|
|
115
|
+
setChecked(id: number, checked: boolean): boolean;
|
|
116
|
+
setPinned(id: number, pinned: boolean): boolean;
|
|
117
|
+
setIcon(id: number, icon: string): boolean;
|
|
118
|
+
setTooltip(id: number, tooltip: string): boolean;
|
|
119
|
+
setPulse(id: number, pulse: AddonCommand['pulse']): boolean;
|
|
120
|
+
/** Whether the command has a button to colour — the pulse needs one, and a
|
|
121
|
+
* menu-only command has none. */
|
|
122
|
+
hasButton(id: number): boolean;
|
|
123
|
+
private mutate;
|
|
124
|
+
/** The commands with a button, in placement order — what the toolbar draws.
|
|
125
|
+
* A disabled command keeps its button and is drawn unavailable, which is
|
|
126
|
+
* what enableCommand/disableCommand are for; a removed one is gone. */
|
|
127
|
+
buttons(): AddonCommand[];
|
|
128
|
+
/** The commands with a menu entry, in placement order — what the menu bar
|
|
129
|
+
* draws. Same rule as `buttons()`: a disabled one keeps its entry and is
|
|
130
|
+
* drawn unavailable, and only a removed one is gone. */
|
|
131
|
+
menuItems(): AddonCommand[];
|
|
132
|
+
/** Profile teardown. */
|
|
133
|
+
clear(): void;
|
|
134
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client's own keyboard shortcuts — Mudlet's menu accelerators, and the
|
|
3
|
+
* handful of things this client has that Mudlet does not.
|
|
4
|
+
*
|
|
5
|
+
* Mudlet's are fixed, compiled into the menu actions. These are defaults: the
|
|
6
|
+
* settings dialog can move any of them, and the stored override is what the
|
|
7
|
+
* dispatcher and the menu labels both read. That is the one place this
|
|
8
|
+
* deliberately goes further than Mudlet — in a browser a shortcut can collide
|
|
9
|
+
* with something the browser or an extension already holds, and a player who
|
|
10
|
+
* cannot reach the script editor because Alt+E is spoken for has no recourse
|
|
11
|
+
* unless the binding moves.
|
|
12
|
+
*
|
|
13
|
+
* The keys themselves are Mudlet's, including the platform split: the menu
|
|
14
|
+
* group is Alt on Windows and Linux and Ctrl on macOS (mudlet.cpp:1462-1512),
|
|
15
|
+
* where Alt is a text-entry modifier. Commands Mudlet has no key for start
|
|
16
|
+
* unbound rather than being given one this client invented — a player who wants
|
|
17
|
+
* one can say so, and a default that disagreed with Mudlet's would be a trap
|
|
18
|
+
* for anyone who uses both.
|
|
19
|
+
*
|
|
20
|
+
* Mudlet's profile-switching keys (Ctrl+1…9, Ctrl+Tab) are absent by design:
|
|
21
|
+
* multiple profiles here are multiple browser tabs, and the browser owns those
|
|
22
|
+
* keys. `addonCommands.ts` still reserves them against packages, because a
|
|
23
|
+
* package written for desktop Mudlet will expect them to be taken.
|
|
24
|
+
*/
|
|
25
|
+
import { type StockToolbarButton } from '../../branding';
|
|
26
|
+
/** Everything the client can be asked to do from the keyboard. */
|
|
27
|
+
export type AppCommandId = 'connect' | 'disconnect' | 'reconnect' | 'closeProfile' | 'scriptEditor' | 'map' | 'notepad' | 'files' | 'logs' | 'toggleReplay' | 'preferences' | 'toggleTimestamps' | 'mute' | 'toggleLogging' | 'fullscreen' | 'toggleButtonBar' | 'inputLine' | 'docs' | 'help' | 'about';
|
|
28
|
+
export interface AppShortcutDef {
|
|
29
|
+
id: AppCommandId;
|
|
30
|
+
label: string;
|
|
31
|
+
/**
|
|
32
|
+
* The stock button this command belongs to, where it has one. A brand that
|
|
33
|
+
* hid the button has removed the feature, so the shortcut goes with it —
|
|
34
|
+
* both the binding and its row in the settings. A key that still opened the
|
|
35
|
+
* script editor after the brand took the script editor away would be a back
|
|
36
|
+
* door into something they deliberately removed.
|
|
37
|
+
*/
|
|
38
|
+
stock?: StockToolbarButton;
|
|
39
|
+
/** The menu this command lives in, so the settings list is grouped the way
|
|
40
|
+
* the menu bar is rather than as one flat run of nineteen rows. */
|
|
41
|
+
group: 'Games' | 'Toolbox' | 'Options' | 'Window' | 'Help';
|
|
42
|
+
/** Mudlet's key on Windows and Linux, and on macOS. Empty on both where
|
|
43
|
+
* Mudlet has no key for it. */
|
|
44
|
+
defaultKey: string;
|
|
45
|
+
defaultKeyMac: string;
|
|
46
|
+
}
|
|
47
|
+
/** Mudlet's menu group: Alt+<letter> on Windows and Linux, Ctrl+<letter> on
|
|
48
|
+
* macOS. Written out rather than generated so each entry is greppable. */
|
|
49
|
+
export declare const APP_SHORTCUTS: readonly AppShortcutDef[];
|
|
50
|
+
/**
|
|
51
|
+
* The commands this build actually exposes.
|
|
52
|
+
*
|
|
53
|
+
* A brand that hid a stock button removed the feature, and a shortcut is
|
|
54
|
+
* another door onto the same room — so the binding goes with the button, and so
|
|
55
|
+
* does its row in the settings. Otherwise a white-label client that took the
|
|
56
|
+
* script editor away would still open it on Alt+E, and offer to rebind it.
|
|
57
|
+
*
|
|
58
|
+
* Commands with no `stock` id (timestamps, logging, fullscreen, the bars, the
|
|
59
|
+
* command line, About) belong to no button and are always available.
|
|
60
|
+
*/
|
|
61
|
+
export declare function availableShortcuts(): readonly AppShortcutDef[];
|
|
62
|
+
/** The order the settings list draws the groups in — the menu bar's own. */
|
|
63
|
+
export declare const SHORTCUT_GROUPS: readonly AppShortcutDef['group'][];
|
|
64
|
+
/** Which key map this machine gets, in the same spelling `getOS()` uses so the
|
|
65
|
+
* addon-command registry and this agree on what "mac" means. */
|
|
66
|
+
export declare function shortcutPlatform(): string;
|
|
67
|
+
/** What the client would use with nothing overridden. `platform` is what
|
|
68
|
+
* `getOS()` reports: 'mac' picks Mudlet's macOS key. */
|
|
69
|
+
export declare function defaultShortcut(def: AppShortcutDef, platform: string): string;
|
|
70
|
+
/** What a stored override means. A key that is present and empty is a binding
|
|
71
|
+
* the player deliberately cleared, which is not the same as never having
|
|
72
|
+
* touched it — clearing has to survive a default changing under them. */
|
|
73
|
+
export type ShortcutOverrides = Readonly<Record<string, string>>;
|
|
74
|
+
/** The key actually in force for `def`. */
|
|
75
|
+
export declare function effectiveShortcut(def: AppShortcutDef, overrides: ShortcutOverrides | undefined, platform: string): string;
|
|
76
|
+
/** A reader for one command's key, for the menu entries that draw it beside
|
|
77
|
+
* their label. Undefined rather than empty for an unbound command, so a menu
|
|
78
|
+
* entry can leave the column blank rather than drawing nothing-in-particular. */
|
|
79
|
+
export declare function shortcutLookup(overrides: ShortcutOverrides | undefined, platform: string): (id: AppCommandId) => string | undefined;
|
|
80
|
+
/** Every command with a key, as `{id, label, shortcut}`. Commands with no key
|
|
81
|
+
* are left out — there is nothing to dispatch or to warn about. */
|
|
82
|
+
export declare function boundShortcuts(overrides: ShortcutOverrides | undefined, platform: string): {
|
|
83
|
+
id: AppCommandId;
|
|
84
|
+
label: string;
|
|
85
|
+
shortcut: string;
|
|
86
|
+
}[];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `addCommand` for the application embedding this client.
|
|
3
|
+
*
|
|
4
|
+
* A package written in Lua can already place a command on the toolbar and the
|
|
5
|
+
* menu bar and change it afterwards. A white-label host had no equivalent: it
|
|
6
|
+
* could declare buttons in its `BrandConfig` at boot and nothing after, so a
|
|
7
|
+
* command that appears when the player logs in, or greys out while a request is
|
|
8
|
+
* in flight, meant re-rendering the whole client with a new brand object.
|
|
9
|
+
*
|
|
10
|
+
* This is the same contract from JavaScript. It is a module-level singleton
|
|
11
|
+
* rather than a React context on purpose — a host app's command usually lives
|
|
12
|
+
* next to the state that decides whether it should be there, which is rarely a
|
|
13
|
+
* component inside the client's tree.
|
|
14
|
+
*
|
|
15
|
+
* Ids are strings and never reused, so a removed command's id answers as
|
|
16
|
+
* unknown for good rather than coming back as something else.
|
|
17
|
+
*/
|
|
18
|
+
import type { ReactNode } from 'react';
|
|
19
|
+
import type { BrandToolbarContext } from '../../branding';
|
|
20
|
+
import type { CommandSurface } from './addonCommands';
|
|
21
|
+
export interface HostCommandRequest {
|
|
22
|
+
/** The caller's own id, if it wants one — `commands.remove('roll')` then
|
|
23
|
+
* works without holding on to what `add` returned. Absent gets a generated
|
|
24
|
+
* one. Placing a second command under an id that is taken replaces it. */
|
|
25
|
+
id?: string;
|
|
26
|
+
/** Shown on the button and the menu entry. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** An image URL, or any node — an inline SVG needs no round trip through a
|
|
29
|
+
* file. Sized to the text by the stylesheet either way. */
|
|
30
|
+
icon?: ReactNode;
|
|
31
|
+
tooltip?: string;
|
|
32
|
+
/** Where on the menu bar: '/'-separated, the first segment naming a
|
|
33
|
+
* top-level menu (an existing title joins it, a new one opens a menu at
|
|
34
|
+
* the end of the bar). Absent puts it among the other package tools. */
|
|
35
|
+
menuPath?: string;
|
|
36
|
+
/** Qt-style key sequence, e.g. "Ctrl+Alt+K". */
|
|
37
|
+
shortcut?: string;
|
|
38
|
+
/** Which bars it appears on. Absent means both. */
|
|
39
|
+
surfaces?: CommandSurface;
|
|
40
|
+
enabled?: boolean;
|
|
41
|
+
checked?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Run when the command is picked. The context is the same one brand
|
|
44
|
+
* toolbar buttons get: `send` a command as if typed, `raiseEvent` for the
|
|
45
|
+
* profile's Lua handlers, and the open profile's id.
|
|
46
|
+
*
|
|
47
|
+
* Called with null when no profile is open — a command can be placed before
|
|
48
|
+
* the player has picked one, and refusing to fire silently would be worse
|
|
49
|
+
* than letting the host decide.
|
|
50
|
+
*/
|
|
51
|
+
onClick: (ctx: BrandToolbarContext | null) => void;
|
|
52
|
+
}
|
|
53
|
+
export interface HostCommand extends HostCommandRequest {
|
|
54
|
+
id: string;
|
|
55
|
+
surfaces: CommandSurface;
|
|
56
|
+
enabled: boolean;
|
|
57
|
+
checked: boolean;
|
|
58
|
+
}
|
|
59
|
+
export declare class HostCommandRegistry {
|
|
60
|
+
private readonly commands;
|
|
61
|
+
private next;
|
|
62
|
+
private readonly listeners;
|
|
63
|
+
/** The snapshot handed to React. Rebuilt on change rather than on read, so
|
|
64
|
+
* `useSyncExternalStore` sees a stable reference between changes and does
|
|
65
|
+
* not re-render on every commit. */
|
|
66
|
+
private snapshot;
|
|
67
|
+
subscribe: (fn: () => void) => (() => void);
|
|
68
|
+
/** Every placed command, in placement order — which is drawing order. */
|
|
69
|
+
list: () => readonly HostCommand[];
|
|
70
|
+
private changed;
|
|
71
|
+
/** Place a command. Returns its id, for everything below. */
|
|
72
|
+
add(request: HostCommandRequest): string;
|
|
73
|
+
/** False for an id nobody knows, rather than throwing — one sequence covers
|
|
74
|
+
* every command, so an unknown id names nothing at all. */
|
|
75
|
+
remove(id: string): boolean;
|
|
76
|
+
/** Change anything about a placed command except its id. */
|
|
77
|
+
update(id: string, patch: Partial<HostCommandRequest>): boolean;
|
|
78
|
+
setEnabled(id: string, enabled: boolean): boolean;
|
|
79
|
+
setChecked(id: string, checked: boolean): boolean;
|
|
80
|
+
setIcon(id: string, icon: string): boolean;
|
|
81
|
+
setTooltip(id: string, tooltip: string): boolean;
|
|
82
|
+
/** Drop everything. For a host tearing its own UI down; the client never
|
|
83
|
+
* calls this, since these commands outlive any one profile. */
|
|
84
|
+
clear(): void;
|
|
85
|
+
}
|
|
86
|
+
/** The one registry the client reads. Exported from the package root as
|
|
87
|
+
* `commands`. */
|
|
88
|
+
export declare const hostCommands: HostCommandRegistry;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One step in its canonical spelling: modifiers in a fixed order, lower case,
|
|
3
|
+
* joined to the key by '+'. "Ctrl+Alt+L", "alt+ctrl+l" and "CTRL+ALT+L" all
|
|
4
|
+
* become "ctrl+alt+l".
|
|
5
|
+
*/
|
|
6
|
+
export declare function canonicalStep(step: string): string;
|
|
7
|
+
/** A whole sequence as canonical steps, or null when Qt could not read it. */
|
|
8
|
+
export declare function canonicalSequence(shortcut: string): string[] | null;
|
|
9
|
+
/** The key half of a step, from a physical key code. Null for a modifier key
|
|
10
|
+
* pressed on its own — holding Ctrl is not yet a shortcut. */
|
|
11
|
+
export declare function keyNameFromCode(code: string): string | null;
|
|
12
|
+
/** A keypress in the same spelling as `canonicalStep`, or null when it is not
|
|
13
|
+
* a key a shortcut can be built from. */
|
|
14
|
+
export declare function stepFromEvent(e: Pick<KeyboardEvent, 'code' | 'ctrlKey' | 'altKey' | 'shiftKey' | 'metaKey'>): string | null;
|
|
15
|
+
/** Whether a step carries a modifier. A bare key is not safe to dispatch while
|
|
16
|
+
* the player is typing into something. */
|
|
17
|
+
export declare function stepHasModifier(step: string): boolean;
|
|
18
|
+
/** Written the way a person reads it: "Ctrl+Alt+L", "Alt+E", "F3". Steps in a
|
|
19
|
+
* multi-step sequence are joined with ", " as Qt writes them. */
|
|
20
|
+
export declare function formatSequence(steps: readonly string[]): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Qt key-sequence parsing, as much of it as deciding whether to accept a
|
|
3
|
+
* package's shortcut needs.
|
|
4
|
+
*
|
|
5
|
+
* Counting the steps in "Ctrl+Alt+F1, Ctrl+Alt+F2" looks like splitting on
|
|
6
|
+
* commas until you meet the two characters that are both punctuation AND keys:
|
|
7
|
+
*
|
|
8
|
+
* "Ctrl+," the comma key. One step, not two of nothing.
|
|
9
|
+
* "Ctrl++" the plus key. One step whose last character is the same
|
|
10
|
+
* one that joins a modifier to its key.
|
|
11
|
+
* "Ctrl+,, X" the comma key, then a separator, then X. Two steps.
|
|
12
|
+
* "Ctrl++, X" the plus key, then a separator, then X. Two steps — and
|
|
13
|
+
* the reading that looks at what precedes the comma calls
|
|
14
|
+
* this one, which is how a five-step sequence slipped past
|
|
15
|
+
* the length check to be truncated by Qt after all.
|
|
16
|
+
*
|
|
17
|
+
* So this parses rather than splits: each step is its modifiers, then exactly
|
|
18
|
+
* one key, and only a comma that follows a completed key is a separator. Qt
|
|
19
|
+
* steps over that separator and the single space after it, which is why a
|
|
20
|
+
* sequence written with a trailing one — what generating a list in a loop
|
|
21
|
+
* produces — is the steps it names and not one more of nothing.
|
|
22
|
+
*/
|
|
23
|
+
/** Qt's QKeySequence holds this many steps and silently drops the rest. */
|
|
24
|
+
export declare const MAX_STEPS = 4;
|
|
25
|
+
export interface SequenceProblem {
|
|
26
|
+
/** 'length' when the sequence has more steps than Qt can hold, 'key' when a
|
|
27
|
+
* step names something Qt cannot read. */
|
|
28
|
+
kind: 'length' | 'key';
|
|
29
|
+
/** The unreadable chunk, for a 'key' problem. */
|
|
30
|
+
chunk?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The steps in a Qt key sequence, or a problem describing why it is not one.
|
|
34
|
+
* An empty (or whitespace-only) shortcut is no shortcut at all and parses to
|
|
35
|
+
* zero steps, which is not an error — a command may simply have no key.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseKeySequence(shortcut: string): {
|
|
38
|
+
steps: string[];
|
|
39
|
+
} | {
|
|
40
|
+
problem: SequenceProblem;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A shortcut as a key binding would hold it: one DOM `KeyboardEvent.code` plus
|
|
44
|
+
* the modifiers pressed with it.
|
|
45
|
+
*
|
|
46
|
+
* Null for anything a binding cannot be: a sequence of more than one step (a
|
|
47
|
+
* binding is one key and its modifiers, so a two-step sequence can never be the
|
|
48
|
+
* one holding it — as `mudlet::addonShortcutUsable` decides with
|
|
49
|
+
* `sequence.count() == 1`), an empty shortcut, or a key the browser has no code
|
|
50
|
+
* for.
|
|
51
|
+
*/
|
|
52
|
+
export declare function shortcutAsBinding(shortcut: string): {
|
|
53
|
+
code: string;
|
|
54
|
+
modifiers: string[];
|
|
55
|
+
} | null;
|
|
56
|
+
/** The refusal a package should read, or null when the sequence is fine. */
|
|
57
|
+
export declare function shortcutProblemMessage(shortcut: string): string | null;
|
|
@@ -3,7 +3,27 @@ interface ContextMenuProps {
|
|
|
3
3
|
x: number;
|
|
4
4
|
y: number;
|
|
5
5
|
onClose: () => void;
|
|
6
|
+
/** Accessible name for the menu, e.g. "Output actions". */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** Override for popups that are not lists of commands — the script editor's
|
|
9
|
+
* colour picker is a grid of swatches, and calling that a menu when it holds
|
|
10
|
+
* no menuitem misdescribes it. */
|
|
11
|
+
role?: 'menu' | 'group';
|
|
12
|
+
/** Where to hand focus back on close, when that is not the element the menu
|
|
13
|
+
* was opened from. The output console needs this: a right-click focuses the
|
|
14
|
+
* console (it is a tab stop), but the player types into the command line, so
|
|
15
|
+
* returning focus to the opener would send their next keystroke nowhere. */
|
|
16
|
+
returnFocusTo?: () => HTMLElement | null | undefined;
|
|
17
|
+
/** Extra class on the menu box, for a screen that styles its menus to
|
|
18
|
+
* match its own layout (the launcher's are larger than the app's). */
|
|
19
|
+
className?: string;
|
|
6
20
|
children: React.ReactNode;
|
|
7
21
|
}
|
|
8
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Where an arrow/Home/End press should move within a menu of `count` entries,
|
|
24
|
+
* given the currently focused index (-1 when focus is outside). Returns null for
|
|
25
|
+
* keys the menu doesn't handle. Wraps at both ends. Pure — exported for testing.
|
|
26
|
+
*/
|
|
27
|
+
export declare function nextMenuIndex(count: number, current: number, key: string): number | null;
|
|
28
|
+
export declare function ContextMenu({ x, y, onClose, label, role, returnFocusTo, className, children }: ContextMenuProps): import("react").ReactPortal;
|
|
9
29
|
export {};
|
|
@@ -4,6 +4,10 @@ interface FontPickerProps {
|
|
|
4
4
|
value: OutputFontSource | undefined;
|
|
5
5
|
onChange: (next: OutputFontSource | undefined) => void;
|
|
6
6
|
vfs: ProfileVFS | null;
|
|
7
|
+
/** What is drawn with when nothing is chosen. The main display falls back to
|
|
8
|
+
* the browser's monospace; the map's room symbols to the bundled Bitstream
|
|
9
|
+
* Vera Sans Mono — so the picker has to be told, rather than assert one. */
|
|
10
|
+
fallbackLabel?: string;
|
|
7
11
|
}
|
|
8
|
-
export declare function FontPicker({ value, onChange, vfs }: FontPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare function FontPicker({ value, onChange, vfs, fallbackLabel }: FontPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
9
13
|
export {};
|
|
@@ -12,8 +12,20 @@ export interface ModalFocusOptions {
|
|
|
12
12
|
* modal manages its own initial focus (e.g. a specific field or button). */
|
|
13
13
|
autoFocus?: boolean;
|
|
14
14
|
/** Close on Escape via `onClose`. Default true. Set false when the modal has
|
|
15
|
-
* its own Escape handling (then `onClose` may be omitted).
|
|
15
|
+
* its own Escape handling (then `onClose` may be omitted). Read live on
|
|
16
|
+
* every key, so it may vary over the dialog's life — a dialog can hand
|
|
17
|
+
* Escape to an inner editor for exactly as long as that editor is open
|
|
18
|
+
* (the file browser's inline rename does) without the trap being torn
|
|
19
|
+
* down and re-armed, which would re-grab focus. */
|
|
16
20
|
closeOnEscape?: boolean;
|
|
21
|
+
/** Gate for a dialog whose node is not in the DOM on the first render — a
|
|
22
|
+
* portal whose container is only known after a layout effect, say. The
|
|
23
|
+
* setup below runs once, off a null ref, and refs don't re-render, so
|
|
24
|
+
* without this the trap, the Escape handler and the focus restore are all
|
|
25
|
+
* silently skipped (issue #49). Flip it true in the render that mounts the
|
|
26
|
+
* dialog node. One-way: flipping it back to false counts as a close and
|
|
27
|
+
* restores focus to the opener. Default true (node present immediately). */
|
|
28
|
+
ready?: boolean;
|
|
17
29
|
/** Where focus should land on close, instead of the opener. Use when the
|
|
18
30
|
* dialog was raised by the game rather than by a click, so "the opener" is
|
|
19
31
|
* either nothing or a control that has since gone away — the GMCP login
|
|
@@ -11,6 +11,21 @@ export interface HelpTopic {
|
|
|
11
11
|
}
|
|
12
12
|
export declare const HELP_TOPICS: HelpTopic[];
|
|
13
13
|
export declare const DEFAULT_HELP_TOPIC: string;
|
|
14
|
+
/**
|
|
15
|
+
* Add a topic that only some builds have.
|
|
16
|
+
*
|
|
17
|
+
* The manual is otherwise a fixed list, but a few features are stock-app-only —
|
|
18
|
+
* the credential vault above all — and a branded build must not carry
|
|
19
|
+
* documentation for something it doesn't ship. Those topics are registered from
|
|
20
|
+
* `main.tsx` at boot, alongside the feature itself, so they never enter the
|
|
21
|
+
* library's module graph. See `vault/vaultAccess` for the same seam.
|
|
22
|
+
*
|
|
23
|
+
* Idempotent, and ordered by `after` rather than appended, so an added topic
|
|
24
|
+
* lands next to the one it relates to instead of at the bottom.
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerHelpTopic(topic: HelpTopic, opts?: {
|
|
27
|
+
after?: string;
|
|
28
|
+
}): void;
|
|
14
29
|
/** Resolve a markdown link href to a topic id, or null if it isn't one of ours.
|
|
15
30
|
* Handles `./storage.md`, `storage.md`, `docs/help/storage.md` and a `#anchor`
|
|
16
31
|
* suffix — the shapes a relative link between these files can take. */
|