waybetter 0.1.1 → 0.6.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 +140 -6
- package/bin/waybetter.mjs +46 -0
- package/build/runtime.mjs +105 -0
- package/cli/buildenv.mjs +130 -0
- package/cli/dev.mjs +97 -0
- package/cli/i18n.mjs +382 -0
- package/cli/manifests.mjs +383 -0
- package/cli/privacy.mjs +768 -0
- package/cli/release.mjs +444 -0
- package/cli/remote.mjs +260 -0
- package/cli/store.mjs +326 -0
- package/cli/strings.mjs +121 -0
- package/dist/runtime/column.d.ts +93 -0
- package/dist/runtime/column.js +451 -0
- package/dist/runtime/column.js.map +1 -0
- package/dist/runtime/commandReport.d.ts +19 -0
- package/dist/runtime/commandReport.js +47 -0
- package/dist/runtime/commandReport.js.map +1 -0
- package/dist/runtime/commands.d.ts +72 -0
- package/dist/runtime/commands.js +214 -0
- package/dist/runtime/commands.js.map +1 -0
- package/dist/runtime/devErrors.d.ts +16 -0
- package/dist/runtime/devErrors.js +30 -0
- package/dist/runtime/devErrors.js.map +1 -0
- package/dist/runtime/domHub.d.ts +21 -0
- package/dist/runtime/domHub.js +139 -4
- package/dist/runtime/domHub.js.map +1 -1
- package/dist/runtime/featureModules.d.ts +157 -0
- package/dist/runtime/featureModules.js +484 -0
- package/dist/runtime/featureModules.js.map +1 -0
- package/dist/runtime/featureTable.d.ts +144 -0
- package/dist/runtime/featureTable.js +223 -0
- package/dist/runtime/featureTable.js.map +1 -0
- package/dist/runtime/fonts.d.ts +22 -0
- package/dist/runtime/fonts.js +72 -0
- package/dist/runtime/fonts.js.map +1 -0
- package/dist/runtime/i18n.d.ts +138 -0
- package/dist/runtime/i18n.js +614 -0
- package/dist/runtime/i18n.js.map +1 -0
- package/dist/runtime/i18nCheck.d.ts +30 -0
- package/dist/runtime/i18nCheck.js +224 -0
- package/dist/runtime/i18nCheck.js.map +1 -0
- package/dist/runtime/pageLang.d.ts +8 -0
- package/dist/runtime/pageLang.js +64 -0
- package/dist/runtime/pageLang.js.map +1 -0
- package/dist/runtime/pageStrings.d.ts +35 -0
- package/dist/runtime/pageStrings.js +76 -0
- package/dist/runtime/pageStrings.js.map +1 -0
- package/dist/runtime/panelButton.d.ts +33 -0
- package/dist/runtime/panelButton.js +83 -0
- package/dist/runtime/panelButton.js.map +1 -0
- package/dist/runtime/permissions.d.ts +47 -0
- package/dist/runtime/permissions.js +141 -0
- package/dist/runtime/permissions.js.map +1 -0
- package/dist/runtime/pluginApi.d.ts +51 -2
- package/dist/runtime/pluginApi.js +137 -22
- package/dist/runtime/pluginApi.js.map +1 -1
- package/dist/runtime/pluginI18n.d.ts +29 -0
- package/dist/runtime/pluginI18n.js +119 -0
- package/dist/runtime/pluginI18n.js.map +1 -0
- package/dist/runtime/settingsForm.d.ts +66 -0
- package/dist/runtime/settingsForm.js +114 -0
- package/dist/runtime/settingsForm.js.map +1 -0
- package/dist/runtime/site.d.ts +5 -0
- package/dist/runtime/site.js +1 -1
- package/dist/runtime/site.js.map +1 -1
- package/dist/runtime/siteRuntime.d.ts +144 -0
- package/dist/runtime/siteRuntime.js +175 -0
- package/dist/runtime/siteRuntime.js.map +1 -0
- package/dist/runtime/stringPackHook.d.ts +84 -0
- package/dist/runtime/stringPackHook.js +220 -0
- package/dist/runtime/stringPackHook.js.map +1 -0
- package/dist/runtime/stringPackTranslate.d.ts +59 -0
- package/dist/runtime/stringPackTranslate.js +264 -0
- package/dist/runtime/stringPackTranslate.js.map +1 -0
- package/dist/runtime/stringPacks.d.ts +200 -0
- package/dist/runtime/stringPacks.js +474 -0
- package/dist/runtime/stringPacks.js.map +1 -0
- package/dist/runtime/styles.d.ts +15 -0
- package/dist/runtime/styles.js +81 -0
- package/dist/runtime/styles.js.map +1 -0
- package/dist/runtime/textNet.d.ts +15 -0
- package/dist/runtime/textNet.js +131 -0
- package/dist/runtime/textNet.js.map +1 -0
- package/dist/runtime/themeApi.d.ts +121 -0
- package/dist/runtime/themeApi.js +220 -0
- package/dist/runtime/themeApi.js.map +1 -0
- package/dist/runtime/themeChoice.d.ts +52 -0
- package/dist/runtime/themeChoice.js +69 -0
- package/dist/runtime/themeChoice.js.map +1 -0
- package/dist/runtime/themeComponents.d.ts +435 -0
- package/dist/runtime/themeComponents.js +463 -0
- package/dist/runtime/themeComponents.js.map +1 -0
- package/dist/runtime/themeDecor.d.ts +73 -0
- package/dist/runtime/themeDecor.js +131 -0
- package/dist/runtime/themeDecor.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +11 -0
- package/dist/runtime/themeDoctor.js +51 -0
- package/dist/runtime/themeDoctor.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +130 -0
- package/dist/runtime/themeIcons.js +263 -0
- package/dist/runtime/themeIcons.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +100 -0
- package/dist/runtime/themeRuntime.js +497 -0
- package/dist/runtime/themeRuntime.js.map +1 -0
- package/dist/runtime/themeSchema.d.ts +10 -0
- package/dist/runtime/themeSchema.js +150 -0
- package/dist/runtime/themeSchema.js.map +1 -0
- package/dist/runtime/themeSpec.d.ts +259 -0
- package/dist/runtime/themeSpec.js +439 -0
- package/dist/runtime/themeSpec.js.map +1 -0
- package/dist/runtime/themeTokens.d.ts +12 -0
- package/dist/runtime/themeTokens.js +14 -6
- package/dist/runtime/themeTokens.js.map +1 -1
- package/dist/runtime/themeVariants.d.ts +30 -0
- package/dist/runtime/themeVariants.js +53 -0
- package/dist/runtime/themeVariants.js.map +1 -0
- package/dist/runtime/ui.d.ts +192 -0
- package/dist/runtime/ui.js +926 -0
- package/dist/runtime/ui.js.map +1 -0
- package/dist/shell/InstallDialog.d.ts +40 -0
- package/dist/shell/InstallDialog.js +170 -0
- package/dist/shell/InstallDialog.js.map +1 -0
- package/dist/shell/StoreView.d.ts +66 -0
- package/dist/shell/StoreView.js +103 -0
- package/dist/shell/StoreView.js.map +1 -0
- package/dist/shell/addressModel.js.map +1 -1
- package/dist/shell/chrome.js.map +1 -1
- package/dist/shell/deckModel.d.ts +117 -0
- package/dist/shell/deckModel.js +267 -0
- package/dist/shell/deckModel.js.map +1 -0
- package/dist/shell/frame/AccountSwitcher.d.ts +42 -0
- package/dist/shell/frame/AccountSwitcher.js +243 -0
- package/dist/shell/frame/AccountSwitcher.js.map +1 -0
- package/dist/shell/frame/AddColumnDialog.d.ts +8 -0
- package/dist/shell/frame/AddColumnDialog.js +81 -0
- package/dist/shell/frame/AddColumnDialog.js.map +1 -0
- package/dist/shell/frame/AppMenu.d.ts +21 -0
- package/dist/shell/frame/AppMenu.js +642 -0
- package/dist/shell/frame/AppMenu.js.map +1 -0
- package/dist/shell/frame/CommandPalette.d.ts +7 -0
- package/dist/shell/frame/CommandPalette.js +118 -0
- package/dist/shell/frame/CommandPalette.js.map +1 -0
- package/dist/shell/frame/DeckView.d.ts +13 -0
- package/dist/shell/frame/DeckView.js +287 -0
- package/dist/shell/frame/DeckView.js.map +1 -0
- package/dist/shell/frame/FindBar.d.ts +10 -0
- package/dist/shell/frame/FindBar.js +108 -0
- package/dist/shell/frame/FindBar.js.map +1 -0
- package/dist/shell/frame/MediaPanel.d.ts +8 -0
- package/dist/shell/frame/MediaPanel.js +76 -0
- package/dist/shell/frame/MediaPanel.js.map +1 -0
- package/dist/shell/frame/NewTabPage.d.ts +9 -0
- package/dist/shell/frame/NewTabPage.js +71 -0
- package/dist/shell/frame/NewTabPage.js.map +1 -0
- package/dist/shell/frame/PaneTheme.d.ts +16 -0
- package/dist/shell/frame/PaneTheme.js +67 -0
- package/dist/shell/frame/PaneTheme.js.map +1 -0
- package/dist/shell/frame/ReportDialog.d.ts +3 -0
- package/dist/shell/frame/ReportDialog.js +95 -0
- package/dist/shell/frame/ReportDialog.js.map +1 -0
- package/dist/shell/frame/Shell.d.ts +8 -0
- package/dist/shell/frame/Shell.js +1131 -0
- package/dist/shell/frame/Shell.js.map +1 -0
- package/dist/shell/frame/Titlebar.d.ts +16 -0
- package/dist/shell/frame/Titlebar.js +77 -0
- package/dist/shell/frame/Titlebar.js.map +1 -0
- package/dist/shell/frame/TitlebarExtras.d.ts +4 -0
- package/dist/shell/frame/TitlebarExtras.js +202 -0
- package/dist/shell/frame/TitlebarExtras.js.map +1 -0
- package/dist/shell/frame/WebPanel.d.ts +4 -0
- package/dist/shell/frame/WebPanel.js +182 -0
- package/dist/shell/frame/WebPanel.js.map +1 -0
- package/dist/shell/frame/accountModel.d.ts +49 -0
- package/dist/shell/frame/accountModel.js +67 -0
- package/dist/shell/frame/accountModel.js.map +1 -0
- package/dist/shell/frame/accountSwitcher.css +91 -0
- package/dist/shell/frame/appI18n.d.ts +44 -0
- package/dist/shell/frame/appI18n.js +64 -0
- package/dist/shell/frame/appI18n.js.map +1 -0
- package/dist/shell/frame/appMenu.css +121 -0
- package/dist/shell/frame/backupModel.d.ts +38 -0
- package/dist/shell/frame/backupModel.js +192 -0
- package/dist/shell/frame/backupModel.js.map +1 -0
- package/dist/shell/frame/boot.d.ts +8 -0
- package/dist/shell/frame/boot.js +35 -0
- package/dist/shell/frame/boot.js.map +1 -0
- package/dist/shell/frame/brand.d.ts +1 -0
- package/dist/shell/frame/brand.js +4 -0
- package/dist/shell/frame/brand.js.map +1 -0
- package/dist/shell/frame/bridge.d.ts +35 -0
- package/dist/shell/frame/bridge.js +70 -0
- package/dist/shell/frame/bridge.js.map +1 -0
- package/dist/shell/frame/chromeTheme.d.ts +29 -0
- package/dist/shell/frame/chromeTheme.js +81 -0
- package/dist/shell/frame/chromeTheme.js.map +1 -0
- package/dist/shell/frame/deck.css +209 -0
- package/dist/shell/frame/deckStore.d.ts +89 -0
- package/dist/shell/frame/deckStore.js +239 -0
- package/dist/shell/frame/deckStore.js.map +1 -0
- package/dist/shell/frame/devHost.d.ts +35 -0
- package/dist/shell/frame/devHost.js +80 -0
- package/dist/shell/frame/devHost.js.map +1 -0
- package/dist/shell/frame/devModel.d.ts +7 -0
- package/dist/shell/frame/devModel.js +17 -0
- package/dist/shell/frame/devModel.js.map +1 -0
- package/dist/shell/frame/diag.d.ts +7 -0
- package/dist/shell/frame/diag.js +39 -0
- package/dist/shell/frame/diag.js.map +1 -0
- package/dist/shell/frame/findBar.css +14 -0
- package/dist/shell/frame/frameMessages.d.ts +248 -0
- package/dist/shell/frame/frameMessages.js +252 -0
- package/dist/shell/frame/frameMessages.js.map +1 -0
- package/dist/shell/frame/hooks.d.ts +39 -0
- package/dist/shell/frame/hooks.js +97 -0
- package/dist/shell/frame/hooks.js.map +1 -0
- package/dist/shell/frame/i18n.d.ts +27 -0
- package/dist/shell/frame/i18n.js +66 -0
- package/dist/shell/frame/i18n.js.map +1 -0
- package/dist/shell/frame/iconPack.d.ts +11 -0
- package/dist/shell/frame/iconPack.js +45 -0
- package/dist/shell/frame/iconPack.js.map +1 -0
- package/dist/shell/frame/icons.d.ts +71 -0
- package/dist/shell/frame/icons.js +75 -0
- package/dist/shell/frame/icons.js.map +1 -0
- package/dist/shell/frame/index.d.ts +34 -0
- package/dist/shell/frame/index.js +43 -0
- package/dist/shell/frame/index.js.map +1 -0
- package/dist/shell/frame/language.d.ts +58 -0
- package/dist/shell/frame/language.js +165 -0
- package/dist/shell/frame/language.js.map +1 -0
- package/dist/shell/frame/mediaModel.d.ts +34 -0
- package/dist/shell/frame/mediaModel.js +53 -0
- package/dist/shell/frame/mediaModel.js.map +1 -0
- package/dist/shell/frame/menuMessages.en.json +54 -0
- package/dist/shell/frame/menuModel.d.ts +277 -0
- package/dist/shell/frame/menuModel.js +293 -0
- package/dist/shell/frame/menuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.d.ts +139 -0
- package/dist/shell/frame/paletteModel.js +112 -0
- package/dist/shell/frame/paletteModel.js.map +1 -0
- package/dist/shell/frame/paneTheme.css +9 -0
- package/dist/shell/frame/pluginCommandStore.d.ts +23 -0
- package/dist/shell/frame/pluginCommandStore.js +70 -0
- package/dist/shell/frame/pluginCommandStore.js.map +1 -0
- package/dist/shell/frame/reportModel.d.ts +52 -0
- package/dist/shell/frame/reportModel.js +105 -0
- package/dist/shell/frame/reportModel.js.map +1 -0
- package/dist/shell/frame/safeStore.d.ts +7 -0
- package/dist/shell/frame/safeStore.js +40 -0
- package/dist/shell/frame/safeStore.js.map +1 -0
- package/dist/shell/frame/searchInput.d.ts +2 -0
- package/dist/shell/frame/searchInput.js +11 -0
- package/dist/shell/frame/searchInput.js.map +1 -0
- package/dist/shell/frame/shell.css +629 -0
- package/dist/shell/frame/site.d.ts +206 -0
- package/dist/shell/frame/site.js +22 -0
- package/dist/shell/frame/site.js.map +1 -0
- package/dist/shell/frame/state.d.ts +99 -0
- package/dist/shell/frame/state.js +284 -0
- package/dist/shell/frame/state.js.map +1 -0
- package/dist/shell/frame/syncGate.d.ts +10 -0
- package/dist/shell/frame/syncGate.js +36 -0
- package/dist/shell/frame/syncGate.js.map +1 -0
- package/dist/shell/frame/syncHost.d.ts +35 -0
- package/dist/shell/frame/syncHost.js +85 -0
- package/dist/shell/frame/syncHost.js.map +1 -0
- package/dist/shell/frame/tabStill.d.ts +2 -0
- package/dist/shell/frame/tabStill.js +62 -0
- package/dist/shell/frame/tabStill.js.map +1 -0
- package/dist/shell/frame/themeScopes.d.ts +29 -0
- package/dist/shell/frame/themeScopes.js +61 -0
- package/dist/shell/frame/themeScopes.js.map +1 -0
- package/dist/shell/frame/themeStore.d.ts +99 -0
- package/dist/shell/frame/themeStore.js +252 -0
- package/dist/shell/frame/themeStore.js.map +1 -0
- package/dist/shell/frame/windowBinding.d.ts +2 -0
- package/dist/shell/frame/windowBinding.js +7 -0
- package/dist/shell/frame/windowBinding.js.map +1 -0
- package/dist/shell/frame/workspaceModel.d.ts +82 -0
- package/dist/shell/frame/workspaceModel.js +250 -0
- package/dist/shell/frame/workspaceModel.js.map +1 -0
- package/dist/shell/frame/workspaces.css +84 -0
- package/dist/shell/frame/workspaces.d.ts +22 -0
- package/dist/shell/frame/workspaces.js +125 -0
- package/dist/shell/frame/workspaces.js.map +1 -0
- package/dist/shell/frame/zoomStore.d.ts +10 -0
- package/dist/shell/frame/zoomStore.js +65 -0
- package/dist/shell/frame/zoomStore.js.map +1 -0
- package/dist/shell/installController.d.ts +122 -0
- package/dist/shell/installController.js +146 -0
- package/dist/shell/installController.js.map +1 -0
- package/dist/shell/installerMessages.d.ts +30 -0
- package/dist/shell/installerMessages.js +36 -0
- package/dist/shell/installerMessages.js.map +1 -0
- package/dist/shell/linkDrop.js.map +1 -1
- package/dist/shell/messages.d.ts +16 -0
- package/dist/shell/messages.js +27 -0
- package/dist/shell/messages.js.map +1 -0
- package/dist/shell/palette.js.map +1 -1
- package/dist/shell/paneModel.d.ts +22 -0
- package/dist/shell/paneModel.js +24 -1
- package/dist/shell/paneModel.js.map +1 -1
- package/dist/shell/panel/Appearance.d.ts +8 -0
- package/dist/shell/panel/Appearance.js +256 -0
- package/dist/shell/panel/Appearance.js.map +1 -0
- package/dist/shell/panel/BackupPanel.d.ts +5 -0
- package/dist/shell/panel/BackupPanel.js +198 -0
- package/dist/shell/panel/BackupPanel.js.map +1 -0
- package/dist/shell/panel/DeveloperPanel.d.ts +4 -0
- package/dist/shell/panel/DeveloperPanel.js +51 -0
- package/dist/shell/panel/DeveloperPanel.js.map +1 -0
- package/dist/shell/panel/FeatureToggles.d.ts +13 -0
- package/dist/shell/panel/FeatureToggles.js +42 -0
- package/dist/shell/panel/FeatureToggles.js.map +1 -0
- package/dist/shell/panel/Home.d.ts +3 -0
- package/dist/shell/panel/Home.js +23 -0
- package/dist/shell/panel/Home.js.map +1 -0
- package/dist/shell/panel/IconPackInstall.d.ts +15 -0
- package/dist/shell/panel/IconPackInstall.js +41 -0
- package/dist/shell/panel/IconPackInstall.js.map +1 -0
- package/dist/shell/panel/LanguageSettings.d.ts +1 -0
- package/dist/shell/panel/LanguageSettings.js +54 -0
- package/dist/shell/panel/LanguageSettings.js.map +1 -0
- package/dist/shell/panel/MakePanel.d.ts +3 -0
- package/dist/shell/panel/MakePanel.js +237 -0
- package/dist/shell/panel/MakePanel.js.map +1 -0
- package/dist/shell/panel/MarkdownDoc.d.ts +6 -0
- package/dist/shell/panel/MarkdownDoc.js +35 -0
- package/dist/shell/panel/MarkdownDoc.js.map +1 -0
- package/dist/shell/panel/Modes.d.ts +40 -0
- package/dist/shell/panel/Modes.js +270 -0
- package/dist/shell/panel/Modes.js.map +1 -0
- package/dist/shell/panel/NavIcon.d.ts +4 -0
- package/dist/shell/panel/NavIcon.js +6 -0
- package/dist/shell/panel/NavIcon.js.map +1 -0
- package/dist/shell/panel/Panel.d.ts +7 -0
- package/dist/shell/panel/Panel.js +139 -0
- package/dist/shell/panel/Panel.js.map +1 -0
- package/dist/shell/panel/PluginFeatures.d.ts +24 -0
- package/dist/shell/panel/PluginFeatures.js +165 -0
- package/dist/shell/panel/PluginFeatures.js.map +1 -0
- package/dist/shell/panel/Plugins.d.ts +33 -0
- package/dist/shell/panel/Plugins.js +112 -0
- package/dist/shell/panel/Plugins.js.map +1 -0
- package/dist/shell/panel/PowerSettings.d.ts +4 -0
- package/dist/shell/panel/PowerSettings.js +52 -0
- package/dist/shell/panel/PowerSettings.js.map +1 -0
- package/dist/shell/panel/Settings.d.ts +23 -0
- package/dist/shell/panel/Settings.js +116 -0
- package/dist/shell/panel/Settings.js.map +1 -0
- package/dist/shell/panel/ShareSetup.d.ts +8 -0
- package/dist/shell/panel/ShareSetup.js +130 -0
- package/dist/shell/panel/ShareSetup.js.map +1 -0
- package/dist/shell/panel/StoreSection.d.ts +6 -0
- package/dist/shell/panel/StoreSection.js +48 -0
- package/dist/shell/panel/StoreSection.js.map +1 -0
- package/dist/shell/panel/StringPacks.d.ts +11 -0
- package/dist/shell/panel/StringPacks.js +106 -0
- package/dist/shell/panel/StringPacks.js.map +1 -0
- package/dist/shell/panel/ThemeBuilder.d.ts +5 -0
- package/dist/shell/panel/ThemeBuilder.js +205 -0
- package/dist/shell/panel/ThemeBuilder.js.map +1 -0
- package/dist/shell/panel/backup.css +34 -0
- package/dist/shell/panel/builder.css +232 -0
- package/dist/shell/panel/builderModel.d.ts +55 -0
- package/dist/shell/panel/builderModel.js +95 -0
- package/dist/shell/panel/builderModel.js.map +1 -0
- package/dist/shell/panel/compare.d.ts +10 -0
- package/dist/shell/panel/compare.js +51 -0
- package/dist/shell/panel/compare.js.map +1 -0
- package/dist/shell/panel/controls.d.ts +135 -0
- package/dist/shell/panel/controls.js +213 -0
- package/dist/shell/panel/controls.js.map +1 -0
- package/dist/shell/panel/featureModel.d.ts +69 -0
- package/dist/shell/panel/featureModel.js +79 -0
- package/dist/shell/panel/featureModel.js.map +1 -0
- package/dist/shell/panel/fonts/FontBrowser.d.ts +10 -0
- package/dist/shell/panel/fonts/FontBrowser.js +189 -0
- package/dist/shell/panel/fonts/FontBrowser.js.map +1 -0
- package/dist/shell/panel/fonts/FontRoles.d.ts +20 -0
- package/dist/shell/panel/fonts/FontRoles.js +77 -0
- package/dist/shell/panel/fonts/FontRoles.js.map +1 -0
- package/dist/shell/panel/fonts/catalog.d.ts +37 -0
- package/dist/shell/panel/fonts/catalog.js +68 -0
- package/dist/shell/panel/fonts/catalog.js.map +1 -0
- package/dist/shell/panel/fonts/googleFontsCatalog.json +1 -0
- package/dist/shell/panel/index.d.ts +20 -0
- package/dist/shell/panel/index.js +34 -0
- package/dist/shell/panel/index.js.map +1 -0
- package/dist/shell/panel/languageModel.d.ts +5 -0
- package/dist/shell/panel/languageModel.js +7 -0
- package/dist/shell/panel/languageModel.js.map +1 -0
- package/dist/shell/panel/make.css +72 -0
- package/dist/shell/panel/makeModel.d.ts +32 -0
- package/dist/shell/panel/makeModel.js +84 -0
- package/dist/shell/panel/makeModel.js.map +1 -0
- package/dist/shell/panel/markdown.d.ts +46 -0
- package/dist/shell/panel/markdown.js +100 -0
- package/dist/shell/panel/markdown.js.map +1 -0
- package/dist/shell/panel/nav.d.ts +12 -0
- package/dist/shell/panel/nav.js +50 -0
- package/dist/shell/panel/nav.js.map +1 -0
- package/dist/shell/panel/panel.css +401 -0
- package/dist/shell/panel/panelMessages.d.ts +763 -0
- package/dist/shell/panel/panelMessages.js +767 -0
- package/dist/shell/panel/panelMessages.js.map +1 -0
- package/dist/shell/panel/plugins.css +59 -0
- package/dist/shell/panel/setupModel.d.ts +87 -0
- package/dist/shell/panel/setupModel.js +152 -0
- package/dist/shell/panel/setupModel.js.map +1 -0
- package/dist/shell/panel/site.d.ts +259 -0
- package/dist/shell/panel/site.js +25 -0
- package/dist/shell/panel/site.js.map +1 -0
- package/dist/shell/panel/strings.css +7 -0
- package/dist/shell/panel/themes.d.ts +10 -0
- package/dist/shell/panel/themes.js +8 -0
- package/dist/shell/panel/themes.js.map +1 -0
- package/dist/shell/profileModel.d.ts +3 -2
- package/dist/shell/profileModel.js +7 -5
- package/dist/shell/profileModel.js.map +1 -1
- package/dist/shell/store.css +230 -0
- package/dist/shell/storeMessages.d.ts +169 -0
- package/dist/shell/storeMessages.js +172 -0
- package/dist/shell/storeMessages.js.map +1 -0
- package/dist/shell/storeModel.d.ts +181 -0
- package/dist/shell/storeModel.js +133 -0
- package/dist/shell/storeModel.js.map +1 -0
- package/dist/shell/stringPacksModel.d.ts +44 -0
- package/dist/shell/stringPacksModel.js +94 -0
- package/dist/shell/stringPacksModel.js.map +1 -0
- package/dist/shell/updateModel.d.ts +2 -1
- package/dist/shell/updateModel.js +5 -4
- package/dist/shell/updateModel.js.map +1 -1
- package/dist/shell/windowControls.d.ts +4 -0
- package/dist/shell/windowControls.js +5 -0
- package/dist/shell/windowControls.js.map +1 -1
- package/i18n-config.schema.json +29 -0
- package/i18n-meta.schema.json +26 -0
- package/i18n.schema.json +42 -0
- package/icons.schema.json +646 -0
- package/languages.schema.json +23 -0
- package/locales/ar-x-fm.json +11 -0
- package/locales/ar.json +1281 -0
- package/locales/bg.json +1280 -0
- package/locales/bn.json +1280 -0
- package/locales/ca.json +1280 -0
- package/locales/cs.json +1280 -0
- package/locales/da.json +1280 -0
- package/locales/de.json +1280 -0
- package/locales/el.json +1280 -0
- package/locales/en-GB.json +27 -0
- package/locales/en.json +1280 -0
- package/locales/en.meta.json +51 -0
- package/locales/es.json +1280 -0
- package/locales/eu.json +1280 -0
- package/locales/fa.json +1281 -0
- package/locales/fi.json +1280 -0
- package/locales/fil.json +1280 -0
- package/locales/fr.json +1280 -0
- package/locales/ga.json +1280 -0
- package/locales/gl.json +1280 -0
- package/locales/gu.json +1280 -0
- package/locales/ha.json +1280 -0
- package/locales/he.json +1281 -0
- package/locales/hi.json +1280 -0
- package/locales/hr.json +1280 -0
- package/locales/hu.json +1279 -0
- package/locales/id.json +1280 -0
- package/locales/ig.json +1280 -0
- package/locales/it.json +1280 -0
- package/locales/ja.json +1280 -0
- package/locales/kn.json +1280 -0
- package/locales/ko.json +1280 -0
- package/locales/mr.json +1280 -0
- package/locales/ms.json +1280 -0
- package/locales/nb.json +1280 -0
- package/locales/nl.json +1280 -0
- package/locales/pl.json +1280 -0
- package/locales/pt.json +1280 -0
- package/locales/ro.json +1280 -0
- package/locales/ru.json +1280 -0
- package/locales/sk.json +1280 -0
- package/locales/sr.json +1280 -0
- package/locales/sv.json +1280 -0
- package/locales/ta.json +1280 -0
- package/locales/th.json +1280 -0
- package/locales/tr.json +1280 -0
- package/locales/uk.json +1280 -0
- package/locales/ur.json +1281 -0
- package/locales/vi.json +1280 -0
- package/locales/yo.json +1280 -0
- package/locales/zh-Hans.json +1280 -0
- package/locales/zh-Hant.json +1280 -0
- package/package.json +139 -5
- package/store-catalog.schema.json +65 -0
- package/theme.schema.json +4659 -0
- package/windows/installer.nsi +926 -0
- package/windows/languages/Basque.nsh +28 -0
- package/windows/languages/Catalan.nsh +28 -0
- package/windows/languages/Croatian.nsh +28 -0
- package/windows/languages/Czech.nsh +28 -0
- package/windows/languages/Danish.nsh +28 -0
- package/windows/languages/Finnish.nsh +28 -0
- package/windows/languages/Galician.nsh +28 -0
- package/windows/languages/Greek.nsh +28 -0
- package/windows/languages/Hungarian.nsh +28 -0
- package/windows/languages/Indonesian.nsh +28 -0
- package/windows/languages/Irish.nsh +28 -0
- package/windows/languages/Malay.nsh +28 -0
- package/windows/languages/Polish.nsh +28 -0
- package/windows/languages/Romanian.nsh +28 -0
- package/windows/languages/Serbian.nsh +28 -0
- package/windows/languages/Slovak.nsh +28 -0
- package/windows/languages/Thai.nsh +28 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// Titlebar extras left of the account switcher: the workspace menu (save the layout, switch with
|
|
3
|
+
// one click, choose the one opened on start) and two quiet chips that appear only when needed
|
|
4
|
+
// (developer mode errors / last reload, newer synced settings from another computer). The tab strip
|
|
5
|
+
// reserves their measured width (`--bt-tb-extra`, shell.css).
|
|
6
|
+
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
7
|
+
import { createPortal } from 'react-dom';
|
|
8
|
+
import { ago } from "./backupModel.js";
|
|
9
|
+
import { useDev, usePaneTick, useSync, useT } from "./hooks.js";
|
|
10
|
+
import { formatNumber, t } from "./i18n.js";
|
|
11
|
+
import { Icon } from "./icons.js";
|
|
12
|
+
import { menuText } from "./menuModel.js";
|
|
13
|
+
import { safe, setSafeMode } from "./safeStore.js";
|
|
14
|
+
import { hasFeature } from "./site.js";
|
|
15
|
+
import { setOverlay, shell } from "./state.js";
|
|
16
|
+
import { WORKSPACE_LIMITS } from "./workspaceModel.js";
|
|
17
|
+
import { deleteWorkspace, loadWorkspaces, renameSavedWorkspace, restoreWorkspace, saveCurrentWorkspace, setStartWorkspace, workspaceList, workspaces, } from "./workspaces.js";
|
|
18
|
+
import { readZoom, stepZoom, zoomOf, zoomTarget } from "./zoomStore.js";
|
|
19
|
+
import './workspaces.css';
|
|
20
|
+
function useWorkspaces() {
|
|
21
|
+
const [, setTick] = useState(0);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const update = () => setTick(tick => tick + 1);
|
|
24
|
+
window.addEventListener('bt-workspaces', update);
|
|
25
|
+
if (!workspaces.loaded)
|
|
26
|
+
void loadWorkspaces();
|
|
27
|
+
return () => window.removeEventListener('bt-workspaces', update);
|
|
28
|
+
}, []);
|
|
29
|
+
return workspaces;
|
|
30
|
+
}
|
|
31
|
+
/** Opens the workspace menu with the "save as" field focused (Ctrl+K → "Save layout as workspace…"). */
|
|
32
|
+
export const openWorkspaceSave = () => window.dispatchEvent(new CustomEvent('bt-workspace-menu', { detail: 'save' }));
|
|
33
|
+
export function TitlebarExtras() {
|
|
34
|
+
const root = useRef(null);
|
|
35
|
+
useLayoutEffect(() => {
|
|
36
|
+
const el = root.current;
|
|
37
|
+
if (!el)
|
|
38
|
+
return;
|
|
39
|
+
const measure = () => document.documentElement.style.setProperty('--bt-tb-extra', `${Math.ceil(el.getBoundingClientRect().width)}px`);
|
|
40
|
+
measure();
|
|
41
|
+
const observer = new ResizeObserver(measure);
|
|
42
|
+
observer.observe(el);
|
|
43
|
+
return () => { observer.disconnect(); document.documentElement.style.removeProperty('--bt-tb-extra'); };
|
|
44
|
+
}, []);
|
|
45
|
+
return _jsxs("div", { className: "bt-tb-extras", ref: root, children: [hasFeature('safeMode') && _jsx(SafeChip, {}), hasFeature('zoom') && _jsx(ZoomChip, {}), hasFeature('sync') && _jsx(SyncChip, {}), hasFeature('developer') && _jsx(DevChip, {}), hasFeature('workspaces') && _jsx(WorkspaceMenu, {})] });
|
|
46
|
+
}
|
|
47
|
+
/** Safe mode: said in the titlebar for as long as it is on; one click leaves it (the tabs load again with the owner's setup). */
|
|
48
|
+
function SafeChip() {
|
|
49
|
+
useT();
|
|
50
|
+
const [, tick] = useState(0);
|
|
51
|
+
const [busy, setBusy] = useState(false);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
const update = () => tick(value => value + 1);
|
|
54
|
+
window.addEventListener('bt-safe', update);
|
|
55
|
+
return () => window.removeEventListener('bt-safe', update);
|
|
56
|
+
}, []);
|
|
57
|
+
if (!safe.active)
|
|
58
|
+
return null;
|
|
59
|
+
return _jsxs("button", { className: "bt-tb-chip bt-safe-chip", title: menuText('safeChip'), "aria-label": `${menuText('safe')}. ${menuText('safeLeave')}`, disabled: busy, onClick: () => { setBusy(true); void setSafeMode(false).catch(() => { }).finally(() => setBusy(false)); }, children: [_jsx(Icon, { name: "shield" }), _jsx("span", { className: "bt-tb-chip-text", children: menuText('safe') }), _jsx("span", { className: "bt-safe-leave", children: menuText('safeLeaveShort') })] });
|
|
60
|
+
}
|
|
61
|
+
/** The page zoom of the pane in front, only while it is not 100% (Ctrl with + and - say nothing else); a click resets it. */
|
|
62
|
+
function ZoomChip() {
|
|
63
|
+
useT();
|
|
64
|
+
usePaneTick();
|
|
65
|
+
const [, tick] = useState(0);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
const update = () => tick(value => value + 1);
|
|
68
|
+
window.addEventListener('bt-zoom', update);
|
|
69
|
+
window.addEventListener('bt-decks', update);
|
|
70
|
+
return () => { window.removeEventListener('bt-zoom', update); window.removeEventListener('bt-decks', update); };
|
|
71
|
+
}, []);
|
|
72
|
+
const tab = zoomTarget();
|
|
73
|
+
// A restored tab may come back zoomed: ask once it is the one in front.
|
|
74
|
+
useEffect(() => { void readZoom(tab); }, [tab]);
|
|
75
|
+
const factor = zoomOf(tab);
|
|
76
|
+
if (!tab || factor === 1)
|
|
77
|
+
return null;
|
|
78
|
+
const percent = formatNumber(factor, { style: 'percent', maximumFractionDigits: 0 });
|
|
79
|
+
const label = menuText('zoomChip', { percent });
|
|
80
|
+
return _jsxs("button", { className: "bt-tb-chip bt-zoom-chip", title: label, "aria-label": label, onClick: () => void stepZoom(0, tab), children: [_jsx(Icon, { name: "zoom" }), _jsx("span", { className: "bt-tb-chip-text", children: percent })] });
|
|
81
|
+
}
|
|
82
|
+
function DevChip() {
|
|
83
|
+
const t = useT();
|
|
84
|
+
const dev = useDev();
|
|
85
|
+
const [now, setNow] = useState(Date.now());
|
|
86
|
+
useEffect(() => { const timer = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(timer); }, []);
|
|
87
|
+
if (!dev.enabled)
|
|
88
|
+
return null;
|
|
89
|
+
const errors = dev.errors.length;
|
|
90
|
+
const recent = dev.last && now - dev.last.at < 4000 ? dev.last.text : null;
|
|
91
|
+
const first = dev.errors[0];
|
|
92
|
+
const title = errors
|
|
93
|
+
? dev.errors.slice(0, 5).map(error => `${error.file}${error.line ? `:${error.line}${error.column ? `:${error.column}` : ''}` : ''} — ${error.message}`).join('\n')
|
|
94
|
+
: t('wb.chip.dev.title');
|
|
95
|
+
return _jsxs("button", { className: `bt-tb-chip bt-dev-chip${errors ? ' is-error' : ''}${recent ? ' is-fresh' : ''}`, title: title, onClick: () => shell.openPanelSection('developer'), children: [_jsx("span", { className: "bt-tb-chip-dot", "aria-hidden": "true" }), _jsx("span", { className: "bt-tb-chip-text", children: errors ? `${t('wb.chip.dev.errors', { count: errors })}${first ? ` · ${first.file}${first.line ? `:${first.line}` : ''}` : ''}` : recent ?? t('wb.chip.dev.label') })] });
|
|
96
|
+
}
|
|
97
|
+
function SyncChip() {
|
|
98
|
+
const t = useT();
|
|
99
|
+
const sync = useSync();
|
|
100
|
+
if (!sync.newer)
|
|
101
|
+
return null;
|
|
102
|
+
return _jsxs("button", { className: "bt-tb-chip bt-sync-chip", title: t('wb.chip.sync.title', { device: sync.newer.deviceName, when: ago(sync.newer.createdAt) }), onClick: () => { shell.openPanelSection('backup'); requestAnimationFrame(() => window.dispatchEvent(new CustomEvent('bt-sync-review', { detail: sync.newer?.name }))); }, children: [_jsx(Icon, { name: "reload" }), _jsx("span", { className: "bt-tb-chip-text", children: t('wb.backup.fromDevice', { device: sync.newer.deviceName }) })] });
|
|
103
|
+
}
|
|
104
|
+
function WorkspaceMenu() {
|
|
105
|
+
const t = useT();
|
|
106
|
+
const store = useWorkspaces();
|
|
107
|
+
const [open, setOpen] = useState(false);
|
|
108
|
+
const [mode, setMode] = useState({ kind: 'list' });
|
|
109
|
+
const [name, setName] = useState('');
|
|
110
|
+
const [error, setError] = useState('');
|
|
111
|
+
const [anchor, setAnchor] = useState({ top: 50, right: 8 });
|
|
112
|
+
const button = useRef(null);
|
|
113
|
+
const menu = useRef(null);
|
|
114
|
+
const active = store.store.items.find(item => item.id === store.active);
|
|
115
|
+
const list = workspaceList();
|
|
116
|
+
const show = (next = { kind: 'list' }) => {
|
|
117
|
+
const rect = button.current?.getBoundingClientRect();
|
|
118
|
+
if (rect)
|
|
119
|
+
setAnchor({ top: Math.round(rect.bottom + 6), right: Math.max(8, Math.round(window.innerWidth - rect.right)) });
|
|
120
|
+
setMode(next);
|
|
121
|
+
setError('');
|
|
122
|
+
setName(next.kind === 'save' ? (active ? '' : suggestName()) : '');
|
|
123
|
+
setOpen(true);
|
|
124
|
+
};
|
|
125
|
+
const close = (refocus = false) => { setOpen(false); setMode({ kind: 'list' }); setError(''); if (refocus)
|
|
126
|
+
button.current?.focus(); };
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
const onOpen = (event) => show(event.detail === 'save' ? { kind: 'save' } : { kind: 'list' });
|
|
129
|
+
window.addEventListener('bt-workspace-menu', onOpen);
|
|
130
|
+
return () => window.removeEventListener('bt-workspace-menu', onOpen);
|
|
131
|
+
}, [active?.id]);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (!open)
|
|
134
|
+
return;
|
|
135
|
+
setOverlay(1);
|
|
136
|
+
const onBlur = () => close();
|
|
137
|
+
window.addEventListener('blur', onBlur);
|
|
138
|
+
return () => { setOverlay(-1); window.removeEventListener('blur', onBlur); };
|
|
139
|
+
}, [open]);
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
if (!open)
|
|
142
|
+
return;
|
|
143
|
+
requestAnimationFrame(() => menu.current?.querySelector('input, .bt-ws-main, button')?.focus());
|
|
144
|
+
}, [open, mode.kind]);
|
|
145
|
+
async function run(action, done = true) {
|
|
146
|
+
setError('');
|
|
147
|
+
try {
|
|
148
|
+
await action();
|
|
149
|
+
if (done)
|
|
150
|
+
close();
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
catch (failure) {
|
|
154
|
+
setError(failure instanceof Error ? failure.message : String(failure));
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const onKey = (event) => {
|
|
159
|
+
if (event.key === 'Escape') {
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
event.stopPropagation();
|
|
162
|
+
if (mode.kind !== 'list')
|
|
163
|
+
setMode({ kind: 'list' });
|
|
164
|
+
else
|
|
165
|
+
close(true);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
169
|
+
const items = Array.from(menu.current?.querySelectorAll('.bt-ws-main, .bt-ws-save') ?? []);
|
|
170
|
+
if (!items.length)
|
|
171
|
+
return;
|
|
172
|
+
event.preventDefault();
|
|
173
|
+
const at = items.indexOf(document.activeElement);
|
|
174
|
+
items[(at + (event.key === 'ArrowDown' ? 1 : -1) + items.length) % items.length]?.focus();
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
return _jsxs(_Fragment, { children: [_jsxs("button", { ref: button, className: "bt-ws-button", "aria-haspopup": "menu", "aria-expanded": open, title: active ? `Workspace: ${active.name}` : 'Workspaces: save this layout, switch with one click', "aria-label": active ? t('wb.ws.named', { name: active.name }) : t('wb.ws.title'), onClick: () => (open ? close() : show()), children: [_jsx(WorkspaceGlyph, {}), active && _jsx("span", { className: "bt-ws-button-name", children: active.name })] }), open && createPortal(_jsx("div", { className: "bt-menu-backdrop", onMouseDown: () => close(), onContextMenu: event => { event.preventDefault(); close(); }, children: _jsxs("div", { ref: menu, className: "bt-menu bt-ws-menu bt-pop bt-pop--right", role: "menu", "aria-label": t('wb.ws.title'), style: { top: anchor.top, right: anchor.right }, onMouseDown: event => event.stopPropagation(), onKeyDown: onKey, children: [_jsxs("div", { className: "bt-ws-head", role: "presentation", children: [_jsx("strong", { children: t('wb.ws.title') }), _jsx("span", { children: t('wb.ws.hint') })] }), list.length === 0 && mode.kind === 'list' && _jsx("div", { className: "bt-ws-empty", children: t('wb.ws.empty') }), list.map(item => {
|
|
178
|
+
const isActive = item.id === store.active;
|
|
179
|
+
if (mode.kind === 'rename' && mode.id === item.id) {
|
|
180
|
+
return _jsxs("form", { className: "bt-ws-form", onSubmit: event => { event.preventDefault(); void run(() => renameSavedWorkspace(item.id, name), false).then(ok => ok && setMode({ kind: 'list' })); }, children: [_jsx("input", { className: "bt-ws-input", value: name, maxLength: WORKSPACE_LIMITS.name, onChange: event => setName(event.target.value), "aria-label": t('wb.ws.newName', { name: item.name }), spellCheck: false }), _jsx("button", { type: "submit", className: "bt-ws-primary", disabled: !name.trim(), children: t('wb.ws.rename') })] }, item.id);
|
|
181
|
+
}
|
|
182
|
+
if (mode.kind === 'confirm' && mode.id === item.id) {
|
|
183
|
+
return _jsxs("div", { className: "bt-ws-confirm", role: "alertdialog", "aria-label": t('wb.ws.deleteNamed', { name: item.name }), children: [_jsx("span", { children: t('wb.ws.deleteConfirm', { name: item.name }) }), _jsxs("div", { children: [_jsx("button", { className: "bt-ws-danger", onClick: () => void run(() => deleteWorkspace(item.id), false).then(ok => ok && setMode({ kind: 'list' })), children: t('kit.delete') }), _jsx("button", { className: "bt-ws-cancel", onClick: () => setMode({ kind: 'list' }), children: t('wb.common.cancel') })] })] }, item.id);
|
|
184
|
+
}
|
|
185
|
+
return _jsxs("div", { className: `bt-ws-row${isActive ? ' is-active' : ''}`, role: "none", children: [_jsxs("button", { role: "menuitem", className: "bt-ws-main", "aria-current": isActive ? 'true' : undefined, onClick: () => void run(() => restoreWorkspace(item.id)), children: [_jsxs("span", { className: "bt-ws-name", children: [item.name, item.isDefault && _jsx("span", { className: "bt-ws-badge", title: t('wb.ws.onStartTitle'), children: t('wb.ws.onStart') })] }), _jsxs("span", { className: "bt-ws-meta", children: [t('wb.ws.tabs', { count: item.tabs }), isActive ? ` · ${t('wb.ws.openNow')}` : ''] })] }), _jsxs("span", { className: "bt-ws-actions", children: [isActive && _jsx("button", { className: "bt-ws-icon", title: t('wb.ws.update'), "aria-label": t('wb.ws.updateNamed', { name: item.name }), onClick: () => void run(() => saveCurrentWorkspace(item.name, item.id)), children: _jsx(Icon, { name: "check" }) }), _jsx("button", { className: "bt-ws-icon", title: item.isDefault ? t('wb.ws.stopStart') : t('wb.ws.setStart'), "aria-pressed": item.isDefault, "aria-label": item.isDefault ? t('wb.ws.stopStartNamed', { name: item.name }) : t('wb.ws.setStartNamed', { name: item.name }), onClick: () => void run(() => setStartWorkspace(item.isDefault ? null : item.id), false), children: _jsx(Icon, { name: item.isDefault ? 'pin' : 'unpin' }) }), _jsx("button", { className: "bt-ws-icon", title: t('wb.ws.rename'), "aria-label": t('wb.ws.renameNamed', { name: item.name }), onClick: () => { setName(item.name); setMode({ kind: 'rename', id: item.id }); }, children: _jsx(Icon, { name: "edit" }) }), _jsx("button", { className: "bt-ws-icon", title: t('kit.delete'), "aria-label": t('wb.ws.deleteNamed', { name: item.name }), onClick: () => setMode({ kind: 'confirm', id: item.id }), children: _jsx(Icon, { name: "trash" }) })] })] }, item.id);
|
|
186
|
+
}), _jsx("hr", {}), mode.kind === 'save'
|
|
187
|
+
? _jsxs("form", { className: "bt-ws-form", onSubmit: event => { event.preventDefault(); void run(() => saveCurrentWorkspace(name)); }, children: [_jsx("input", { className: "bt-ws-input", value: name, placeholder: t('wb.ws.namePlaceholder'), maxLength: WORKSPACE_LIMITS.name, onChange: event => setName(event.target.value), "aria-label": t('wb.ws.name'), spellCheck: false }), _jsx("button", { type: "submit", className: "bt-ws-primary", disabled: !name.trim(), children: t('wb.common.save') })] })
|
|
188
|
+
: _jsxs("button", { role: "menuitem", className: "bt-ws-save", onClick: () => { setName(suggestName()); setMode({ kind: 'save' }); }, children: [_jsx("span", { className: "bt-ws-save-icon", children: _jsx(Icon, { name: "plus" }) }), _jsxs("span", { className: "bt-ws-text", children: [_jsx("span", { className: "bt-ws-name", children: t('wb.ws.save') }), _jsx("span", { className: "bt-ws-meta", children: t('wb.ws.saveMeta', { count: shell.api?.panels.length ?? 0 }) })] })] }), error && _jsx("div", { className: "bt-ws-error", role: "alert", children: error })] }) }), document.body)] });
|
|
189
|
+
}
|
|
190
|
+
function suggestName() {
|
|
191
|
+
const taken = new Set(workspaces.store.items.map(item => item.name));
|
|
192
|
+
for (let n = 1;; n += 1) {
|
|
193
|
+
const candidate = n === 1 ? t('wb.ws.default') : t('wb.ws.defaultN', { n });
|
|
194
|
+
if (!taken.has(candidate))
|
|
195
|
+
return candidate;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/** Three stacked panes: a layout. */
|
|
199
|
+
function WorkspaceGlyph() {
|
|
200
|
+
return _jsxs("svg", { className: "bt-ws-glyph", viewBox: "0 0 16 16", "aria-hidden": "true", children: [_jsx("rect", { x: "1.75", y: "2.25", width: "12.5", height: "11.5", rx: "2.25" }), _jsx("path", { d: "M6.75 2.5v11M6.75 8h7.25" })] });
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=TitlebarExtras.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TitlebarExtras.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/TitlebarExtras.tsx"],"names":[],"mappings":"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","sourcesContent":["// Titlebar extras left of the account switcher: the workspace menu (save the layout, switch with\n// one click, choose the one opened on start) and two quiet chips that appear only when needed\n// (developer mode errors / last reload, newer synced settings from another computer). The tab strip\n// reserves their measured width (`--bt-tb-extra`, shell.css).\n\nimport { useEffect, useLayoutEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ago } from './backupModel.ts';\nimport { useDev, usePaneTick, useSync, useT } from './hooks.ts';\nimport { formatNumber, t } from './i18n.ts';\nimport { Icon } from './icons.tsx';\nimport { menuText } from './menuModel.ts';\nimport { safe, setSafeMode } from './safeStore.ts';\nimport { hasFeature } from './site.ts';\nimport { setOverlay, shell } from './state.ts';\nimport { WORKSPACE_LIMITS } from './workspaceModel.ts';\nimport {\n deleteWorkspace, loadWorkspaces, renameSavedWorkspace, restoreWorkspace, saveCurrentWorkspace, setStartWorkspace, workspaceList, workspaces,\n} from './workspaces.ts';\nimport { readZoom, stepZoom, zoomOf, zoomTarget } from './zoomStore.ts';\nimport './workspaces.css';\n\nfunction useWorkspaces() {\n const [, setTick] = useState(0);\n useEffect(() => {\n const update = () => setTick(tick => tick + 1);\n window.addEventListener('bt-workspaces', update);\n if (!workspaces.loaded) void loadWorkspaces();\n return () => window.removeEventListener('bt-workspaces', update);\n }, []);\n return workspaces;\n}\n\n/** Opens the workspace menu with the \"save as\" field focused (Ctrl+K → \"Save layout as workspace…\"). */\nexport const openWorkspaceSave = () => window.dispatchEvent(new CustomEvent('bt-workspace-menu', { detail: 'save' }));\n\nexport function TitlebarExtras() {\n const root = useRef<HTMLDivElement>(null);\n useLayoutEffect(() => {\n const el = root.current;\n if (!el) return;\n const measure = () => document.documentElement.style.setProperty('--bt-tb-extra', `${Math.ceil(el.getBoundingClientRect().width)}px`);\n measure();\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => { observer.disconnect(); document.documentElement.style.removeProperty('--bt-tb-extra'); };\n }, []);\n return <div className=\"bt-tb-extras\" ref={root}>\n {hasFeature('safeMode') && <SafeChip/>}\n {hasFeature('zoom') && <ZoomChip/>}\n {hasFeature('sync') && <SyncChip/>}\n {hasFeature('developer') && <DevChip/>}\n {hasFeature('workspaces') && <WorkspaceMenu/>}\n </div>;\n}\n\n/** Safe mode: said in the titlebar for as long as it is on; one click leaves it (the tabs load again with the owner's setup). */\nfunction SafeChip() {\n useT();\n const [, tick] = useState(0);\n const [busy, setBusy] = useState(false);\n useEffect(() => {\n const update = () => tick(value => value + 1);\n window.addEventListener('bt-safe', update);\n return () => window.removeEventListener('bt-safe', update);\n }, []);\n if (!safe.active) return null;\n return <button className=\"bt-tb-chip bt-safe-chip\" title={menuText('safeChip')} aria-label={`${menuText('safe')}. ${menuText('safeLeave')}`} disabled={busy}\n onClick={() => { setBusy(true); void setSafeMode(false).catch(() => {}).finally(() => setBusy(false)); }}>\n <Icon name=\"shield\"/><span className=\"bt-tb-chip-text\">{menuText('safe')}</span><span className=\"bt-safe-leave\">{menuText('safeLeaveShort')}</span>\n </button>;\n}\n\n/** The page zoom of the pane in front, only while it is not 100% (Ctrl with + and - say nothing else); a click resets it. */\nfunction ZoomChip() {\n useT();\n usePaneTick();\n const [, tick] = useState(0);\n useEffect(() => {\n const update = () => tick(value => value + 1);\n window.addEventListener('bt-zoom', update);\n window.addEventListener('bt-decks', update);\n return () => { window.removeEventListener('bt-zoom', update); window.removeEventListener('bt-decks', update); };\n }, []);\n const tab = zoomTarget();\n // A restored tab may come back zoomed: ask once it is the one in front.\n useEffect(() => { void readZoom(tab); }, [tab]);\n const factor = zoomOf(tab);\n if (!tab || factor === 1) return null;\n const percent = formatNumber(factor, { style: 'percent', maximumFractionDigits: 0 });\n const label = menuText('zoomChip', { percent });\n return <button className=\"bt-tb-chip bt-zoom-chip\" title={label} aria-label={label} onClick={() => void stepZoom(0, tab)}>\n <Icon name=\"zoom\"/><span className=\"bt-tb-chip-text\">{percent}</span>\n </button>;\n}\n\nfunction DevChip() {\n const t = useT();\n const dev = useDev();\n const [now, setNow] = useState(Date.now());\n useEffect(() => { const timer = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(timer); }, []);\n if (!dev.enabled) return null;\n const errors = dev.errors.length;\n const recent = dev.last && now - dev.last.at < 4000 ? dev.last.text : null;\n const first = dev.errors[0];\n const title = errors\n ? dev.errors.slice(0, 5).map(error => `${error.file}${error.line ? `:${error.line}${error.column ? `:${error.column}` : ''}` : ''} — ${error.message}`).join('\\n')\n : t('wb.chip.dev.title');\n return <button className={`bt-tb-chip bt-dev-chip${errors ? ' is-error' : ''}${recent ? ' is-fresh' : ''}`} title={title}\n onClick={() => shell.openPanelSection('developer')}>\n <span className=\"bt-tb-chip-dot\" aria-hidden=\"true\"/>\n <span className=\"bt-tb-chip-text\">{errors ? `${t('wb.chip.dev.errors', { count: errors })}${first ? ` · ${first.file}${first.line ? `:${first.line}` : ''}` : ''}` : recent ?? t('wb.chip.dev.label')}</span>\n </button>;\n}\n\nfunction SyncChip() {\n const t = useT();\n const sync = useSync();\n if (!sync.newer) return null;\n return <button className=\"bt-tb-chip bt-sync-chip\" title={t('wb.chip.sync.title', { device: sync.newer.deviceName, when: ago(sync.newer.createdAt) })}\n onClick={() => { shell.openPanelSection('backup'); requestAnimationFrame(() => window.dispatchEvent(new CustomEvent('bt-sync-review', { detail: sync.newer?.name }))); }}>\n <Icon name=\"reload\"/><span className=\"bt-tb-chip-text\">{t('wb.backup.fromDevice', { device: sync.newer.deviceName })}</span>\n </button>;\n}\n\ntype Mode = { kind: 'list' } | { kind: 'save' } | { kind: 'rename'; id: string } | { kind: 'confirm'; id: string };\n\nfunction WorkspaceMenu() {\n const t = useT();\n const store = useWorkspaces();\n const [open, setOpen] = useState(false);\n const [mode, setMode] = useState<Mode>({ kind: 'list' });\n const [name, setName] = useState('');\n const [error, setError] = useState('');\n const [anchor, setAnchor] = useState({ top: 50, right: 8 });\n const button = useRef<HTMLButtonElement>(null);\n const menu = useRef<HTMLDivElement>(null);\n const active = store.store.items.find(item => item.id === store.active);\n const list = workspaceList();\n\n const show = (next: Mode = { kind: 'list' }) => {\n const rect = button.current?.getBoundingClientRect();\n if (rect) setAnchor({ top: Math.round(rect.bottom + 6), right: Math.max(8, Math.round(window.innerWidth - rect.right)) });\n setMode(next); setError('');\n setName(next.kind === 'save' ? (active ? '' : suggestName()) : '');\n setOpen(true);\n };\n const close = (refocus = false) => { setOpen(false); setMode({ kind: 'list' }); setError(''); if (refocus) button.current?.focus(); };\n\n useEffect(() => {\n const onOpen = (event: Event) => show((event as CustomEvent<string>).detail === 'save' ? { kind: 'save' } : { kind: 'list' });\n window.addEventListener('bt-workspace-menu', onOpen);\n return () => window.removeEventListener('bt-workspace-menu', onOpen);\n }, [active?.id]);\n useEffect(() => {\n if (!open) return;\n setOverlay(1);\n const onBlur = () => close();\n window.addEventListener('blur', onBlur);\n return () => { setOverlay(-1); window.removeEventListener('blur', onBlur); };\n }, [open]);\n useEffect(() => {\n if (!open) return;\n requestAnimationFrame(() => menu.current?.querySelector<HTMLElement>('input, .bt-ws-main, button')?.focus());\n }, [open, mode.kind]);\n\n async function run(action: () => Promise<unknown>, done = true) {\n setError('');\n try { await action(); if (done) close(); return true; }\n catch (failure) { setError(failure instanceof Error ? failure.message : String(failure)); return false; }\n }\n\n const onKey = (event: ReactKeyboardEvent) => {\n if (event.key === 'Escape') { event.preventDefault(); event.stopPropagation(); if (mode.kind !== 'list') setMode({ kind: 'list' }); else close(true); return; }\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n const items = Array.from(menu.current?.querySelectorAll<HTMLElement>('.bt-ws-main, .bt-ws-save') ?? []);\n if (!items.length) return;\n event.preventDefault();\n const at = items.indexOf(document.activeElement as HTMLElement);\n items[(at + (event.key === 'ArrowDown' ? 1 : -1) + items.length) % items.length]?.focus();\n }\n };\n\n return <>\n <button ref={button} className=\"bt-ws-button\" aria-haspopup=\"menu\" aria-expanded={open}\n title={active ? `Workspace: ${active.name}` : 'Workspaces: save this layout, switch with one click'}\n aria-label={active ? t('wb.ws.named', { name: active.name }) : t('wb.ws.title')} onClick={() => (open ? close() : show())}>\n <WorkspaceGlyph/>\n {active && <span className=\"bt-ws-button-name\">{active.name}</span>}\n </button>\n {open && createPortal(<div className=\"bt-menu-backdrop\" onMouseDown={() => close()} onContextMenu={event => { event.preventDefault(); close(); }}>\n <div ref={menu} className=\"bt-menu bt-ws-menu bt-pop bt-pop--right\" role=\"menu\" aria-label={t('wb.ws.title')} style={{ top: anchor.top, right: anchor.right }}\n onMouseDown={event => event.stopPropagation()} onKeyDown={onKey}>\n <div className=\"bt-ws-head\" role=\"presentation\">\n <strong>{t('wb.ws.title')}</strong>\n <span>{t('wb.ws.hint')}</span>\n </div>\n {list.length === 0 && mode.kind === 'list' && <div className=\"bt-ws-empty\">{t('wb.ws.empty')}</div>}\n {list.map(item => {\n const isActive = item.id === store.active;\n if (mode.kind === 'rename' && mode.id === item.id) {\n return <form key={item.id} className=\"bt-ws-form\" onSubmit={event => { event.preventDefault(); void run(() => renameSavedWorkspace(item.id, name), false).then(ok => ok && setMode({ kind: 'list' })); }}>\n <input className=\"bt-ws-input\" value={name} maxLength={WORKSPACE_LIMITS.name} onChange={event => setName(event.target.value)} aria-label={t('wb.ws.newName', { name: item.name })} spellCheck={false}/>\n <button type=\"submit\" className=\"bt-ws-primary\" disabled={!name.trim()}>{t('wb.ws.rename')}</button>\n </form>;\n }\n if (mode.kind === 'confirm' && mode.id === item.id) {\n return <div key={item.id} className=\"bt-ws-confirm\" role=\"alertdialog\" aria-label={t('wb.ws.deleteNamed', { name: item.name })}>\n <span>{t('wb.ws.deleteConfirm', { name: item.name })}</span>\n <div>\n <button className=\"bt-ws-danger\" onClick={() => void run(() => deleteWorkspace(item.id), false).then(ok => ok && setMode({ kind: 'list' }))}>{t('kit.delete')}</button>\n <button className=\"bt-ws-cancel\" onClick={() => setMode({ kind: 'list' })}>{t('wb.common.cancel')}</button>\n </div>\n </div>;\n }\n return <div key={item.id} className={`bt-ws-row${isActive ? ' is-active' : ''}`} role=\"none\">\n <button role=\"menuitem\" className=\"bt-ws-main\" aria-current={isActive ? 'true' : undefined} onClick={() => void run(() => restoreWorkspace(item.id))}>\n <span className=\"bt-ws-name\">{item.name}{item.isDefault && <span className=\"bt-ws-badge\" title={t('wb.ws.onStartTitle')}>{t('wb.ws.onStart')}</span>}</span>\n <span className=\"bt-ws-meta\">{t('wb.ws.tabs', { count: item.tabs })}{isActive ? ` · ${t('wb.ws.openNow')}` : ''}</span>\n </button>\n <span className=\"bt-ws-actions\">\n {isActive && <button className=\"bt-ws-icon\" title={t('wb.ws.update')} aria-label={t('wb.ws.updateNamed', { name: item.name })}\n onClick={() => void run(() => saveCurrentWorkspace(item.name, item.id))}><Icon name=\"check\"/></button>}\n <button className=\"bt-ws-icon\" title={item.isDefault ? t('wb.ws.stopStart') : t('wb.ws.setStart')} aria-pressed={item.isDefault}\n aria-label={item.isDefault ? t('wb.ws.stopStartNamed', { name: item.name }) : t('wb.ws.setStartNamed', { name: item.name })}\n onClick={() => void run(() => setStartWorkspace(item.isDefault ? null : item.id), false)}><Icon name={item.isDefault ? 'pin' : 'unpin'}/></button>\n <button className=\"bt-ws-icon\" title={t('wb.ws.rename')} aria-label={t('wb.ws.renameNamed', { name: item.name })} onClick={() => { setName(item.name); setMode({ kind: 'rename', id: item.id }); }}><Icon name=\"edit\"/></button>\n <button className=\"bt-ws-icon\" title={t('kit.delete')} aria-label={t('wb.ws.deleteNamed', { name: item.name })} onClick={() => setMode({ kind: 'confirm', id: item.id })}><Icon name=\"trash\"/></button>\n </span>\n </div>;\n })}\n <hr/>\n {mode.kind === 'save'\n ? <form className=\"bt-ws-form\" onSubmit={event => { event.preventDefault(); void run(() => saveCurrentWorkspace(name)); }}>\n <input className=\"bt-ws-input\" value={name} placeholder={t('wb.ws.namePlaceholder')} maxLength={WORKSPACE_LIMITS.name} onChange={event => setName(event.target.value)} aria-label={t('wb.ws.name')} spellCheck={false}/>\n <button type=\"submit\" className=\"bt-ws-primary\" disabled={!name.trim()}>{t('wb.common.save')}</button>\n </form>\n : <button role=\"menuitem\" className=\"bt-ws-save\" onClick={() => { setName(suggestName()); setMode({ kind: 'save' }); }}>\n <span className=\"bt-ws-save-icon\"><Icon name=\"plus\"/></span>\n <span className=\"bt-ws-text\"><span className=\"bt-ws-name\">{t('wb.ws.save')}</span><span className=\"bt-ws-meta\">{t('wb.ws.saveMeta', { count: shell.api?.panels.length ?? 0 })}</span></span>\n </button>}\n {error && <div className=\"bt-ws-error\" role=\"alert\">{error}</div>}\n </div>\n </div>, document.body)}\n </>;\n}\n\nfunction suggestName() {\n const taken = new Set(workspaces.store.items.map(item => item.name));\n for (let n = 1; ; n += 1) { const candidate = n === 1 ? t('wb.ws.default') : t('wb.ws.defaultN', { n }); if (!taken.has(candidate)) return candidate; }\n}\n\n/** Three stacked panes: a layout. */\nfunction WorkspaceGlyph() {\n return <svg className=\"bt-ws-glyph\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n <rect x=\"1.75\" y=\"2.25\" width=\"12.5\" height=\"11.5\" rx=\"2.25\"/>\n <path d=\"M6.75 2.5v11M6.75 8h7.25\"/>\n </svg>;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { IDockviewPanelProps } from 'dockview';
|
|
2
|
+
import { type WebParams } from './state.ts';
|
|
3
|
+
/** One browser tab: toolbar with the smart address bar over a placeholder the native webview covers. */
|
|
4
|
+
export declare function WebPanel(props: IDockviewPanelProps<WebParams>): import("react").JSX.Element;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { tabProfile } from "../profileModel.js";
|
|
4
|
+
import { AccountAvatar, accountName } from "./AccountSwitcher.js";
|
|
5
|
+
import { WB_MARK } from "./brand.js";
|
|
6
|
+
import { invoke } from "./bridge.js";
|
|
7
|
+
import { FindBar } from "./FindBar.js";
|
|
8
|
+
import { useProfiles, useSiteText, useT } from "./hooks.js";
|
|
9
|
+
import { Icon } from "./icons.js";
|
|
10
|
+
import { openPaneTheme } from "./PaneTheme.js";
|
|
11
|
+
import { toUrl } from "./searchInput.js";
|
|
12
|
+
import { site } from "./site.js";
|
|
13
|
+
import { scheduleSync, setOverlay, shell, tabAction } from "./state.js";
|
|
14
|
+
import { useTabStill } from "./tabStill.js";
|
|
15
|
+
/** One browser tab: toolbar with the smart address bar over a placeholder the native webview covers. */
|
|
16
|
+
export function WebPanel(props) {
|
|
17
|
+
const t = useT();
|
|
18
|
+
const { params, api } = props;
|
|
19
|
+
const viewport = useRef(null);
|
|
20
|
+
const input = useRef(null);
|
|
21
|
+
const omni = useRef(null);
|
|
22
|
+
const [draft, setDraft] = useState(null);
|
|
23
|
+
const [caret, setCaret] = useState(0);
|
|
24
|
+
const [splitMenu, setSplitMenu] = useState(false);
|
|
25
|
+
// Find in page: the find field takes the address field's place while it is open (FindBar.tsx).
|
|
26
|
+
const [finding, setFinding] = useState(false);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const open = (event) => { if (event.detail === api.id) {
|
|
29
|
+
setDraft(null);
|
|
30
|
+
setFinding(true);
|
|
31
|
+
} };
|
|
32
|
+
window.addEventListener('bt-find', open);
|
|
33
|
+
return () => window.removeEventListener('bt-find', open);
|
|
34
|
+
}, [api.id]);
|
|
35
|
+
// Windows: the page's last frame, shown while its webview is hidden (host `tab-still`).
|
|
36
|
+
const still = useTabStill(api.id);
|
|
37
|
+
useSiteText();
|
|
38
|
+
const profiles = useProfiles();
|
|
39
|
+
const { logo, product, addressCompleter, themes } = site();
|
|
40
|
+
// Same rule as the tab's account dot: shown once there is more than one account.
|
|
41
|
+
const account = profiles.profiles.length > 1 ? tabProfile(profiles, params.profile) : null;
|
|
42
|
+
const editing = draft !== null;
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
const el = viewport.current;
|
|
45
|
+
if (!el)
|
|
46
|
+
return;
|
|
47
|
+
shell.placeholders.set(api.id, el);
|
|
48
|
+
const observer = new ResizeObserver(scheduleSync);
|
|
49
|
+
observer.observe(el);
|
|
50
|
+
const visibility = api.onDidVisibilityChange(scheduleSync);
|
|
51
|
+
scheduleSync();
|
|
52
|
+
return () => {
|
|
53
|
+
observer.disconnect();
|
|
54
|
+
visibility.dispose();
|
|
55
|
+
if (shell.placeholders.get(api.id) === el)
|
|
56
|
+
shell.placeholders.delete(api.id);
|
|
57
|
+
scheduleSync();
|
|
58
|
+
};
|
|
59
|
+
}, [api]);
|
|
60
|
+
// An overlay (the shell rises above the tab webviews, or hides them) while the menu is open; Esc closes it.
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!splitMenu)
|
|
63
|
+
return;
|
|
64
|
+
setOverlay(1);
|
|
65
|
+
const onKey = (event) => { if (event.key === 'Escape') {
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
setSplitMenu(false);
|
|
68
|
+
} };
|
|
69
|
+
window.addEventListener('keydown', onKey);
|
|
70
|
+
return () => { setOverlay(-1); window.removeEventListener('keydown', onKey); };
|
|
71
|
+
}, [splitMenu]);
|
|
72
|
+
// Entering edit mode focuses the mono input; a seeded draft keeps the caret at the end.
|
|
73
|
+
const seeded = useRef(false);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!editing)
|
|
76
|
+
return;
|
|
77
|
+
const el = input.current;
|
|
78
|
+
if (!el)
|
|
79
|
+
return;
|
|
80
|
+
el.focus();
|
|
81
|
+
if (seeded.current) {
|
|
82
|
+
seeded.current = false;
|
|
83
|
+
el.setSelectionRange(el.value.length, el.value.length);
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
el.select();
|
|
87
|
+
}, [editing]);
|
|
88
|
+
const enterEdit = (seed) => {
|
|
89
|
+
seeded.current = seed !== undefined;
|
|
90
|
+
setDraft(seed ?? params.url);
|
|
91
|
+
};
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
const focusAddress = (event) => {
|
|
94
|
+
if (event.detail !== api.id)
|
|
95
|
+
return;
|
|
96
|
+
setFinding(false);
|
|
97
|
+
if (draft === null)
|
|
98
|
+
enterEdit();
|
|
99
|
+
else {
|
|
100
|
+
input.current?.focus();
|
|
101
|
+
input.current?.select();
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
window.addEventListener('bt-focus-address', focusAddress);
|
|
105
|
+
return () => window.removeEventListener('bt-focus-address', focusAddress);
|
|
106
|
+
});
|
|
107
|
+
const navigate = (url) => {
|
|
108
|
+
invoke('tab_navigate', { id: api.id, url }).catch(() => { });
|
|
109
|
+
tabAction(api.id, 'focus');
|
|
110
|
+
};
|
|
111
|
+
const go = () => {
|
|
112
|
+
if (draft === null)
|
|
113
|
+
return;
|
|
114
|
+
const url = toUrl(draft, site().searchUrl);
|
|
115
|
+
setDraft(null);
|
|
116
|
+
navigate(url);
|
|
117
|
+
};
|
|
118
|
+
// The site's completions for the token being typed (inline, so no overlay hides the page).
|
|
119
|
+
const chips = draft === null || !addressCompleter ? [] : addressCompleter.suggest(draft, caret, 5);
|
|
120
|
+
const trackCaret = () => setCaret(input.current?.selectionStart ?? draft?.length ?? 0);
|
|
121
|
+
const acceptChip = (insert) => {
|
|
122
|
+
if (draft === null || !addressCompleter)
|
|
123
|
+
return;
|
|
124
|
+
const next = addressCompleter.apply(draft, caret, insert);
|
|
125
|
+
setDraft(next.text);
|
|
126
|
+
setCaret(next.caret);
|
|
127
|
+
requestAnimationFrame(() => { input.current?.focus(); input.current?.setSelectionRange(next.caret, next.caret); });
|
|
128
|
+
};
|
|
129
|
+
const onChipsKey = (event) => {
|
|
130
|
+
if (event.target !== event.currentTarget)
|
|
131
|
+
return;
|
|
132
|
+
const mod = event.ctrlKey || event.metaKey || event.altKey;
|
|
133
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
enterEdit();
|
|
136
|
+
}
|
|
137
|
+
else if (!mod && event.key.length === 1) {
|
|
138
|
+
event.preventDefault();
|
|
139
|
+
enterEdit(event.key);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const model = site().address(params.url);
|
|
143
|
+
const segments = model?.segments ?? [];
|
|
144
|
+
return _jsxs("div", { className: "bt-web", children: [_jsxs("div", { className: "bt-addressbar", children: [_jsx("button", { className: "bt-icon", title: t('wb.web.backTitle'), "aria-label": t('wb.web.back'), onClick: () => tabAction(api.id, 'back'), children: _jsx(Icon, { name: "back" }) }), _jsx("button", { className: "bt-icon", title: t('wb.web.forwardTitle'), "aria-label": t('wb.web.forward'), onClick: () => tabAction(api.id, 'forward'), children: _jsx(Icon, { name: "forward" }) }), _jsx("button", { className: "bt-icon", title: params.loading ? t('wb.web.stop') : t('wb.web.reloadTitle'), "aria-label": params.loading ? t('wb.web.stop') : t('wb.shell.menu.reload'), onClick: () => tabAction(api.id, params.loading ? 'stop' : 'reload'), children: _jsx(Icon, { name: params.loading ? 'stop' : 'reload' }) }), account && _jsx("span", { className: "bt-pane-account", role: "img", "aria-label": t('wb.shell.tab.account', { name: accountName(account) }), title: t('wb.web.paneAccount', { name: accountName(account) }), style: { ['--bt-pane-account']: account.color }, children: _jsx(AccountAvatar, { profile: account, size: 20 }) }), finding ? _jsx(FindBar, { tabId: api.id, url: params.url, onClose: () => setFinding(false) }) : editing
|
|
145
|
+
? _jsxs("div", { className: "bt-omni bt-omni--edit", ref: omni, children: [_jsx(Icon, { name: "search", className: "bt-omni-lead" }), _jsx("input", { ref: input, spellCheck: false, "aria-label": t('wb.web.address'), value: draft, onChange: event => { setDraft(event.target.value); setCaret(event.target.selectionStart ?? event.target.value.length); }, onSelect: trackCaret, onKeyUp: trackCaret, onBlur: () => setDraft(null), onKeyDown: event => {
|
|
146
|
+
if (event.key === 'Tab' && !event.shiftKey && chips[0]) {
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
acceptChip(chips[0].insert);
|
|
149
|
+
}
|
|
150
|
+
if (event.key === 'Enter') {
|
|
151
|
+
event.preventDefault();
|
|
152
|
+
go();
|
|
153
|
+
}
|
|
154
|
+
if (event.key === 'Escape') {
|
|
155
|
+
event.preventDefault();
|
|
156
|
+
setDraft(null);
|
|
157
|
+
tabAction(api.id, 'focus');
|
|
158
|
+
}
|
|
159
|
+
} }), chips.length > 0 && _jsx("span", { className: "bt-omni-ops", role: "listbox", "aria-label": addressCompleter?.label(), children: chips.map((chip, index) => _jsx("button", { type: "button", role: "option", "aria-selected": index === 0, className: "bt-omni-op", title: `${chip.hint}${index === 0 ? ` (${t('wb.web.tabKey')})` : ''}`, onMouseDown: event => event.preventDefault(), onClick: () => acceptChip(chip.insert), children: chip.label }, chip.insert)) }), params.loading && _jsx("span", { className: "bt-omni-progress", "aria-label": t('wb.common.loading') })] })
|
|
160
|
+
: _jsxs("div", { className: "bt-omni", ref: omni, role: "button", tabIndex: 0, "aria-label": t('wb.web.addressValue', { url: params.url }), title: params.url, onClick: () => enterEdit(), onKeyDown: onChipsKey, children: [model?.insecure && _jsx("span", { className: "bt-chip-insecure", children: t('wb.web.insecure') }), model
|
|
161
|
+
? _jsxs("button", { className: "bt-chip-site", title: model.site.href, onClick: event => { event.stopPropagation(); if (segments.length)
|
|
162
|
+
navigate(model.site.href);
|
|
163
|
+
else
|
|
164
|
+
enterEdit(); }, children: [model.site.kind !== 'host'
|
|
165
|
+
? _jsx("img", { src: logo, alt: "", width: 14, height: 14 })
|
|
166
|
+
: params.favicon ? _jsx("img", { src: params.favicon, alt: "", width: 14, height: 14 }) : null, model.site.label] })
|
|
167
|
+
: _jsx("span", { className: "bt-omni-raw", children: params.url }), segments.map((segment, index) => {
|
|
168
|
+
const last = index === segments.length - 1;
|
|
169
|
+
// The model already wraps search queries in straight quotes; show typographic ones.
|
|
170
|
+
const label = segment.quoted ? segment.label.replace(/^"/, '“').replace(/"$/, '”') : segment.label;
|
|
171
|
+
return _jsxs(Fragment, { children: [_jsx("span", { className: "bt-sep", "aria-hidden": "true", children: "/" }), last
|
|
172
|
+
? _jsx("span", { className: `bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`, "aria-current": "page", children: label })
|
|
173
|
+
: _jsx("button", { className: `bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`, title: segment.href, onClick: event => { event.stopPropagation(); navigate(segment.href); }, children: label })] }, `${index}:${segment.href}`);
|
|
174
|
+
}), _jsx("span", { className: "bt-omni-fill" }), _jsx("button", { className: "bt-omni-action", title: t('wb.shell.menu.openBrowser'), "aria-label": t('wb.shell.menu.openBrowser'), onClick: event => { event.stopPropagation(); invoke('open_external_url', { url: params.url }).catch(() => { }); }, children: _jsx(Icon, { name: "external" }) }), params.loading && _jsx("span", { className: "bt-omni-progress", "aria-label": t('wb.common.loading') })] }), _jsxs("div", { className: "bt-split", children: [_jsx("button", { className: "bt-icon bt-split-main", title: t('wb.web.splitTitle'), "aria-label": t('wb.shell.menu.splitRight'), onClick: () => shell.split(api.id, 'right'), children: _jsx(Icon, { name: "split" }) }), _jsx("button", { className: "bt-icon bt-split-more", title: t('wb.web.splitMore'), "aria-label": t('wb.web.splitMore'), "aria-haspopup": "menu", "aria-expanded": splitMenu, onClick: () => setSplitMenu(open => !open), onBlur: () => setTimeout(() => setSplitMenu(false), 150), children: _jsx(Icon, { name: "chevron" }) }), splitMenu && _jsxs("div", { className: "bt-menu bt-split-menu bt-pop", role: "menu", children: [_jsxs("button", { role: "menuitem", onMouseDown: event => event.preventDefault(), onClick: () => { setSplitMenu(false); shell.split(api.id, 'right'); }, children: [_jsx(Icon, { name: "split" }), _jsx("span", { className: "bt-menu-label", children: t('wb.shell.menu.splitRight') }), _jsx("span", { className: "bt-menu-keys", children: 'Ctrl \\' })] }), _jsxs("button", { role: "menuitem", onMouseDown: event => event.preventDefault(), onClick: () => { setSplitMenu(false); shell.split(api.id, 'below'); }, children: [_jsx(Icon, { name: "splitDown" }), _jsx("span", { className: "bt-menu-label", children: t('wb.shell.menu.splitDown') }), _jsx("span", { className: "bt-menu-keys", children: 'Ctrl \u21e7 \\' })] }), themes && _jsxs(_Fragment, { children: [_jsx("hr", {}), _jsxs("button", { role: "menuitem", onMouseDown: event => event.preventDefault(), onClick: event => {
|
|
175
|
+
setSplitMenu(false);
|
|
176
|
+
const box = event.currentTarget.closest('.bt-split').getBoundingClientRect();
|
|
177
|
+
openPaneTheme({ id: api.id, profile: tabProfile(profiles, params.profile).id, x: box.right - 272, y: box.bottom + 6 });
|
|
178
|
+
}, children: [_jsx(Icon, { name: "palette" }), _jsx("span", { className: "bt-menu-label", children: t('wb.shell.menu.paneTheme') })] })] })] })] }), _jsx("button", { className: "bt-brand-button", title: `${product} (Ctrl+Shift+W)`, "aria-label": product, onClick: () => shell.openPanel(api.id), children: _jsx("img", { className: "bt-wb", src: WB_MARK, alt: "", width: 30, height: 17, draggable: false }) })] }), _jsxs("div", { className: "bt-viewport", ref: viewport, children: [still
|
|
179
|
+
? _jsx("div", { className: "bt-still", "aria-hidden": "true", style: { backgroundImage: `url("${still}")` } })
|
|
180
|
+
: _jsxs("div", { className: "bt-skeleton", "aria-hidden": "true", children: [_jsx("i", {}), _jsx("b", { children: [0, 1, 2, 3].map(i => _jsx("span", {}, i)) })] }), !still && _jsxs("div", { className: "bt-viewport-hint", children: [params.loading ? _jsx("span", { className: "bt-spinner", "aria-hidden": "true" }) : null, _jsx("span", { children: params.title || model?.site.label || t('wb.common.loading') })] })] })] });
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=WebPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebPanel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/WebPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { IDockviewPanelProps } from 'dockview';\nimport { Fragment, useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { tabProfile } from '../profileModel.ts';\nimport { AccountAvatar, accountName } from './AccountSwitcher.tsx';\nimport { WB_MARK } from './brand.ts';\nimport { invoke } from './bridge.ts';\nimport { FindBar } from './FindBar.tsx';\nimport { useProfiles, useSiteText, useT } from './hooks.ts';\nimport { Icon } from './icons.tsx';\nimport { openPaneTheme } from './PaneTheme.tsx';\nimport { toUrl } from './searchInput.ts';\nimport { site } from './site.ts';\nimport { scheduleSync, setOverlay, shell, tabAction, type WebParams } from './state.ts';\nimport { useTabStill } from './tabStill.ts';\n\n/** One browser tab: toolbar with the smart address bar over a placeholder the native webview covers. */\nexport function WebPanel(props: IDockviewPanelProps<WebParams>) {\n const t = useT();\n const { params, api } = props;\n const viewport = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const omni = useRef<HTMLDivElement>(null);\n const [draft, setDraft] = useState<string | null>(null);\n const [caret, setCaret] = useState(0);\n const [splitMenu, setSplitMenu] = useState(false);\n // Find in page: the find field takes the address field's place while it is open (FindBar.tsx).\n const [finding, setFinding] = useState(false);\n useEffect(() => {\n const open = (event: Event) => { if ((event as CustomEvent<string>).detail === api.id) { setDraft(null); setFinding(true); } };\n window.addEventListener('bt-find', open);\n return () => window.removeEventListener('bt-find', open);\n }, [api.id]);\n // Windows: the page's last frame, shown while its webview is hidden (host `tab-still`).\n const still = useTabStill(api.id);\n useSiteText();\n const profiles = useProfiles();\n const { logo, product, addressCompleter, themes } = site();\n // Same rule as the tab's account dot: shown once there is more than one account.\n const account = profiles.profiles.length > 1 ? tabProfile(profiles, params.profile) : null;\n const editing = draft !== null;\n\n useEffect(() => {\n const el = viewport.current;\n if (!el) return;\n shell.placeholders.set(api.id, el);\n const observer = new ResizeObserver(scheduleSync);\n observer.observe(el);\n const visibility = api.onDidVisibilityChange(scheduleSync);\n scheduleSync();\n return () => {\n observer.disconnect();\n visibility.dispose();\n if (shell.placeholders.get(api.id) === el) shell.placeholders.delete(api.id);\n scheduleSync();\n };\n }, [api]);\n\n // An overlay (the shell rises above the tab webviews, or hides them) while the menu is open; Esc closes it.\n useEffect(() => {\n if (!splitMenu) return;\n setOverlay(1);\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape') { event.preventDefault(); setSplitMenu(false); } };\n window.addEventListener('keydown', onKey);\n return () => { setOverlay(-1); window.removeEventListener('keydown', onKey); };\n }, [splitMenu]);\n\n // Entering edit mode focuses the mono input; a seeded draft keeps the caret at the end.\n const seeded = useRef(false);\n useEffect(() => {\n if (!editing) return;\n const el = input.current;\n if (!el) return;\n el.focus();\n if (seeded.current) { seeded.current = false; el.setSelectionRange(el.value.length, el.value.length); } else el.select();\n }, [editing]);\n\n const enterEdit = (seed?: string) => {\n seeded.current = seed !== undefined;\n setDraft(seed ?? params.url);\n };\n\n useEffect(() => {\n const focusAddress = (event: Event) => {\n if ((event as CustomEvent<string>).detail !== api.id) return;\n setFinding(false);\n if (draft === null) enterEdit();\n else { input.current?.focus(); input.current?.select(); }\n };\n window.addEventListener('bt-focus-address', focusAddress);\n return () => window.removeEventListener('bt-focus-address', focusAddress);\n });\n\n const navigate = (url: string) => {\n invoke('tab_navigate', { id: api.id, url }).catch(() => {});\n tabAction(api.id, 'focus');\n };\n\n const go = () => {\n if (draft === null) return;\n const url = toUrl(draft, site().searchUrl);\n setDraft(null);\n navigate(url);\n };\n\n // The site's completions for the token being typed (inline, so no overlay hides the page).\n const chips = draft === null || !addressCompleter ? [] : addressCompleter.suggest(draft, caret, 5);\n const trackCaret = () => setCaret(input.current?.selectionStart ?? draft?.length ?? 0);\n const acceptChip = (insert: string) => {\n if (draft === null || !addressCompleter) return;\n const next = addressCompleter.apply(draft, caret, insert);\n setDraft(next.text);\n setCaret(next.caret);\n requestAnimationFrame(() => { input.current?.focus(); input.current?.setSelectionRange(next.caret, next.caret); });\n };\n\n const onChipsKey = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n const mod = event.ctrlKey || event.metaKey || event.altKey;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); enterEdit(); }\n else if (!mod && event.key.length === 1) { event.preventDefault(); enterEdit(event.key); }\n };\n\n const model = site().address(params.url);\n const segments = model?.segments ?? [];\n\n return <div className=\"bt-web\">\n <div className=\"bt-addressbar\">\n <button className=\"bt-icon\" title={t('wb.web.backTitle')} aria-label={t('wb.web.back')} onClick={() => tabAction(api.id, 'back')}><Icon name=\"back\"/></button>\n <button className=\"bt-icon\" title={t('wb.web.forwardTitle')} aria-label={t('wb.web.forward')} onClick={() => tabAction(api.id, 'forward')}><Icon name=\"forward\"/></button>\n <button className=\"bt-icon\" title={params.loading ? t('wb.web.stop') : t('wb.web.reloadTitle')} aria-label={params.loading ? t('wb.web.stop') : t('wb.shell.menu.reload')} onClick={() => tabAction(api.id, params.loading ? 'stop' : 'reload')}><Icon name={params.loading ? 'stop' : 'reload'}/></button>\n {account && <span className=\"bt-pane-account\" role=\"img\" aria-label={t('wb.shell.tab.account', { name: accountName(account) })} title={t('wb.web.paneAccount', { name: accountName(account) })}\n style={{ ['--bt-pane-account' as string]: account.color }}><AccountAvatar profile={account} size={20}/></span>}\n {finding ? <FindBar tabId={api.id} url={params.url} onClose={() => setFinding(false)}/> : editing\n ? <div className=\"bt-omni bt-omni--edit\" ref={omni}>\n <Icon name=\"search\" className=\"bt-omni-lead\"/>\n <input ref={input} spellCheck={false} aria-label={t('wb.web.address')} value={draft}\n onChange={event => { setDraft(event.target.value); setCaret(event.target.selectionStart ?? event.target.value.length); }}\n onSelect={trackCaret} onKeyUp={trackCaret}\n onBlur={() => setDraft(null)}\n onKeyDown={event => {\n if (event.key === 'Tab' && !event.shiftKey && chips[0]) { event.preventDefault(); acceptChip(chips[0].insert); }\n if (event.key === 'Enter') { event.preventDefault(); go(); }\n if (event.key === 'Escape') { event.preventDefault(); setDraft(null); tabAction(api.id, 'focus'); }\n }}/>\n {chips.length > 0 && <span className=\"bt-omni-ops\" role=\"listbox\" aria-label={addressCompleter?.label()}>\n {chips.map((chip, index) => <button key={chip.insert} type=\"button\" role=\"option\" aria-selected={index === 0} className=\"bt-omni-op\" title={`${chip.hint}${index === 0 ? ` (${t('wb.web.tabKey')})` : ''}`}\n onMouseDown={event => event.preventDefault()} onClick={() => acceptChip(chip.insert)}>{chip.label}</button>)}\n </span>}\n {params.loading && <span className=\"bt-omni-progress\" aria-label={t('wb.common.loading')}/>}\n </div>\n : <div className=\"bt-omni\" ref={omni} role=\"button\" tabIndex={0} aria-label={t('wb.web.addressValue', { url: params.url })} title={params.url}\n onClick={() => enterEdit()} onKeyDown={onChipsKey}>\n {model?.insecure && <span className=\"bt-chip-insecure\">{t('wb.web.insecure')}</span>}\n {model\n ? <button className=\"bt-chip-site\" title={model.site.href} onClick={event => { event.stopPropagation(); if (segments.length) navigate(model.site.href); else enterEdit(); }}>\n {model.site.kind !== 'host'\n ? <img src={logo} alt=\"\" width={14} height={14}/>\n : params.favicon ? <img src={params.favicon} alt=\"\" width={14} height={14}/> : null}\n {model.site.label}\n </button>\n : <span className=\"bt-omni-raw\">{params.url}</span>}\n {segments.map((segment, index) => {\n const last = index === segments.length - 1;\n // The model already wraps search queries in straight quotes; show typographic ones.\n const label = segment.quoted ? segment.label.replace(/^\"/, '“').replace(/\"$/, '”') : segment.label;\n return <Fragment key={`${index}:${segment.href}`}>\n <span className=\"bt-sep\" aria-hidden=\"true\">/</span>\n {last\n ? <span className={`bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`} aria-current=\"page\">{label}</span>\n : <button className={`bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`} title={segment.href}\n onClick={event => { event.stopPropagation(); navigate(segment.href); }}>{label}</button>}\n </Fragment>;\n })}\n <span className=\"bt-omni-fill\"/>\n <button className=\"bt-omni-action\" title={t('wb.shell.menu.openBrowser')} aria-label={t('wb.shell.menu.openBrowser')}\n onClick={event => { event.stopPropagation(); invoke('open_external_url', { url: params.url }).catch(() => {}); }}><Icon name=\"external\"/></button>\n {params.loading && <span className=\"bt-omni-progress\" aria-label={t('wb.common.loading')}/>}\n </div>}\n <div className=\"bt-split\">\n <button className=\"bt-icon bt-split-main\" title={t('wb.web.splitTitle')} aria-label={t('wb.shell.menu.splitRight')} onClick={() => shell.split(api.id, 'right')}><Icon name=\"split\"/></button>\n <button className=\"bt-icon bt-split-more\" title={t('wb.web.splitMore')} aria-label={t('wb.web.splitMore')} aria-haspopup=\"menu\" aria-expanded={splitMenu}\n onClick={() => setSplitMenu(open => !open)} onBlur={() => setTimeout(() => setSplitMenu(false), 150)}><Icon name=\"chevron\"/></button>\n {splitMenu && <div className=\"bt-menu bt-split-menu bt-pop\" role=\"menu\">\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={() => { setSplitMenu(false); shell.split(api.id, 'right'); }}>\n <Icon name=\"split\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.splitRight')}</span><span className=\"bt-menu-keys\">{'Ctrl \\\\'}</span></button>\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={() => { setSplitMenu(false); shell.split(api.id, 'below'); }}>\n <Icon name=\"splitDown\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.splitDown')}</span><span className=\"bt-menu-keys\">{'Ctrl \\u21e7 \\\\'}</span></button>\n {themes && <>\n <hr/>\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={event => {\n setSplitMenu(false);\n const box = (event.currentTarget.closest('.bt-split') as HTMLElement).getBoundingClientRect();\n openPaneTheme({ id: api.id, profile: tabProfile(profiles, params.profile).id, x: box.right - 272, y: box.bottom + 6 });\n }}><Icon name=\"palette\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.paneTheme')}</span></button>\n </>}\n </div>}\n </div>\n <button className=\"bt-brand-button\" title={`${product} (Ctrl+Shift+W)`} aria-label={product} onClick={() => shell.openPanel(api.id)}>\n <img className=\"bt-wb\" src={WB_MARK} alt=\"\" width={30} height={17} draggable={false}/>\n </button>\n </div>\n <div className=\"bt-viewport\" ref={viewport}>\n {/* Until the page's own webview is on screen: its last frame, else the site's shape (rail, timeline), not a blank pane. */}\n {still\n ? <div className=\"bt-still\" aria-hidden=\"true\" style={{ backgroundImage: `url(\"${still}\")` }}/>\n : <div className=\"bt-skeleton\" aria-hidden=\"true\"><i/><b>{[0, 1, 2, 3].map(i => <span key={i}/>)}</b></div>}\n {!still && <div className=\"bt-viewport-hint\">{params.loading ? <span className=\"bt-spinner\" aria-hidden=\"true\"/> : null}<span>{params.title || model?.site.label || t('wb.common.loading')}</span></div>}\n </div>\n </div>;\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type Profile, type ProfileSettings } from '../profileModel.ts';
|
|
2
|
+
/** A tab as the switcher sees it: its account and whether it is on screen right now. */
|
|
3
|
+
export type PaneInfo = {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: 'web' | 'start' | 'panel';
|
|
6
|
+
/** Profile id as stored on the tab (missing or unknown = default). */
|
|
7
|
+
profile?: string;
|
|
8
|
+
url?: string;
|
|
9
|
+
/** Shown on screen (the visible tab of its group). */
|
|
10
|
+
visible: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type AccountAction = {
|
|
13
|
+
type: 'focus';
|
|
14
|
+
paneId: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'open';
|
|
17
|
+
url: string;
|
|
18
|
+
profile: string;
|
|
19
|
+
where: 'beside' | 'tab';
|
|
20
|
+
};
|
|
21
|
+
/** The site's pages an account click opens (`site.homeUrl`, `site.loginUrl`, `site.isSiteUrl`). */
|
|
22
|
+
export type AccountPages = {
|
|
23
|
+
homeUrl: string;
|
|
24
|
+
loginUrl: string;
|
|
25
|
+
isSiteUrl?: (url: string) => boolean;
|
|
26
|
+
};
|
|
27
|
+
/** Where a click on this account lands: its feed once signed in, the site's sign-in otherwise. */
|
|
28
|
+
export declare function accountStartUrl(profile: Profile, pages: Pick<AccountPages, 'homeUrl' | 'loginUrl'>): string;
|
|
29
|
+
/** The account the focused tab runs in (the app's panel has none: the default account). */
|
|
30
|
+
export declare function focusedAccount(settings: ProfileSettings, panes: readonly PaneInfo[], activeId: string | null | undefined): Profile;
|
|
31
|
+
/**
|
|
32
|
+
* The click's result. `force` (Shift/Ctrl-click, "Open in new tab") always opens a new tab in the
|
|
33
|
+
* focused group. Otherwise a visible web pane of the account is focused (the focused one first, then
|
|
34
|
+
* a pane on the site), and only when there is none does a new pane open beside the focused one.
|
|
35
|
+
*/
|
|
36
|
+
export declare function accountAction(settings: ProfileSettings, panes: readonly PaneInfo[], activeId: string | null | undefined, profileId: string, options: {
|
|
37
|
+
force?: boolean;
|
|
38
|
+
} & AccountPages): AccountAction;
|
|
39
|
+
/** "Use for new tabs": the only thing `active` means now. Unknown ids change nothing. */
|
|
40
|
+
export declare const setDefaultAccount: (settings: ProfileSettings, id: string) => ProfileSettings;
|
|
41
|
+
/** "Add account": a fresh profile for the site's sign-in. It does not become the default. */
|
|
42
|
+
export declare function addAccountProfile(settings: ProfileSettings, id?: string): {
|
|
43
|
+
settings: ProfileSettings;
|
|
44
|
+
profile: string;
|
|
45
|
+
};
|
|
46
|
+
/** Open tabs per account id (for "N tabs" and for closing them before a remove). */
|
|
47
|
+
export declare function tabsByAccount(settings: ProfileSettings, panes: readonly PaneInfo[]): Map<string, string[]>;
|
|
48
|
+
/** Roving focus in the menu: wraps around; Home/End jump to the ends. */
|
|
49
|
+
export declare function moveFocus(index: number, key: string, count: number): number;
|