waybetter 0.6.0 → 0.7.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.
Files changed (190) hide show
  1. package/README.md +1 -2
  2. package/bin/waybetter.mjs +2 -5
  3. package/cli/buildenv.mjs +1 -1
  4. package/cli/release.mjs +11 -18
  5. package/cli/releasecheck.mjs +15 -0
  6. package/cli/remote.mjs +4 -4
  7. package/cli/store.mjs +80 -28
  8. package/cli/strings.mjs +2 -0
  9. package/dist/runtime/stringPackHook.js +2 -2
  10. package/dist/runtime/stringPackHook.js.map +1 -1
  11. package/dist/runtime/stringPackTranslate.d.ts +3 -1
  12. package/dist/runtime/stringPackTranslate.js +6 -3
  13. package/dist/runtime/stringPackTranslate.js.map +1 -1
  14. package/dist/runtime/stringPacks.d.ts +53 -5
  15. package/dist/runtime/stringPacks.js +161 -25
  16. package/dist/runtime/stringPacks.js.map +1 -1
  17. package/dist/runtime/themeBar.d.ts +28 -0
  18. package/dist/runtime/themeBar.js +82 -0
  19. package/dist/runtime/themeBar.js.map +1 -0
  20. package/dist/runtime/themeComponents.js +16 -3
  21. package/dist/runtime/themeComponents.js.map +1 -1
  22. package/dist/runtime/themeDecor.js +3 -1
  23. package/dist/runtime/themeDecor.js.map +1 -1
  24. package/dist/runtime/themeDerive.d.ts +69 -0
  25. package/dist/runtime/themeDerive.js +117 -0
  26. package/dist/runtime/themeDerive.js.map +1 -0
  27. package/dist/runtime/themeDoctor.d.ts +44 -3
  28. package/dist/runtime/themeDoctor.js +86 -25
  29. package/dist/runtime/themeDoctor.js.map +1 -1
  30. package/dist/runtime/themeGuards.d.ts +60 -0
  31. package/dist/runtime/themeGuards.js +235 -0
  32. package/dist/runtime/themeGuards.js.map +1 -0
  33. package/dist/runtime/themeIcons.d.ts +1 -1
  34. package/dist/runtime/themeIcons.js +13 -5
  35. package/dist/runtime/themeIcons.js.map +1 -1
  36. package/dist/runtime/themeInk.d.ts +37 -0
  37. package/dist/runtime/themeInk.js +111 -0
  38. package/dist/runtime/themeInk.js.map +1 -0
  39. package/dist/runtime/themeInvariants.d.ts +39 -0
  40. package/dist/runtime/themeInvariants.js +273 -0
  41. package/dist/runtime/themeInvariants.js.map +1 -0
  42. package/dist/runtime/themeRuntime.d.ts +15 -1
  43. package/dist/runtime/themeRuntime.js +78 -5
  44. package/dist/runtime/themeRuntime.js.map +1 -1
  45. package/dist/runtime/themeSpec.d.ts +5 -1
  46. package/dist/runtime/themeSpec.js +9 -13
  47. package/dist/runtime/themeSpec.js.map +1 -1
  48. package/dist/shell/InstallDialog.js +14 -8
  49. package/dist/shell/InstallDialog.js.map +1 -1
  50. package/dist/shell/StoreView.d.ts +12 -0
  51. package/dist/shell/StoreView.js +9 -4
  52. package/dist/shell/StoreView.js.map +1 -1
  53. package/dist/shell/frame/AppMenu.d.ts +26 -3
  54. package/dist/shell/frame/AppMenu.js +106 -27
  55. package/dist/shell/frame/AppMenu.js.map +1 -1
  56. package/dist/shell/frame/FindBar.js +1 -1
  57. package/dist/shell/frame/FindBar.js.map +1 -1
  58. package/dist/shell/frame/Shell.d.ts +1 -0
  59. package/dist/shell/frame/Shell.js +10 -2
  60. package/dist/shell/frame/Shell.js.map +1 -1
  61. package/dist/shell/frame/Titlebar.d.ts +2 -1
  62. package/dist/shell/frame/Titlebar.js +5 -3
  63. package/dist/shell/frame/Titlebar.js.map +1 -1
  64. package/dist/shell/frame/WebPanel.js +4 -1
  65. package/dist/shell/frame/WebPanel.js.map +1 -1
  66. package/dist/shell/frame/accountSwitcher.css +10 -10
  67. package/dist/shell/frame/appMenu.css +19 -13
  68. package/dist/shell/frame/boot.js +2 -0
  69. package/dist/shell/frame/boot.js.map +1 -1
  70. package/dist/shell/frame/chromeTheme.d.ts +19 -1
  71. package/dist/shell/frame/chromeTheme.js +51 -14
  72. package/dist/shell/frame/chromeTheme.js.map +1 -1
  73. package/dist/shell/frame/deck.css +30 -30
  74. package/dist/shell/frame/edges.css +159 -0
  75. package/dist/shell/frame/index.d.ts +2 -2
  76. package/dist/shell/frame/index.js +1 -1
  77. package/dist/shell/frame/index.js.map +1 -1
  78. package/dist/shell/frame/mediaModel.d.ts +13 -0
  79. package/dist/shell/frame/mediaModel.js +14 -0
  80. package/dist/shell/frame/mediaModel.js.map +1 -1
  81. package/dist/shell/frame/menuMessages.en.json +43 -1
  82. package/dist/shell/frame/menuModel.d.ts +42 -0
  83. package/dist/shell/frame/menuModel.js +8 -0
  84. package/dist/shell/frame/menuModel.js.map +1 -1
  85. package/dist/shell/frame/nativeMenu.d.ts +5 -0
  86. package/dist/shell/frame/nativeMenu.js +178 -0
  87. package/dist/shell/frame/nativeMenu.js.map +1 -0
  88. package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
  89. package/dist/shell/frame/nativeMenuModel.js +186 -0
  90. package/dist/shell/frame/nativeMenuModel.js.map +1 -0
  91. package/dist/shell/frame/paletteModel.js +3 -1
  92. package/dist/shell/frame/paletteModel.js.map +1 -1
  93. package/dist/shell/frame/paneTheme.css +1 -1
  94. package/dist/shell/frame/reportModel.d.ts +1 -1
  95. package/dist/shell/frame/reportModel.js +1 -1
  96. package/dist/shell/frame/reportModel.js.map +1 -1
  97. package/dist/shell/frame/shell.css +56 -51
  98. package/dist/shell/frame/state.d.ts +2 -0
  99. package/dist/shell/frame/state.js +3 -1
  100. package/dist/shell/frame/state.js.map +1 -1
  101. package/dist/shell/frame/themeStore.js +21 -6
  102. package/dist/shell/frame/themeStore.js.map +1 -1
  103. package/dist/shell/frame/workspaces.css +12 -12
  104. package/dist/shell/installController.d.ts +16 -1
  105. package/dist/shell/installController.js +31 -5
  106. package/dist/shell/installController.js.map +1 -1
  107. package/dist/shell/panel/Appearance.js +12 -3
  108. package/dist/shell/panel/Appearance.js.map +1 -1
  109. package/dist/shell/panel/Settings.d.ts +1 -1
  110. package/dist/shell/panel/Settings.js +4 -3
  111. package/dist/shell/panel/Settings.js.map +1 -1
  112. package/dist/shell/panel/StoreSection.d.ts +2 -1
  113. package/dist/shell/panel/StoreSection.js +31 -1
  114. package/dist/shell/panel/StoreSection.js.map +1 -1
  115. package/dist/shell/panel/StringPacks.d.ts +12 -3
  116. package/dist/shell/panel/StringPacks.js +33 -8
  117. package/dist/shell/panel/StringPacks.js.map +1 -1
  118. package/dist/shell/panel/backup.css +1 -1
  119. package/dist/shell/panel/builder.css +48 -40
  120. package/dist/shell/panel/make.css +8 -7
  121. package/dist/shell/panel/panel.css +401 -401
  122. package/dist/shell/panel/panelMessages.d.ts +41 -1
  123. package/dist/shell/panel/panelMessages.js +13 -1
  124. package/dist/shell/panel/panelMessages.js.map +1 -1
  125. package/dist/shell/panel/plugins.css +5 -5
  126. package/dist/shell/panel/strings.css +1 -1
  127. package/dist/shell/store.css +34 -14
  128. package/dist/shell/storeMessages.d.ts +24 -0
  129. package/dist/shell/storeMessages.js +24 -0
  130. package/dist/shell/storeMessages.js.map +1 -1
  131. package/dist/shell/storeModel.d.ts +31 -7
  132. package/dist/shell/storeModel.js +15 -2
  133. package/dist/shell/storeModel.js.map +1 -1
  134. package/dist/shell/stringPacksModel.js +7 -2
  135. package/dist/shell/stringPacksModel.js.map +1 -1
  136. package/icons.schema.json +9 -0
  137. package/locales/ar.json +109 -2
  138. package/locales/bg.json +109 -2
  139. package/locales/bn.json +109 -2
  140. package/locales/ca.json +109 -2
  141. package/locales/cs.json +109 -2
  142. package/locales/da.json +109 -2
  143. package/locales/de.json +109 -2
  144. package/locales/el.json +109 -2
  145. package/locales/en.json +108 -2
  146. package/locales/es.json +109 -2
  147. package/locales/eu.json +109 -2
  148. package/locales/fa.json +109 -2
  149. package/locales/fi.json +109 -2
  150. package/locales/fil.json +109 -2
  151. package/locales/fr.json +109 -2
  152. package/locales/ga.json +109 -2
  153. package/locales/gl.json +109 -2
  154. package/locales/gu.json +109 -2
  155. package/locales/ha.json +109 -2
  156. package/locales/he.json +109 -2
  157. package/locales/hi.json +109 -2
  158. package/locales/hr.json +109 -2
  159. package/locales/hu.json +110 -2
  160. package/locales/id.json +109 -2
  161. package/locales/ig.json +109 -2
  162. package/locales/it.json +109 -2
  163. package/locales/ja.json +109 -2
  164. package/locales/kn.json +109 -2
  165. package/locales/ko.json +109 -2
  166. package/locales/mr.json +109 -2
  167. package/locales/ms.json +109 -2
  168. package/locales/nb.json +109 -2
  169. package/locales/nl.json +109 -2
  170. package/locales/pl.json +109 -2
  171. package/locales/pt.json +109 -2
  172. package/locales/ro.json +109 -2
  173. package/locales/ru.json +109 -2
  174. package/locales/sk.json +109 -2
  175. package/locales/sr.json +109 -2
  176. package/locales/sv.json +109 -2
  177. package/locales/ta.json +109 -2
  178. package/locales/th.json +109 -2
  179. package/locales/tr.json +109 -2
  180. package/locales/uk.json +109 -2
  181. package/locales/ur.json +109 -2
  182. package/locales/vi.json +109 -2
  183. package/locales/yo.json +109 -2
  184. package/locales/zh-Hans.json +109 -2
  185. package/locales/zh-Hant.json +109 -2
  186. package/package.json +2 -3
  187. package/store-catalog.schema.json +18 -5
  188. package/theme.schema.json +9 -0
  189. package/windows/installer.nsi +22 -2
  190. package/cli/privacy.mjs +0 -768
