waybetter 0.1.0 → 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 +143 -9
- 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 +148 -6
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../runtime/src/ui.ts"],"names":[],"mappings":"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","sourcesContent":["// `api.ui`: toasts, alerts, confirmations, prompts and dialogs for plugins, drawn in the active\n// theme's colors, corners and font. Everything lives in one Shadow DOM host (`<wb-ui>`), so the\n// site's CSS cannot reach it and it cannot reach the site; the host exists only while something is\n// on screen, and a plugin's `scope.ui` closes whatever that plugin opened when it stops.\n//\n// Accessibility: dialogs are `role=\"dialog\"` (alerts and confirmations `role=\"alertdialog\"`),\n// `aria-modal`, labelled by their title and described by their message; focus moves in, is trapped\n// (Tab / Shift+Tab wrap), and returns to where it was. Esc dismisses, Enter in a single-line field\n// runs the default action. Stacked dialogs make the ones below inert. Toasts are a polite live\n// region (danger toasts `role=\"alert\"`), pause while hovered or focused, and stack (four at most).\n// Motion is skipped with `prefers-reduced-motion`. Text is always set as text (never parsed as HTML).\n\nimport { adoptStyles, type RootStyles } from './styles.ts';\nimport { themeVars, type ResolvedTheme, type ThemeApi } from './themeApi.ts';\n\nexport type Tone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\n/** Dialog content: text, a node, or a function that fills the dialog's body element. */\nexport type Content = string | Node | ((body: HTMLElement) => void) | null | undefined;\n\nexport type ModalAction = {\n label: string;\n /** `primary` (filled, the theme's button colors), `secondary` (outlined, default), `danger`, `plain` (text). */\n tone?: 'primary' | 'secondary' | 'danger' | 'plain';\n /** Runs on click. Return `false` (or a promise of `false`) to keep the dialog open. */\n onClick?: (handle: ModalHandle) => unknown;\n /** What `closed` resolves with when this action closes the dialog (default: the label). */\n value?: unknown;\n /** Enter in a single-line field (or on the dialog itself) runs this action. */\n default?: boolean;\n /** Focused when the dialog opens. */\n autoFocus?: boolean;\n disabled?: boolean;\n};\n\nexport type ModalOptions = {\n role?: 'dialog' | 'alertdialog';\n title?: string;\n /** Text under the title (also the dialog's accessible description). */\n message?: string;\n /** Accessible name when there is no visible title. */\n label?: string;\n content?: Content;\n actions?: ModalAction[];\n /** px, or `sm` (380), `md` (480, default), `lg` (640). Always fits the window. */\n width?: number | 'sm' | 'md' | 'lg';\n /** Adds a tone icon before the title. */\n tone?: Tone;\n /** Esc and the close button dismiss it (default true). */\n dismissible?: boolean;\n /** A click on the backdrop dismisses it (default false; alerts and confirmations say true). */\n closeOnBackdrop?: boolean;\n /** Shows a close button in the header (default: dismissible and titled). */\n closeButton?: boolean;\n /** Element or selector (inside the dialog) to focus first. */\n initialFocus?: HTMLElement | string;\n /** Extra CSS for this dialog's content (scoped to the kit's shadow root). */\n css?: string;\n /** `closed` resolves with this when dismissed (Esc, backdrop, close button, owner stopped). */\n dismissValue?: unknown;\n /** Buttons stacked full width (the site's confirmation sheet look) instead of a right-aligned row. */\n stackActions?: boolean;\n onClose?: (result: unknown) => void;\n};\n\nexport type ModalHandle = {\n /** The dialog element (`role=\"dialog\"`). */\n readonly element: HTMLElement;\n /** Where `content` went; add or replace your own nodes here. */\n readonly body: HTMLElement;\n readonly open: boolean;\n /** Resolves with the close result once the dialog is gone. */\n readonly closed: Promise<unknown>;\n close(result?: unknown): void;\n /** Shows (or clears with null) an error line above the actions, announced to screen readers. */\n setError(message: string | null): void;\n /** Disables the actions while something runs. */\n setBusy(busy: boolean): void;\n};\n\nexport type DialogOptions = Omit<ModalOptions, 'role'>;\nexport type AlertOptions = { title?: string; message?: string; tone?: Tone; okLabel?: string };\nexport type ConfirmOptions = { title?: string; message?: string; confirmLabel?: string; cancelLabel?: string; danger?: boolean };\nexport type PromptOptions = {\n title?: string;\n message?: string;\n label?: string;\n value?: string;\n placeholder?: string;\n /** Return an error message (or false) to refuse the value; anything else accepts it. */\n validate?: (value: string) => string | boolean | null | undefined;\n /** A textarea instead of a single line (Ctrl/Cmd+Enter submits). */\n multiline?: boolean;\n maxLength?: number;\n confirmLabel?: string;\n cancelLabel?: string;\n width?: ModalOptions['width'];\n};\n\nexport type ToastAction = { label: string; onClick: () => void };\nexport type ToastOptions = {\n tone?: Tone;\n /** ms on screen (default 3200, 6000 with an action); 0 keeps it until closed. */\n duration?: number;\n action?: ToastAction;\n};\nexport type ToastHandle = { readonly element: HTMLElement; close(): void; readonly closed: Promise<void> };\n\ntype Child = Node | string | number | null | undefined | false | Child[];\nexport type ElementProps = Record<string, unknown>;\n\nexport type UiKit = {\n toast(message: string, options?: ToastOptions | number): ToastHandle;\n alert(options: AlertOptions | string): Promise<void>;\n confirm(options: ConfirmOptions | string): Promise<boolean>;\n prompt(options: PromptOptions | string): Promise<string | null>;\n dialog(options: DialogOptions): ModalHandle;\n modal(options: ModalOptions): ModalHandle;\n /**\n * A safe element builder for dialog content: `h('label', { class: 'wb-check' }, input, 'Text')`.\n * Strings become text nodes; `on<event>` functions become listeners; `value`/`checked`/`disabled`\n * are set as properties; everything else as attributes (no `innerHTML`, no string handlers, no\n * `javascript:` URLs).\n */\n h(tag: string, props?: ElementProps | null, ...children: Child[]): HTMLElement;\n};\n\nexport type UiKitOptions = {\n theme: ThemeApi;\n /** Custom element name of the shadow host (default `wb-ui`). */\n hostTag?: string;\n /** Id of the shadow host element. */\n hostId?: string;\n zIndex?: number;\n /** Console prefix. */\n product?: string;\n /**\n * The kit's own words (buttons, accessible names, default errors) in the app's language:\n * called with a `kit.*` key and returns the translation, or undefined for English.\n */\n text?: (key: KitKey) => string | undefined;\n};\n\n/** The kit's default words (English source; `kit.*` keys in the framework catalogs). */\nexport const KIT_MESSAGES = {\n 'kit.ok': 'OK',\n 'kit.cancel': 'Cancel',\n 'kit.delete': 'Delete',\n 'kit.close': 'Close',\n 'kit.dismiss': 'Dismiss',\n 'kit.dialog': 'Dialog',\n 'kit.value': 'Value',\n 'kit.checkValue': 'Please check this value.',\n 'kit.failed': 'Something went wrong.',\n // Feature modules (featureModules.ts): the settings dialog and the health notes.\n 'kit.save': 'Save',\n 'kit.feature.paused': '{feature} ({area}) is paused: this page changed.',\n 'kit.feature.pausedOne': 'A feature of {area} is paused: this page changed.',\n 'kit.feature.pausedList': 'Paused features of {area}',\n 'kit.feature.needsEnglish': '{feature} needs the site in English.',\n 'kit.feature.settings': '{name} settings',\n} as const;\nexport type KitKey = keyof typeof KIT_MESSAGES;\n\nexport type RootUiKit = UiKit & {\n /** A kit whose dialogs and toasts are closed by `dispose()` (a plugin's `scope.ui`). */\n scoped(): { kit: UiKit; dispose(): void };\n /** Open dialogs, bottom first (for tests and the shell). */\n openModals(): number;\n};\n\n// ---------------------------------------------------------------------------------------------\n// Pure helpers (tested without a DOM)\n\nexport const WIDTHS = { sm: 380, md: 480, lg: 640 } as const;\nexport const MAX_TOASTS = 4;\n\n/** Dialog width in px for an option value. */\nexport function dialogWidth(width: ModalOptions['width']): number {\n if (typeof width === 'number' && Number.isFinite(width)) return Math.max(260, Math.min(960, Math.round(width)));\n return WIDTHS[width as keyof typeof WIDTHS] ?? WIDTHS.md;\n}\n\n/** How long a toast stays: explicit ms, 0 = until closed; defaults 3200 / 6000 with an action. */\nexport function toastDuration(options: ToastOptions): number {\n const value = options.duration;\n if (typeof value === 'number' && Number.isFinite(value)) return value <= 0 ? 0 : Math.max(800, Math.min(60_000, value));\n if (value === Infinity) return 0;\n return options.action ? 6000 : 3200;\n}\n\n/** Tab / Shift+Tab inside a trap: the index to focus next, or -1 to let the browser move focus. */\nexport function trapIndex(count: number, current: number, backwards: boolean): number {\n if (count === 0) return -1;\n if (current < 0) return backwards ? count - 1 : 0;\n if (backwards && current === 0) return count - 1;\n if (!backwards && current === count - 1) return 0;\n return -1;\n}\n\n/** A validator's answer as an error message (null = valid). */\nexport function validationMessage(result: unknown, fallback: string = KIT_MESSAGES['kit.checkValue']): string | null {\n if (typeof result === 'string') return result.trim() ? result : null;\n if (result === false) return fallback;\n return null;\n}\n\nconst BLOCKED_PROPS = new Set(['innerhtml', 'outerhtml', 'srcdoc', 'insertadjacenthtml']);\nconst PROPERTY_PROPS = new Set(['value', 'checked', 'disabled', 'selected', 'indeterminate', 'multiple', 'readOnly', 'required', 'rows', 'maxLength', 'spellcheck', 'tabIndex']);\nconst URL_ATTRS = /^(href|src|srcset|action|formaction|xlink:href|poster|ping|cite|background)$/i;\nconst SAFE_SCHEMES = new Set(['http', 'https', 'mailto']);\n\n/**\n * Whether a URL attribute value is safe: relative, or http(s)/mailto. Checked the way browsers read\n * a URL (tabs and newlines anywhere and leading control characters/spaces are ignored), so\n * `java\\tscript:` or `\\x01javascript:` do not slip through.\n */\nexport function isSafeUrl(value: string): boolean {\n const normalized = String(value).replace(/[\\t\\n\\r]/g, '').replace(/^[\\u0000-\\u0020]+/, '');\n const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(normalized);\n return !scheme || SAFE_SCHEMES.has(scheme[1]!.toLowerCase());\n}\n\n/** The builder behind `ui.h`, for any document. */\nexport function buildElement(doc: Document, tag: string, props?: ElementProps | null, ...children: Child[]): HTMLElement {\n if (!/^[a-z][a-z0-9-]*$/i.test(tag) || /^(script|style|iframe|object|embed)$/i.test(tag)) throw new Error(`ui.h: unsupported tag ${JSON.stringify(tag)}`);\n const element = doc.createElement(tag);\n for (const [key, value] of Object.entries(props ?? {})) {\n if (value === undefined || value === null || value === false && !PROPERTY_PROPS.has(key)) continue;\n if (BLOCKED_PROPS.has(key.toLowerCase())) continue;\n if (key === 'class' || key === 'className') element.className = String(value);\n else if (key === 'text') element.textContent = String(value);\n else if (key === 'style' && typeof value === 'object') Object.assign(element.style, value);\n else if (key === 'dataset' && typeof value === 'object') Object.assign(element.dataset, value);\n else if (/^on[a-z]/i.test(key)) { if (typeof value === 'function') element.addEventListener(key.slice(2).toLowerCase(), value as EventListener); }\n else if (PROPERTY_PROPS.has(key)) (element as unknown as Record<string, unknown>)[key] = value;\n else if (URL_ATTRS.test(key) && !isSafeUrl(String(value))) continue;\n else element.setAttribute(key, value === true ? '' : String(value));\n }\n const append = (child: Child) => {\n if (child === null || child === undefined || child === false) return;\n if (Array.isArray(child)) { for (const item of child) append(item); return; }\n element.appendChild(typeof child === 'object' ? child : doc.createTextNode(String(child)));\n };\n for (const child of children) append(child);\n return element;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Styles (inside the shadow root; every value comes from `--wb-*` set on the host)\n\nconst DANGER = '#f4212e';\nconst TONES: Record<Tone, string> = { neutral: 'var(--wb-accent)', info: 'var(--wb-accent)', success: '#00ba7c', warning: '#ffad1f', danger: DANGER };\n// Toast colors keep their label at 4.5:1 or more (neutral toasts use the theme's inverse pair,\n// which the theme engine keeps legible).\nconst TOAST_TONES: Record<Exclude<Tone, 'neutral' | 'info'>, [string, string]> = { success: ['#00805a', '#ffffff'], warning: ['#ffd400', '#0f1419'], danger: ['#d0121f', '#ffffff'] };\n\nexport const UI_CSS = `\n:host { all: initial; }\n.wb-root { font-family: var(--wb-font-dialog, var(--wb-font)); color: var(--wb-text); -webkit-font-smoothing: antialiased; }\n.wb-root *, .wb-root *::before, .wb-root *::after { box-sizing: border-box; }\n.wb-layer { position: fixed; inset: 0; display: grid; place-items: center; padding: 16px; pointer-events: auto; overscroll-behavior: contain; }\n.wb-backdrop { position: absolute; inset: 0; background: var(--wb-scrim); animation: wb-fade .16s ease-out; }\n.wb-dialog { position: relative; width: min(var(--wb-dialog-width, 480px), 100%); max-height: calc(100vh - 32px); overflow: auto; overscroll-behavior: contain;\n display: flex; flex-direction: column; gap: 0; padding: 20px 24px 22px; background: var(--wb-bg); color: var(--wb-text);\n border: 1px solid var(--wb-border); border-radius: var(--wb-radius); box-shadow: 0 24px 64px -12px rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.12);\n font: 400 15px/1.45 var(--wb-font-dialog, var(--wb-font)); outline: none; animation: wb-in .18s cubic-bezier(.2,.9,.3,1.2); }\n.wb-layer.wb-closing .wb-dialog { animation: wb-out .12s ease-in forwards; }\n.wb-layer.wb-closing .wb-backdrop { animation: wb-fade-out .12s ease-in forwards; }\n.wb-layer[inert] .wb-dialog { filter: saturate(.9); }\n.wb-head { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 4px; }\n.wb-title { flex: 1; margin: 0; font: 800 20px/1.25 var(--wb-font-dialog, var(--wb-font)); letter-spacing: -.01em; color: var(--wb-text); overflow-wrap: anywhere; }\n.wb-icon { flex: none; width: 24px; height: 24px; margin-top: 1px; color: var(--wb-tone); }\n.wb-icon svg { display: block; width: 24px; height: 24px; }\n.wb-close { flex: none; display: grid; place-items: center; width: 32px; height: 32px; margin: -6px -10px 0 0; padding: 0; border: 0; border-radius: 999px;\n background: transparent; color: var(--wb-text); cursor: pointer; }\n.wb-close:hover { background: var(--wb-hover); }\n.wb-close svg { width: 18px; height: 18px; }\n.wb-message { margin: 4px 0 0; color: var(--wb-muted); white-space: pre-line; overflow-wrap: anywhere; }\n.wb-body { margin-top: 14px; min-width: 0; }\n.wb-body:empty { display: none; }\n.wb-error { margin: 12px 0 0; color: var(--wb-danger); font-size: 13px; font-weight: 600; }\n.wb-error[hidden] { display: none; }\n.wb-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 22px; }\n.wb-actions:empty { display: none; }\n.wb-actions.wb-stack { flex-direction: column; align-items: stretch; gap: 12px; margin-top: 24px; }\n.wb-actions.wb-stack .wb-btn { height: 44px; font-size: 16px; }\n.wb-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 72px; height: 36px; padding: 0 18px;\n border: 1px solid transparent; border-radius: var(--wb-button-radius); font: 700 15px/1 var(--wb-font-dialog, var(--wb-font)); cursor: pointer; white-space: nowrap;\n transition: background-color .12s, filter .12s, opacity .12s; }\n.wb-btn:disabled, .wb-btn[aria-disabled=\"true\"] { opacity: .5; cursor: default; }\n.wb-btn:focus-visible, .wb-close:focus-visible, .wb-toast button:focus-visible { outline: 2px solid var(--wb-accent); outline-offset: 2px; }\n.wb-primary { background: var(--wb-inverse); color: var(--wb-on-inverse); }\n.wb-primary:not(:disabled):not([aria-disabled=\"true\"]):hover { filter: brightness(.92) contrast(1.05); }\n.wb-danger { background: var(--wb-danger); color: #fff; }\n.wb-danger:not(:disabled):hover { filter: brightness(.92); }\n.wb-secondary { background: transparent; color: var(--wb-text); border-color: var(--wb-border-strong); }\n.wb-secondary:not(:disabled):hover { background: var(--wb-hover); }\n.wb-plain { background: transparent; color: var(--wb-accent); min-width: 0; padding: 0 10px; }\n.wb-plain:not(:disabled):hover { background: var(--wb-hover); }\n.wb-btn[aria-busy=\"true\"] { cursor: progress; }\n/* Form parts for dialog content. */\n.wb-field { display: flex; flex-direction: column; gap: 6px; margin: 0 0 12px; }\n.wb-field:last-child { margin-bottom: 0; }\n.wb-label { font-size: 13px; font-weight: 600; color: var(--wb-muted); }\n.wb-hint { margin: 0; font-size: 13px; color: var(--wb-muted); }\n.wb-input, .wb-dialog input[type=\"text\"], .wb-dialog input[type=\"search\"], .wb-dialog input[type=\"url\"], .wb-dialog input[type=\"number\"], .wb-dialog textarea, .wb-dialog select {\n width: 100%; min-height: 40px; padding: 9px 12px; border: 1px solid var(--wb-border-strong); border-radius: var(--wb-field-radius);\n background: var(--wb-bg); color: var(--wb-text); font: 400 15px/1.4 var(--wb-font-dialog, var(--wb-font)); outline: none; transition: border-color .12s, box-shadow .12s; }\n.wb-dialog textarea { min-height: 96px; resize: vertical; }\n.wb-dialog textarea.wb-mono { font: 400 13px/1.5 var(--wb-font-mono, ui-monospace, \"Cascadia Mono\", Consolas, Menlo, monospace); }\n.wb-input::placeholder, .wb-dialog input::placeholder, .wb-dialog textarea::placeholder { color: var(--wb-muted); opacity: .8; }\n.wb-input:focus, .wb-dialog input:focus, .wb-dialog textarea:focus, .wb-dialog select:focus { border-color: var(--wb-accent); box-shadow: 0 0 0 1px var(--wb-accent); }\n.wb-dialog [aria-invalid=\"true\"] { border-color: var(--wb-danger) !important; box-shadow: 0 0 0 1px var(--wb-danger) !important; }\n.wb-check { display: flex; align-items: flex-start; gap: 10px; padding: 7px 0; cursor: pointer; line-height: 1.35; }\n.wb-check input { flex: none; width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--wb-accent); cursor: pointer; }\n.wb-check small { display: block; color: var(--wb-muted); font-size: 13px; }\n.wb-divider { height: 1px; margin: 12px 0; background: var(--wb-border); border: 0; }\n.wb-row { display: flex; align-items: center; gap: 10px; }\n.wb-muted { color: var(--wb-muted); }\n.wb-dialog a { color: var(--wb-accent); }\n/* Toasts */\n.wb-toasts { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 8px;\n width: max-content; max-width: min(560px, calc(100vw - 32px)); pointer-events: none; }\n.wb-toast { display: flex; align-items: center; gap: 12px; min-height: 44px; max-width: 100%; padding: 10px 10px 10px 16px; border-radius: min(var(--wb-radius), 12px);\n background: var(--wb-toast-bg); color: var(--wb-toast-fg); box-shadow: 0 10px 30px -6px rgba(0,0,0,.4); pointer-events: auto;\n font: 500 15px/1.35 var(--wb-font-dialog, var(--wb-font)); animation: wb-toast-in .2s cubic-bezier(.2,.9,.3,1.2); }\n.wb-toast.wb-closing { animation: wb-toast-out .14s ease-in forwards; }\n${Object.entries(TOAST_TONES).map(([tone, [bg, fg]]) => `.wb-toast[data-tone=\"${tone}\"] { --wb-toast-bg: ${bg}; --wb-toast-fg: ${fg}; }`).join(' ')}\n.wb-toast-icon { flex: none; display: grid; margin-left: -4px; }\n.wb-toast-icon svg { width: 20px; height: 20px; }\n.wb-toast[data-tone=\"info\"] .wb-toast-icon { color: var(--wb-accent); }\n.wb-toast-text { flex: 1; min-width: 0; overflow-wrap: anywhere; white-space: pre-line; padding-right: 4px; }\n.wb-toast button { flex: none; border: 0; cursor: pointer; color: inherit; font: 700 14px/1 var(--wb-font-dialog, var(--wb-font)); }\n.wb-toast-action { height: 30px; padding: 0 12px; border-radius: var(--wb-button-radius); background: color-mix(in srgb, currentColor 16%, transparent); }\n.wb-toast-action:hover { background: color-mix(in srgb, currentColor 26%, transparent); }\n.wb-toast-close { display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border-radius: 999px; background: transparent; opacity: .8; }\n.wb-toast-close:hover { opacity: 1; background: color-mix(in srgb, currentColor 16%, transparent); }\n.wb-toast-close svg { width: 16px; height: 16px; }\n@keyframes wb-fade { from { opacity: 0; } }\n@keyframes wb-fade-out { to { opacity: 0; } }\n@keyframes wb-in { from { opacity: 0; transform: translateY(6px) scale(.97); } }\n@keyframes wb-out { to { opacity: 0; transform: scale(.98); } }\n@keyframes wb-toast-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }\n@keyframes wb-toast-out { to { opacity: 0; transform: translateY(6px); } }\n@media (prefers-reduced-motion: reduce) {\n .wb-root *, .wb-root *::before, .wb-root *::after { animation: none !important; transition: none !important; }\n}\n`;\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\nconst ICONS: Record<Exclude<Tone, 'neutral'> | 'close', string> = {\n info: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm1 15h-2v-6h2v6Zm0-8h-2V7h2v2Z',\n success: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm-1.2 14.2-4-4 1.4-1.4 2.6 2.6 5-5 1.4 1.4-6.4 6.4Z',\n warning: 'M12 2 1 21h22L12 2Zm1 16h-2v-2h2v2Zm0-4h-2v-5h2v5Z',\n danger: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm1 15h-2v-2h2v2Zm0-4h-2V7h2v6Z',\n close: 'M10.59 12 4.54 5.96l1.42-1.42L12 10.59l6.04-6.05 1.42 1.42L13.41 12l6.05 6.04-1.42 1.42L12 13.41l-6.04 6.05-1.42-1.42L10.59 12Z',\n};\n\nconst FOCUSABLE = 'a[href],button:not([disabled]),input:not([disabled]):not([type=\"hidden\"]),select:not([disabled]),textarea:not([disabled]),[contenteditable]:not([contenteditable=\"false\"]),[tabindex]:not([tabindex=\"-1\"])';\n\n// ---------------------------------------------------------------------------------------------\n\ntype Entry = { close(result?: unknown): void };\ntype Owner = Set<Entry>;\n\ntype OpenModal = {\n layer: HTMLElement;\n panel: HTMLElement;\n handle: ModalHandle;\n dismiss(): void;\n returnTo: HTMLElement | null;\n lastFocus: HTMLElement | null;\n};\n\n/** The deepest focused element, through open shadow roots. */\nexport function deepActiveElement(doc: Document): HTMLElement | null {\n let active = doc.activeElement as HTMLElement | null;\n while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement as HTMLElement;\n return active;\n}\n\nexport function createUiKit(win: Window & typeof globalThis, options: UiKitOptions): RootUiKit {\n const doc = win.document;\n const hostTag = options.hostTag ?? 'wb-ui';\n const product = options.product ?? 'wayBetter';\n const report = (error: unknown) => console.error(`[${product}] ui callback failed`, error);\n const word = (key: KitKey): string => {\n try {\n const value = options.text?.(key);\n if (typeof value === 'string' && value) return value;\n } catch { /* a broken translator must not break a dialog */ }\n return KIT_MESSAGES[key];\n };\n const isShadowRoot = (node: unknown): node is ShadowRoot => typeof win.ShadowRoot === 'function' && node instanceof win.ShadowRoot;\n const reducedMotion = () => { try { return !!win.matchMedia?.('(prefers-reduced-motion: reduce)').matches; } catch { return false; } };\n\n let host: HTMLElement | null = null;\n let root: ShadowRoot | HTMLElement | null = null;\n let layers: HTMLElement | null = null;\n let toastRegion: HTMLElement | null = null;\n let offTheme: (() => void) | null = null;\n const stack: OpenModal[] = [];\n const toasts: Array<{ element: HTMLElement; key: string; restart(): void; close(): void; closed: Promise<void> }> = [];\n let seq = 0;\n let pendingExits = 0;\n const ownerIds = new WeakMap<Owner, number>();\n\n const paint = (theme: ResolvedTheme) => {\n if (!host) return;\n const vars = themeVars(theme);\n const dark = theme.mode === 'dark';\n vars['--wb-scrim'] = dark ? 'rgba(91, 112, 131, 0.4)' : 'rgba(15, 20, 25, 0.4)';\n vars['--wb-hover'] = `color-mix(in srgb, ${theme.colors.text} ${dark ? 12 : 8}%, transparent)`;\n vars['--wb-border-strong'] = `color-mix(in srgb, ${theme.colors.border} 70%, ${theme.colors.muted})`;\n vars['--wb-field-radius'] = `${Math.min(10, Math.max(2, Math.round(theme.radius / 2)))}px`;\n vars['--wb-danger'] = DANGER;\n vars['--wb-toast-bg'] = theme.colors.inverse;\n vars['--wb-toast-fg'] = theme.colors.onInverse;\n for (const [name, value] of Object.entries(vars)) host.style.setProperty(name, value);\n host.style.setProperty('color-scheme', theme.mode);\n };\n\n const ensureRoot = () => {\n if (host?.isConnected && root && layers && toastRegion) return;\n if (host) {\n // Someone removed the host while things were open: close them (their promises resolve).\n offTheme?.();\n offTheme = null;\n for (const entry of [...stack]) entry.dismiss();\n for (const item of [...toasts]) item.close();\n }\n host?.remove();\n host = doc.createElement(hostTag);\n host.setAttribute('data-wb-ui', '');\n if (options.hostId) host.id = options.hostId;\n // The host sits above the site; it takes no clicks itself (its layers and toasts do).\n host.style.cssText = `all:initial;position:fixed;inset:0;z-index:${options.zIndex ?? 2147483600};pointer-events:none;display:block;`;\n root = typeof host.attachShadow === 'function' ? host.attachShadow({ mode: 'open' }) : host;\n const wrap = doc.createElement('div');\n wrap.className = 'wb-root';\n layers = doc.createElement('div');\n toastRegion = doc.createElement('div');\n toastRegion.className = 'wb-toasts';\n toastRegion.setAttribute('aria-live', 'polite');\n toastRegion.setAttribute('aria-relevant', 'additions');\n wrap.append(layers, toastRegion);\n root.append(wrap);\n // An adopted sheet (see styles.ts): the site's CSP cannot refuse it, and it stays with the root\n // wherever the host is moved. A host without a shadow root keeps a <style> child.\n if (isShadowRoot(root)) adoptStyles(root, UI_CSS);\n else {\n const style = doc.createElement('style');\n style.textContent = UI_CSS;\n root.prepend(style);\n }\n // Keys typed in a dialog are ours: the site's (and plugins') page shortcuts never see them.\n for (const type of ['keydown', 'keyup', 'keypress']) root.addEventListener(type, event => event.stopPropagation());\n (doc.body ?? doc.documentElement).appendChild(host);\n paint(options.theme.current());\n offTheme = options.theme.onChange(paint);\n };\n\n /** Removes the host once nothing is on screen, so a stopped plugin leaves the page as it was. */\n const maybeTeardown = () => {\n if (stack.length || toasts.length || pendingExits) return;\n offTheme?.();\n offTheme = null;\n host?.remove();\n host = root = layers = toastRegion = null;\n };\n\n const later = (fn: () => void, ms: number) => {\n if (ms <= 0) { fn(); return; }\n pendingExits += 1;\n win.setTimeout(() => { pendingExits -= 1; fn(); maybeTeardown(); }, ms);\n };\n\n const svg = (path: string) => {\n const icon = doc.createElementNS(SVG_NS, 'svg');\n icon.setAttribute('viewBox', '0 0 24 24');\n icon.setAttribute('aria-hidden', 'true');\n const shape = doc.createElementNS(SVG_NS, 'path');\n shape.setAttribute('d', path);\n shape.setAttribute('fill', 'currentColor');\n icon.appendChild(shape);\n return icon;\n };\n\n const tabbables = (panel: HTMLElement) => Array.from(panel.querySelectorAll<HTMLElement>(FOCUSABLE))\n .filter(el => el.tabIndex >= 0 && !el.closest('[hidden],[inert]') && el.getClientRects().length > 0);\n\n const focus = (el: HTMLElement | null | undefined) => { try { el?.focus({ preventScroll: true }); } catch { /* Detached. */ } };\n\n // One focus guard for all dialogs: focus that lands outside the kit goes back to the top dialog.\n let guardWindow = 0;\n let guardCount = 0;\n const onFocusIn = (event: FocusEvent) => {\n const top = stack[stack.length - 1];\n if (!top || event.target === host) return;\n // Another focus trap (the site's own modal) fighting ours must not loop forever: give up after 20 tries a second.\n const now = Date.now();\n if (now - guardWindow > 1000) { guardWindow = now; guardCount = 0; }\n if (++guardCount > 20) return;\n focus(top.lastFocus?.isConnected && top.panel.contains(top.lastFocus) ? top.lastFocus : tabbables(top.panel)[0] ?? top.panel);\n };\n const syncStack = () => {\n stack.forEach((entry, index) => {\n const top = index === stack.length - 1;\n entry.layer.toggleAttribute('inert', !top);\n if (top) entry.layer.removeAttribute('aria-hidden');\n else entry.layer.setAttribute('aria-hidden', 'true');\n });\n if (stack.length) doc.addEventListener('focusin', onFocusIn, true);\n else doc.removeEventListener('focusin', onFocusIn, true);\n };\n\n function modal(input: ModalOptions, owner?: Owner): ModalHandle {\n ensureRoot();\n const opts = input ?? {};\n const id = `wb-${++seq}`;\n const dismissible = opts.dismissible !== false;\n const layer = doc.createElement('div');\n layer.className = 'wb-layer';\n const backdrop = doc.createElement('div');\n backdrop.className = 'wb-backdrop';\n const panel = doc.createElement('div');\n panel.className = 'wb-dialog';\n panel.setAttribute('role', opts.role === 'alertdialog' ? 'alertdialog' : 'dialog');\n panel.setAttribute('aria-modal', 'true');\n panel.tabIndex = -1;\n panel.style.setProperty('--wb-dialog-width', `${dialogWidth(opts.width)}px`);\n if (opts.tone) panel.style.setProperty('--wb-tone', TONES[opts.tone]);\n\n if (opts.title || (dismissible && opts.closeButton)) {\n const head = doc.createElement('div');\n head.className = 'wb-head';\n if (opts.tone && opts.tone !== 'neutral') {\n const icon = doc.createElement('span');\n icon.className = 'wb-icon';\n icon.appendChild(svg(ICONS[opts.tone]));\n head.appendChild(icon);\n }\n const title = doc.createElement('h2');\n title.className = 'wb-title';\n title.id = `${id}-title`;\n title.textContent = opts.title ?? '';\n head.appendChild(title);\n if (dismissible && (opts.closeButton ?? !!opts.title)) {\n const x = doc.createElement('button');\n x.type = 'button';\n x.className = 'wb-close';\n x.setAttribute('aria-label', word('kit.close'));\n x.appendChild(svg(ICONS.close));\n x.addEventListener('click', () => dismiss());\n head.appendChild(x);\n }\n panel.appendChild(head);\n if (opts.title) panel.setAttribute('aria-labelledby', title.id);\n }\n if (!opts.title) panel.setAttribute('aria-label', opts.label || opts.message || word('kit.dialog'));\n if (opts.message) {\n const message = doc.createElement('p');\n message.className = 'wb-message';\n message.id = `${id}-message`;\n message.textContent = opts.message;\n panel.appendChild(message);\n panel.setAttribute('aria-describedby', message.id);\n }\n // The dialog's own CSS, on the kit's root while the dialog is open (adopted where possible).\n let ownStyles: RootStyles | null = null;\n if (opts.css) {\n if (root && isShadowRoot(root)) ownStyles = adoptStyles(root, opts.css);\n else {\n const style = doc.createElement('style');\n style.textContent = opts.css;\n panel.appendChild(style);\n }\n }\n const body = doc.createElement('div');\n body.className = 'wb-body';\n panel.appendChild(body);\n const error = doc.createElement('p');\n error.className = 'wb-error';\n error.id = `${id}-error`;\n error.setAttribute('role', 'alert');\n error.hidden = true;\n panel.appendChild(error);\n const actionRow = doc.createElement('div');\n actionRow.className = opts.stackActions ? 'wb-actions wb-stack' : 'wb-actions';\n panel.appendChild(actionRow);\n\n let isOpen = true;\n let resolveClosed!: (value: unknown) => void;\n const closed = new Promise<unknown>(resolve => { resolveClosed = resolve; });\n const buttons: HTMLButtonElement[] = [];\n let defaultAction: { action: ModalAction; button: HTMLButtonElement } | null = null;\n let autoFocus: HTMLElement | null = null;\n\n // Busy buttons are aria-disabled, not disabled: a disabled button would drop keyboard focus.\n let busy = false;\n const setBusy = (value: boolean) => {\n busy = value;\n for (const button of buttons) {\n if (value) { button.setAttribute('aria-disabled', 'true'); button.setAttribute('aria-busy', 'true'); }\n else { button.removeAttribute('aria-busy'); if (!button.dataset.disabled) button.removeAttribute('aria-disabled'); }\n }\n };\n const handle: ModalHandle = {\n element: panel,\n body,\n get open() { return isOpen; },\n closed,\n close: result => close(result),\n setError(message) {\n error.textContent = message ?? '';\n error.hidden = !message;\n },\n setBusy,\n };\n\n const run = async (action: ModalAction) => {\n if (!isOpen || busy) return;\n let keep = false;\n if (action.onClick) {\n let result: unknown;\n try {\n result = action.onClick(handle);\n if (result && typeof (result as Promise<unknown>).then === 'function') {\n setBusy(true);\n try { result = await result; } finally { if (isOpen) setBusy(false); }\n }\n } catch (err) {\n report(err);\n handle.setError(err instanceof Error && err.message ? err.message : word('kit.failed'));\n return;\n }\n keep = result === false;\n }\n if (!keep && isOpen) close('value' in action ? action.value : action.label);\n };\n\n for (const action of opts.actions ?? []) {\n const button = doc.createElement('button');\n button.type = 'button';\n button.className = `wb-btn wb-${action.tone ?? 'secondary'}`;\n button.textContent = action.label;\n if (action.disabled) { button.disabled = true; button.dataset.disabled = '1'; }\n button.addEventListener('click', () => { void run(action); });\n buttons.push(button);\n actionRow.appendChild(button);\n if (action.default && !defaultAction) defaultAction = { action, button };\n if (action.autoFocus && !autoFocus) autoFocus = button;\n }\n\n const fill = (content: Content) => {\n if (content === null || content === undefined) return;\n if (typeof content === 'string') { const p = doc.createElement('p'); p.className = 'wb-message'; p.textContent = content; body.appendChild(p); }\n else if (typeof content === 'function') content(body);\n else body.appendChild(content);\n };\n try { fill(opts.content); } catch (err) { report(err); }\n\n const dismiss = () => { if (isOpen) close(opts.dismissValue); };\n const entry: OpenModal = { layer, panel, handle, dismiss, returnTo: deepActiveElement(doc), lastFocus: null };\n const ownerEntry: Entry = { close: () => dismiss() };\n owner?.add(ownerEntry);\n\n function close(result?: unknown) {\n if (!isOpen) return;\n isOpen = false;\n owner?.delete(ownerEntry);\n const index = stack.indexOf(entry);\n const wasTop = index === stack.length - 1;\n if (index >= 0) stack.splice(index, 1);\n syncStack();\n layer.setAttribute('inert', '');\n layer.classList.add('wb-closing');\n later(() => { layer.remove(); ownStyles?.remove(); }, reducedMotion() ? 0 : 130);\n // Dialogs opened from this one return focus where this one would have.\n for (const other of stack) if (other.returnTo && layer.contains(other.returnTo)) other.returnTo = entry.returnTo;\n // Focus never lingers in a dialog that is animating out (keys would still go to its fields).\n const active = deepActiveElement(doc);\n if (active && layer.contains(active)) active.blur();\n if (wasTop) {\n const next = stack[stack.length - 1];\n const back = entry.returnTo;\n if (back?.isConnected && (!next || next.panel.contains(back))) focus(back);\n if (next && deepActiveElement(doc) !== back) focus(next.lastFocus?.isConnected && next.panel.contains(next.lastFocus) ? next.lastFocus : next.panel);\n }\n try { opts.onClose?.(result); } catch (err) { report(err); }\n resolveClosed(result);\n maybeTeardown();\n }\n\n // Keyboard: Tab stays inside; Esc dismisses; Enter runs the default action from a single-line field.\n layer.addEventListener('keydown', event => {\n if (stack[stack.length - 1] !== entry) return;\n // Keys that belong to an input method (composing CJK text) are not ours.\n if (event.isComposing || event.keyCode === 229) return;\n if (event.key === 'Tab') {\n const list = tabbables(panel);\n const active = deepActiveElement(doc);\n const next = trapIndex(list.length, active ? list.indexOf(active) : -1, event.shiftKey);\n if (list.length === 0) { event.preventDefault(); focus(panel); }\n else if (next >= 0) { event.preventDefault(); focus(list[next]); }\n } else if (event.key === 'Escape') {\n event.preventDefault();\n if (dismissible) dismiss();\n } else if (event.key === 'Enter' && defaultAction && !defaultAction.button.disabled && !busy) {\n const target = event.composedPath()[0] as HTMLElement;\n const tag = target?.nodeName;\n const singleLine = tag === 'INPUT' && !/^(checkbox|radio|button|submit|reset|file)$/i.test((target as HTMLInputElement).type);\n const multilineSubmit = tag === 'TEXTAREA' && (event.ctrlKey || event.metaKey);\n if (singleLine || multilineSubmit || target === panel) {\n event.preventDefault();\n void run(defaultAction.action);\n }\n }\n });\n layer.addEventListener('focusin', event => { entry.lastFocus = event.composedPath()[0] as HTMLElement; });\n // A backdrop click counts only when the press also started on it (a text selection dragged out\n // of a field must not close the dialog).\n let pressedBackdrop = false;\n backdrop.addEventListener('pointerdown', () => { pressedBackdrop = true; });\n // Pressing the backdrop must not move focus out of the dialog (to <body>, where keys reach the page).\n backdrop.addEventListener('mousedown', event => event.preventDefault());\n // Focus that drops to nothing (a click on a non-focusable spot, a removed element) comes back.\n layer.addEventListener('focusout', event => {\n if (event.relatedTarget) return;\n win.setTimeout(() => {\n if (!isOpen || stack[stack.length - 1] !== entry) return;\n const active = deepActiveElement(doc);\n if (!active || active === doc.body || active === doc.documentElement) focus(entry.lastFocus?.isConnected ? entry.lastFocus : panel);\n }, 0);\n });\n layer.addEventListener('pointerup', event => {\n const onBackdrop = pressedBackdrop && event.target === backdrop;\n pressedBackdrop = false;\n if (onBackdrop && opts.closeOnBackdrop && dismissible) dismiss();\n });\n // The page behind never scrolls while a dialog is open.\n layer.addEventListener('wheel', event => {\n let node = event.target as HTMLElement | null;\n while (node && node !== layer) {\n if (node.scrollHeight > node.clientHeight + 1 && /auto|scroll/.test(win.getComputedStyle(node).overflowY)) {\n const down = event.deltaY > 0;\n if (down ? node.scrollTop + node.clientHeight < node.scrollHeight - 1 : node.scrollTop > 0) return;\n }\n node = node.parentElement;\n }\n event.preventDefault();\n }, { passive: false });\n\n layer.append(backdrop, panel);\n layers!.appendChild(layer);\n stack.push(entry);\n syncStack();\n\n let initial: HTMLElement | null = null;\n try { initial = typeof opts.initialFocus === 'string' ? panel.querySelector<HTMLElement>(opts.initialFocus) : opts.initialFocus ?? null; } catch (err) { report(err); }\n const firstField = panel.querySelector<HTMLElement>('.wb-body input:not([type=\"hidden\"]):not([disabled]), .wb-body textarea:not([disabled]), .wb-body select:not([disabled])');\n focus(initial ?? autoFocus ?? firstField ?? defaultAction?.button ?? buttons[0] ?? panel);\n return handle;\n }\n\n function toast(message: string, input?: ToastOptions | number, owner?: Owner): ToastHandle {\n ensureRoot();\n const opts: ToastOptions = typeof input === 'number' ? { duration: input } : input ?? {};\n const tone = opts.tone ?? 'neutral';\n const text = String(message ?? '');\n let ownerId = 0;\n if (owner) { ownerId = ownerIds.get(owner) ?? ++seq; ownerIds.set(owner, ownerId); }\n const key = `${ownerId}|${tone}|${text}|${opts.action?.label ?? ''}`;\n // The same message again restarts the visible one instead of stacking a copy.\n const same = toasts.find(item => item.key === key);\n if (same) {\n same.restart();\n return { element: same.element, close: same.close, closed: same.closed };\n }\n const element = doc.createElement('div');\n element.className = 'wb-toast';\n element.dataset.tone = tone;\n element.setAttribute('role', tone === 'danger' ? 'alert' : 'status');\n if (tone !== 'neutral') {\n const icon = doc.createElement('span');\n icon.className = 'wb-toast-icon';\n icon.appendChild(svg(ICONS[tone]));\n element.appendChild(icon);\n }\n const label = doc.createElement('span');\n label.className = 'wb-toast-text';\n label.textContent = text;\n element.appendChild(label);\n let resolveClosed!: () => void;\n const closed = new Promise<void>(resolve => { resolveClosed = resolve; });\n let timer = 0;\n let open = true;\n const duration = toastDuration(opts);\n const ownerEntry: Entry = { close: () => close() };\n let held = false;\n const start = () => { win.clearTimeout(timer); if (duration > 0 && !held) timer = win.setTimeout(close, duration); };\n const hold = (value: boolean) => { held = value; if (value) win.clearTimeout(timer); else start(); };\n function close() {\n if (!open) return;\n open = false;\n win.clearTimeout(timer);\n // A focused toast going away hands focus back to the open dialog (or lets go of it).\n const active = deepActiveElement(doc);\n if (active && element.contains(active)) {\n const top = stack[stack.length - 1];\n if (top) focus(top.lastFocus?.isConnected && top.panel.contains(top.lastFocus) ? top.lastFocus : top.panel);\n else active.blur();\n }\n owner?.delete(ownerEntry);\n const index = toasts.indexOf(item);\n if (index >= 0) toasts.splice(index, 1);\n element.classList.add('wb-closing');\n later(() => element.remove(), reducedMotion() ? 0 : 150);\n resolveClosed();\n maybeTeardown();\n }\n if (opts.action) {\n const action = opts.action;\n const button = doc.createElement('button');\n button.type = 'button';\n button.className = 'wb-toast-action';\n button.textContent = action.label;\n button.addEventListener('click', () => {\n try { action.onClick(); } catch (err) { report(err); }\n close();\n });\n element.appendChild(button);\n }\n const dismissButton = doc.createElement('button');\n dismissButton.type = 'button';\n dismissButton.className = 'wb-toast-close';\n dismissButton.setAttribute('aria-label', word('kit.dismiss'));\n dismissButton.appendChild(svg(ICONS.close));\n dismissButton.addEventListener('click', () => close());\n element.appendChild(dismissButton);\n // Hovering or focusing a toast holds it on screen.\n element.addEventListener('pointerenter', () => hold(true));\n element.addEventListener('pointerleave', () => hold(false));\n element.addEventListener('focusin', () => hold(true));\n element.addEventListener('focusout', () => hold(false));\n element.addEventListener('keydown', event => { if (event.key === 'Escape') close(); });\n const item = { element, key, restart: start, close, closed };\n toasts.push(item);\n owner?.add(ownerEntry);\n toastRegion!.appendChild(element);\n while (toasts.length > MAX_TOASTS) toasts[0]!.close();\n start();\n return { element, close, closed };\n }\n\n const text = (value: unknown) => (typeof value === 'string' ? value : value == null ? '' : String(value));\n\n function alert(input: AlertOptions | string, owner?: Owner): Promise<void> {\n const opts: AlertOptions = typeof input === 'string' ? { message: input } : input ?? {};\n const handle = modal({\n role: 'alertdialog', title: text(opts.title) || undefined, message: text(opts.message) || undefined, tone: opts.tone,\n width: 'sm', closeOnBackdrop: true, closeButton: false, stackActions: true,\n actions: [{ label: opts.okLabel || word('kit.ok'), tone: 'primary', default: true, autoFocus: true, value: undefined }],\n }, owner);\n return handle.closed.then(() => undefined);\n }\n\n function confirm(input: ConfirmOptions | string, owner?: Owner): Promise<boolean> {\n const opts: ConfirmOptions = typeof input === 'string' ? { message: input } : input ?? {};\n const danger = !!opts.danger;\n const handle = modal({\n role: 'alertdialog', title: text(opts.title) || undefined, message: text(opts.message) || undefined,\n width: 'sm', closeOnBackdrop: true, closeButton: false, stackActions: true, dismissValue: false,\n actions: [\n // A destructive confirmation starts on Cancel, so Enter never destroys by accident.\n { label: opts.confirmLabel || (danger ? word('kit.delete') : word('kit.ok')), tone: danger ? 'danger' : 'primary', value: true, default: !danger, autoFocus: !danger },\n { label: opts.cancelLabel || word('kit.cancel'), tone: 'secondary', value: false, autoFocus: danger },\n ],\n }, owner);\n return handle.closed.then(result => result === true);\n }\n\n function prompt(input: PromptOptions | string, owner?: Owner): Promise<string | null> {\n const opts: PromptOptions = typeof input === 'string' ? { title: input } : input ?? {};\n const field = doc.createElement(opts.multiline ? 'textarea' : 'input') as HTMLInputElement | HTMLTextAreaElement;\n if (field instanceof win.HTMLInputElement) field.type = 'text';\n field.className = opts.multiline ? '' : 'wb-input';\n field.value = text(opts.value);\n if (opts.placeholder) field.placeholder = opts.placeholder;\n if (opts.maxLength && opts.maxLength > 0) field.maxLength = Math.floor(opts.maxLength);\n field.spellcheck = true;\n let tried = false;\n let handle!: ModalHandle;\n const check = () => {\n let message: string | null = null;\n try { message = validationMessage(opts.validate?.(field.value), word('kit.checkValue')); } catch (err) { message = err instanceof Error ? err.message : word('kit.checkValue'); }\n field.setAttribute('aria-invalid', message ? 'true' : 'false');\n handle.setError(message);\n return !message;\n };\n field.addEventListener('input', () => { if (tried) check(); });\n handle = modal({\n role: 'dialog', title: text(opts.title) || undefined, message: text(opts.message) || undefined, width: opts.width ?? 'sm', dismissValue: null,\n content: body => {\n const wrap = doc.createElement('label');\n wrap.className = 'wb-field';\n if (opts.label) {\n const caption = doc.createElement('span');\n caption.className = 'wb-label';\n caption.textContent = opts.label;\n wrap.appendChild(caption);\n } else field.setAttribute('aria-label', text(opts.title) || word('kit.value'));\n wrap.appendChild(field);\n body.appendChild(wrap);\n },\n actions: [\n { label: opts.cancelLabel || word('kit.cancel'), tone: 'secondary', value: null },\n { label: opts.confirmLabel || word('kit.ok'), tone: 'primary', default: true, onClick: () => { tried = true; return check() ? undefined : false; }, value: undefined },\n ],\n initialFocus: field,\n }, owner);\n field.setAttribute('aria-describedby', `${handle.element.querySelector('.wb-error')?.id ?? ''}`);\n // The OK action's result is the field's value at the moment it closed.\n return handle.closed.then(result => (result === null || !tried ? null : field.value));\n }\n\n const make = (owner?: Owner): UiKit => Object.freeze({\n toast: (message: string, options?: ToastOptions | number) => toast(message, options, owner),\n alert: (options: AlertOptions | string) => alert(options, owner),\n confirm: (options: ConfirmOptions | string) => confirm(options, owner),\n prompt: (options: PromptOptions | string) => prompt(options, owner),\n dialog: (options: DialogOptions) => modal({ closeOnBackdrop: false, ...options, role: 'dialog' }, owner),\n modal: (options: ModalOptions) => modal(options, owner),\n h: (tag: string, props?: ElementProps | null, ...children: Child[]) => buildElement(doc, tag, props, ...children),\n });\n\n const base = make();\n return Object.freeze({\n ...base,\n scoped() {\n const owner: Owner = new Set();\n return {\n kit: make(owner),\n dispose() {\n for (const entry of [...owner]) {\n try { entry.close(); } catch (err) { report(err); }\n }\n owner.clear();\n },\n };\n },\n openModals: () => stack.length,\n });\n}\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { InstallController, InstallRequest } from './installController.ts';
|
|
3
|
+
import type { StoreText } from './storeMessages.ts';
|
|
4
|
+
import { type InstallKind } from './storeModel.ts';
|
|
5
|
+
import { type StringsSummary } from './stringPacksModel.ts';
|
|
6
|
+
/** Milliseconds before Install can be pressed (native code refuses a commit faster than 600 ms). */
|
|
7
|
+
export declare const REVIEW_MS = 1000;
|
|
8
|
+
/** Class names for the app's own buttons (defaults: the framework's `.wb-btn`). */
|
|
9
|
+
export type InstallClassNames = {
|
|
10
|
+
primary: string;
|
|
11
|
+
secondary: string;
|
|
12
|
+
icon: string;
|
|
13
|
+
pop: string;
|
|
14
|
+
};
|
|
15
|
+
export type InstallHostProps<Theme> = {
|
|
16
|
+
controller: InstallController<Theme>;
|
|
17
|
+
t: StoreText;
|
|
18
|
+
/** The site's name in messages ("X"). */
|
|
19
|
+
site: string;
|
|
20
|
+
/** Shows or hides the app's tab webviews under the screen (+1 when it opens, -1 when it closes). */
|
|
21
|
+
setOverlay(delta: 1 | -1): void;
|
|
22
|
+
/** "Open Plugins" / "Open Appearance" after an install. */
|
|
23
|
+
openSection(kind: InstallKind): void;
|
|
24
|
+
/** A live preview of a staged theme (the app's theme preview). */
|
|
25
|
+
renderThemePreview?(theme: Theme): ReactNode;
|
|
26
|
+
/** A string pack's coverage against the site's inventory (the app has the inventory). */
|
|
27
|
+
stringsSummary?(text: string): StringsSummary | null;
|
|
28
|
+
/** Drops on elements matching this selector are handled by them (e.g. an import box). */
|
|
29
|
+
ownDropTargets?: string;
|
|
30
|
+
closeIcon?: ReactNode;
|
|
31
|
+
classNames?: Partial<InstallClassNames>;
|
|
32
|
+
};
|
|
33
|
+
/** Re-renders with the controller's current request. */
|
|
34
|
+
export declare function useInstallRequest<Theme>(controller: InstallController<Theme>): InstallRequest<Theme> | null;
|
|
35
|
+
/**
|
|
36
|
+
* Install links, the screen, and file drops on the window. A file dragged over the shell (tab
|
|
37
|
+
* strip, titlebar, settings) shows a drop target over the whole window; files dragged straight into
|
|
38
|
+
* a site tab stay the site's (e.g. images for a post).
|
|
39
|
+
*/
|
|
40
|
+
export declare function InstallHost<Theme>(props: InstallHostProps<Theme>): import("react").JSX.Element;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// The install screen, shared by every wayBetter app: every theme or plugin that is not copied into
|
|
3
|
+
// the plugins folder by hand (a waybetter:// link, a dropped file, the Store) is shown here first
|
|
4
|
+
// with its name, author, version, where it came from, its sha256, the permissions a plugin declares
|
|
5
|
+
// and the exact code or CSS that will be written. Nothing installs until Install is pressed (enabled
|
|
6
|
+
// after a moment, so a stray click or Enter cannot confirm it). Lives in the shell; the app hides
|
|
7
|
+
// its tab webviews while it is open (`setOverlay`). Styles: `store.css` (framework `--wb-*` tokens).
|
|
8
|
+
import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
10
|
+
import { formatBytes, permissionBadges, previewLines } from "./storeModel.js";
|
|
11
|
+
import { coveragePercent } from "./stringPacksModel.js";
|
|
12
|
+
/** Milliseconds before Install can be pressed (native code refuses a commit faster than 600 ms). */
|
|
13
|
+
export const REVIEW_MS = 1000;
|
|
14
|
+
const PREVIEW_LINES = 160;
|
|
15
|
+
const DEFAULT_CLASSES = { primary: 'wb-btn is-primary', secondary: 'wb-btn', icon: 'wb-icon-btn', pop: '' };
|
|
16
|
+
/** Re-renders with the controller's current request. */
|
|
17
|
+
export function useInstallRequest(controller) {
|
|
18
|
+
return useSyncExternalStore(controller.subscribe, controller.current, controller.current);
|
|
19
|
+
}
|
|
20
|
+
function Glyph({ d, size = 18 }) {
|
|
21
|
+
return _jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: d, fill: "none", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
22
|
+
}
|
|
23
|
+
const G = {
|
|
24
|
+
plugin: 'M9 3v5M15 3v5M6 8h12v3a6 6 0 0 1-12 0zM12 17v4',
|
|
25
|
+
theme: 'M12 3a9 9 0 1 0 0 18c1.5 0 2-1 2-1.8 0-1.2-.9-1.5-.9-2.5 0-1 .8-1.7 1.8-1.7h2A4.2 4.2 0 0 0 21 10.8 8.8 8.8 0 0 0 12 3zM7.5 11h.01M10.5 7.5h.01M15 8h.01',
|
|
26
|
+
shield: 'M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6z',
|
|
27
|
+
check: 'M5 12.5l4.2 4.2L19 7',
|
|
28
|
+
link: 'M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1',
|
|
29
|
+
file: 'M7 3h7l5 5v13H7zM14 3v5h5',
|
|
30
|
+
warn: 'M12 4l9 16H3zM12 10v4M12 17h.01',
|
|
31
|
+
copy: 'M9 9h10v10H9zM5 15V5h10',
|
|
32
|
+
close: 'M6 6l12 12M18 6L6 18',
|
|
33
|
+
strings: 'M4 5h9M8.5 3v2M11 5c-.8 3.8-3.4 6.6-7 8M6.5 8.5c1.1 1.6 2.7 3 4.5 3.8M13 21l4-9 4 9M14.4 18h5.2',
|
|
34
|
+
};
|
|
35
|
+
function Fact({ label, children, wide }) {
|
|
36
|
+
return _jsxs("div", { className: `wbi-fact${wide ? ' is-wide' : ''}`, children: [_jsx("dt", { children: label }), _jsx("dd", { children: children })] });
|
|
37
|
+
}
|
|
38
|
+
function CodePreview({ text, label, t }) {
|
|
39
|
+
const [all, setAll] = useState(false);
|
|
40
|
+
const { lines, hidden } = previewLines(text, PREVIEW_LINES, all);
|
|
41
|
+
return _jsxs("section", { className: "wbi-code", "aria-label": label, children: [_jsxs("header", { children: [_jsx("span", { children: label }), _jsx("small", { children: t('wb.install.lines', { count: text.split('\n').length }) })] }), _jsx("pre", { tabIndex: 0, children: _jsx("code", { children: lines.map((line, i) => _jsxs("span", { className: "wbi-line", children: [_jsx("i", { children: i + 1 }), line || ' '] }, i)) }) }), hidden > 0 && _jsx("button", { className: "wbi-more", onClick: () => setAll(true), children: t('wb.install.moreLines', { count: hidden }) })] });
|
|
42
|
+
}
|
|
43
|
+
function sourceIcon(preview) {
|
|
44
|
+
return preview.source.kind === 'store' ? G.shield : preview.source.kind === 'link' ? G.link : G.file;
|
|
45
|
+
}
|
|
46
|
+
/** Where it comes from, in the owner's language (native code's `label` is English). */
|
|
47
|
+
function sourceLabel(source, t) {
|
|
48
|
+
if (source.kind === 'store')
|
|
49
|
+
return t('wb.install.source.store');
|
|
50
|
+
if (source.kind === 'link') {
|
|
51
|
+
let host = '';
|
|
52
|
+
try {
|
|
53
|
+
host = new URL(source.url ?? '').hostname;
|
|
54
|
+
}
|
|
55
|
+
catch { /* no host */ }
|
|
56
|
+
return t('wb.install.source.link', { host });
|
|
57
|
+
}
|
|
58
|
+
return t('wb.install.source.file');
|
|
59
|
+
}
|
|
60
|
+
function Ready({ request, props }) {
|
|
61
|
+
const { t, site, controller, classes } = props;
|
|
62
|
+
const preview = request.preview;
|
|
63
|
+
const ready = request.status === 'ready' ? request : null;
|
|
64
|
+
const theme = ready ? ready.theme : null;
|
|
65
|
+
const facts = theme !== null ? controller.facts(theme) : null;
|
|
66
|
+
const plugin = preview.plugin;
|
|
67
|
+
const [armed, setArmed] = useState(false);
|
|
68
|
+
// On by default only when it is from the signed store or declares its permissions and the code
|
|
69
|
+
// scan found nothing to point out; otherwise the owner turns it on deliberately.
|
|
70
|
+
const [enable, setEnable] = useState(preview.kind === 'theme' || preview.kind === 'strings' || (!preview.existing && (preview.source.signed || (preview.plugin?.permissions != null && preview.findings.length === 0))));
|
|
71
|
+
const [copied, setCopied] = useState(false);
|
|
72
|
+
useEffect(() => { const timer = setTimeout(() => setArmed(true), REVIEW_MS); return () => clearTimeout(timer); }, [preview.token]);
|
|
73
|
+
const strings = preview.kind === 'strings' ? preview.strings ?? null : null;
|
|
74
|
+
const summary = strings ? props.stringsSummary?.(preview.text) ?? null : null;
|
|
75
|
+
const name = plugin?.name ?? facts?.name ?? preview.theme?.name ?? strings?.name ?? t('wb.install.untitled');
|
|
76
|
+
const author = plugin?.author || facts?.author || preview.theme?.author || strings?.authors.join(', ') || '';
|
|
77
|
+
const version = preview.version || preview.store?.version || '';
|
|
78
|
+
const updating = preview.existing && !preview.existing.same;
|
|
79
|
+
const verb = preview.existing?.same ? t('wb.install.reinstall') : updating || ready?.replaces ? t('wb.install.update') : t('wb.store.install');
|
|
80
|
+
const step = preview.existing?.same ? 'reinstall' : updating || ready?.replaces ? 'update' : 'install';
|
|
81
|
+
const eyebrow = preview.kind === 'strings' ? t(`wb.install.eyebrow.strings.${step}`) : t(`wb.install.eyebrow.${step}`, { kind: preview.kind });
|
|
82
|
+
const badges = preview.kind === 'plugin' ? permissionBadges(plugin?.permissions, t, site) : [];
|
|
83
|
+
const installing = request.status === 'installing';
|
|
84
|
+
const description = plugin?.description || facts?.description || strings?.description;
|
|
85
|
+
return _jsxs(_Fragment, { children: [_jsxs("header", { className: "wbi-head", children: [_jsx("div", { className: `wbi-tile is-${preview.kind}`, style: facts?.tile ? { background: facts.tile.background, color: facts.tile.color, boxShadow: `inset 0 0 0 1px ${facts.tile.border}` } : undefined, children: _jsx(Glyph, { d: preview.kind === 'plugin' ? G.plugin : preview.kind === 'strings' ? G.strings : G.theme, size: 22 }) }), _jsxs("div", { className: "wbi-title", children: [_jsx("span", { className: "wbi-eyebrow", children: eyebrow }), _jsx("h2", { id: "wbi-title", children: name }), _jsx("p", { children: [author && t('wb.store.by', { author }), version && `v${version}`].filter(Boolean).join(' · ') || t('wb.install.noAuthor') })] }), _jsx("button", { className: `${classes.icon} wbi-close`, "aria-label": t('wb.install.cancel'), onClick: () => void controller.cancel(), children: props.closeIcon ?? _jsx(Glyph, { d: G.close, size: 16 }) })] }), _jsxs("div", { className: "wbi-body", children: [_jsxs("div", { className: `wbi-source is-${preview.source.kind}`, children: [_jsx(Glyph, { d: sourceIcon(preview) }), _jsxs("div", { children: [_jsx("strong", { children: sourceLabel(preview.source, t) }), preview.source.url && _jsx("code", { title: preview.source.url, children: preview.source.url })] }), preview.source.signed && _jsxs("span", { className: "wbi-verified", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.verified')] })] }), description && _jsx("p", { className: "wbi-desc", children: description }), _jsxs("dl", { className: "wbi-facts", children: [preview.file && _jsx(Fact, { label: t('wb.install.file'), children: preview.file }), _jsx(Fact, { label: t('wb.install.size'), children: formatBytes(preview.size) }), preview.existing && _jsx(Fact, { label: t('wb.install.installedNow'), children: preview.existing.same ? t('wb.install.identical', { version: preview.existing.version || '?' }) : `v${preview.existing.version || '?'}${preview.existing.enabled ? ` · ${t('wb.install.on')}` : ''}` }), ready?.replaces && _jsx(Fact, { label: t('wb.install.replaces'), children: t('wb.install.replacesValue') }), preview.store?.license && _jsx(Fact, { label: t('wb.install.license'), children: preview.store.license }), preview.store?.credits && _jsx(Fact, { label: t('wb.install.credits'), wide: true, children: preview.store.credits }), _jsxs(Fact, { label: "SHA-256", wide: true, children: [_jsx("span", { className: "wbi-hash", children: preview.sha256 }), _jsx("button", { className: "wbi-copy", "aria-label": t('wb.install.copyHash'), onClick: () => void navigator.clipboard?.writeText(preview.sha256).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1400); }).catch(() => { }), children: _jsx(Glyph, { d: copied ? G.check : G.copy, size: 14 }) })] })] }), preview.kind === 'plugin' && _jsxs("section", { className: "wbi-perms", "aria-label": t('wb.store.permissions'), children: [_jsx("h3", { children: t('wb.install.permissions') }), _jsx("ul", { children: badges.map(badge => _jsxs("li", { className: `is-${badge.tone}`, children: [_jsx("span", { className: "wbi-chip", children: badge.label }), _jsx("span", { children: badge.detail })] }, badge.id)) }), _jsxs("p", { className: "wbi-note", children: [_jsx(Glyph, { d: G.warn, size: 14 }), t('wb.install.pageAccess', { site })] }), preview.findings.length > 0 && _jsxs("div", { className: "wbi-findings", children: [_jsx("strong", { children: t('wb.install.theCode') }), preview.findings.map(finding => _jsx("span", { children: finding }, finding))] })] }), strings && _jsxs("section", { className: "wbi-perms wbi-strings", "aria-label": t('wb.store.stringsItem'), children: [_jsxs("p", { className: "wbi-note is-ok", children: [_jsx(Glyph, { d: G.check, size: 14 }), t('wb.install.strings.dataOnly', { site })] }), _jsxs("dl", { className: "wbi-facts", children: [_jsx(Fact, { label: t('wb.install.strings.language'), children: strings.language }), _jsx(Fact, { label: t('wb.install.strings.coverage'), wide: true, children: summary && !summary.otherCatalog
|
|
86
|
+
? t('wb.install.strings.coverageValue', { translated: String(summary.translated), translatable: String(summary.translatable), site, percent: coveragePercent(summary) })
|
|
87
|
+
: t('wb.install.strings.count', { count: strings.strings }) })] }), summary?.otherCatalog && _jsxs("p", { className: "wbi-note", children: [_jsx(Glyph, { d: G.warn, size: 14 }), t('wb.install.strings.otherCatalog', { site })] }), summary && !summary.otherCatalog && _jsxs("ul", { className: "wbi-strings-notes", children: [summary.closed > 0 && _jsx("li", { children: t('wb.install.strings.closed', { count: summary.closed, site }) }), summary.unknown > 0 && _jsx("li", { children: t('wb.install.strings.unknown', { count: summary.unknown, site }) }), summary.refused > 0 && _jsx("li", { children: t('wb.install.strings.refused', { count: summary.refused, site }) })] }), summary && summary.sample.length > 0 && _jsxs("div", { className: "wbi-findings", children: [_jsx("strong", { children: t('wb.install.strings.sample') }), summary.sample.map(text => _jsx("span", { children: text }, text))] })] }), theme !== null && _jsxs("section", { className: "wbi-theme", children: [props.renderThemePreview?.(theme), (ready?.warnings.length ?? 0) > 0 && _jsx("ul", { className: "wbi-warnings", children: ready.warnings.map(warning => _jsx("li", { children: warning }, warning)) })] }), facts?.css ? _jsx(CodePreview, { t: t, text: facts.css, label: t('wb.install.themeCss', { site }) }) : null, _jsx(CodePreview, { t: t, text: preview.text, label: preview.kind === 'plugin' ? t('wb.install.code') : preview.kind === 'strings' ? t('wb.install.strings.file') : t('wb.install.themeFile') })] }), _jsxs("footer", { className: "wbi-foot", children: [_jsxs("label", { className: "wbi-check", children: [_jsx("input", { type: "checkbox", checked: enable, disabled: installing || Boolean(preview.existing?.enabled), onChange: event => setEnable(event.target.checked) }), _jsx("span", { children: preview.kind === 'plugin' ? (preview.existing?.enabled ? t('wb.install.staysOn') : t('wb.install.turnOn')) : t('wb.install.useNow') })] }), _jsx("span", { className: "wbi-foot-end" }), _jsx("button", { className: classes.secondary, onClick: () => void controller.cancel(), disabled: installing, children: t('wb.install.cancel') }), _jsx("button", { className: `${classes.primary} wbi-install${armed ? '' : ' is-arming'}`, disabled: !armed || installing, onClick: () => void controller.confirm(enable), children: installing ? t('wb.install.installing') : verb })] })] });
|
|
88
|
+
}
|
|
89
|
+
function Done({ request, props }) {
|
|
90
|
+
const { t, site, controller, classes } = props;
|
|
91
|
+
return _jsxs("div", { className: "wbi-state", children: [_jsx("div", { className: "wbi-state-icon is-ok", children: _jsx(Glyph, { d: G.check, size: 26 }) }), _jsx("h2", { id: "wbi-title", children: t('wb.install.done', { name: request.name }) }), _jsx("p", { children: request.kind === 'plugin'
|
|
92
|
+
? (request.enabled ? t('wb.install.done.pluginOn', { site }) : t('wb.install.done.pluginOff'))
|
|
93
|
+
: request.kind === 'strings'
|
|
94
|
+
? (request.enabled ? t('wb.install.done.stringsOn', { site }) : t('wb.install.done.stringsOff'))
|
|
95
|
+
: (request.enabled ? t('wb.install.done.themeOn') : t('wb.install.done.themeOff')) }), request.fonts.length > 0 && _jsx("p", { className: "wbi-muted", children: t('wb.install.done.fonts', { fonts: request.fonts.join(', ') }) }), _jsxs("div", { className: "wbi-state-actions", children: [_jsx("button", { className: classes.secondary, onClick: () => { controller.close(); props.openSection(request.kind); }, children: request.kind === 'plugin' ? t('wb.install.openPlugins') : request.kind === 'strings' ? t('wb.install.openStrings') : t('wb.install.openAppearance') }), _jsx("button", { className: classes.primary, autoFocus: true, onClick: controller.close, children: t('wb.install.doneButton') })] })] });
|
|
96
|
+
}
|
|
97
|
+
function Dialog({ request, props }) {
|
|
98
|
+
const { t, controller, classes, setOverlay } = props;
|
|
99
|
+
const box = useRef(null);
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
setOverlay(1);
|
|
102
|
+
return () => setOverlay(-1);
|
|
103
|
+
}, []);
|
|
104
|
+
useEffect(() => { box.current?.querySelector('.wbi-close, [autofocus]')?.focus(); }, [request.status]);
|
|
105
|
+
const dismiss = () => (request.status === 'ready' ? void controller.cancel() : request.status === 'installing' ? undefined : controller.close());
|
|
106
|
+
const onKey = (event) => {
|
|
107
|
+
if (event.key === 'Escape') {
|
|
108
|
+
event.preventDefault();
|
|
109
|
+
dismiss();
|
|
110
|
+
}
|
|
111
|
+
// Enter never confirms an install; only a click on Install does.
|
|
112
|
+
if (event.key === 'Enter' && event.target.classList.contains('wbi-install'))
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
};
|
|
115
|
+
return createPortal(_jsx("div", { className: "wbi-backdrop", onMouseDown: dismiss, children: _jsxs("div", { ref: box, className: `wbi ${classes.pop} is-${request.status}`.replace(/\s+/g, ' '), role: "dialog", "aria-modal": "true", "aria-labelledby": "wbi-title", onMouseDown: event => event.stopPropagation(), onKeyDown: onKey, children: [request.status === 'loading' && _jsxs("div", { className: "wbi-state", children: [_jsx("div", { className: "wbi-spinner", "aria-hidden": "true" }), _jsx("h2", { id: "wbi-title", children: request.title }), _jsx("p", { children: request.detail }), _jsx("div", { className: "wbi-state-actions", children: _jsx("button", { className: classes.secondary, onClick: controller.close, children: t('wb.install.cancel') }) })] }), (request.status === 'ready' || request.status === 'installing') && _jsx(Ready, { request: request, props: props }), request.status === 'done' && _jsx(Done, { request: request, props: props }), request.status === 'error' && _jsxs("div", { className: "wbi-state", children: [_jsx("div", { className: "wbi-state-icon is-warn", children: _jsx(Glyph, { d: G.warn, size: 26 }) }), _jsx("h2", { id: "wbi-title", children: request.title }), _jsx("p", { children: request.message }), _jsx("div", { className: "wbi-state-actions", children: _jsx("button", { className: classes.primary, autoFocus: true, onClick: controller.close, children: t('wb.install.close') }) })] })] }) }), document.body);
|
|
116
|
+
}
|
|
117
|
+
const hasFiles = (event) => Array.from(event.dataTransfer?.types ?? []).includes('Files');
|
|
118
|
+
/**
|
|
119
|
+
* Install links, the screen, and file drops on the window. A file dragged over the shell (tab
|
|
120
|
+
* strip, titlebar, settings) shows a drop target over the whole window; files dragged straight into
|
|
121
|
+
* a site tab stay the site's (e.g. images for a post).
|
|
122
|
+
*/
|
|
123
|
+
export function InstallHost(props) {
|
|
124
|
+
const { t, controller, setOverlay, ownDropTargets } = props;
|
|
125
|
+
const shared = { ...props, classes: { ...DEFAULT_CLASSES, ...props.classNames } };
|
|
126
|
+
const request = useInstallRequest(controller);
|
|
127
|
+
const [dropping, setDropping] = useState(false);
|
|
128
|
+
useEffect(() => controller.start(), [controller]);
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
let last = 0;
|
|
131
|
+
let timer;
|
|
132
|
+
const own = (event) => Boolean(ownDropTargets && event.target?.closest?.(ownDropTargets));
|
|
133
|
+
const stop = () => { clearInterval(timer); timer = undefined; setDropping(false); };
|
|
134
|
+
const over = (event) => {
|
|
135
|
+
if (!hasFiles(event) || own(event))
|
|
136
|
+
return;
|
|
137
|
+
event.preventDefault();
|
|
138
|
+
if (event.dataTransfer)
|
|
139
|
+
event.dataTransfer.dropEffect = 'copy';
|
|
140
|
+
last = Date.now();
|
|
141
|
+
if (!timer) {
|
|
142
|
+
setDropping(true);
|
|
143
|
+
// Esc or leaving the window ends a drag without an event here.
|
|
144
|
+
timer = setInterval(() => { if (Date.now() - last > 900)
|
|
145
|
+
stop(); }, 200);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const drop = (event) => {
|
|
149
|
+
if (!hasFiles(event) || own(event))
|
|
150
|
+
return;
|
|
151
|
+
event.preventDefault();
|
|
152
|
+
stop();
|
|
153
|
+
const file = event.dataTransfer?.files[0];
|
|
154
|
+
if (file)
|
|
155
|
+
void controller.requestFile(file);
|
|
156
|
+
};
|
|
157
|
+
window.addEventListener('dragenter', over, true);
|
|
158
|
+
window.addEventListener('dragover', over, true);
|
|
159
|
+
window.addEventListener('drop', drop, true);
|
|
160
|
+
return () => { stop(); window.removeEventListener('dragenter', over, true); window.removeEventListener('dragover', over, true); window.removeEventListener('drop', drop, true); };
|
|
161
|
+
}, [controller, ownDropTargets]);
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (!dropping)
|
|
164
|
+
return;
|
|
165
|
+
setOverlay(1);
|
|
166
|
+
return () => setOverlay(-1);
|
|
167
|
+
}, [dropping]);
|
|
168
|
+
return _jsxs(_Fragment, { children: [dropping && createPortal(_jsx("div", { className: "wbi-drop", "aria-hidden": "true", children: _jsxs("div", { children: [_jsx(Glyph, { d: G.file, size: 30 }), _jsx("strong", { children: t('wb.install.drop') }), _jsx("span", { children: t('wb.install.dropHint') })] }) }), document.body), request && _jsx(Dialog, { request: request, props: shared })] });
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=InstallDialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InstallDialog.js","sourceRoot":"","sources":["../../../../../shell/src/InstallDialog.tsx"],"names":[],"mappings":"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","sourcesContent":["// The install screen, shared by every wayBetter app: every theme or plugin that is not copied into\n// the plugins folder by hand (a waybetter:// link, a dropped file, the Store) is shown here first\n// with its name, author, version, where it came from, its sha256, the permissions a plugin declares\n// and the exact code or CSS that will be written. Nothing installs until Install is pressed (enabled\n// after a moment, so a stray click or Enter cannot confirm it). Lives in the shell; the app hides\n// its tab webviews while it is open (`setOverlay`). Styles: `store.css` (framework `--wb-*` tokens).\n\nimport { useEffect, useRef, useState, useSyncExternalStore, type KeyboardEvent, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { InstallController, InstallRequest } from './installController.ts';\nimport type { StoreText } from './storeMessages.ts';\nimport { formatBytes, permissionBadges, previewLines, type InstallKind, type InstallPreview } from './storeModel.ts';\nimport { coveragePercent, type StringsSummary } from './stringPacksModel.ts';\n\n/** Milliseconds before Install can be pressed (native code refuses a commit faster than 600 ms). */\nexport const REVIEW_MS = 1000;\nconst PREVIEW_LINES = 160;\n\n/** Class names for the app's own buttons (defaults: the framework's `.wb-btn`). */\nexport type InstallClassNames = { primary: string; secondary: string; icon: string; pop: string };\nconst DEFAULT_CLASSES: InstallClassNames = { primary: 'wb-btn is-primary', secondary: 'wb-btn', icon: 'wb-icon-btn', pop: '' };\n\nexport type InstallHostProps<Theme> = {\n controller: InstallController<Theme>;\n t: StoreText;\n /** The site's name in messages (\"X\"). */\n site: string;\n /** Shows or hides the app's tab webviews under the screen (+1 when it opens, -1 when it closes). */\n setOverlay(delta: 1 | -1): void;\n /** \"Open Plugins\" / \"Open Appearance\" after an install. */\n openSection(kind: InstallKind): void;\n /** A live preview of a staged theme (the app's theme preview). */\n renderThemePreview?(theme: Theme): ReactNode;\n /** A string pack's coverage against the site's inventory (the app has the inventory). */\n stringsSummary?(text: string): StringsSummary | null;\n /** Drops on elements matching this selector are handled by them (e.g. an import box). */\n ownDropTargets?: string;\n closeIcon?: ReactNode;\n classNames?: Partial<InstallClassNames>;\n};\n\n/** Re-renders with the controller's current request. */\nexport function useInstallRequest<Theme>(controller: InstallController<Theme>): InstallRequest<Theme> | null {\n return useSyncExternalStore(controller.subscribe, controller.current, controller.current);\n}\n\nfunction Glyph({ d, size = 18 }: { d: string; size?: number }) {\n return <svg width={size} height={size} viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d={d} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.7\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/></svg>;\n}\nconst G = {\n plugin: 'M9 3v5M15 3v5M6 8h12v3a6 6 0 0 1-12 0zM12 17v4',\n theme: 'M12 3a9 9 0 1 0 0 18c1.5 0 2-1 2-1.8 0-1.2-.9-1.5-.9-2.5 0-1 .8-1.7 1.8-1.7h2A4.2 4.2 0 0 0 21 10.8 8.8 8.8 0 0 0 12 3zM7.5 11h.01M10.5 7.5h.01M15 8h.01',\n shield: 'M12 3l7 3v5c0 4.6-3 8.5-7 10-4-1.5-7-5.4-7-10V6z',\n check: 'M5 12.5l4.2 4.2L19 7',\n link: 'M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1',\n file: 'M7 3h7l5 5v13H7zM14 3v5h5',\n warn: 'M12 4l9 16H3zM12 10v4M12 17h.01',\n copy: 'M9 9h10v10H9zM5 15V5h10',\n close: 'M6 6l12 12M18 6L6 18',\n strings: 'M4 5h9M8.5 3v2M11 5c-.8 3.8-3.4 6.6-7 8M6.5 8.5c1.1 1.6 2.7 3 4.5 3.8M13 21l4-9 4 9M14.4 18h5.2',\n};\n\nfunction Fact({ label, children, wide }: { label: string; children: ReactNode; wide?: boolean }) {\n return <div className={`wbi-fact${wide ? ' is-wide' : ''}`}><dt>{label}</dt><dd>{children}</dd></div>;\n}\n\nfunction CodePreview({ text, label, t }: { text: string; label: string; t: StoreText }) {\n const [all, setAll] = useState(false);\n const { lines, hidden } = previewLines(text, PREVIEW_LINES, all);\n return <section className=\"wbi-code\" aria-label={label}>\n <header><span>{label}</span><small>{t('wb.install.lines', { count: text.split('\\n').length })}</small></header>\n <pre tabIndex={0}><code>{lines.map((line, i) => <span key={i} className=\"wbi-line\"><i>{i + 1}</i>{line || ' '}</span>)}</code></pre>\n {hidden > 0 && <button className=\"wbi-more\" onClick={() => setAll(true)}>{t('wb.install.moreLines', { count: hidden })}</button>}\n </section>;\n}\n\nfunction sourceIcon(preview: InstallPreview) {\n return preview.source.kind === 'store' ? G.shield : preview.source.kind === 'link' ? G.link : G.file;\n}\n\n/** Where it comes from, in the owner's language (native code's `label` is English). */\nfunction sourceLabel(source: InstallPreview['source'], t: StoreText): string {\n if (source.kind === 'store') return t('wb.install.source.store');\n if (source.kind === 'link') {\n let host = '';\n try { host = new URL(source.url ?? '').hostname; } catch { /* no host */ }\n return t('wb.install.source.link', { host });\n }\n return t('wb.install.source.file');\n}\n\ntype Shared<Theme> = Omit<InstallHostProps<Theme>, 'classNames'> & { classes: InstallClassNames };\n\nfunction Ready<Theme>({ request, props }: { request: Extract<InstallRequest<Theme>, { status: 'ready' | 'installing' }>; props: Shared<Theme> }) {\n const { t, site, controller, classes } = props;\n const preview = request.preview;\n const ready = request.status === 'ready' ? request : null;\n const theme = ready ? ready.theme : null;\n const facts = theme !== null ? controller.facts(theme) : null;\n const plugin = preview.plugin;\n const [armed, setArmed] = useState(false);\n // On by default only when it is from the signed store or declares its permissions and the code\n // scan found nothing to point out; otherwise the owner turns it on deliberately.\n const [enable, setEnable] = useState(preview.kind === 'theme' || preview.kind === 'strings' || (!preview.existing && (preview.source.signed || (preview.plugin?.permissions != null && preview.findings.length === 0))));\n const [copied, setCopied] = useState(false);\n useEffect(() => { const timer = setTimeout(() => setArmed(true), REVIEW_MS); return () => clearTimeout(timer); }, [preview.token]);\n const strings = preview.kind === 'strings' ? preview.strings ?? null : null;\n const summary = strings ? props.stringsSummary?.(preview.text) ?? null : null;\n const name = plugin?.name ?? facts?.name ?? preview.theme?.name ?? strings?.name ?? t('wb.install.untitled');\n const author = plugin?.author || facts?.author || preview.theme?.author || strings?.authors.join(', ') || '';\n const version = preview.version || preview.store?.version || '';\n const updating = preview.existing && !preview.existing.same;\n const verb = preview.existing?.same ? t('wb.install.reinstall') : updating || ready?.replaces ? t('wb.install.update') : t('wb.store.install');\n const step = preview.existing?.same ? 'reinstall' : updating || ready?.replaces ? 'update' : 'install';\n const eyebrow = preview.kind === 'strings' ? t(`wb.install.eyebrow.strings.${step}`) : t(`wb.install.eyebrow.${step}`, { kind: preview.kind });\n const badges = preview.kind === 'plugin' ? permissionBadges(plugin?.permissions, t, site) : [];\n const installing = request.status === 'installing';\n const description = plugin?.description || facts?.description || strings?.description;\n return <>\n <header className=\"wbi-head\">\n <div className={`wbi-tile is-${preview.kind}`} style={facts?.tile ? { background: facts.tile.background, color: facts.tile.color, boxShadow: `inset 0 0 0 1px ${facts.tile.border}` } : undefined}>\n <Glyph d={preview.kind === 'plugin' ? G.plugin : preview.kind === 'strings' ? G.strings : G.theme} size={22}/>\n </div>\n <div className=\"wbi-title\">\n <span className=\"wbi-eyebrow\">{eyebrow}</span>\n <h2 id=\"wbi-title\">{name}</h2>\n <p>{[author && t('wb.store.by', { author }), version && `v${version}`].filter(Boolean).join(' · ') || t('wb.install.noAuthor')}</p>\n </div>\n <button className={`${classes.icon} wbi-close`} aria-label={t('wb.install.cancel')} onClick={() => void controller.cancel()}>{props.closeIcon ?? <Glyph d={G.close} size={16}/>}</button>\n </header>\n\n <div className=\"wbi-body\">\n <div className={`wbi-source is-${preview.source.kind}`}>\n <Glyph d={sourceIcon(preview)}/>\n <div>\n <strong>{sourceLabel(preview.source, t)}</strong>\n {preview.source.url && <code title={preview.source.url}>{preview.source.url}</code>}\n </div>\n {preview.source.signed && <span className=\"wbi-verified\"><Glyph d={G.check} size={14}/>{t('wb.install.verified')}</span>}\n </div>\n\n {description && <p className=\"wbi-desc\">{description}</p>}\n\n <dl className=\"wbi-facts\">\n {preview.file && <Fact label={t('wb.install.file')}>{preview.file}</Fact>}\n <Fact label={t('wb.install.size')}>{formatBytes(preview.size)}</Fact>\n {preview.existing && <Fact label={t('wb.install.installedNow')}>{preview.existing.same ? t('wb.install.identical', { version: preview.existing.version || '?' }) : `v${preview.existing.version || '?'}${preview.existing.enabled ? ` · ${t('wb.install.on')}` : ''}`}</Fact>}\n {ready?.replaces && <Fact label={t('wb.install.replaces')}>{t('wb.install.replacesValue')}</Fact>}\n {preview.store?.license && <Fact label={t('wb.install.license')}>{preview.store.license}</Fact>}\n {preview.store?.credits && <Fact label={t('wb.install.credits')} wide>{preview.store.credits}</Fact>}\n <Fact label=\"SHA-256\" wide>\n <span className=\"wbi-hash\">{preview.sha256}</span>\n <button className=\"wbi-copy\" aria-label={t('wb.install.copyHash')} onClick={() => void navigator.clipboard?.writeText(preview.sha256).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1400); }).catch(() => {})}>\n <Glyph d={copied ? G.check : G.copy} size={14}/>\n </button>\n </Fact>\n </dl>\n\n {preview.kind === 'plugin' && <section className=\"wbi-perms\" aria-label={t('wb.store.permissions')}>\n <h3>{t('wb.install.permissions')}</h3>\n <ul>\n {badges.map(badge => <li key={badge.id} className={`is-${badge.tone}`}><span className=\"wbi-chip\">{badge.label}</span><span>{badge.detail}</span></li>)}\n </ul>\n <p className=\"wbi-note\"><Glyph d={G.warn} size={14}/>{t('wb.install.pageAccess', { site })}</p>\n {preview.findings.length > 0 && <div className=\"wbi-findings\"><strong>{t('wb.install.theCode')}</strong>{preview.findings.map(finding => <span key={finding}>{finding}</span>)}</div>}\n </section>}\n\n {strings && <section className=\"wbi-perms wbi-strings\" aria-label={t('wb.store.stringsItem')}>\n <p className=\"wbi-note is-ok\"><Glyph d={G.check} size={14}/>{t('wb.install.strings.dataOnly', { site })}</p>\n <dl className=\"wbi-facts\">\n <Fact label={t('wb.install.strings.language')}>{strings.language}</Fact>\n <Fact label={t('wb.install.strings.coverage')} wide>\n {summary && !summary.otherCatalog\n ? t('wb.install.strings.coverageValue', { translated: String(summary.translated), translatable: String(summary.translatable), site, percent: coveragePercent(summary) })\n : t('wb.install.strings.count', { count: strings.strings })}\n </Fact>\n </dl>\n {summary?.otherCatalog && <p className=\"wbi-note\"><Glyph d={G.warn} size={14}/>{t('wb.install.strings.otherCatalog', { site })}</p>}\n {summary && !summary.otherCatalog && <ul className=\"wbi-strings-notes\">\n {summary.closed > 0 && <li>{t('wb.install.strings.closed', { count: summary.closed, site })}</li>}\n {summary.unknown > 0 && <li>{t('wb.install.strings.unknown', { count: summary.unknown, site })}</li>}\n {summary.refused > 0 && <li>{t('wb.install.strings.refused', { count: summary.refused, site })}</li>}\n </ul>}\n {summary && summary.sample.length > 0 && <div className=\"wbi-findings\"><strong>{t('wb.install.strings.sample')}</strong>{summary.sample.map(text => <span key={text}>{text}</span>)}</div>}\n </section>}\n\n {theme !== null && <section className=\"wbi-theme\">\n {props.renderThemePreview?.(theme)}\n {(ready?.warnings.length ?? 0) > 0 && <ul className=\"wbi-warnings\">{ready!.warnings.map(warning => <li key={warning}>{warning}</li>)}</ul>}\n </section>}\n\n {facts?.css ? <CodePreview t={t} text={facts.css} label={t('wb.install.themeCss', { site })}/> : null}\n <CodePreview t={t} text={preview.text} label={preview.kind === 'plugin' ? t('wb.install.code') : preview.kind === 'strings' ? t('wb.install.strings.file') : t('wb.install.themeFile')}/>\n </div>\n\n <footer className=\"wbi-foot\">\n <label className=\"wbi-check\">\n <input type=\"checkbox\" checked={enable} disabled={installing || Boolean(preview.existing?.enabled)} onChange={event => setEnable(event.target.checked)}/>\n <span>{preview.kind === 'plugin' ? (preview.existing?.enabled ? t('wb.install.staysOn') : t('wb.install.turnOn')) : t('wb.install.useNow')}</span>\n </label>\n <span className=\"wbi-foot-end\"/>\n <button className={classes.secondary} onClick={() => void controller.cancel()} disabled={installing}>{t('wb.install.cancel')}</button>\n <button className={`${classes.primary} wbi-install${armed ? '' : ' is-arming'}`} disabled={!armed || installing} onClick={() => void controller.confirm(enable)}>\n {installing ? t('wb.install.installing') : verb}\n </button>\n </footer>\n </>;\n}\n\nfunction Done<Theme>({ request, props }: { request: Extract<InstallRequest<Theme>, { status: 'done' }>; props: Shared<Theme> }) {\n const { t, site, controller, classes } = props;\n return <div className=\"wbi-state\">\n <div className=\"wbi-state-icon is-ok\"><Glyph d={G.check} size={26}/></div>\n <h2 id=\"wbi-title\">{t('wb.install.done', { name: request.name })}</h2>\n <p>{request.kind === 'plugin'\n ? (request.enabled ? t('wb.install.done.pluginOn', { site }) : t('wb.install.done.pluginOff'))\n : request.kind === 'strings'\n ? (request.enabled ? t('wb.install.done.stringsOn', { site }) : t('wb.install.done.stringsOff'))\n : (request.enabled ? t('wb.install.done.themeOn') : t('wb.install.done.themeOff'))}</p>\n {request.fonts.length > 0 && <p className=\"wbi-muted\">{t('wb.install.done.fonts', { fonts: request.fonts.join(', ') })}</p>}\n <div className=\"wbi-state-actions\">\n <button className={classes.secondary} onClick={() => { controller.close(); props.openSection(request.kind); }}>{request.kind === 'plugin' ? t('wb.install.openPlugins') : request.kind === 'strings' ? t('wb.install.openStrings') : t('wb.install.openAppearance')}</button>\n <button className={classes.primary} autoFocus onClick={controller.close}>{t('wb.install.doneButton')}</button>\n </div>\n </div>;\n}\n\nfunction Dialog<Theme>({ request, props }: { request: InstallRequest<Theme>; props: Shared<Theme> }) {\n const { t, controller, classes, setOverlay } = props;\n const box = useRef<HTMLDivElement>(null);\n useEffect(() => {\n setOverlay(1);\n return () => setOverlay(-1);\n }, []);\n useEffect(() => { box.current?.querySelector<HTMLElement>('.wbi-close, [autofocus]')?.focus(); }, [request.status]);\n const dismiss = () => (request.status === 'ready' ? void controller.cancel() : request.status === 'installing' ? undefined : controller.close());\n const onKey = (event: KeyboardEvent) => {\n if (event.key === 'Escape') { event.preventDefault(); dismiss(); }\n // Enter never confirms an install; only a click on Install does.\n if (event.key === 'Enter' && (event.target as HTMLElement).classList.contains('wbi-install')) event.preventDefault();\n };\n return createPortal(<div className=\"wbi-backdrop\" onMouseDown={dismiss}>\n <div ref={box} className={`wbi ${classes.pop} is-${request.status}`.replace(/\\s+/g, ' ')} role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"wbi-title\" onMouseDown={event => event.stopPropagation()} onKeyDown={onKey}>\n {request.status === 'loading' && <div className=\"wbi-state\">\n <div className=\"wbi-spinner\" aria-hidden=\"true\"/>\n <h2 id=\"wbi-title\">{request.title}</h2>\n <p>{request.detail}</p>\n <div className=\"wbi-state-actions\"><button className={classes.secondary} onClick={controller.close}>{t('wb.install.cancel')}</button></div>\n </div>}\n {(request.status === 'ready' || request.status === 'installing') && <Ready request={request} props={props}/>}\n {request.status === 'done' && <Done request={request} props={props}/>}\n {request.status === 'error' && <div className=\"wbi-state\">\n <div className=\"wbi-state-icon is-warn\"><Glyph d={G.warn} size={26}/></div>\n <h2 id=\"wbi-title\">{request.title}</h2>\n <p>{request.message}</p>\n <div className=\"wbi-state-actions\"><button className={classes.primary} autoFocus onClick={controller.close}>{t('wb.install.close')}</button></div>\n </div>}\n </div>\n </div>, document.body);\n}\n\nconst hasFiles = (event: DragEvent) => Array.from(event.dataTransfer?.types ?? []).includes('Files');\n\n/**\n * Install links, the screen, and file drops on the window. A file dragged over the shell (tab\n * strip, titlebar, settings) shows a drop target over the whole window; files dragged straight into\n * a site tab stay the site's (e.g. images for a post).\n */\nexport function InstallHost<Theme>(props: InstallHostProps<Theme>) {\n const { t, controller, setOverlay, ownDropTargets } = props;\n const shared: Shared<Theme> = { ...props, classes: { ...DEFAULT_CLASSES, ...props.classNames } };\n const request = useInstallRequest(controller);\n const [dropping, setDropping] = useState(false);\n useEffect(() => controller.start(), [controller]);\n useEffect(() => {\n let last = 0;\n let timer: ReturnType<typeof setInterval> | undefined;\n const own = (event: DragEvent) => Boolean(ownDropTargets && (event.target as Element | null)?.closest?.(ownDropTargets));\n const stop = () => { clearInterval(timer); timer = undefined; setDropping(false); };\n const over = (event: DragEvent) => {\n if (!hasFiles(event) || own(event)) return;\n event.preventDefault();\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';\n last = Date.now();\n if (!timer) {\n setDropping(true);\n // Esc or leaving the window ends a drag without an event here.\n timer = setInterval(() => { if (Date.now() - last > 900) stop(); }, 200);\n }\n };\n const drop = (event: DragEvent) => {\n if (!hasFiles(event) || own(event)) return;\n event.preventDefault();\n stop();\n const file = event.dataTransfer?.files[0];\n if (file) void controller.requestFile(file);\n };\n window.addEventListener('dragenter', over, true);\n window.addEventListener('dragover', over, true);\n window.addEventListener('drop', drop, true);\n return () => { stop(); window.removeEventListener('dragenter', over, true); window.removeEventListener('dragover', over, true); window.removeEventListener('drop', drop, true); };\n }, [controller, ownDropTargets]);\n useEffect(() => {\n if (!dropping) return;\n setOverlay(1);\n return () => setOverlay(-1);\n }, [dropping]);\n return <>\n {dropping && createPortal(<div className=\"wbi-drop\" aria-hidden=\"true\"><div>\n <Glyph d={G.file} size={30}/>\n <strong>{t('wb.install.drop')}</strong>\n <span>{t('wb.install.dropHint')}</span>\n </div></div>, document.body)}\n {request && <Dialog request={request} props={shared}/>}\n </>;\n}\n"]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { InstallController } from './installController.ts';
|
|
3
|
+
import type { StoreText } from './storeMessages.ts';
|
|
4
|
+
import { type StoreCatalogView, type StoreItem } from './storeModel.ts';
|
|
5
|
+
type ButtonProps = {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
onClick?(): void;
|
|
8
|
+
tone?: 'plain' | 'primary' | 'ghost' | 'danger';
|
|
9
|
+
size?: 'sm' | 'md';
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
title?: string;
|
|
12
|
+
};
|
|
13
|
+
type Option<T extends string> = {
|
|
14
|
+
value: T;
|
|
15
|
+
label: string;
|
|
16
|
+
};
|
|
17
|
+
export type StoreControls = {
|
|
18
|
+
Button(props: ButtonProps): ReactNode;
|
|
19
|
+
SearchField(props: {
|
|
20
|
+
value: string;
|
|
21
|
+
onChange(next: string): void;
|
|
22
|
+
placeholder: string;
|
|
23
|
+
label: string;
|
|
24
|
+
}): ReactNode;
|
|
25
|
+
Segmented<T extends string>(props: {
|
|
26
|
+
value: T;
|
|
27
|
+
options: Array<Option<T>>;
|
|
28
|
+
onChange(next: T): void;
|
|
29
|
+
label: string;
|
|
30
|
+
size?: 'sm' | 'md';
|
|
31
|
+
}): ReactNode;
|
|
32
|
+
EmptyState(props: {
|
|
33
|
+
icon?: ReactNode;
|
|
34
|
+
title: string;
|
|
35
|
+
children?: ReactNode;
|
|
36
|
+
action?: ReactNode;
|
|
37
|
+
}): ReactNode;
|
|
38
|
+
Badge(props: {
|
|
39
|
+
children: ReactNode;
|
|
40
|
+
}): ReactNode;
|
|
41
|
+
};
|
|
42
|
+
export declare const DEFAULT_CONTROLS: StoreControls;
|
|
43
|
+
export type StoreViewProps<Theme> = {
|
|
44
|
+
t: StoreText;
|
|
45
|
+
/** The site's name in messages ("X"). */
|
|
46
|
+
site: string;
|
|
47
|
+
/** `store_catalog` (the app passes `refresh => invoke('store_catalog', { refresh })`). */
|
|
48
|
+
load(refresh: boolean): Promise<StoreCatalogView>;
|
|
49
|
+
/** The install screen's controller: Install opens it; the list refreshes when it closes. */
|
|
50
|
+
controller: InstallController<Theme>;
|
|
51
|
+
/** Theme ids that ship with the app, and the owner's own theme ids now. */
|
|
52
|
+
builtinThemes: readonly string[];
|
|
53
|
+
userThemes: readonly string[];
|
|
54
|
+
/** Removes an installed item (plugin file, or the owner's copy of a store theme); false: nothing to remove. */
|
|
55
|
+
onRemove(item: StoreItem, view: StoreCatalogView): Promise<boolean>;
|
|
56
|
+
/** Makes a built-in theme the current one. */
|
|
57
|
+
onUse(item: StoreItem): Promise<void>;
|
|
58
|
+
notify(text: string, error?: boolean): void;
|
|
59
|
+
/** "3 minutes ago" for a timestamp (the app's relative-time formatter). */
|
|
60
|
+
relativeTime(at: number): string;
|
|
61
|
+
/** Window events after which the list reloads (e.g. the app's "plugins changed"). */
|
|
62
|
+
reloadOn?: readonly string[];
|
|
63
|
+
controls?: Partial<StoreControls>;
|
|
64
|
+
};
|
|
65
|
+
export declare function StoreView<Theme>(props: StoreViewProps<Theme>): import("react").JSX.Element;
|
|
66
|
+
export {};
|