@@ -1 +1 @@
1
- {"version":3,"file":"Titlebar.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/Titlebar.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, type CSSProperties, type MouseEvent as ReactMouseEvent } from 'react';\nimport { RESIZE_BORDER } from '../chrome.ts';\nimport { chipFor } from '../updateModel.ts';\nimport { AccountSwitcher } from './AccountSwitcher.tsx';\nimport { AppMenu, AppMenuLogo } from './AppMenu.tsx';\nimport { invoke } from './bridge.ts';\nimport { useT, useUpdateStatus } from './hooks.ts';\nimport { tx } from './i18n.ts';\nimport { site } from './site.ts';\nimport { TitlebarExtras } from './TitlebarExtras.tsx';\nimport { close, minimize, os, startResize, systemMenu, toggleMaximize, type ResizeDirection } from './windowBinding.ts';\n\nconst isInteractive = (target: EventTarget | null) =>\n target instanceof Element && !!target.closest('button, input, textarea, a, .dv-tab, [role=\"button\"]');\n\n/** Right-click on empty titlebar space: the native system menu (Restore, Move, Size, ...). */\nexport function titlebarContextMenu(event: ReactMouseEvent | MouseEvent) {\n if (isInteractive(event.target)) return;\n event.preventDefault();\n const scale = window.devicePixelRatio || 1;\n systemMenu(Math.round(event.screenX * scale), Math.round(event.screenY * scale));\n}\n\n/**\n * The 44px titlebar row. It sits under the dockview root: the top groups' tab headers are\n * transparent and let clicks through to the drag layer, the logo and the caption buttons. The logo\n * is the app menu's second trigger (AppMenu.tsx); everything else that is empty drags the window.\n */\nexport function Titlebar({ maximized }: { maximized: boolean }) {\n return <header className=\"bt-titlebar\" onContextMenu={titlebarContextMenu}>\n <div className=\"bt-titlebar-drag\" data-tauri-drag-region/>\n <AppMenuLogo/>\n <div className=\"bt-titlebar-spacer\" data-tauri-drag-region/>\n <TitlebarExtras/>\n <AccountSwitcher/>\n <UpdateChip/>\n {/* One home for the app menu: the logo. Alt+F, F10, the palette and the account menu's last row open it there. */}\n <AppMenu trigger={false}/>\n {os !== 'macos' && <WindowControls maximized={maximized}/>}\n </header>;\n}\n\n/** \"Update ready · restart\": appears only when a verified update is downloaded (or failed to start). */\nfunction UpdateChip() {\n const [status, apply] = useUpdateStatus();\n const chip = chipFor(status, site().product, key => tx(key, undefined, '') || undefined);\n // Widen the tab strip's right reserve while the chip is shown so tabs never sit under it.\n useEffect(() => {\n const root = document.documentElement;\n if (chip) root.dataset.update = chip.kind; else delete root.dataset.update;\n return () => { delete root.dataset.update; };\n }, [chip?.kind]);\n if (!chip) return null;\n if (chip.kind === 'problem') {\n return <button className=\"bt-update-chip bt-update-chip--problem\" title={chip.title}\n onClick={() => invoke('open_external_url', { url: chip.href }).catch(() => {})}>{chip.label}</button>;\n }\n return <button className={`bt-update-chip bt-update-chip--${chip.kind}`} title={chip.title} disabled={chip.kind === 'installing'} onClick={apply}>\n <span className=\"bt-update-chip-dot\" aria-hidden=\"true\"/>{chip.label}\n </button>;\n}\n\nfunction WindowControls({ maximized }: { maximized: boolean }) {\n const t = useT();\n return <div className=\"bt-captions\">\n <button className=\"bt-caption\" aria-label={t('wb.shell.window.minimize')} title={t('wb.shell.window.minimize')} onClick={minimize}>\n <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M0 5.5h10\"/></svg>\n </button>\n <button className=\"bt-caption\" aria-label={maximized ? t('wb.shell.window.restore') : t('wb.shell.window.maximize')} title={maximized ? t('wb.shell.window.restore') : t('wb.shell.window.maximize')} onClick={toggleMaximize}>\n {maximized\n ? <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M.5 2.5h7v7h-7z\"/><path d=\"M2.5 2.5v-2h7v7h-2\"/></svg>\n : <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M.5.5h9v9h-9z\"/></svg>}\n </button>\n <button className=\"bt-caption bt-caption--close\" aria-label={t('wb.common.close')} title={t('wb.common.close')} onClick={close}>\n <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M0 0l10 10M10 0L0 10\"/></svg>\n </button>\n </div>;\n}\n\nconst CORNER = RESIZE_BORDER * 2;\nconst GRIPS: Array<[ResizeDirection, CSSProperties]> = [\n ['North', { top: 0, left: CORNER, right: CORNER, height: RESIZE_BORDER, cursor: 'ns-resize' }],\n ['South', { bottom: 0, left: CORNER, right: CORNER, height: RESIZE_BORDER, cursor: 'ns-resize' }],\n ['West', { left: 0, top: CORNER, bottom: CORNER, width: RESIZE_BORDER, cursor: 'ew-resize' }],\n ['East', { right: 0, top: CORNER, bottom: CORNER, width: RESIZE_BORDER, cursor: 'ew-resize' }],\n ['NorthWest', { top: 0, left: 0, width: CORNER, height: CORNER, cursor: 'nwse-resize' }],\n ['SouthEast', { bottom: 0, right: 0, width: CORNER, height: CORNER, cursor: 'nwse-resize' }],\n ['NorthEast', { top: 0, right: 0, width: CORNER, height: CORNER, cursor: 'nesw-resize' }],\n ['SouthWest', { bottom: 0, left: 0, width: CORNER, height: CORNER, cursor: 'nesw-resize' }],\n];\n\n/**\n * The shell webview covers the whole frameless window, so the OS never sees its edges:\n * these grips start native resize drags. Tab webviews are inset by the same band (Rust clamps too).\n */\nexport function ResizeGrips() {\n return <>{GRIPS.map(([direction, style]) =>\n <div key={direction} className=\"bt-grip\" style={style} aria-hidden=\"true\"\n onPointerDown={event => { if (event.button === 0) { event.preventDefault(); startResize(direction); } }}/>)}</>;\n}\n"]}
1
+ {"version":3,"file":"Titlebar.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/Titlebar.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, type CSSProperties, type MouseEvent as ReactMouseEvent } from 'react';\nimport { RESIZE_BORDER } from '../chrome.ts';\nimport { chipFor } from '../updateModel.ts';\nimport { AccountSwitcher } from './AccountSwitcher.tsx';\nimport { AppMenu, AppMenuLogo, menuTrigger } from './AppMenu.tsx';\nimport { invoke } from './bridge.ts';\nimport { useT, useUpdateStatus } from './hooks.ts';\nimport { tx } from './i18n.ts';\nimport { site } from './site.ts';\nimport { TitlebarExtras } from './TitlebarExtras.tsx';\nimport { close, minimize, os, startResize, systemMenu, toggleMaximize, type ResizeDirection } from './windowBinding.ts';\n\nconst isInteractive = (target: EventTarget | null) =>\n target instanceof Element && !!target.closest('button, input, textarea, a, .dv-tab, [role=\"button\"]');\n\n/** Right-click on empty titlebar space: the native system menu (Restore, Move, Size, ...). */\nexport function titlebarContextMenu(event: ReactMouseEvent | MouseEvent) {\n if (isInteractive(event.target)) return;\n event.preventDefault();\n const scale = window.devicePixelRatio || 1;\n systemMenu(Math.round(event.screenX * scale), Math.round(event.screenY * scale));\n}\n\n/**\n * The 44px titlebar row. It sits under the dockview root: the top groups' tab headers are\n * transparent and let clicks through to the drag layer, the logo and the caption buttons. The logo\n * is part of the drag region, unless the app chose it as the menu's trigger (`ShellMenu.trigger`);\n * everything else that is empty drags the window.\n */\nexport function Titlebar({ maximized }: { maximized: boolean }) {\n const trigger = menuTrigger();\n return <header className=\"bt-titlebar\" onContextMenu={titlebarContextMenu}>\n <div className=\"bt-titlebar-drag\" data-tauri-drag-region/>\n {trigger === 'logo' ? <AppMenuLogo/> : <img className=\"bt-titlebar-logo\" src={site().logo} alt=\"\" draggable={false} data-tauri-drag-region/>}\n <div className=\"bt-titlebar-spacer\" data-tauri-drag-region/>\n <TitlebarExtras/>\n <AccountSwitcher/>\n <UpdateChip/>\n {/* The app menu, mounted once; it hangs under its trigger (by default each pane's wB button). */}\n <AppMenu trigger={trigger}/>\n {os !== 'macos' && <WindowControls maximized={maximized}/>}\n </header>;\n}\n\n/** \"Update ready · restart\": appears only when a verified update is downloaded (or failed to start). */\nfunction UpdateChip() {\n const [status, apply] = useUpdateStatus();\n const chip = chipFor(status, site().product, key => tx(key, undefined, '') || undefined);\n // Widen the tab strip's right reserve while the chip is shown so tabs never sit under it.\n useEffect(() => {\n const root = document.documentElement;\n if (chip) root.dataset.update = chip.kind; else delete root.dataset.update;\n return () => { delete root.dataset.update; };\n }, [chip?.kind]);\n if (!chip) return null;\n if (chip.kind === 'problem') {\n return <button className=\"bt-update-chip bt-update-chip--problem\" title={chip.title}\n onClick={() => invoke('open_external_url', { url: chip.href }).catch(() => {})}>{chip.label}</button>;\n }\n return <button className={`bt-update-chip bt-update-chip--${chip.kind}`} title={chip.title} disabled={chip.kind === 'installing'} onClick={apply}>\n <span className=\"bt-update-chip-dot\" aria-hidden=\"true\"/>{chip.label}\n </button>;\n}\n\nfunction WindowControls({ maximized }: { maximized: boolean }) {\n const t = useT();\n return <div className=\"bt-captions\">\n <button className=\"bt-caption\" aria-label={t('wb.shell.window.minimize')} title={t('wb.shell.window.minimize')} onClick={minimize}>\n <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M0 5.5h10\"/></svg>\n </button>\n <button className=\"bt-caption\" aria-label={maximized ? t('wb.shell.window.restore') : t('wb.shell.window.maximize')} title={maximized ? t('wb.shell.window.restore') : t('wb.shell.window.maximize')} onClick={toggleMaximize}>\n {maximized\n ? <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M.5 2.5h7v7h-7z\"/><path d=\"M2.5 2.5v-2h7v7h-2\"/></svg>\n : <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M.5.5h9v9h-9z\"/></svg>}\n </button>\n <button className=\"bt-caption bt-caption--close\" aria-label={t('wb.common.close')} title={t('wb.common.close')} onClick={close}>\n <svg viewBox=\"0 0 10 10\" aria-hidden=\"true\"><path d=\"M0 0l10 10M10 0L0 10\"/></svg>\n </button>\n </div>;\n}\n\nconst CORNER = RESIZE_BORDER * 2;\nconst GRIPS: Array<[ResizeDirection, CSSProperties]> = [\n ['North', { top: 0, left: CORNER, right: CORNER, height: RESIZE_BORDER, cursor: 'ns-resize' }],\n ['South', { bottom: 0, left: CORNER, right: CORNER, height: RESIZE_BORDER, cursor: 'ns-resize' }],\n ['West', { left: 0, top: CORNER, bottom: CORNER, width: RESIZE_BORDER, cursor: 'ew-resize' }],\n ['East', { right: 0, top: CORNER, bottom: CORNER, width: RESIZE_BORDER, cursor: 'ew-resize' }],\n ['NorthWest', { top: 0, left: 0, width: CORNER, height: CORNER, cursor: 'nwse-resize' }],\n ['SouthEast', { bottom: 0, right: 0, width: CORNER, height: CORNER, cursor: 'nwse-resize' }],\n ['NorthEast', { top: 0, right: 0, width: CORNER, height: CORNER, cursor: 'nesw-resize' }],\n ['SouthWest', { bottom: 0, left: 0, width: CORNER, height: CORNER, cursor: 'nesw-resize' }],\n];\n\n/**\n * The shell webview covers the whole frameless window, so the OS never sees its edges:\n * these grips start native resize drags. Tab webviews are inset by the same band (Rust clamps too).\n */\nexport function ResizeGrips() {\n return <>{GRIPS.map(([direction, style]) =>\n <div key={direction} className=\"bt-grip\" style={style} aria-hidden=\"true\"\n onPointerDown={event => { if (event.button === 0) { event.preventDefault(); startResize(direction); } }}/>)}</>;\n}\n"]}
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { Fragment, useEffect, useRef, useState } from 'react';
3
3
  import { tabProfile } from "../profileModel.js";
4
4
  import { AccountAvatar, accountName } from "./AccountSwitcher.js";
5
+ import { menuTrigger, PaneMenuButton } from "./AppMenu.js";
5
6
  import { WB_MARK } from "./brand.js";
6
7
  import { invoke } from "./bridge.js";
7
8
  import { FindBar } from "./FindBar.js";
@@ -175,7 +176,9 @@ export function WebPanel(props) {
175
176
  setSplitMenu(false);
176
177
  const box = event.currentTarget.closest('.bt-split').getBoundingClientRect();
177
178
  openPaneTheme({ id: api.id, profile: tabProfile(profiles, params.profile).id, x: box.right - 272, y: box.bottom + 6 });
178
- }, children: [_jsx(Icon, { name: "palette" }), _jsx("span", { className: "bt-menu-label", children: t('wb.shell.menu.paneTheme') })] })] })] })] }), _jsx("button", { className: "bt-brand-button", title: `${product} (Ctrl+Shift+W)`, "aria-label": product, onClick: () => shell.openPanel(api.id), children: _jsx("img", { className: "bt-wb", src: WB_MARK, alt: "", width: 30, height: 17, draggable: false }) })] }), _jsxs("div", { className: "bt-viewport", ref: viewport, children: [still
179
+ }, children: [_jsx(Icon, { name: "palette" }), _jsx("span", { className: "bt-menu-label", children: t('wb.shell.menu.paneTheme') })] })] })] })] }), menuTrigger() === 'pane'
180
+ ? _jsx(PaneMenuButton, { pane: api.id, children: _jsx("img", { className: "bt-wb", src: WB_MARK, alt: "", width: 30, height: 17, draggable: false }) })
181
+ : _jsx("button", { className: "bt-brand-button", title: `${product} (Ctrl+Shift+W)`, "aria-label": product, onClick: () => shell.openPanel(api.id), children: _jsx("img", { className: "bt-wb", src: WB_MARK, alt: "", width: 30, height: 17, draggable: false }) })] }), _jsxs("div", { className: "bt-viewport", ref: viewport, children: [still
179
182
  ? _jsx("div", { className: "bt-still", "aria-hidden": "true", style: { backgroundImage: `url("${still}")` } })
180
183
  : _jsxs("div", { className: "bt-skeleton", "aria-hidden": "true", children: [_jsx("i", {}), _jsx("b", { children: [0, 1, 2, 3].map(i => _jsx("span", {}, i)) })] }), !still && _jsxs("div", { className: "bt-viewport-hint", children: [params.loading ? _jsx("span", { className: "bt-spinner", "aria-hidden": "true" }) : null, _jsx("span", { children: params.title || model?.site.label || t('wb.common.loading') })] })] })] });
181
184
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WebPanel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/WebPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { IDockviewPanelProps } from 'dockview';\nimport { Fragment, useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { tabProfile } from '../profileModel.ts';\nimport { AccountAvatar, accountName } from './AccountSwitcher.tsx';\nimport { WB_MARK } from './brand.ts';\nimport { invoke } from './bridge.ts';\nimport { FindBar } from './FindBar.tsx';\nimport { useProfiles, useSiteText, useT } from './hooks.ts';\nimport { Icon } from './icons.tsx';\nimport { openPaneTheme } from './PaneTheme.tsx';\nimport { toUrl } from './searchInput.ts';\nimport { site } from './site.ts';\nimport { scheduleSync, setOverlay, shell, tabAction, type WebParams } from './state.ts';\nimport { useTabStill } from './tabStill.ts';\n\n/** One browser tab: toolbar with the smart address bar over a placeholder the native webview covers. */\nexport function WebPanel(props: IDockviewPanelProps<WebParams>) {\n const t = useT();\n const { params, api } = props;\n const viewport = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const omni = useRef<HTMLDivElement>(null);\n const [draft, setDraft] = useState<string | null>(null);\n const [caret, setCaret] = useState(0);\n const [splitMenu, setSplitMenu] = useState(false);\n // Find in page: the find field takes the address field's place while it is open (FindBar.tsx).\n const [finding, setFinding] = useState(false);\n useEffect(() => {\n const open = (event: Event) => { if ((event as CustomEvent<string>).detail === api.id) { setDraft(null); setFinding(true); } };\n window.addEventListener('bt-find', open);\n return () => window.removeEventListener('bt-find', open);\n }, [api.id]);\n // Windows: the page's last frame, shown while its webview is hidden (host `tab-still`).\n const still = useTabStill(api.id);\n useSiteText();\n const profiles = useProfiles();\n const { logo, product, addressCompleter, themes } = site();\n // Same rule as the tab's account dot: shown once there is more than one account.\n const account = profiles.profiles.length > 1 ? tabProfile(profiles, params.profile) : null;\n const editing = draft !== null;\n\n useEffect(() => {\n const el = viewport.current;\n if (!el) return;\n shell.placeholders.set(api.id, el);\n const observer = new ResizeObserver(scheduleSync);\n observer.observe(el);\n const visibility = api.onDidVisibilityChange(scheduleSync);\n scheduleSync();\n return () => {\n observer.disconnect();\n visibility.dispose();\n if (shell.placeholders.get(api.id) === el) shell.placeholders.delete(api.id);\n scheduleSync();\n };\n }, [api]);\n\n // An overlay (the shell rises above the tab webviews, or hides them) while the menu is open; Esc closes it.\n useEffect(() => {\n if (!splitMenu) return;\n setOverlay(1);\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape') { event.preventDefault(); setSplitMenu(false); } };\n window.addEventListener('keydown', onKey);\n return () => { setOverlay(-1); window.removeEventListener('keydown', onKey); };\n }, [splitMenu]);\n\n // Entering edit mode focuses the mono input; a seeded draft keeps the caret at the end.\n const seeded = useRef(false);\n useEffect(() => {\n if (!editing) return;\n const el = input.current;\n if (!el) return;\n el.focus();\n if (seeded.current) { seeded.current = false; el.setSelectionRange(el.value.length, el.value.length); } else el.select();\n }, [editing]);\n\n const enterEdit = (seed?: string) => {\n seeded.current = seed !== undefined;\n setDraft(seed ?? params.url);\n };\n\n useEffect(() => {\n const focusAddress = (event: Event) => {\n if ((event as CustomEvent<string>).detail !== api.id) return;\n setFinding(false);\n if (draft === null) enterEdit();\n else { input.current?.focus(); input.current?.select(); }\n };\n window.addEventListener('bt-focus-address', focusAddress);\n return () => window.removeEventListener('bt-focus-address', focusAddress);\n });\n\n const navigate = (url: string) => {\n invoke('tab_navigate', { id: api.id, url }).catch(() => {});\n tabAction(api.id, 'focus');\n };\n\n const go = () => {\n if (draft === null) return;\n const url = toUrl(draft, site().searchUrl);\n setDraft(null);\n navigate(url);\n };\n\n // The site's completions for the token being typed (inline, so no overlay hides the page).\n const chips = draft === null || !addressCompleter ? [] : addressCompleter.suggest(draft, caret, 5);\n const trackCaret = () => setCaret(input.current?.selectionStart ?? draft?.length ?? 0);\n const acceptChip = (insert: string) => {\n if (draft === null || !addressCompleter) return;\n const next = addressCompleter.apply(draft, caret, insert);\n setDraft(next.text);\n setCaret(next.caret);\n requestAnimationFrame(() => { input.current?.focus(); input.current?.setSelectionRange(next.caret, next.caret); });\n };\n\n const onChipsKey = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n const mod = event.ctrlKey || event.metaKey || event.altKey;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); enterEdit(); }\n else if (!mod && event.key.length === 1) { event.preventDefault(); enterEdit(event.key); }\n };\n\n const model = site().address(params.url);\n const segments = model?.segments ?? [];\n\n return <div className=\"bt-web\">\n <div className=\"bt-addressbar\">\n <button className=\"bt-icon\" title={t('wb.web.backTitle')} aria-label={t('wb.web.back')} onClick={() => tabAction(api.id, 'back')}><Icon name=\"back\"/></button>\n <button className=\"bt-icon\" title={t('wb.web.forwardTitle')} aria-label={t('wb.web.forward')} onClick={() => tabAction(api.id, 'forward')}><Icon name=\"forward\"/></button>\n <button className=\"bt-icon\" title={params.loading ? t('wb.web.stop') : t('wb.web.reloadTitle')} aria-label={params.loading ? t('wb.web.stop') : t('wb.shell.menu.reload')} onClick={() => tabAction(api.id, params.loading ? 'stop' : 'reload')}><Icon name={params.loading ? 'stop' : 'reload'}/></button>\n {account && <span className=\"bt-pane-account\" role=\"img\" aria-label={t('wb.shell.tab.account', { name: accountName(account) })} title={t('wb.web.paneAccount', { name: accountName(account) })}\n style={{ ['--bt-pane-account' as string]: account.color }}><AccountAvatar profile={account} size={20}/></span>}\n {finding ? <FindBar tabId={api.id} url={params.url} onClose={() => setFinding(false)}/> : editing\n ? <div className=\"bt-omni bt-omni--edit\" ref={omni}>\n <Icon name=\"search\" className=\"bt-omni-lead\"/>\n <input ref={input} spellCheck={false} aria-label={t('wb.web.address')} value={draft}\n onChange={event => { setDraft(event.target.value); setCaret(event.target.selectionStart ?? event.target.value.length); }}\n onSelect={trackCaret} onKeyUp={trackCaret}\n onBlur={() => setDraft(null)}\n onKeyDown={event => {\n if (event.key === 'Tab' && !event.shiftKey && chips[0]) { event.preventDefault(); acceptChip(chips[0].insert); }\n if (event.key === 'Enter') { event.preventDefault(); go(); }\n if (event.key === 'Escape') { event.preventDefault(); setDraft(null); tabAction(api.id, 'focus'); }\n }}/>\n {chips.length > 0 && <span className=\"bt-omni-ops\" role=\"listbox\" aria-label={addressCompleter?.label()}>\n {chips.map((chip, index) => <button key={chip.insert} type=\"button\" role=\"option\" aria-selected={index === 0} className=\"bt-omni-op\" title={`${chip.hint}${index === 0 ? ` (${t('wb.web.tabKey')})` : ''}`}\n onMouseDown={event => event.preventDefault()} onClick={() => acceptChip(chip.insert)}>{chip.label}</button>)}\n </span>}\n {params.loading && <span className=\"bt-omni-progress\" aria-label={t('wb.common.loading')}/>}\n </div>\n : <div className=\"bt-omni\" ref={omni} role=\"button\" tabIndex={0} aria-label={t('wb.web.addressValue', { url: params.url })} title={params.url}\n onClick={() => enterEdit()} onKeyDown={onChipsKey}>\n {model?.insecure && <span className=\"bt-chip-insecure\">{t('wb.web.insecure')}</span>}\n {model\n ? <button className=\"bt-chip-site\" title={model.site.href} onClick={event => { event.stopPropagation(); if (segments.length) navigate(model.site.href); else enterEdit(); }}>\n {model.site.kind !== 'host'\n ? <img src={logo} alt=\"\" width={14} height={14}/>\n : params.favicon ? <img src={params.favicon} alt=\"\" width={14} height={14}/> : null}\n {model.site.label}\n </button>\n : <span className=\"bt-omni-raw\">{params.url}</span>}\n {segments.map((segment, index) => {\n const last = index === segments.length - 1;\n // The model already wraps search queries in straight quotes; show typographic ones.\n const label = segment.quoted ? segment.label.replace(/^\"/, '“').replace(/\"$/, '”') : segment.label;\n return <Fragment key={`${index}:${segment.href}`}>\n <span className=\"bt-sep\" aria-hidden=\"true\">/</span>\n {last\n ? <span className={`bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`} aria-current=\"page\">{label}</span>\n : <button className={`bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`} title={segment.href}\n onClick={event => { event.stopPropagation(); navigate(segment.href); }}>{label}</button>}\n </Fragment>;\n })}\n <span className=\"bt-omni-fill\"/>\n <button className=\"bt-omni-action\" title={t('wb.shell.menu.openBrowser')} aria-label={t('wb.shell.menu.openBrowser')}\n onClick={event => { event.stopPropagation(); invoke('open_external_url', { url: params.url }).catch(() => {}); }}><Icon name=\"external\"/></button>\n {params.loading && <span className=\"bt-omni-progress\" aria-label={t('wb.common.loading')}/>}\n </div>}\n <div className=\"bt-split\">\n <button className=\"bt-icon bt-split-main\" title={t('wb.web.splitTitle')} aria-label={t('wb.shell.menu.splitRight')} onClick={() => shell.split(api.id, 'right')}><Icon name=\"split\"/></button>\n <button className=\"bt-icon bt-split-more\" title={t('wb.web.splitMore')} aria-label={t('wb.web.splitMore')} aria-haspopup=\"menu\" aria-expanded={splitMenu}\n onClick={() => setSplitMenu(open => !open)} onBlur={() => setTimeout(() => setSplitMenu(false), 150)}><Icon name=\"chevron\"/></button>\n {splitMenu && <div className=\"bt-menu bt-split-menu bt-pop\" role=\"menu\">\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={() => { setSplitMenu(false); shell.split(api.id, 'right'); }}>\n <Icon name=\"split\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.splitRight')}</span><span className=\"bt-menu-keys\">{'Ctrl \\\\'}</span></button>\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={() => { setSplitMenu(false); shell.split(api.id, 'below'); }}>\n <Icon name=\"splitDown\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.splitDown')}</span><span className=\"bt-menu-keys\">{'Ctrl \\u21e7 \\\\'}</span></button>\n {themes && <>\n <hr/>\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={event => {\n setSplitMenu(false);\n const box = (event.currentTarget.closest('.bt-split') as HTMLElement).getBoundingClientRect();\n openPaneTheme({ id: api.id, profile: tabProfile(profiles, params.profile).id, x: box.right - 272, y: box.bottom + 6 });\n }}><Icon name=\"palette\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.paneTheme')}</span></button>\n </>}\n </div>}\n </div>\n <button className=\"bt-brand-button\" title={`${product} (Ctrl+Shift+W)`} aria-label={product} onClick={() => shell.openPanel(api.id)}>\n <img className=\"bt-wb\" src={WB_MARK} alt=\"\" width={30} height={17} draggable={false}/>\n </button>\n </div>\n <div className=\"bt-viewport\" ref={viewport}>\n {/* Until the page's own webview is on screen: its last frame, else the site's shape (rail, timeline), not a blank pane. */}\n {still\n ? <div className=\"bt-still\" aria-hidden=\"true\" style={{ backgroundImage: `url(\"${still}\")` }}/>\n : <div className=\"bt-skeleton\" aria-hidden=\"true\"><i/><b>{[0, 1, 2, 3].map(i => <span key={i}/>)}</b></div>}\n {!still && <div className=\"bt-viewport-hint\">{params.loading ? <span className=\"bt-spinner\" aria-hidden=\"true\"/> : null}<span>{params.title || model?.site.label || t('wb.common.loading')}</span></div>}\n </div>\n </div>;\n}\n"]}
1
+ {"version":3,"file":"WebPanel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/WebPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { IDockviewPanelProps } from 'dockview';\nimport { Fragment, useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { tabProfile } from '../profileModel.ts';\nimport { AccountAvatar, accountName } from './AccountSwitcher.tsx';\nimport { menuTrigger, PaneMenuButton } from './AppMenu.tsx';\nimport { WB_MARK } from './brand.ts';\nimport { invoke } from './bridge.ts';\nimport { FindBar } from './FindBar.tsx';\nimport { useProfiles, useSiteText, useT } from './hooks.ts';\nimport { Icon } from './icons.tsx';\nimport { openPaneTheme } from './PaneTheme.tsx';\nimport { toUrl } from './searchInput.ts';\nimport { site } from './site.ts';\nimport { scheduleSync, setOverlay, shell, tabAction, type WebParams } from './state.ts';\nimport { useTabStill } from './tabStill.ts';\n\n/** One browser tab: toolbar with the smart address bar over a placeholder the native webview covers. */\nexport function WebPanel(props: IDockviewPanelProps<WebParams>) {\n const t = useT();\n const { params, api } = props;\n const viewport = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const omni = useRef<HTMLDivElement>(null);\n const [draft, setDraft] = useState<string | null>(null);\n const [caret, setCaret] = useState(0);\n const [splitMenu, setSplitMenu] = useState(false);\n // Find in page: the find field takes the address field's place while it is open (FindBar.tsx).\n const [finding, setFinding] = useState(false);\n useEffect(() => {\n const open = (event: Event) => { if ((event as CustomEvent<string>).detail === api.id) { setDraft(null); setFinding(true); } };\n window.addEventListener('bt-find', open);\n return () => window.removeEventListener('bt-find', open);\n }, [api.id]);\n // Windows: the page's last frame, shown while its webview is hidden (host `tab-still`).\n const still = useTabStill(api.id);\n useSiteText();\n const profiles = useProfiles();\n const { logo, product, addressCompleter, themes } = site();\n // Same rule as the tab's account dot: shown once there is more than one account.\n const account = profiles.profiles.length > 1 ? tabProfile(profiles, params.profile) : null;\n const editing = draft !== null;\n\n useEffect(() => {\n const el = viewport.current;\n if (!el) return;\n shell.placeholders.set(api.id, el);\n const observer = new ResizeObserver(scheduleSync);\n observer.observe(el);\n const visibility = api.onDidVisibilityChange(scheduleSync);\n scheduleSync();\n return () => {\n observer.disconnect();\n visibility.dispose();\n if (shell.placeholders.get(api.id) === el) shell.placeholders.delete(api.id);\n scheduleSync();\n };\n }, [api]);\n\n // An overlay (the shell rises above the tab webviews, or hides them) while the menu is open; Esc closes it.\n useEffect(() => {\n if (!splitMenu) return;\n setOverlay(1);\n const onKey = (event: KeyboardEvent) => { if (event.key === 'Escape') { event.preventDefault(); setSplitMenu(false); } };\n window.addEventListener('keydown', onKey);\n return () => { setOverlay(-1); window.removeEventListener('keydown', onKey); };\n }, [splitMenu]);\n\n // Entering edit mode focuses the mono input; a seeded draft keeps the caret at the end.\n const seeded = useRef(false);\n useEffect(() => {\n if (!editing) return;\n const el = input.current;\n if (!el) return;\n el.focus();\n if (seeded.current) { seeded.current = false; el.setSelectionRange(el.value.length, el.value.length); } else el.select();\n }, [editing]);\n\n const enterEdit = (seed?: string) => {\n seeded.current = seed !== undefined;\n setDraft(seed ?? params.url);\n };\n\n useEffect(() => {\n const focusAddress = (event: Event) => {\n if ((event as CustomEvent<string>).detail !== api.id) return;\n setFinding(false);\n if (draft === null) enterEdit();\n else { input.current?.focus(); input.current?.select(); }\n };\n window.addEventListener('bt-focus-address', focusAddress);\n return () => window.removeEventListener('bt-focus-address', focusAddress);\n });\n\n const navigate = (url: string) => {\n invoke('tab_navigate', { id: api.id, url }).catch(() => {});\n tabAction(api.id, 'focus');\n };\n\n const go = () => {\n if (draft === null) return;\n const url = toUrl(draft, site().searchUrl);\n setDraft(null);\n navigate(url);\n };\n\n // The site's completions for the token being typed (inline, so no overlay hides the page).\n const chips = draft === null || !addressCompleter ? [] : addressCompleter.suggest(draft, caret, 5);\n const trackCaret = () => setCaret(input.current?.selectionStart ?? draft?.length ?? 0);\n const acceptChip = (insert: string) => {\n if (draft === null || !addressCompleter) return;\n const next = addressCompleter.apply(draft, caret, insert);\n setDraft(next.text);\n setCaret(next.caret);\n requestAnimationFrame(() => { input.current?.focus(); input.current?.setSelectionRange(next.caret, next.caret); });\n };\n\n const onChipsKey = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n if (event.target !== event.currentTarget) return;\n const mod = event.ctrlKey || event.metaKey || event.altKey;\n if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); enterEdit(); }\n else if (!mod && event.key.length === 1) { event.preventDefault(); enterEdit(event.key); }\n };\n\n const model = site().address(params.url);\n const segments = model?.segments ?? [];\n\n return <div className=\"bt-web\">\n <div className=\"bt-addressbar\">\n <button className=\"bt-icon\" title={t('wb.web.backTitle')} aria-label={t('wb.web.back')} onClick={() => tabAction(api.id, 'back')}><Icon name=\"back\"/></button>\n <button className=\"bt-icon\" title={t('wb.web.forwardTitle')} aria-label={t('wb.web.forward')} onClick={() => tabAction(api.id, 'forward')}><Icon name=\"forward\"/></button>\n <button className=\"bt-icon\" title={params.loading ? t('wb.web.stop') : t('wb.web.reloadTitle')} aria-label={params.loading ? t('wb.web.stop') : t('wb.shell.menu.reload')} onClick={() => tabAction(api.id, params.loading ? 'stop' : 'reload')}><Icon name={params.loading ? 'stop' : 'reload'}/></button>\n {account && <span className=\"bt-pane-account\" role=\"img\" aria-label={t('wb.shell.tab.account', { name: accountName(account) })} title={t('wb.web.paneAccount', { name: accountName(account) })}\n style={{ ['--bt-pane-account' as string]: account.color }}><AccountAvatar profile={account} size={20}/></span>}\n {finding ? <FindBar tabId={api.id} url={params.url} onClose={() => setFinding(false)}/> : editing\n ? <div className=\"bt-omni bt-omni--edit\" ref={omni}>\n <Icon name=\"search\" className=\"bt-omni-lead\"/>\n <input ref={input} spellCheck={false} aria-label={t('wb.web.address')} value={draft}\n onChange={event => { setDraft(event.target.value); setCaret(event.target.selectionStart ?? event.target.value.length); }}\n onSelect={trackCaret} onKeyUp={trackCaret}\n onBlur={() => setDraft(null)}\n onKeyDown={event => {\n if (event.key === 'Tab' && !event.shiftKey && chips[0]) { event.preventDefault(); acceptChip(chips[0].insert); }\n if (event.key === 'Enter') { event.preventDefault(); go(); }\n if (event.key === 'Escape') { event.preventDefault(); setDraft(null); tabAction(api.id, 'focus'); }\n }}/>\n {chips.length > 0 && <span className=\"bt-omni-ops\" role=\"listbox\" aria-label={addressCompleter?.label()}>\n {chips.map((chip, index) => <button key={chip.insert} type=\"button\" role=\"option\" aria-selected={index === 0} className=\"bt-omni-op\" title={`${chip.hint}${index === 0 ? ` (${t('wb.web.tabKey')})` : ''}`}\n onMouseDown={event => event.preventDefault()} onClick={() => acceptChip(chip.insert)}>{chip.label}</button>)}\n </span>}\n {params.loading && <span className=\"bt-omni-progress\" aria-label={t('wb.common.loading')}/>}\n </div>\n : <div className=\"bt-omni\" ref={omni} role=\"button\" tabIndex={0} aria-label={t('wb.web.addressValue', { url: params.url })} title={params.url}\n onClick={() => enterEdit()} onKeyDown={onChipsKey}>\n {model?.insecure && <span className=\"bt-chip-insecure\">{t('wb.web.insecure')}</span>}\n {model\n ? <button className=\"bt-chip-site\" title={model.site.href} onClick={event => { event.stopPropagation(); if (segments.length) navigate(model.site.href); else enterEdit(); }}>\n {model.site.kind !== 'host'\n ? <img src={logo} alt=\"\" width={14} height={14}/>\n : params.favicon ? <img src={params.favicon} alt=\"\" width={14} height={14}/> : null}\n {model.site.label}\n </button>\n : <span className=\"bt-omni-raw\">{params.url}</span>}\n {segments.map((segment, index) => {\n const last = index === segments.length - 1;\n // The model already wraps search queries in straight quotes; show typographic ones.\n const label = segment.quoted ? segment.label.replace(/^\"/, '“').replace(/\"$/, '”') : segment.label;\n return <Fragment key={`${index}:${segment.href}`}>\n <span className=\"bt-sep\" aria-hidden=\"true\">/</span>\n {last\n ? <span className={`bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`} aria-current=\"page\">{label}</span>\n : <button className={`bt-seg ${segment.mono ? 'bt-seg--mono' : ''}`} title={segment.href}\n onClick={event => { event.stopPropagation(); navigate(segment.href); }}>{label}</button>}\n </Fragment>;\n })}\n <span className=\"bt-omni-fill\"/>\n <button className=\"bt-omni-action\" title={t('wb.shell.menu.openBrowser')} aria-label={t('wb.shell.menu.openBrowser')}\n onClick={event => { event.stopPropagation(); invoke('open_external_url', { url: params.url }).catch(() => {}); }}><Icon name=\"external\"/></button>\n {params.loading && <span className=\"bt-omni-progress\" aria-label={t('wb.common.loading')}/>}\n </div>}\n <div className=\"bt-split\">\n <button className=\"bt-icon bt-split-main\" title={t('wb.web.splitTitle')} aria-label={t('wb.shell.menu.splitRight')} onClick={() => shell.split(api.id, 'right')}><Icon name=\"split\"/></button>\n <button className=\"bt-icon bt-split-more\" title={t('wb.web.splitMore')} aria-label={t('wb.web.splitMore')} aria-haspopup=\"menu\" aria-expanded={splitMenu}\n onClick={() => setSplitMenu(open => !open)} onBlur={() => setTimeout(() => setSplitMenu(false), 150)}><Icon name=\"chevron\"/></button>\n {splitMenu && <div className=\"bt-menu bt-split-menu bt-pop\" role=\"menu\">\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={() => { setSplitMenu(false); shell.split(api.id, 'right'); }}>\n <Icon name=\"split\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.splitRight')}</span><span className=\"bt-menu-keys\">{'Ctrl \\\\'}</span></button>\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={() => { setSplitMenu(false); shell.split(api.id, 'below'); }}>\n <Icon name=\"splitDown\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.splitDown')}</span><span className=\"bt-menu-keys\">{'Ctrl \\u21e7 \\\\'}</span></button>\n {themes && <>\n <hr/>\n <button role=\"menuitem\" onMouseDown={event => event.preventDefault()} onClick={event => {\n setSplitMenu(false);\n const box = (event.currentTarget.closest('.bt-split') as HTMLElement).getBoundingClientRect();\n openPaneTheme({ id: api.id, profile: tabProfile(profiles, params.profile).id, x: box.right - 272, y: box.bottom + 6 });\n }}><Icon name=\"palette\"/><span className=\"bt-menu-label\">{t('wb.shell.menu.paneTheme')}</span></button>\n </>}\n </div>}\n </div>\n {/* The app menu's trigger (its Settings row and the other panel rows open the panel); an app whose menu hangs elsewhere keeps it as the panel's button. */}\n {menuTrigger() === 'pane'\n ? <PaneMenuButton pane={api.id}><img className=\"bt-wb\" src={WB_MARK} alt=\"\" width={30} height={17} draggable={false}/></PaneMenuButton>\n : <button className=\"bt-brand-button\" title={`${product} (Ctrl+Shift+W)`} aria-label={product} onClick={() => shell.openPanel(api.id)}>\n <img className=\"bt-wb\" src={WB_MARK} alt=\"\" width={30} height={17} draggable={false}/>\n </button>}\n </div>\n <div className=\"bt-viewport\" ref={viewport}>\n {/* Until the page's own webview is on screen: its last frame, else the site's shape (rail, timeline), not a blank pane. */}\n {still\n ? <div className=\"bt-still\" aria-hidden=\"true\" style={{ backgroundImage: `url(\"${still}\")` }}/>\n : <div className=\"bt-skeleton\" aria-hidden=\"true\"><i/><b>{[0, 1, 2, 3].map(i => <span key={i}/>)}</b></div>}\n {!still && <div className=\"bt-viewport-hint\">{params.loading ? <span className=\"bt-spinner\" aria-hidden=\"true\"/> : null}<span>{params.title || model?.site.label || t('wb.common.loading')}</span></div>}\n </div>\n </div>;\n}\n"]}
@@ -9,15 +9,15 @@
9
9
  .bt-acct-head .bt-kbd { height: 16px; min-width: 0; font: 500 10.5px/1 var(--bt-ui); }
10
10
 
11
11
  /* One account: the whole row is the main action; "…" sits at the right edge. */
12
- .bt-acct-row { position: relative; display: flex; flex-direction: column; border-radius: 10px; }
12
+ .bt-acct-row { position: relative; display: flex; flex-direction: column; border-radius: calc(10px * var(--bt-rs, 1)); }
13
13
  .bt-acct-line { position: relative; display: flex; align-items: center; }
14
14
  .bt-acct-row.is-focused { background: rgb(var(--bt-accent-rgb) / .08); box-shadow: inset 0 0 0 1px rgb(var(--bt-accent-rgb) / .22); }
15
15
  .bt-acct-row.is-focused::before {
16
- content: ''; position: absolute; inset-inline-start: -5px; top: 12px; height: 24px; width: 3px; border-start-start-radius: 0; border-start-end-radius: 3px; border-end-end-radius: 3px; border-end-start-radius: 0; background: var(--bt-accent);
16
+ content: ''; position: absolute; inset-inline-start: -5px; top: 12px; height: 24px; width: 3px; border-start-start-radius: 0; border-start-end-radius: calc(3px * var(--bt-rs, 1)); border-end-end-radius: calc(3px * var(--bt-rs, 1)); border-end-start-radius: 0; background: var(--bt-accent);
17
17
  }
18
18
  .bt-acct-row.is-open { background: rgb(var(--bt-text-rgb) / .035); }
19
19
 
20
- .bt-menu .bt-acct-main { flex: 1; min-width: 0; height: auto; gap: 11px; padding-block: 8px; padding-inline: 8px 40px; border-radius: 10px; }
20
+ .bt-menu .bt-acct-main { flex: 1; min-width: 0; height: auto; gap: 11px; padding-block: 8px; padding-inline: 8px 40px; border-radius: calc(10px * var(--bt-rs, 1)); }
21
21
  .bt-menu .bt-acct-main:focus-visible { box-shadow: var(--bt-ring); }
22
22
  .bt-acct-avatar { position: relative; display: inline-grid; flex: none; }
23
23
  .bt-acct-avatar.is-signed-out .bt-avatar, .bt-acct-avatar.is-new .bt-avatar { filter: saturate(.35); opacity: .7; }
@@ -29,10 +29,10 @@
29
29
  .bt-acct-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
30
30
  .bt-acct-name { display: flex; align-items: center; gap: 6px; min-width: 0; font: 600 13.5px/1.15 var(--bt-ui); color: var(--bt-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
31
31
  .bt-acct-meta { font: 400 12px/1.2 var(--bt-ui); color: var(--bt-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
32
- .bt-acct-meta.is-signed-out, .bt-acct-meta.is-new { color: #f0b14a; }
32
+ .bt-acct-meta.is-signed-out, .bt-acct-meta.is-new { color: var(--bt-warn); }
33
33
  .bt-acct-count { color: var(--bt-muted); }
34
34
  .bt-acct-badge {
35
- flex: none; padding: 2px 6px; border-radius: 999px; background: rgb(var(--bt-text-rgb) / .07); color: var(--bt-text-2);
35
+ flex: none; padding: 2px 6px; border-radius: calc(999px * var(--bt-rs, 1)); background: rgb(var(--bt-text-rgb) / .07); color: var(--bt-text-2);
36
36
  font: 500 10.5px/1.2 var(--bt-ui); letter-spacing: .01em;
37
37
  }
38
38
 
@@ -61,11 +61,11 @@
61
61
  .bt-acct-sub .bt-menu-keys { font-size: 11px; }
62
62
  .bt-menu .bt-acct-sub button[aria-checked=true]:disabled { color: var(--bt-text-2); }
63
63
  .bt-menu .bt-acct-sub button[aria-checked=true]:disabled > .bt-glyph { color: var(--bt-accent); opacity: 1; }
64
- .bt-menu .bt-acct-danger { color: #ff8a80; }
65
- .bt-menu .bt-acct-danger > .bt-glyph { color: #ff8a80; }
64
+ .bt-menu .bt-acct-danger { color: var(--bt-danger-ink); }
65
+ .bt-menu .bt-acct-danger > .bt-glyph { color: var(--bt-danger-ink); }
66
66
 
67
67
  .bt-acct-confirm {
68
- display: flex; flex-direction: column; gap: 10px; margin: 2px 6px 6px; padding: 10px 12px; border-radius: 9px;
68
+ display: flex; flex-direction: column; gap: 10px; margin: 2px 6px 6px; padding: 10px 12px; border-radius: calc(9px * var(--bt-rs, 1));
69
69
  background: rgba(229, 72, 77, .08); box-shadow: inset 0 0 0 1px rgba(229, 72, 77, .25); color: var(--bt-text-2); font: 400 12.5px/1.45 var(--bt-ui);
70
70
  }
71
71
  .bt-acct-confirm strong { color: var(--bt-text); font-weight: 600; }
@@ -75,14 +75,14 @@
75
75
  .bt-menu .bt-acct-remove:hover:not(:disabled), .bt-menu .bt-acct-remove:focus-visible { background: #d93d42; }
76
76
  .bt-menu .bt-acct-cancel { background: var(--bt-hover); }
77
77
 
78
- .bt-menu .bt-acct-add { height: auto; gap: 11px; padding: 8px; border-radius: 10px; }
78
+ .bt-menu .bt-acct-add { height: auto; gap: 11px; padding: 8px; border-radius: calc(10px * var(--bt-rs, 1)); }
79
79
  .bt-menu .bt-acct-add:focus-visible { box-shadow: var(--bt-ring); }
80
80
  .bt-acct-add .bt-acct-name { color: var(--bt-text-2); }
81
81
  .bt-acct-add-icon { display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: 50%; box-shadow: inset 0 0 0 1px var(--bt-line-strong); color: var(--bt-muted); }
82
82
  .bt-acct-add-icon .bt-glyph { width: 15px; height: 15px; }
83
83
  .bt-menu .bt-acct-add:hover .bt-acct-add-icon { box-shadow: inset 0 0 0 1px rgb(var(--bt-accent-rgb) / .6); color: var(--bt-accent-ink); }
84
84
 
85
- .bt-acct-error { padding: 6px 10px; color: #ff8a80; font: 12px/1.4 var(--bt-ui); }
85
+ .bt-acct-error { padding: 6px 10px; color: var(--bt-danger-ink); font: 12px/1.4 var(--bt-ui); }
86
86
 
87
87
  /* Each pane's account, left of its address bar (same color as the tab's account dot). */
88
88
  .bt-pane-account {
@@ -5,7 +5,7 @@
5
5
  /* The button: the last thing before the caption buttons. */
6
6
  .bt-app-button {
7
7
  align-self: center; display: inline-grid; place-items: center; width: 30px; height: 30px; flex: none; margin-right: 8px; padding: 0; box-sizing: border-box; /* rtl-ok: titlebar */
8
- border: 1px solid transparent; border-radius: 15px; background: transparent; color: var(--bt-text-2); cursor: pointer;
8
+ border: 1px solid transparent; border-radius: calc(15px * var(--bt-rs, 1)); background: transparent; color: var(--bt-text-2); cursor: pointer;
9
9
  transition: background-color var(--bt-t1) var(--bt-ease), border-color var(--bt-t1) var(--bt-ease), color var(--bt-t1) var(--bt-ease);
10
10
  }
11
11
  .bt-app-button:hover { background: var(--bt-hover); border-color: var(--bt-line-soft); color: var(--bt-text); }
@@ -16,17 +16,23 @@
16
16
  /* An app that shows no menu button (`<AppMenu trigger={false}/>`, the logo is the menu's home) reserves no room for it. */
17
17
  html:not(:has(.bt-app-button)) { --bt-tb-menu: 0px; }
18
18
 
19
- /* The logo at the start of the titlebar: the menu's second trigger (a 30px target around the 20px
20
- mark; with its margins it takes the 50px the tab strip leaves in --bt-tb-left). */
21
- .bt-titlebar-logo {
19
+ /* The logo at the start of the titlebar. Plain, it is part of the drag region (clicks fall through
20
+ to it); as the app's chosen trigger it is a 30px target around the 20px mark. Either way it takes
21
+ the 50px the tab strip leaves in --bt-tb-left. */
22
+ img.bt-titlebar-logo { width: 20px; height: 20px; margin: 12px 14px 12px 16px; flex: 0 0 20px; -webkit-user-drag: none; } /* rtl-ok: titlebar */
23
+ button.bt-titlebar-logo {
22
24
  align-self: center; display: inline-grid; place-items: center; width: 30px; height: 30px; flex: 0 0 30px; margin: 0 9px 0 11px; padding: 0; box-sizing: border-box; /* rtl-ok: titlebar */
23
- border: 1px solid transparent; border-radius: 9px; background: transparent; cursor: pointer; -webkit-user-drag: none;
25
+ border: 1px solid transparent; border-radius: calc(9px * var(--bt-rs, 1)); background: transparent; cursor: pointer; -webkit-user-drag: none;
24
26
  transition: background-color var(--bt-t1) var(--bt-ease), border-color var(--bt-t1) var(--bt-ease);
25
27
  }
26
- .bt-titlebar-logo img { display: block; width: 20px; height: 20px; pointer-events: none; -webkit-user-drag: none; }
27
- .bt-titlebar-logo:hover { background: var(--bt-hover); border-color: var(--bt-line-soft); }
28
- .bt-titlebar-logo[aria-expanded=true] { background: var(--bt-hover); border-color: rgb(var(--bt-accent-rgb) / .5); }
29
- .bt-titlebar-logo:focus-visible { outline: 0; box-shadow: var(--bt-ring); }
28
+ button.bt-titlebar-logo img { display: block; width: 20px; height: 20px; pointer-events: none; -webkit-user-drag: none; }
29
+ button.bt-titlebar-logo:hover { background: var(--bt-hover); border-color: var(--bt-line-soft); }
30
+ button.bt-titlebar-logo[aria-expanded=true] { background: var(--bt-hover); border-color: rgb(var(--bt-accent-rgb) / .5); }
31
+ button.bt-titlebar-logo:focus-visible { outline: 0; box-shadow: var(--bt-ring); }
32
+
33
+ /* Each pane's wB button is the menu's trigger: it stays lit while the menu hangs from it. */
34
+ .bt-pane-menu[aria-expanded=true] { background: var(--bt-hover); border-color: rgb(var(--bt-accent-rgb) / .55); }
35
+ .bt-pane-menu:focus-visible { outline: 0; box-shadow: var(--bt-ring); }
30
36
 
31
37
  /* The menu and its submenus. `display: contents`: the layers are positioned on their own. */
32
38
  .bt-app-layers { display: contents; }
@@ -70,14 +76,14 @@ html:not(:has(.bt-app-button)) { --bt-tb-menu: 0px; }
70
76
  .bt-app-zoom { display: flex; align-items: center; gap: 10px; height: 36px; flex: none; padding-inline: 10px 3px; color: var(--bt-text); }
71
77
  .bt-app-zoom > .bt-glyph { color: var(--bt-muted); }
72
78
  .bt-app-zoom.is-off > .bt-glyph, .bt-app-zoom.is-off .bt-menu-label, .bt-app-zoom.is-off .bt-app-zoom-value { color: var(--bt-faint); }
73
- .bt-app-zoom-step { display: flex; align-items: center; flex: none; height: 28px; border-radius: 9px; direction: ltr; background: rgb(var(--bt-text-rgb) / .04); box-shadow: inset 0 0 0 1px var(--bt-line); }
74
- .bt-app-menu .bt-app-zoom button { width: 30px; height: 28px; flex: none; padding: 0; justify-content: center; border-radius: 8px; color: var(--bt-text-2); }
79
+ .bt-app-zoom-step { display: flex; align-items: center; flex: none; height: 28px; border-radius: calc(9px * var(--bt-rs, 1)); direction: ltr; background: rgb(var(--bt-text-rgb) / .04); box-shadow: inset 0 0 0 1px var(--bt-line); }
80
+ .bt-app-menu .bt-app-zoom button { width: 30px; height: 28px; flex: none; padding: 0; justify-content: center; border-radius: calc(8px * var(--bt-rs, 1)); color: var(--bt-text-2); }
75
81
  .bt-app-menu .bt-app-zoom button > .bt-glyph { width: 14px; height: 14px; color: inherit; }
76
82
  .bt-app-menu .bt-app-zoom button:focus { color: var(--bt-text); }
77
83
  .bt-app-menu .bt-app-zoom button[aria-disabled=true] { color: var(--bt-faint); cursor: default; }
78
84
  .bt-app-menu .bt-app-zoom button[aria-disabled=true]:active { background: var(--bt-hover); }
79
85
  .bt-app-zoom-value { min-width: 50px; padding: 0 2px; text-align: center; color: var(--bt-text); font: 500 12px/1 var(--bt-mono); font-variant-numeric: tabular-nums; }
80
- .bt-app-menu .bt-app-zoom .bt-app-zoom-reset { width: 28px; border-radius: 9px; }
86
+ .bt-app-menu .bt-app-zoom .bt-app-zoom-reset { width: 28px; border-radius: calc(9px * var(--bt-rs, 1)); }
81
87
 
82
88
  /* Words that are not a choice: the mode question, an empty list, an error. */
83
89
  .bt-app-note { display: flex; flex-direction: column; gap: 3px; max-width: 288px; padding: 8px 10px 7px; box-sizing: border-box; }
@@ -86,7 +92,7 @@ html:not(:has(.bt-app-button)) { --bt-tb-menu: 0px; }
86
92
  .bt-app-note.is-error span { color: var(--bt-danger); }
87
93
 
88
94
  /* The account menu's last row: the way here from where the account name is. */
89
- .bt-menu .bt-acct-settings { flex: none; height: 34px; gap: 11px; padding: 0 8px; border-radius: 10px; color: var(--bt-text-2); }
95
+ .bt-menu .bt-acct-settings { flex: none; height: 34px; gap: 11px; padding: 0 8px; border-radius: calc(10px * var(--bt-rs, 1)); color: var(--bt-text-2); }
90
96
  .bt-menu .bt-acct-settings > .bt-glyph { width: 32px; height: 15px; }
91
97
  .bt-menu .bt-acct-settings:focus-visible { box-shadow: var(--bt-ring); }
92
98
 
@@ -23,6 +23,8 @@ export function bootScript(options = {}) {
23
23
  for (const [name, value] of Object.entries(vars)) {
24
24
  if (/^--wb-[a-z]-[a-z0-9-]+$/.test(name) && typeof value === 'string' && value.length < 400) root.style.setProperty(name, value);
25
25
  }
26
+ // The edge style (frame/edges.css) from the first frame too, like chromeEdges() in themeStore.
27
+ if (vars['--wb-c-edges'] === 'bevel') root.dataset.wbEdges = 'bevel';
26
28
  // shell.css (loaded with the shell's modules) paints the same ground; this rule only covers
27
29
  // the frames before it, and \`html.bt-raised\` (more specific) still clears it.
28
30
  const style = document.createElement('style');
@@ -1 +1 @@
1
- {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/boot.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,qGAAqG;AACrG,iGAAiG;AACjG,gGAAgG;AAChG,4FAA4F;AAC5F,gEAAgE;AAEhE,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAC,UAA8B,EAAE;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC;IACvD,OAAO;8DACqD,cAAc;;;;oBAIxD,KAAK;mDAC0B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;;;;;;;6DASpB,WAAW;;;;CAIvE,CAAC;AACF,CAAC","sourcesContent":["// The first-frame script (`boot.js`, a classic script in the shell page's <head>): the chrome\n// colors the global theme had last time (themeStore.ts writes them under BOOT_CACHE_KEY), so a light\n// theme never starts on the dark default while the shell's modules and the persisted theme load.\n// Shell webview only: other local webviews of the app (e.g. a popover) share the page and paint\n// their own background. The app serves `bootScript()` as `/boot.js` (see the README: a Vite\n// plugin or a build step writes it; nothing is copied by hand).\n\n/** localStorage key of the last chrome variables (`--wb-*` name → value). */\nexport const BOOT_CACHE_KEY = 'bt.chrome.vars';\n\n/** The page ground before any theme (Night Ink), as shell.css paints it. */\nexport const BOOT_GROUND = '#07080c';\n\n/** The boot script's source. `label`: the shell webview's label (waybetter-host `policy::SHELL_LABEL`). */\nexport function bootScript(options: { label?: string } = {}): string {\n const label = JSON.stringify(options.label ?? 'shell');\n return `// Generated from waybetter/shell/frame/boot (bootScript): runs before the shell's first frame and\n// paints the chrome colors the global theme had last time (${BOOT_CACHE_KEY}).\n(() => {\n try {\n const label = window.__TAURI_INTERNALS__?.metadata?.currentWebview?.label;\n if (label !== ${label}) return;\n const vars = JSON.parse(localStorage.getItem(${JSON.stringify(BOOT_CACHE_KEY)}) || 'null');\n if (!vars || typeof vars !== 'object') return;\n const root = document.documentElement;\n for (const [name, value] of Object.entries(vars)) {\n if (/^--wb-[a-z]-[a-z0-9-]+$/.test(name) && typeof value === 'string' && value.length < 400) root.style.setProperty(name, value);\n }\n // shell.css (loaded with the shell's modules) paints the same ground; this rule only covers\n // the frames before it, and \\`html.bt-raised\\` (more specific) still clears it.\n const style = document.createElement('style');\n style.textContent = 'html{background:var(--wb-c-ground,${BOOT_GROUND})}';\n document.head.appendChild(style);\n } catch { /* No cache yet or blocked storage: the default ground. */ }\n})();\n`;\n}\n"]}
1
+ {"version":3,"file":"boot.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/boot.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,qGAAqG;AACrG,iGAAiG;AACjG,gGAAgG;AAChG,4FAA4F;AAC5F,gEAAgE;AAEhE,6EAA6E;AAC7E,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE/C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AAErC,2GAA2G;AAC3G,MAAM,UAAU,UAAU,CAAC,UAA8B,EAAE;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC;IACvD,OAAO;8DACqD,cAAc;;;;oBAIxD,KAAK;mDAC0B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;;;;;;;;;6DAWpB,WAAW;;;;CAIvE,CAAC;AACF,CAAC","sourcesContent":["// The first-frame script (`boot.js`, a classic script in the shell page's <head>): the chrome\n// colors the global theme had last time (themeStore.ts writes them under BOOT_CACHE_KEY), so a light\n// theme never starts on the dark default while the shell's modules and the persisted theme load.\n// Shell webview only: other local webviews of the app (e.g. a popover) share the page and paint\n// their own background. The app serves `bootScript()` as `/boot.js` (see the README: a Vite\n// plugin or a build step writes it; nothing is copied by hand).\n\n/** localStorage key of the last chrome variables (`--wb-*` name → value). */\nexport const BOOT_CACHE_KEY = 'bt.chrome.vars';\n\n/** The page ground before any theme (Night Ink), as shell.css paints it. */\nexport const BOOT_GROUND = '#07080c';\n\n/** The boot script's source. `label`: the shell webview's label (waybetter-host `policy::SHELL_LABEL`). */\nexport function bootScript(options: { label?: string } = {}): string {\n const label = JSON.stringify(options.label ?? 'shell');\n return `// Generated from waybetter/shell/frame/boot (bootScript): runs before the shell's first frame and\n// paints the chrome colors the global theme had last time (${BOOT_CACHE_KEY}).\n(() => {\n try {\n const label = window.__TAURI_INTERNALS__?.metadata?.currentWebview?.label;\n if (label !== ${label}) return;\n const vars = JSON.parse(localStorage.getItem(${JSON.stringify(BOOT_CACHE_KEY)}) || 'null');\n if (!vars || typeof vars !== 'object') return;\n const root = document.documentElement;\n for (const [name, value] of Object.entries(vars)) {\n if (/^--wb-[a-z]-[a-z0-9-]+$/.test(name) && typeof value === 'string' && value.length < 400) root.style.setProperty(name, value);\n }\n // The edge style (frame/edges.css) from the first frame too, like chromeEdges() in themeStore.\n if (vars['--wb-c-edges'] === 'bevel') root.dataset.wbEdges = 'bevel';\n // shell.css (loaded with the shell's modules) paints the same ground; this rule only covers\n // the frames before it, and \\`html.bt-raised\\` (more specific) still clears it.\n const style = document.createElement('style');\n style.textContent = 'html{background:var(--wb-c-ground,${BOOT_GROUND})}';\n document.head.appendChild(style);\n } catch { /* No cache yet or blocked storage: the default ground. */ }\n})();\n`;\n}\n"]}
@@ -1,8 +1,10 @@
1
+ import { type SurfaceSet } from '../../runtime/themeDerive.ts';
1
2
  /** The shell's own interface font (what an inheriting chrome role falls back to outside the page). */
2
3
  export declare const SHELL_UI_FONT = "'Geist Variable', system-ui, sans-serif";
3
4
  export declare const SHELL_MONO_FONT = "'Geist Mono Variable', ui-monospace, monospace";
4
5
  /** A theme as the chrome needs it: seven colors (none: the site's own colors) and two font stacks. */
5
6
  export type ChromeTheme = {
7
+ /** `page`, `inverse` and `onInverse` are optional: a bevelled chrome builds its face and title bar from them. */
6
8
  colors?: {
7
9
  bg: string;
8
10
  surface: string;
@@ -11,7 +13,18 @@ export type ChromeTheme = {
11
13
  text: string;
12
14
  muted: string;
13
15
  accent: string;
16
+ page?: string;
17
+ inverse?: string;
18
+ onInverse?: string;
14
19
  } | null;
20
+ /** The theme's corner radius in px: every chrome radius scales by radius / 12 (0 to 1.5, `--wb-c-rs`). Absent: wayBetter's own. */
21
+ radius?: number | null;
22
+ /**
23
+ * How the chrome's edges are drawn. `bevel`: raised and sunken edges after 98.css (MIT, Jordan
24
+ * Scales), square corners, a face color under tabs, menus and dialogs, a title-bar gradient
25
+ * (frame/edges.css, keyed on `html[data-wb-edges]`). Absent: wayBetter's own soft edges.
26
+ */
27
+ edges?: 'bevel' | null;
15
28
  /** The chrome's font stack when the theme sets one other than SHELL_UI_FONT. */
16
29
  chromeFont?: string | null;
17
30
  /** The mono font stack when the theme sets one. */
@@ -20,10 +33,15 @@ export type ChromeTheme = {
20
33
  export declare function luminance(hex: string): number;
21
34
  export declare function contrast(a: string, b: string): number;
22
35
  export declare function mix(a: string, b: string, t: number): string;
36
+ /** The theme's surfaces (theme engine v3, themeDerive.ts): the chrome takes its title bar, face and selection from them. */
37
+ export declare function chromeSurfaces(theme: ChromeTheme): SurfaceSet | null;
23
38
  /**
24
39
  * CSS custom properties for the chrome in `theme`. A theme that keeps the site's colors changes
25
- * only the fonts; `own` keeps wayBetter's own style entirely (empty result).
40
+ * only the fonts (and keeps wayBetter's own corners and edges); `own` keeps wayBetter's own style
41
+ * entirely (empty result).
26
42
  */
27
43
  export declare function chromeVars(theme: ChromeTheme, own?: boolean): Record<string, string>;
28
44
  /** Every variable chromeVars may set (to clear them when a pane returns to the global theme). */
29
45
  export declare const CHROME_VAR_NAMES: string[];
46
+ /** The edge style a set of chrome variables asks for (`html[data-wb-edges]`), or null. */
47
+ export declare function chromeEdges(vars: Record<string, string>): string | null;
@@ -2,6 +2,9 @@
2
2
  // the shell's `--wb-c-*` (tabs, address bar, titlebar, menus) and the panel's `--wb-p-*` tokens,
3
3
  // which shell.css (and the app's panel CSS) read with Night Ink as the fallback. Pure (tests,
4
4
  // shell, panel). The app turns its theme documents into a `ChromeTheme` (site.themes.chrome).
5
+ // Inks come from the engine's contrast solver and surfaces (theme engine v3, steps 4-5).
6
+ import { deriveSurfaces, surfacesInputFromV2 } from "../../runtime/themeDerive.js";
7
+ import { inkOn } from "../../runtime/themeInk.js";
5
8
  /** The shell's own interface font (what an inheriting chrome role falls back to outside the page). */
6
9
  export const SHELL_UI_FONT = "'Geist Variable', system-ui, sans-serif";
7
10
  export const SHELL_MONO_FONT = "'Geist Mono Variable', ui-monospace, monospace";
@@ -23,21 +26,16 @@ export function mix(a, b, t) {
23
26
  return toHex(x.map((v, i) => v + (y[i] - v) * t));
24
27
  }
25
28
  const channels = (hex) => hexToRgb(hex).join(' ');
26
- /** Moves `color` toward `pole` until it reads at `ratio` on `surface`. */
27
- function legible(color, surface, ratio) {
28
- if (contrast(color, surface) >= ratio)
29
- return color;
30
- const pole = luminance(surface) > 0.18 ? '#000000' : '#ffffff';
31
- for (let t = 0.1; t <= 1; t += 0.1) {
32
- const next = mix(color, pole, t);
33
- if (contrast(next, surface) >= ratio)
34
- return next;
35
- }
36
- return pole;
29
+ /** The theme's surfaces (theme engine v3, themeDerive.ts): the chrome takes its title bar, face and selection from them. */
30
+ export function chromeSurfaces(theme) {
31
+ return theme.colors ? deriveSurfaces(surfacesInputFromV2(theme.colors, { bevel: theme.edges === 'bevel' })) : null;
37
32
  }
33
+ /** The colour closest to `color` that reads at `ratio` on `surface` (the engine's solver, themeInk.ts). */
34
+ const legible = (color, surface, ratio) => inkOn(surface, color, ratio).ink;
38
35
  /**
39
36
  * CSS custom properties for the chrome in `theme`. A theme that keeps the site's colors changes
40
- * only the fonts; `own` keeps wayBetter's own style entirely (empty result).
37
+ * only the fonts (and keeps wayBetter's own corners and edges); `own` keeps wayBetter's own style
38
+ * entirely (empty result).
41
39
  */
42
40
  export function chromeVars(theme, own = false) {
43
41
  if (own)
@@ -51,6 +49,10 @@ export function chromeVars(theme, own = false) {
51
49
  const colors = theme.colors;
52
50
  if (!colors)
53
51
  return vars;
52
+ // Radii follow the theme's own corners: square themes get a square chrome, round ones a rounder one.
53
+ if (typeof theme.radius === 'number' && Number.isFinite(theme.radius)) {
54
+ vars['--wb-c-rs'] = String(Math.round(Math.min(1.5, Math.max(0, theme.radius / 12)) * 100) / 100);
55
+ }
54
56
  const { bg, surface, elevated, border, text, muted, accent } = colors;
55
57
  const dark = luminance(bg) < luminance(text);
56
58
  const ink = legible(mix(accent, text, 0.55), elevated, 4.5);
@@ -59,9 +61,15 @@ export function chromeVars(theme, own = false) {
59
61
  '--wb-c-ground': bg, '--wb-c-chrome': surface, '--wb-c-field': mix(surface, elevated, 0.45),
60
62
  '--wb-c-raised': elevated, '--wb-c-raised-2': mix(elevated, border, 0.45),
61
63
  '--wb-c-line': border, '--wb-c-line-soft': mix(border, bg, 0.45), '--wb-c-line-strong': mix(border, text, 0.14),
62
- '--wb-c-text': text, '--wb-c-text-2': mix(text, muted, 0.4), '--wb-c-muted': muted, '--wb-c-faint': mix(muted, bg, 0.38),
64
+ '--wb-c-text': text, '--wb-c-text-2': mix(text, muted, 0.4), '--wb-c-muted': legible(muted, elevated, 4.5),
65
+ // Shortcut hints and section labels sit on the menus' raised surface: they keep 4.5:1 there (a 38% fade toward the ground read 2.1 to 3.6:1).
66
+ '--wb-c-faint': legible(mix(muted, bg, 0.38), elevated, 4.5),
63
67
  '--wb-c-text-rgb': channels(text), '--wb-c-accent': accent, '--wb-c-accent-rgb': channels(accent), '--wb-c-accent-ink': ink,
64
68
  '--wb-c-scheme': dark ? 'dark' : 'light',
69
+ // Status inks (a signed-out account, an error) readable on the menus' raised surface, whatever its shade.
70
+ '--wb-c-warn': legible(dark ? '#f0b14a' : '#9a5b00', elevated, 4.5), '--wb-c-danger-ink': legible(dark ? '#ff8a80' : '#b3261e', elevated, 4.5),
71
+ // The chrome's marks (active tab, palette edge) in the theme's accent instead of wayBetter's brush.
72
+ '--wb-c-brush': `linear-gradient(90deg, ${accent}, ${accent})`,
65
73
  ...(dark ? {} : { '--wb-c-shadow-pop': `0 18px 44px -14px rgba(${hexToRgb(mix(text, bg, 0.2)).join(', ')}, .28), 0 3px 10px rgba(0, 0, 0, .08)` }),
66
74
  // Panel.
67
75
  '--wb-p-ground': bg, '--wb-p-chrome': mix(bg, surface, 0.5), '--wb-p-card': surface, '--wb-p-field': mix(surface, elevated, 0.5), '--wb-p-raise': elevated,
@@ -71,11 +79,40 @@ export function chromeVars(theme, own = false) {
71
79
  '--wb-p-text-rgb': channels(text), '--wb-p-popover': elevated, '--wb-p-thumb': `linear-gradient(180deg, ${mix(elevated, text, 0.08)}, ${elevated})`,
72
80
  '--wb-p-track': mix(elevated, border, 0.5), '--wb-p-knob': mix(muted, text, 0.3),
73
81
  });
82
+ if (theme.edges === 'bevel')
83
+ Object.assign(vars, bevelVars(colors));
74
84
  return vars;
75
85
  }
86
+ /**
87
+ * A bevelled chrome: the face every raised part is made of (the theme's `page`, else its raised
88
+ * surface), the four edge lines of 98.css derived from that face (white highlight, light, shadow,
89
+ * near-black), the field under text (the theme's background) and the active title bar (inverse to
90
+ * accent, its label readable on both ends).
91
+ */
92
+ function bevelVars(colors) {
93
+ const set = deriveSurfaces(surfacesInputFromV2(colors, { bevel: true }));
94
+ const face = set.chrome.fill;
95
+ const strong = set.strong;
96
+ return {
97
+ '--wb-c-edges': 'bevel', '--wb-c-face': face, '--wb-c-face-text': legible(colors.text, face, 7),
98
+ '--wb-c-bevel-hi': mix(face, '#ffffff', 1), '--wb-c-bevel-lt': mix(face, '#ffffff', 0.49),
99
+ '--wb-c-bevel-sh': mix(face, '#000000', 0.335), '--wb-c-bevel-dk': mix(face, '#000000', 0.95),
100
+ // The active title bar is the strong surface: inverse to its gradient end, one ink readable on both.
101
+ '--wb-c-title-from': strong.fill, '--wb-c-title-to': strong.fill2 ?? strong.fill, '--wb-c-title-text': strong.ink,
102
+ // Selected rows (menus, lists): the title bar's own color, as in a 98 menu.
103
+ '--wb-c-select': strong.fill, '--wb-c-select-text': strong.ink,
104
+ // Menus are the face: status inks are measured on it.
105
+ '--wb-c-muted': set.chrome.inkSoft, '--wb-c-faint': set.chrome.inkSoft,
106
+ '--wb-c-warn': legible('#806000', face, 4.5), '--wb-c-danger-ink': legible('#a00000', face, 4.5),
107
+ };
108
+ }
76
109
  /** Every variable chromeVars may set (to clear them when a pane returns to the global theme). */
77
110
  export const CHROME_VAR_NAMES = Object.keys(chromeVars({
78
111
  colors: { bg: '#000000', surface: '#111111', elevated: '#222222', border: '#333333', text: '#ffffff', muted: '#999999', accent: '#1d9bf0' },
79
- chromeFont: 'A', monoFont: 'B',
112
+ chromeFont: 'A', monoFont: 'B', radius: 12, edges: 'bevel',
80
113
  })).concat('--wb-c-shadow-pop');
114
+ /** The edge style a set of chrome variables asks for (`html[data-wb-edges]`), or null. */
115
+ export function chromeEdges(vars) {
116
+ return vars['--wb-c-edges'] === 'bevel' ? 'bevel' : null;
117
+ }
81
118
  //# sourceMappingURL=chromeTheme.js.map