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.
- package/README.md +1 -2
- package/bin/waybetter.mjs +2 -5
- package/cli/buildenv.mjs +1 -1
- package/cli/release.mjs +11 -18
- package/cli/releasecheck.mjs +15 -0
- package/cli/remote.mjs +4 -4
- package/cli/store.mjs +80 -28
- package/cli/strings.mjs +2 -0
- package/dist/runtime/stringPackHook.js +2 -2
- package/dist/runtime/stringPackHook.js.map +1 -1
- package/dist/runtime/stringPackTranslate.d.ts +3 -1
- package/dist/runtime/stringPackTranslate.js +6 -3
- package/dist/runtime/stringPackTranslate.js.map +1 -1
- package/dist/runtime/stringPacks.d.ts +53 -5
- package/dist/runtime/stringPacks.js +161 -25
- package/dist/runtime/stringPacks.js.map +1 -1
- package/dist/runtime/themeBar.d.ts +28 -0
- package/dist/runtime/themeBar.js +82 -0
- package/dist/runtime/themeBar.js.map +1 -0
- package/dist/runtime/themeComponents.js +16 -3
- package/dist/runtime/themeComponents.js.map +1 -1
- package/dist/runtime/themeDecor.js +3 -1
- package/dist/runtime/themeDecor.js.map +1 -1
- package/dist/runtime/themeDerive.d.ts +69 -0
- package/dist/runtime/themeDerive.js +117 -0
- package/dist/runtime/themeDerive.js.map +1 -0
- package/dist/runtime/themeDoctor.d.ts +44 -3
- package/dist/runtime/themeDoctor.js +86 -25
- package/dist/runtime/themeDoctor.js.map +1 -1
- package/dist/runtime/themeGuards.d.ts +60 -0
- package/dist/runtime/themeGuards.js +235 -0
- package/dist/runtime/themeGuards.js.map +1 -0
- package/dist/runtime/themeIcons.d.ts +1 -1
- package/dist/runtime/themeIcons.js +13 -5
- package/dist/runtime/themeIcons.js.map +1 -1
- package/dist/runtime/themeInk.d.ts +37 -0
- package/dist/runtime/themeInk.js +111 -0
- package/dist/runtime/themeInk.js.map +1 -0
- package/dist/runtime/themeInvariants.d.ts +39 -0
- package/dist/runtime/themeInvariants.js +273 -0
- package/dist/runtime/themeInvariants.js.map +1 -0
- package/dist/runtime/themeRuntime.d.ts +15 -1
- package/dist/runtime/themeRuntime.js +78 -5
- package/dist/runtime/themeRuntime.js.map +1 -1
- package/dist/runtime/themeSpec.d.ts +5 -1
- package/dist/runtime/themeSpec.js +9 -13
- package/dist/runtime/themeSpec.js.map +1 -1
- package/dist/shell/InstallDialog.js +14 -8
- package/dist/shell/InstallDialog.js.map +1 -1
- package/dist/shell/StoreView.d.ts +12 -0
- package/dist/shell/StoreView.js +9 -4
- package/dist/shell/StoreView.js.map +1 -1
- package/dist/shell/frame/AppMenu.d.ts +26 -3
- package/dist/shell/frame/AppMenu.js +106 -27
- package/dist/shell/frame/AppMenu.js.map +1 -1
- package/dist/shell/frame/FindBar.js +1 -1
- package/dist/shell/frame/FindBar.js.map +1 -1
- package/dist/shell/frame/Shell.d.ts +1 -0
- package/dist/shell/frame/Shell.js +10 -2
- package/dist/shell/frame/Shell.js.map +1 -1
- package/dist/shell/frame/Titlebar.d.ts +2 -1
- package/dist/shell/frame/Titlebar.js +5 -3
- package/dist/shell/frame/Titlebar.js.map +1 -1
- package/dist/shell/frame/WebPanel.js +4 -1
- package/dist/shell/frame/WebPanel.js.map +1 -1
- package/dist/shell/frame/accountSwitcher.css +10 -10
- package/dist/shell/frame/appMenu.css +19 -13
- package/dist/shell/frame/boot.js +2 -0
- package/dist/shell/frame/boot.js.map +1 -1
- package/dist/shell/frame/chromeTheme.d.ts +19 -1
- package/dist/shell/frame/chromeTheme.js +51 -14
- package/dist/shell/frame/chromeTheme.js.map +1 -1
- package/dist/shell/frame/deck.css +30 -30
- package/dist/shell/frame/edges.css +159 -0
- package/dist/shell/frame/index.d.ts +2 -2
- package/dist/shell/frame/index.js +1 -1
- package/dist/shell/frame/index.js.map +1 -1
- package/dist/shell/frame/mediaModel.d.ts +13 -0
- package/dist/shell/frame/mediaModel.js +14 -0
- package/dist/shell/frame/mediaModel.js.map +1 -1
- package/dist/shell/frame/menuMessages.en.json +43 -1
- package/dist/shell/frame/menuModel.d.ts +42 -0
- package/dist/shell/frame/menuModel.js +8 -0
- package/dist/shell/frame/menuModel.js.map +1 -1
- package/dist/shell/frame/nativeMenu.d.ts +5 -0
- package/dist/shell/frame/nativeMenu.js +178 -0
- package/dist/shell/frame/nativeMenu.js.map +1 -0
- package/dist/shell/frame/nativeMenuModel.d.ts +102 -0
- package/dist/shell/frame/nativeMenuModel.js +186 -0
- package/dist/shell/frame/nativeMenuModel.js.map +1 -0
- package/dist/shell/frame/paletteModel.js +3 -1
- package/dist/shell/frame/paletteModel.js.map +1 -1
- package/dist/shell/frame/paneTheme.css +1 -1
- package/dist/shell/frame/reportModel.d.ts +1 -1
- package/dist/shell/frame/reportModel.js +1 -1
- package/dist/shell/frame/reportModel.js.map +1 -1
- package/dist/shell/frame/shell.css +56 -51
- package/dist/shell/frame/state.d.ts +2 -0
- package/dist/shell/frame/state.js +3 -1
- package/dist/shell/frame/state.js.map +1 -1
- package/dist/shell/frame/themeStore.js +21 -6
- package/dist/shell/frame/themeStore.js.map +1 -1
- package/dist/shell/frame/workspaces.css +12 -12
- package/dist/shell/installController.d.ts +16 -1
- package/dist/shell/installController.js +31 -5
- package/dist/shell/installController.js.map +1 -1
- package/dist/shell/panel/Appearance.js +12 -3
- package/dist/shell/panel/Appearance.js.map +1 -1
- package/dist/shell/panel/Settings.d.ts +1 -1
- package/dist/shell/panel/Settings.js +4 -3
- package/dist/shell/panel/Settings.js.map +1 -1
- package/dist/shell/panel/StoreSection.d.ts +2 -1
- package/dist/shell/panel/StoreSection.js +31 -1
- package/dist/shell/panel/StoreSection.js.map +1 -1
- package/dist/shell/panel/StringPacks.d.ts +12 -3
- package/dist/shell/panel/StringPacks.js +33 -8
- package/dist/shell/panel/StringPacks.js.map +1 -1
- package/dist/shell/panel/backup.css +1 -1
- package/dist/shell/panel/builder.css +48 -40
- package/dist/shell/panel/make.css +8 -7
- package/dist/shell/panel/panel.css +401 -401
- package/dist/shell/panel/panelMessages.d.ts +41 -1
- package/dist/shell/panel/panelMessages.js +13 -1
- package/dist/shell/panel/panelMessages.js.map +1 -1
- package/dist/shell/panel/plugins.css +5 -5
- package/dist/shell/panel/strings.css +1 -1
- package/dist/shell/store.css +34 -14
- package/dist/shell/storeMessages.d.ts +24 -0
- package/dist/shell/storeMessages.js +24 -0
- package/dist/shell/storeMessages.js.map +1 -1
- package/dist/shell/storeModel.d.ts +31 -7
- package/dist/shell/storeModel.js +15 -2
- package/dist/shell/storeModel.js.map +1 -1
- package/dist/shell/stringPacksModel.js +7 -2
- package/dist/shell/stringPacksModel.js.map +1 -1
- package/icons.schema.json +9 -0
- package/locales/ar.json +109 -2
- package/locales/bg.json +109 -2
- package/locales/bn.json +109 -2
- package/locales/ca.json +109 -2
- package/locales/cs.json +109 -2
- package/locales/da.json +109 -2
- package/locales/de.json +109 -2
- package/locales/el.json +109 -2
- package/locales/en.json +108 -2
- package/locales/es.json +109 -2
- package/locales/eu.json +109 -2
- package/locales/fa.json +109 -2
- package/locales/fi.json +109 -2
- package/locales/fil.json +109 -2
- package/locales/fr.json +109 -2
- package/locales/ga.json +109 -2
- package/locales/gl.json +109 -2
- package/locales/gu.json +109 -2
- package/locales/ha.json +109 -2
- package/locales/he.json +109 -2
- package/locales/hi.json +109 -2
- package/locales/hr.json +109 -2
- package/locales/hu.json +110 -2
- package/locales/id.json +109 -2
- package/locales/ig.json +109 -2
- package/locales/it.json +109 -2
- package/locales/ja.json +109 -2
- package/locales/kn.json +109 -2
- package/locales/ko.json +109 -2
- package/locales/mr.json +109 -2
- package/locales/ms.json +109 -2
- package/locales/nb.json +109 -2
- package/locales/nl.json +109 -2
- package/locales/pl.json +109 -2
- package/locales/pt.json +109 -2
- package/locales/ro.json +109 -2
- package/locales/ru.json +109 -2
- package/locales/sk.json +109 -2
- package/locales/sr.json +109 -2
- package/locales/sv.json +109 -2
- package/locales/ta.json +109 -2
- package/locales/th.json +109 -2
- package/locales/tr.json +109 -2
- package/locales/uk.json +109 -2
- package/locales/ur.json +109 -2
- package/locales/vi.json +109 -2
- package/locales/yo.json +109 -2
- package/locales/zh-Hans.json +109 -2
- package/locales/zh-Hant.json +109 -2
- package/package.json +2 -3
- package/store-catalog.schema.json +18 -5
- package/theme.schema.json +9 -0
- package/windows/installer.nsi +22 -2
- package/cli/privacy.mjs +0 -768
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** One entry of a list the bar shows with a check (themes, modes, accounts, plugins, workspaces). */
|
|
2
|
+
export type Choice = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
checked: boolean;
|
|
6
|
+
};
|
|
7
|
+
/** What the bar reflects right now. Absent lists leave their submenu out. */
|
|
8
|
+
export type NativeMenuState = {
|
|
9
|
+
product: string;
|
|
10
|
+
hasPanel: boolean;
|
|
11
|
+
canSplit: boolean;
|
|
12
|
+
canFind: boolean;
|
|
13
|
+
safeActive: boolean;
|
|
14
|
+
features: {
|
|
15
|
+
find: boolean;
|
|
16
|
+
zoom: boolean;
|
|
17
|
+
deck: boolean;
|
|
18
|
+
store: boolean;
|
|
19
|
+
safeMode: boolean;
|
|
20
|
+
workspaces: boolean;
|
|
21
|
+
updates: boolean;
|
|
22
|
+
};
|
|
23
|
+
themes?: Choice[];
|
|
24
|
+
iconPacks?: Choice[];
|
|
25
|
+
modes?: Choice[];
|
|
26
|
+
accounts: Choice[];
|
|
27
|
+
plugins?: Choice[];
|
|
28
|
+
workspaces?: Choice[];
|
|
29
|
+
/** The app can install a file chosen from a dialog, share the setup, has docs and a website. */
|
|
30
|
+
installFromFile: boolean;
|
|
31
|
+
shareSetup: boolean;
|
|
32
|
+
docs: boolean;
|
|
33
|
+
website?: string;
|
|
34
|
+
};
|
|
35
|
+
/** What a chosen id does. The controller (nativeMenu.ts) wires these to the shell. */
|
|
36
|
+
export type NativeMenuActions = {
|
|
37
|
+
about(): void;
|
|
38
|
+
checkUpdates(): void;
|
|
39
|
+
settings(): void;
|
|
40
|
+
safeMode(): void;
|
|
41
|
+
newTab(): void;
|
|
42
|
+
splitRight(): void;
|
|
43
|
+
splitDown(): void;
|
|
44
|
+
closeTab(): void;
|
|
45
|
+
installFromFile(): void;
|
|
46
|
+
shareSetup(): void;
|
|
47
|
+
find(): void;
|
|
48
|
+
findNext(): void;
|
|
49
|
+
findPrevious(): void;
|
|
50
|
+
zoomIn(): void;
|
|
51
|
+
zoomOut(): void;
|
|
52
|
+
zoomReset(): void;
|
|
53
|
+
deck(): void;
|
|
54
|
+
theme(id: string): void;
|
|
55
|
+
iconPack(id: string): void;
|
|
56
|
+
mode(id: string): void;
|
|
57
|
+
account(id: string): void;
|
|
58
|
+
addAccount(): void;
|
|
59
|
+
plugin(id: string, on: boolean): void;
|
|
60
|
+
store(): void;
|
|
61
|
+
pluginsFolder(): void;
|
|
62
|
+
workspace(id: string): void;
|
|
63
|
+
saveWorkspace(): void;
|
|
64
|
+
docs(): void;
|
|
65
|
+
report(): void;
|
|
66
|
+
website(): void;
|
|
67
|
+
};
|
|
68
|
+
type Words = (name: string, params?: Record<string, string | number>) => string;
|
|
69
|
+
type Node = {
|
|
70
|
+
kind: 'item';
|
|
71
|
+
id: string;
|
|
72
|
+
label: string;
|
|
73
|
+
accelerator?: string;
|
|
74
|
+
checked?: boolean;
|
|
75
|
+
enabled?: boolean;
|
|
76
|
+
} | {
|
|
77
|
+
kind: 'separator';
|
|
78
|
+
} | {
|
|
79
|
+
kind: 'submenu';
|
|
80
|
+
label: string;
|
|
81
|
+
items: Node[];
|
|
82
|
+
enabled?: boolean;
|
|
83
|
+
role?: 'window' | 'help';
|
|
84
|
+
} | {
|
|
85
|
+
kind: 'predefined';
|
|
86
|
+
role: string;
|
|
87
|
+
label?: string;
|
|
88
|
+
};
|
|
89
|
+
/** The description `menu_set` takes. */
|
|
90
|
+
export type NativeMenuSpec = {
|
|
91
|
+
menus: Node[];
|
|
92
|
+
};
|
|
93
|
+
/** Ids carry only their alphabet (menu.rs `valid_id`); an app's ids are folded into it. */
|
|
94
|
+
export declare const safeId: (id: string) => string;
|
|
95
|
+
/**
|
|
96
|
+
* The whole bar: App, File, Edit, View, Account, Plugins, Window, Help. `w` reads a `wb.menu.*` word,
|
|
97
|
+
* `text` a catalog key of the frame (the labels the in-app menu already uses).
|
|
98
|
+
*/
|
|
99
|
+
export declare function planNativeMenu(state: NativeMenuState, w: Words, text: (key: string) => string): NativeMenuSpec;
|
|
100
|
+
/** Runs what `id` (an id of [`planNativeMenu`]) stands for; false for an id it does not know. */
|
|
101
|
+
export declare function runNativeMenu(id: string, state: NativeMenuState, act: NativeMenuActions): boolean;
|
|
102
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// Pure model of the native menu bar (macOS): what the shell describes to native code (`menu_set`,
|
|
2
|
+
// waybetter-host menu.rs) and which action each chosen id runs. No React, no Tauri: it is tested
|
|
3
|
+
// under node. Every item runs what the in-app menu, the palette or the keys already run; the bar
|
|
4
|
+
// adds no capability. Words are `wb.menu.*` (menuMessages.en.json) and the frame's own catalog keys.
|
|
5
|
+
/** One line, at most 120 characters (what menu.rs accepts), never empty. */
|
|
6
|
+
const clean = (label, fallback = '-') => label.replace(/[\u0000-\u001f\u007f-\u009f]+/g, ' ').trim().slice(0, 120) || fallback;
|
|
7
|
+
/** Ids carry only their alphabet (menu.rs `valid_id`); an app's ids are folded into it. */
|
|
8
|
+
export const safeId = (id) => id.replace(/[^A-Za-z0-9_.-]/g, '_').slice(0, 60);
|
|
9
|
+
const item = (id, label, rest = {}) => ({ kind: 'item', id, label: clean(label), ...rest });
|
|
10
|
+
const system = (role, label) => ({ kind: 'predefined', role, ...(label ? { label: clean(label) } : {}) });
|
|
11
|
+
const sep = { kind: 'separator' };
|
|
12
|
+
const submenu = (label, items, rest = {}) => ({ kind: 'submenu', label: clean(label), items, ...rest });
|
|
13
|
+
const choices = (prefix, list) => list.map(choice => item(`${prefix}:${safeId(choice.id)}`, choice.label, { checked: choice.checked }));
|
|
14
|
+
/** Separates non-empty groups with rules. */
|
|
15
|
+
const groups = (...parts) => parts.filter(part => part.length).flatMap((part, index) => (index ? [sep, ...part] : part));
|
|
16
|
+
/**
|
|
17
|
+
* The whole bar: App, File, Edit, View, Account, Plugins, Window, Help. `w` reads a `wb.menu.*` word,
|
|
18
|
+
* `text` a catalog key of the frame (the labels the in-app menu already uses).
|
|
19
|
+
*/
|
|
20
|
+
export function planNativeMenu(state, w, text) {
|
|
21
|
+
const { product, features } = state;
|
|
22
|
+
const app = submenu(product, groups([item('app.about', w('about', { product }))], [
|
|
23
|
+
...(features.updates ? [item('app.updates', w('appUpdates'))] : []),
|
|
24
|
+
item('app.settings', w('appSettings'), { accelerator: 'CmdOrCtrl+,' }),
|
|
25
|
+
...(features.safeMode ? [item('app.safe', w('appSafe'), { checked: state.safeActive })] : []),
|
|
26
|
+
], [system('services', w('appServices'))], [system('hide', w('appHide', { product })), system('hide_others', w('appHideOthers')), system('show_all', w('appShowAll'))], [system('quit', w('appQuit', { product }))]));
|
|
27
|
+
const file = submenu(w('barFile'), groups([item('file.new-tab', text('wb.shell.tab.new'), { accelerator: 'CmdOrCtrl+T' })], [
|
|
28
|
+
item('file.split-right', text('wb.shell.menu.splitRight'), { accelerator: 'CmdOrCtrl+\\', enabled: state.canSplit }),
|
|
29
|
+
item('file.split-down', text('wb.shell.menu.splitDown'), { accelerator: 'CmdOrCtrl+Shift+\\', enabled: state.canSplit }),
|
|
30
|
+
], [item('file.close', w('fileClose'), { accelerator: 'CmdOrCtrl+W', enabled: state.hasPanel })], [...(state.installFromFile ? [item('file.install', w('fileInstall'))] : []), ...(state.shareSetup ? [item('file.share', w('fileShare'))] : [])]));
|
|
31
|
+
const edit = submenu(w('barEdit'), groups([system('undo', w('editUndo')), system('redo', w('editRedo'))], [system('cut', w('editCut')), system('copy', w('editCopy')), system('paste', w('editPaste')), system('select_all', w('editSelectAll'))], features.find ? [
|
|
32
|
+
item('edit.find', w('editFind'), { accelerator: 'CmdOrCtrl+F', enabled: state.canFind }),
|
|
33
|
+
item('edit.find-next', w('editFindNext'), { accelerator: 'CmdOrCtrl+G', enabled: state.canFind }),
|
|
34
|
+
item('edit.find-previous', w('editFindPrevious'), { accelerator: 'CmdOrCtrl+Shift+G', enabled: state.canFind }),
|
|
35
|
+
] : []));
|
|
36
|
+
const view = submenu(w('barView'), groups(features.zoom ? [
|
|
37
|
+
item('view.zoom-in', w('viewZoomIn'), { accelerator: 'CmdOrCtrl+=' }),
|
|
38
|
+
item('view.zoom-out', w('viewZoomOut'), { accelerator: 'CmdOrCtrl+-' }),
|
|
39
|
+
item('view.zoom-reset', w('viewActual'), { accelerator: 'CmdOrCtrl+0' }),
|
|
40
|
+
] : [], [
|
|
41
|
+
...(state.themes?.length ? [submenu(w('theme'), choices('theme', state.themes))] : []),
|
|
42
|
+
...(state.iconPacks?.length ? [submenu(w('viewIconPack'), choices('icons', state.iconPacks))] : []),
|
|
43
|
+
...(state.modes?.length ? [submenu(text('wb.modes.section'), choices('mode', state.modes))] : []),
|
|
44
|
+
], features.deck ? [item('view.deck', w('viewDeck'), { accelerator: 'CmdOrCtrl+Shift+D' })] : [], [system('fullscreen', w('viewFullScreen'))]));
|
|
45
|
+
const account = submenu(w('barAccount'), groups(state.accounts.length ? choices('acct', state.accounts) : [item('acct.none', w('acctNone'), { enabled: false })], [item('acct.add', w('acctAdd'))]));
|
|
46
|
+
const plugins = submenu(w('barPlugins'), groups(state.plugins?.length ? choices('plugin', state.plugins) : [], [...(features.store ? [item('plugins.store', w('plugStore'))] : []), item('plugins.folder', w('plugFolder'))]));
|
|
47
|
+
const window = submenu(w('barWindow'), groups([system('minimize', w('winMinimize')), system('maximize', w('winZoom'))], features.workspaces ? [submenu(w('winWorkspaces'), groups(state.workspaces?.length ? choices('ws', state.workspaces) : [item('ws.none', w('noWorkspaces'), { enabled: false })], [item('ws.save', w('saveLayout'))]))] : []), { role: 'window' });
|
|
48
|
+
const help = submenu(w('barHelp'), groups(state.docs ? [item('help.docs', w('helpDocs'))] : [], [item('help.report', w('helpReport'))], state.website ? [item('help.website', state.website)] : []), { role: 'help' });
|
|
49
|
+
return { menus: [app, file, edit, view, account, plugins, window, help] };
|
|
50
|
+
}
|
|
51
|
+
/** Runs what `id` (an id of [`planNativeMenu`]) stands for; false for an id it does not know. */
|
|
52
|
+
export function runNativeMenu(id, state, act) {
|
|
53
|
+
const colon = id.indexOf(':');
|
|
54
|
+
if (colon > 0) {
|
|
55
|
+
const prefix = id.slice(0, colon);
|
|
56
|
+
const rest = id.slice(colon + 1);
|
|
57
|
+
const find = (list) => list?.find(choice => safeId(choice.id) === rest);
|
|
58
|
+
switch (prefix) {
|
|
59
|
+
case 'theme': {
|
|
60
|
+
const choice = find(state.themes);
|
|
61
|
+
if (choice) {
|
|
62
|
+
act.theme(choice.id);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
case 'icons': {
|
|
68
|
+
const choice = find(state.iconPacks);
|
|
69
|
+
if (choice) {
|
|
70
|
+
act.iconPack(choice.id);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
case 'mode': {
|
|
76
|
+
const choice = find(state.modes);
|
|
77
|
+
if (choice) {
|
|
78
|
+
act.mode(choice.id);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
case 'acct': {
|
|
84
|
+
const choice = find(state.accounts);
|
|
85
|
+
if (choice) {
|
|
86
|
+
act.account(choice.id);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
case 'plugin': {
|
|
92
|
+
const choice = find(state.plugins);
|
|
93
|
+
if (choice) {
|
|
94
|
+
act.plugin(choice.id, !choice.checked);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
case 'ws': {
|
|
100
|
+
const choice = find(state.workspaces);
|
|
101
|
+
if (choice) {
|
|
102
|
+
act.workspace(choice.id);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
default: return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
switch (id) {
|
|
111
|
+
case 'app.about':
|
|
112
|
+
act.about();
|
|
113
|
+
return true;
|
|
114
|
+
case 'app.updates':
|
|
115
|
+
act.checkUpdates();
|
|
116
|
+
return true;
|
|
117
|
+
case 'app.settings':
|
|
118
|
+
act.settings();
|
|
119
|
+
return true;
|
|
120
|
+
case 'app.safe':
|
|
121
|
+
act.safeMode();
|
|
122
|
+
return true;
|
|
123
|
+
case 'file.new-tab':
|
|
124
|
+
act.newTab();
|
|
125
|
+
return true;
|
|
126
|
+
case 'file.split-right':
|
|
127
|
+
act.splitRight();
|
|
128
|
+
return true;
|
|
129
|
+
case 'file.split-down':
|
|
130
|
+
act.splitDown();
|
|
131
|
+
return true;
|
|
132
|
+
case 'file.close':
|
|
133
|
+
act.closeTab();
|
|
134
|
+
return true;
|
|
135
|
+
case 'file.install':
|
|
136
|
+
act.installFromFile();
|
|
137
|
+
return true;
|
|
138
|
+
case 'file.share':
|
|
139
|
+
act.shareSetup();
|
|
140
|
+
return true;
|
|
141
|
+
case 'edit.find':
|
|
142
|
+
act.find();
|
|
143
|
+
return true;
|
|
144
|
+
case 'edit.find-next':
|
|
145
|
+
act.findNext();
|
|
146
|
+
return true;
|
|
147
|
+
case 'edit.find-previous':
|
|
148
|
+
act.findPrevious();
|
|
149
|
+
return true;
|
|
150
|
+
case 'view.zoom-in':
|
|
151
|
+
act.zoomIn();
|
|
152
|
+
return true;
|
|
153
|
+
case 'view.zoom-out':
|
|
154
|
+
act.zoomOut();
|
|
155
|
+
return true;
|
|
156
|
+
case 'view.zoom-reset':
|
|
157
|
+
act.zoomReset();
|
|
158
|
+
return true;
|
|
159
|
+
case 'view.deck':
|
|
160
|
+
act.deck();
|
|
161
|
+
return true;
|
|
162
|
+
case 'acct.add':
|
|
163
|
+
act.addAccount();
|
|
164
|
+
return true;
|
|
165
|
+
case 'plugins.store':
|
|
166
|
+
act.store();
|
|
167
|
+
return true;
|
|
168
|
+
case 'plugins.folder':
|
|
169
|
+
act.pluginsFolder();
|
|
170
|
+
return true;
|
|
171
|
+
case 'ws.save':
|
|
172
|
+
act.saveWorkspace();
|
|
173
|
+
return true;
|
|
174
|
+
case 'help.docs':
|
|
175
|
+
act.docs();
|
|
176
|
+
return true;
|
|
177
|
+
case 'help.report':
|
|
178
|
+
act.report();
|
|
179
|
+
return true;
|
|
180
|
+
case 'help.website':
|
|
181
|
+
act.website();
|
|
182
|
+
return true;
|
|
183
|
+
default: return false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=nativeMenuModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeMenuModel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/nativeMenuModel.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure model of the native menu bar (macOS): what the shell describes to native code (`menu_set`,\n// waybetter-host menu.rs) and which action each chosen id runs. No React, no Tauri: it is tested\n// under node. Every item runs what the in-app menu, the palette or the keys already run; the bar\n// adds no capability. Words are `wb.menu.*` (menuMessages.en.json) and the frame's own catalog keys.\n\n/** One entry of a list the bar shows with a check (themes, modes, accounts, plugins, workspaces). */\nexport type Choice = { id: string; label: string; checked: boolean };\n\n/** What the bar reflects right now. Absent lists leave their submenu out. */\nexport type NativeMenuState = {\n product: string;\n hasPanel: boolean;\n canSplit: boolean;\n canFind: boolean;\n safeActive: boolean;\n features: { find: boolean; zoom: boolean; deck: boolean; store: boolean; safeMode: boolean; workspaces: boolean; updates: boolean };\n themes?: Choice[];\n iconPacks?: Choice[];\n modes?: Choice[];\n accounts: Choice[];\n plugins?: Choice[];\n workspaces?: Choice[];\n /** The app can install a file chosen from a dialog, share the setup, has docs and a website. */\n installFromFile: boolean;\n shareSetup: boolean;\n docs: boolean;\n website?: string;\n};\n\n/** What a chosen id does. The controller (nativeMenu.ts) wires these to the shell. */\nexport type NativeMenuActions = {\n about(): void;\n checkUpdates(): void;\n settings(): void;\n safeMode(): void;\n newTab(): void;\n splitRight(): void;\n splitDown(): void;\n closeTab(): void;\n installFromFile(): void;\n shareSetup(): void;\n find(): void;\n findNext(): void;\n findPrevious(): void;\n zoomIn(): void;\n zoomOut(): void;\n zoomReset(): void;\n deck(): void;\n theme(id: string): void;\n iconPack(id: string): void;\n mode(id: string): void;\n account(id: string): void;\n addAccount(): void;\n plugin(id: string, on: boolean): void;\n store(): void;\n pluginsFolder(): void;\n workspace(id: string): void;\n saveWorkspace(): void;\n docs(): void;\n report(): void;\n website(): void;\n};\n\ntype Words = (name: string, params?: Record<string, string | number>) => string;\n\ntype Node =\n | { kind: 'item'; id: string; label: string; accelerator?: string; checked?: boolean; enabled?: boolean }\n | { kind: 'separator' }\n | { kind: 'submenu'; label: string; items: Node[]; enabled?: boolean; role?: 'window' | 'help' }\n | { kind: 'predefined'; role: string; label?: string };\n\n/** The description `menu_set` takes. */\nexport type NativeMenuSpec = { menus: Node[] };\n\n/** One line, at most 120 characters (what menu.rs accepts), never empty. */\nconst clean = (label: string, fallback = '-') => label.replace(/[\\u0000-\\u001f\\u007f-\\u009f]+/g, ' ').trim().slice(0, 120) || fallback;\n/** Ids carry only their alphabet (menu.rs `valid_id`); an app's ids are folded into it. */\nexport const safeId = (id: string) => id.replace(/[^A-Za-z0-9_.-]/g, '_').slice(0, 60);\n\nconst item = (id: string, label: string, rest: { accelerator?: string; checked?: boolean; enabled?: boolean } = {}): Node => ({ kind: 'item', id, label: clean(label), ...rest });\nconst system = (role: string, label?: string): Node => ({ kind: 'predefined', role, ...(label ? { label: clean(label) } : {}) });\nconst sep: Node = { kind: 'separator' };\nconst submenu = (label: string, items: Node[], rest: { enabled?: boolean; role?: 'window' | 'help' } = {}): Node => ({ kind: 'submenu', label: clean(label), items, ...rest });\nconst choices = (prefix: string, list: readonly Choice[]): Node[] => list.map(choice => item(`${prefix}:${safeId(choice.id)}`, choice.label, { checked: choice.checked }));\n\n/** Separates non-empty groups with rules. */\nconst groups = (...parts: Node[][]): Node[] => parts.filter(part => part.length).flatMap((part, index) => (index ? [sep, ...part] : part));\n\n/**\n * The whole bar: App, File, Edit, View, Account, Plugins, Window, Help. `w` reads a `wb.menu.*` word,\n * `text` a catalog key of the frame (the labels the in-app menu already uses).\n */\nexport function planNativeMenu(state: NativeMenuState, w: Words, text: (key: string) => string): NativeMenuSpec {\n const { product, features } = state;\n const app = submenu(product, groups(\n [item('app.about', w('about', { product }))],\n [\n ...(features.updates ? [item('app.updates', w('appUpdates'))] : []),\n item('app.settings', w('appSettings'), { accelerator: 'CmdOrCtrl+,' }),\n ...(features.safeMode ? [item('app.safe', w('appSafe'), { checked: state.safeActive })] : []),\n ],\n [system('services', w('appServices'))],\n [system('hide', w('appHide', { product })), system('hide_others', w('appHideOthers')), system('show_all', w('appShowAll'))],\n [system('quit', w('appQuit', { product }))],\n ));\n const file = submenu(w('barFile'), groups(\n [item('file.new-tab', text('wb.shell.tab.new'), { accelerator: 'CmdOrCtrl+T' })],\n [\n item('file.split-right', text('wb.shell.menu.splitRight'), { accelerator: 'CmdOrCtrl+\\\\', enabled: state.canSplit }),\n item('file.split-down', text('wb.shell.menu.splitDown'), { accelerator: 'CmdOrCtrl+Shift+\\\\', enabled: state.canSplit }),\n ],\n [item('file.close', w('fileClose'), { accelerator: 'CmdOrCtrl+W', enabled: state.hasPanel })],\n [...(state.installFromFile ? [item('file.install', w('fileInstall'))] : []), ...(state.shareSetup ? [item('file.share', w('fileShare'))] : [])],\n ));\n const edit = submenu(w('barEdit'), groups(\n [system('undo', w('editUndo')), system('redo', w('editRedo'))],\n [system('cut', w('editCut')), system('copy', w('editCopy')), system('paste', w('editPaste')), system('select_all', w('editSelectAll'))],\n features.find ? [\n item('edit.find', w('editFind'), { accelerator: 'CmdOrCtrl+F', enabled: state.canFind }),\n item('edit.find-next', w('editFindNext'), { accelerator: 'CmdOrCtrl+G', enabled: state.canFind }),\n item('edit.find-previous', w('editFindPrevious'), { accelerator: 'CmdOrCtrl+Shift+G', enabled: state.canFind }),\n ] : [],\n ));\n const view = submenu(w('barView'), groups(\n features.zoom ? [\n item('view.zoom-in', w('viewZoomIn'), { accelerator: 'CmdOrCtrl+=' }),\n item('view.zoom-out', w('viewZoomOut'), { accelerator: 'CmdOrCtrl+-' }),\n item('view.zoom-reset', w('viewActual'), { accelerator: 'CmdOrCtrl+0' }),\n ] : [],\n [\n ...(state.themes?.length ? [submenu(w('theme'), choices('theme', state.themes))] : []),\n ...(state.iconPacks?.length ? [submenu(w('viewIconPack'), choices('icons', state.iconPacks))] : []),\n ...(state.modes?.length ? [submenu(text('wb.modes.section'), choices('mode', state.modes))] : []),\n ],\n features.deck ? [item('view.deck', w('viewDeck'), { accelerator: 'CmdOrCtrl+Shift+D' })] : [],\n [system('fullscreen', w('viewFullScreen'))],\n ));\n const account = submenu(w('barAccount'), groups(\n state.accounts.length ? choices('acct', state.accounts) : [item('acct.none', w('acctNone'), { enabled: false })],\n [item('acct.add', w('acctAdd'))],\n ));\n const plugins = submenu(w('barPlugins'), groups(\n state.plugins?.length ? choices('plugin', state.plugins) : [],\n [...(features.store ? [item('plugins.store', w('plugStore'))] : []), item('plugins.folder', w('plugFolder'))],\n ));\n const window = submenu(w('barWindow'), groups(\n [system('minimize', w('winMinimize')), system('maximize', w('winZoom'))],\n features.workspaces ? [submenu(w('winWorkspaces'), groups(\n state.workspaces?.length ? choices('ws', state.workspaces) : [item('ws.none', w('noWorkspaces'), { enabled: false })],\n [item('ws.save', w('saveLayout'))],\n ))] : [],\n ), { role: 'window' });\n const help = submenu(w('barHelp'), groups(\n state.docs ? [item('help.docs', w('helpDocs'))] : [],\n [item('help.report', w('helpReport'))],\n state.website ? [item('help.website', state.website)] : [],\n ), { role: 'help' });\n return { menus: [app, file, edit, view, account, plugins, window, help] };\n}\n\n/** Runs what `id` (an id of [`planNativeMenu`]) stands for; false for an id it does not know. */\nexport function runNativeMenu(id: string, state: NativeMenuState, act: NativeMenuActions): boolean {\n const colon = id.indexOf(':');\n if (colon > 0) {\n const prefix = id.slice(0, colon);\n const rest = id.slice(colon + 1);\n const find = (list?: readonly Choice[]) => list?.find(choice => safeId(choice.id) === rest);\n switch (prefix) {\n case 'theme': { const choice = find(state.themes); if (choice) { act.theme(choice.id); return true; } return false; }\n case 'icons': { const choice = find(state.iconPacks); if (choice) { act.iconPack(choice.id); return true; } return false; }\n case 'mode': { const choice = find(state.modes); if (choice) { act.mode(choice.id); return true; } return false; }\n case 'acct': { const choice = find(state.accounts); if (choice) { act.account(choice.id); return true; } return false; }\n case 'plugin': { const choice = find(state.plugins); if (choice) { act.plugin(choice.id, !choice.checked); return true; } return false; }\n case 'ws': { const choice = find(state.workspaces); if (choice) { act.workspace(choice.id); return true; } return false; }\n default: return false;\n }\n }\n switch (id) {\n case 'app.about': act.about(); return true;\n case 'app.updates': act.checkUpdates(); return true;\n case 'app.settings': act.settings(); return true;\n case 'app.safe': act.safeMode(); return true;\n case 'file.new-tab': act.newTab(); return true;\n case 'file.split-right': act.splitRight(); return true;\n case 'file.split-down': act.splitDown(); return true;\n case 'file.close': act.closeTab(); return true;\n case 'file.install': act.installFromFile(); return true;\n case 'file.share': act.shareSetup(); return true;\n case 'edit.find': act.find(); return true;\n case 'edit.find-next': act.findNext(); return true;\n case 'edit.find-previous': act.findPrevious(); return true;\n case 'view.zoom-in': act.zoomIn(); return true;\n case 'view.zoom-out': act.zoomOut(); return true;\n case 'view.zoom-reset': act.zoomReset(); return true;\n case 'view.deck': act.deck(); return true;\n case 'acct.add': act.addAccount(); return true;\n case 'plugins.store': act.store(); return true;\n case 'plugins.folder': act.pluginsFolder(); return true;\n case 'ws.save': act.saveWorkspace(); return true;\n case 'help.docs': act.docs(); return true;\n case 'help.report': act.report(); return true;\n case 'help.website': act.website(); return true;\n default: return false;\n }\n}\n"]}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
// the app's panel opens at a section, plugin commands run in their tab; the site adds its own
|
|
4
4
|
// pages and completions (`site.palette`). Nothing here performs an account action on the user's behalf.
|
|
5
5
|
import { rankItems } from "../palette.js";
|
|
6
|
+
import { os } from "../windowControls.js";
|
|
6
7
|
import { t } from "./i18n.js";
|
|
8
|
+
import { mediaShortcutLabel } from "./mediaModel.js";
|
|
7
9
|
import { menuText } from "./menuModel.js";
|
|
8
10
|
export { fuzzyScore, moveSelection } from "../palette.js";
|
|
9
11
|
/** Commands at most listed from one tab (the runtime and native code cap them too). */
|
|
@@ -86,7 +88,7 @@ export function buildItems(context, query, setup) {
|
|
|
86
88
|
items.push({ id: `panel:${section.id}`, group: setup.product, label: section.label(), keywords: section.keywords, icon: section.icon, action: { type: 'panel', section: section.id } });
|
|
87
89
|
}
|
|
88
90
|
if (setup.media)
|
|
89
|
-
items.push({ id: 'media', group: setup.product, label: t('wb.palette.media'), hint:
|
|
91
|
+
items.push({ id: 'media', group: setup.product, label: t('wb.palette.media'), hint: mediaShortcutLabel(os), keywords: 'photos images screenshots attach paste media', icon: 'image', action: { type: 'media' } });
|
|
90
92
|
// Find in the page of the tab in front (the shell's find bar; nothing is sent anywhere).
|
|
91
93
|
if (setup.find !== false)
|
|
92
94
|
items.push({ id: 'find', group: setup.product, label: menuText('find'), hint: 'Ctrl+F', keywords: 'find search page text match', icon: 'search', action: { type: 'find' } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paletteModel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/paletteModel.ts"],"names":[],"mappings":"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","sourcesContent":["// Pure model for the command palette (no Tauri/DOM imports, so it is unit-tested under node).\n// Every item is navigation only: tabs are focused, profiles open a tab, decks and workspaces open,\n// the app's panel opens at a section, plugin commands run in their tab; the site adds its own\n// pages and completions (`site.palette`). Nothing here performs an account action on the user's behalf.\n\nimport { rankItems } from '../palette.ts';\nimport { t } from './i18n.ts';\nimport type { IconName } from './icons.tsx';\nimport { menuText } from './menuModel.ts';\nimport type { PaletteSite } from './site.ts';\n\nexport { fuzzyScore, moveSelection } from '../palette.ts';\n\nexport type PaletteAction =\n | { type: 'focus-tab'; id: string }\n | { type: 'new-tab'; profile: string }\n | { type: 'panel'; section: string }\n | { type: 'open'; url: string }\n | { type: 'media' }\n /** Decks (navigation only): open a deck, make a new one, add or focus a column. */\n | { type: 'deck'; deckId?: string }\n | { type: 'deck-new' }\n | { type: 'deck-add'; deckId: string }\n | { type: 'deck-focus'; deckId: string; columnId: string }\n /** Replaces the palette query (a completion); never navigates. */\n | { type: 'complete'; text: string }\n /** A plugin's command: the shell asks tab `tab` to run it in its page (`tab_run_command`). */\n | { type: 'plugin-command'; tab: string; command: string }\n /** Workspaces: restore one, or save the current layout under a name. */\n | { type: 'workspace'; id: string }\n | { type: 'workspace-save' }\n /** Opens the app menu (the titlebar's \"Settings and more\"). */\n | { type: 'menu' }\n /** Opens the find bar of the tab in front. */\n | { type: 'find' };\n\n/** The frame's groups; the app's items are grouped under its product name, plugin commands under the plugin's. */\nexport type PaletteGroup = 'Tabs' | 'Deck' | 'Workspaces' | 'Profiles';\n\nexport type PaletteItem = {\n id: string;\n /** A fixed group, the site's group, or a plugin's name for its commands. */\n group: PaletteGroup | (string & {});\n label: string;\n hint?: string;\n keywords?: string;\n /** The row's glyph (tabs show their favicon, profiles their avatar). */\n icon?: IconName;\n action: PaletteAction;\n};\n\nexport type PaletteContext = {\n /** `favicon` and `color` only decorate the list; matching ignores them. */\n tabs: Array<{ id: string; title: string; url: string; favicon?: string }>;\n profiles: Array<{ id: string; name: string; color?: string }>;\n activeProfile: string;\n /** Decks and their columns (titles only); absent when the app has no decks. */\n decks?: Array<{ id: string; name: string; columns: Array<{ id: string; title: string; profile: string }> }>;\n /** The deck tab in front, if any. */\n activeDeck?: string;\n /** Saved workspaces (names only) and the one opened last. */\n workspaces?: Array<{ id: string; name: string; tabs: number; isDefault?: boolean }>;\n activeWorkspace?: string;\n /** Plugin commands of the focused site tab, already named by plugin (`pluginCommandItems`). */\n commands?: { tab: string; items: PluginCommandItem[] };\n};\n\n/** What the palette knows about the app: its site items, its name and which frame features it has. */\nexport type PaletteSetup = { site: PaletteSite; product: string; decks: boolean; media: boolean; workspaces?: boolean; find?: boolean };\n\n/** A plugin command as the palette lists it: the tab's report plus the plugin's display name. */\nexport type PluginCommandItem = { id: string; title: string; keywords: string; plugin: string };\n\n/** Commands at most listed from one tab (the runtime and native code cap them too). */\nexport const MAX_PLUGIN_COMMANDS = 48;\n\n/**\n * Names each reported command (`<file>:<id>`) after its plugin (`@name` from the Plugins list);\n * commands registered outside a plugin's start are listed under \"Plugins\". Bounded.\n */\nexport function pluginCommandItems(reported: ReadonlyArray<{ id: string; title: string; keywords?: string }>, pluginNames: Readonly<Record<string, string>>): PluginCommandItem[] {\n const out: PluginCommandItem[] = [];\n for (const command of reported) {\n if (out.length >= MAX_PLUGIN_COMMANDS) break;\n if (typeof command?.id !== 'string' || typeof command.title !== 'string') continue;\n const at = command.id.indexOf(':');\n if (at <= 0) continue;\n const owner = command.id.slice(0, at);\n const plugin = (owner !== '_' && pluginNames[owner]) || (owner === '_' ? t('wb.palette.plugins') : owner.replace(/\\.plugin\\.js$/, ''));\n out.push({ id: command.id, title: command.title.slice(0, 80), keywords: (command.keywords ?? '').slice(0, 160), plugin });\n }\n return out;\n}\n\n/** The \"Workspaces\" group: switch to a saved workspace, save the current layout. */\nfunction workspaceItems(context: PaletteContext): PaletteItem[] {\n const items: PaletteItem[] = [];\n for (const workspace of context.workspaces ?? []) {\n items.push({\n id: `ws:${workspace.id}`, group: 'Workspaces', label: t('wb.palette.switchTo', { name: workspace.name }),\n hint: workspace.id === context.activeWorkspace ? t('wb.palette.active') : `${t('wb.ws.tabs', { count: workspace.tabs })}${workspace.isDefault ? ` · ${t('wb.palette.onStart')}` : ''}`,\n keywords: 'workspace layout restore session switch', action: { type: 'workspace', id: workspace.id },\n });\n }\n items.push({ id: 'ws-save', group: 'Workspaces', label: t('wb.ws.save'), keywords: 'workspace layout save session tabs panes', action: { type: 'workspace-save' } });\n return items;\n}\n\n/** The \"Deck\" group: open/switch decks, add a column, focus a column of the active deck. */\nfunction deckItems(context: PaletteContext): PaletteItem[] {\n const decks = context.decks ?? [];\n const items: PaletteItem[] = [];\n const active = decks.find(deck => deck.id === context.activeDeck);\n if (!decks.length) {\n items.push({ id: 'deck:open', group: 'Deck', label: t('wb.palette.openPower'), hint: 'Ctrl+Shift+D', keywords: 'deck tweetdeck columns power user', action: { type: 'deck' } });\n return items;\n }\n for (const deck of decks) {\n if (deck.id === active?.id) continue;\n items.push({ id: `deck:${deck.id}`, group: 'Deck', label: t('wb.palette.switchTo', { name: deck.name }), hint: t('wb.deck.columnCount', { count: deck.columns.length }), keywords: 'deck tweetdeck columns power user switch', action: { type: 'deck', deckId: deck.id } });\n }\n const target = active ?? decks[0]!;\n items.push({ id: `deck-add:${target.id}`, group: 'Deck', label: t('wb.palette.addColumn'), hint: target.name, keywords: 'deck column new tweetdeck', action: { type: 'deck-add', deckId: target.id } });\n if (active) {\n active.columns.forEach((column, index) => {\n items.push({ id: `deck-focus:${column.id}`, group: 'Deck', label: t('wb.palette.focusColumn', { name: column.title }), hint: index < 9 ? `Alt+${index + 1}` : undefined, keywords: 'column deck', action: { type: 'deck-focus', deckId: active.id, columnId: column.id } });\n });\n }\n items.push({ id: 'deck-new', group: 'Deck', label: t('wb.palette.newDeck'), keywords: 'deck columns power user create', action: { type: 'deck-new' } });\n return items;\n}\n\nexport function buildItems(context: PaletteContext, query: string, setup: PaletteSetup): PaletteItem[] {\n const { site } = setup;\n const items: PaletteItem[] = [];\n const text = query.trim();\n const search = text ? site.search?.(text) ?? null : null;\n if (search) items.push(search);\n for (const tab of context.tabs) {\n items.push({ id: `tab:${tab.id}`, group: 'Tabs', label: tab.title || tab.url, hint: tab.url, keywords: tab.url, action: { type: 'focus-tab', id: tab.id } });\n }\n if (setup.decks) items.push(...deckItems(context));\n if (setup.workspaces !== false) items.push(...workspaceItems(context));\n for (const profile of context.profiles) {\n items.push({ id: `profile:${profile.id}`, group: 'Profiles', label: t('wb.palette.newTabAs', { name: profile.name }), hint: profile.id === context.activeProfile ? t('wb.palette.active') : undefined, keywords: 'account switch', action: { type: 'new-tab', profile: profile.id } });\n }\n for (const section of site.sections) {\n items.push({ id: `panel:${section.id}`, group: setup.product, label: section.label(), keywords: section.keywords, icon: section.icon, action: { type: 'panel', section: section.id } });\n }\n if (setup.media) items.push({ id: 'media', group: setup.product, label: t('wb.palette.media'), hint: 'Ctrl+Shift+G', keywords: 'photos images screenshots attach paste media', icon: 'image', action: { type: 'media' } });\n // Find in the page of the tab in front (the shell's find bar; nothing is sent anywhere).\n if (setup.find !== false) items.push({ id: 'find', group: setup.product, label: menuText('find'), hint: 'Ctrl+F', keywords: 'find search page text match', icon: 'search', action: { type: 'find' } });\n // The app menu (the titlebar's \"Settings and more\"): language, theme, mode, zoom and the rest.\n items.push({ id: 'app-menu', group: setup.product, label: menuText('label'), hint: 'Alt+F', keywords: 'menu more settings language theme mode zoom options preferences', icon: 'settings', action: { type: 'menu' } });\n // Plugin commands, grouped under each plugin's name; they run in the focused site tab.\n if (context.commands) {\n const { tab } = context.commands;\n // One heading per plugin: stable sort keeps each plugin's own order.\n const sorted = context.commands.items.slice(0, MAX_PLUGIN_COMMANDS).sort((a, b) => a.plugin.localeCompare(b.plugin));\n for (const command of sorted) {\n items.push({ id: `cmd:${command.id}`, group: command.plugin, label: command.title, keywords: `${command.plugin} plugin ${command.keywords}`, icon: 'bolt', action: { type: 'plugin-command', tab, command: command.id } });\n }\n }\n items.push(...site.items?.() ?? []);\n if (!text) return items;\n const completions = site.completions?.(query.replace(/^\\s+/, '')) ?? [];\n const scored = rankItems(items, text, item => item === search);\n // The literal search stays available as the last resort.\n return search ? [...completions, ...scored, search] : [...completions, ...scored];\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"paletteModel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/paletteModel.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,mGAAmG;AACnG,8FAA8F;AAC9F,wGAAwG;AAExG,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,WAAW,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA8D1D,uFAAuF;AACvF,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAyE,EAAE,WAA6C;IACzJ,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,MAAM,IAAI,mBAAmB;YAAE,MAAM;QAC7C,IAAI,OAAO,OAAO,EAAE,EAAE,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,SAAS;QACnF,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC;YAAE,SAAS;QACtB,MAAM,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,CAAC,KAAK,KAAK,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC;QACvI,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oFAAoF;AACpF,SAAS,cAAc,CAAC,OAAuB;IAC7C,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,MAAM,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;YACxG,IAAI,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;YACtL,QAAQ,EAAE,yCAAyC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE;SACrG,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,0CAA0C,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACrK,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4FAA4F;AAC5F,SAAS,SAAS,CAAC,OAAuB;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,mCAAmC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAChL,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE;YAAE,SAAS;QACrC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,qBAAqB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,0CAA0C,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9Q,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC;IACnC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,YAAY,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,2BAA2B,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACxM,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,cAAc,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,wBAAwB,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9Q,CAAC,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,oBAAoB,CAAC,EAAE,QAAQ,EAAE,gCAAgC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;IACxJ,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAuB,EAAE,KAAa,EAAE,KAAmB;IACpF,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/J,CAAC;IACD,IAAI,KAAK,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACnD,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,WAAW,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACzR,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1L,CAAC;IACD,IAAI,KAAK,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,8CAA8C,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACnO,yFAAyF;IACzF,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,6BAA6B,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACvM,+FAA+F;IAC/F,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,iEAAiE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACvN,uFAAuF;IACvF,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,qEAAqE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACrH,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,WAAW,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7N,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxE,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC/D,yDAAyD;IACzD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,EAAE,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,EAAE,GAAG,MAAM,CAAC,CAAC;AACpF,CAAC","sourcesContent":["// Pure model for the command palette (no Tauri/DOM imports, so it is unit-tested under node).\n// Every item is navigation only: tabs are focused, profiles open a tab, decks and workspaces open,\n// the app's panel opens at a section, plugin commands run in their tab; the site adds its own\n// pages and completions (`site.palette`). Nothing here performs an account action on the user's behalf.\n\nimport { rankItems } from '../palette.ts';\nimport { os } from '../windowControls.ts';\nimport { t } from './i18n.ts';\nimport type { IconName } from './icons.tsx';\nimport { mediaShortcutLabel } from './mediaModel.ts';\nimport { menuText } from './menuModel.ts';\nimport type { PaletteSite } from './site.ts';\n\nexport { fuzzyScore, moveSelection } from '../palette.ts';\n\nexport type PaletteAction =\n | { type: 'focus-tab'; id: string }\n | { type: 'new-tab'; profile: string }\n | { type: 'panel'; section: string }\n | { type: 'open'; url: string }\n | { type: 'media' }\n /** Decks (navigation only): open a deck, make a new one, add or focus a column. */\n | { type: 'deck'; deckId?: string }\n | { type: 'deck-new' }\n | { type: 'deck-add'; deckId: string }\n | { type: 'deck-focus'; deckId: string; columnId: string }\n /** Replaces the palette query (a completion); never navigates. */\n | { type: 'complete'; text: string }\n /** A plugin's command: the shell asks tab `tab` to run it in its page (`tab_run_command`). */\n | { type: 'plugin-command'; tab: string; command: string }\n /** Workspaces: restore one, or save the current layout under a name. */\n | { type: 'workspace'; id: string }\n | { type: 'workspace-save' }\n /** Opens the app menu (the titlebar's \"Settings and more\"). */\n | { type: 'menu' }\n /** Opens the find bar of the tab in front. */\n | { type: 'find' };\n\n/** The frame's groups; the app's items are grouped under its product name, plugin commands under the plugin's. */\nexport type PaletteGroup = 'Tabs' | 'Deck' | 'Workspaces' | 'Profiles';\n\nexport type PaletteItem = {\n id: string;\n /** A fixed group, the site's group, or a plugin's name for its commands. */\n group: PaletteGroup | (string & {});\n label: string;\n hint?: string;\n keywords?: string;\n /** The row's glyph (tabs show their favicon, profiles their avatar). */\n icon?: IconName;\n action: PaletteAction;\n};\n\nexport type PaletteContext = {\n /** `favicon` and `color` only decorate the list; matching ignores them. */\n tabs: Array<{ id: string; title: string; url: string; favicon?: string }>;\n profiles: Array<{ id: string; name: string; color?: string }>;\n activeProfile: string;\n /** Decks and their columns (titles only); absent when the app has no decks. */\n decks?: Array<{ id: string; name: string; columns: Array<{ id: string; title: string; profile: string }> }>;\n /** The deck tab in front, if any. */\n activeDeck?: string;\n /** Saved workspaces (names only) and the one opened last. */\n workspaces?: Array<{ id: string; name: string; tabs: number; isDefault?: boolean }>;\n activeWorkspace?: string;\n /** Plugin commands of the focused site tab, already named by plugin (`pluginCommandItems`). */\n commands?: { tab: string; items: PluginCommandItem[] };\n};\n\n/** What the palette knows about the app: its site items, its name and which frame features it has. */\nexport type PaletteSetup = { site: PaletteSite; product: string; decks: boolean; media: boolean; workspaces?: boolean; find?: boolean };\n\n/** A plugin command as the palette lists it: the tab's report plus the plugin's display name. */\nexport type PluginCommandItem = { id: string; title: string; keywords: string; plugin: string };\n\n/** Commands at most listed from one tab (the runtime and native code cap them too). */\nexport const MAX_PLUGIN_COMMANDS = 48;\n\n/**\n * Names each reported command (`<file>:<id>`) after its plugin (`@name` from the Plugins list);\n * commands registered outside a plugin's start are listed under \"Plugins\". Bounded.\n */\nexport function pluginCommandItems(reported: ReadonlyArray<{ id: string; title: string; keywords?: string }>, pluginNames: Readonly<Record<string, string>>): PluginCommandItem[] {\n const out: PluginCommandItem[] = [];\n for (const command of reported) {\n if (out.length >= MAX_PLUGIN_COMMANDS) break;\n if (typeof command?.id !== 'string' || typeof command.title !== 'string') continue;\n const at = command.id.indexOf(':');\n if (at <= 0) continue;\n const owner = command.id.slice(0, at);\n const plugin = (owner !== '_' && pluginNames[owner]) || (owner === '_' ? t('wb.palette.plugins') : owner.replace(/\\.plugin\\.js$/, ''));\n out.push({ id: command.id, title: command.title.slice(0, 80), keywords: (command.keywords ?? '').slice(0, 160), plugin });\n }\n return out;\n}\n\n/** The \"Workspaces\" group: switch to a saved workspace, save the current layout. */\nfunction workspaceItems(context: PaletteContext): PaletteItem[] {\n const items: PaletteItem[] = [];\n for (const workspace of context.workspaces ?? []) {\n items.push({\n id: `ws:${workspace.id}`, group: 'Workspaces', label: t('wb.palette.switchTo', { name: workspace.name }),\n hint: workspace.id === context.activeWorkspace ? t('wb.palette.active') : `${t('wb.ws.tabs', { count: workspace.tabs })}${workspace.isDefault ? ` · ${t('wb.palette.onStart')}` : ''}`,\n keywords: 'workspace layout restore session switch', action: { type: 'workspace', id: workspace.id },\n });\n }\n items.push({ id: 'ws-save', group: 'Workspaces', label: t('wb.ws.save'), keywords: 'workspace layout save session tabs panes', action: { type: 'workspace-save' } });\n return items;\n}\n\n/** The \"Deck\" group: open/switch decks, add a column, focus a column of the active deck. */\nfunction deckItems(context: PaletteContext): PaletteItem[] {\n const decks = context.decks ?? [];\n const items: PaletteItem[] = [];\n const active = decks.find(deck => deck.id === context.activeDeck);\n if (!decks.length) {\n items.push({ id: 'deck:open', group: 'Deck', label: t('wb.palette.openPower'), hint: 'Ctrl+Shift+D', keywords: 'deck tweetdeck columns power user', action: { type: 'deck' } });\n return items;\n }\n for (const deck of decks) {\n if (deck.id === active?.id) continue;\n items.push({ id: `deck:${deck.id}`, group: 'Deck', label: t('wb.palette.switchTo', { name: deck.name }), hint: t('wb.deck.columnCount', { count: deck.columns.length }), keywords: 'deck tweetdeck columns power user switch', action: { type: 'deck', deckId: deck.id } });\n }\n const target = active ?? decks[0]!;\n items.push({ id: `deck-add:${target.id}`, group: 'Deck', label: t('wb.palette.addColumn'), hint: target.name, keywords: 'deck column new tweetdeck', action: { type: 'deck-add', deckId: target.id } });\n if (active) {\n active.columns.forEach((column, index) => {\n items.push({ id: `deck-focus:${column.id}`, group: 'Deck', label: t('wb.palette.focusColumn', { name: column.title }), hint: index < 9 ? `Alt+${index + 1}` : undefined, keywords: 'column deck', action: { type: 'deck-focus', deckId: active.id, columnId: column.id } });\n });\n }\n items.push({ id: 'deck-new', group: 'Deck', label: t('wb.palette.newDeck'), keywords: 'deck columns power user create', action: { type: 'deck-new' } });\n return items;\n}\n\nexport function buildItems(context: PaletteContext, query: string, setup: PaletteSetup): PaletteItem[] {\n const { site } = setup;\n const items: PaletteItem[] = [];\n const text = query.trim();\n const search = text ? site.search?.(text) ?? null : null;\n if (search) items.push(search);\n for (const tab of context.tabs) {\n items.push({ id: `tab:${tab.id}`, group: 'Tabs', label: tab.title || tab.url, hint: tab.url, keywords: tab.url, action: { type: 'focus-tab', id: tab.id } });\n }\n if (setup.decks) items.push(...deckItems(context));\n if (setup.workspaces !== false) items.push(...workspaceItems(context));\n for (const profile of context.profiles) {\n items.push({ id: `profile:${profile.id}`, group: 'Profiles', label: t('wb.palette.newTabAs', { name: profile.name }), hint: profile.id === context.activeProfile ? t('wb.palette.active') : undefined, keywords: 'account switch', action: { type: 'new-tab', profile: profile.id } });\n }\n for (const section of site.sections) {\n items.push({ id: `panel:${section.id}`, group: setup.product, label: section.label(), keywords: section.keywords, icon: section.icon, action: { type: 'panel', section: section.id } });\n }\n if (setup.media) items.push({ id: 'media', group: setup.product, label: t('wb.palette.media'), hint: mediaShortcutLabel(os), keywords: 'photos images screenshots attach paste media', icon: 'image', action: { type: 'media' } });\n // Find in the page of the tab in front (the shell's find bar; nothing is sent anywhere).\n if (setup.find !== false) items.push({ id: 'find', group: setup.product, label: menuText('find'), hint: 'Ctrl+F', keywords: 'find search page text match', icon: 'search', action: { type: 'find' } });\n // The app menu (the titlebar's \"Settings and more\"): language, theme, mode, zoom and the rest.\n items.push({ id: 'app-menu', group: setup.product, label: menuText('label'), hint: 'Alt+F', keywords: 'menu more settings language theme mode zoom options preferences', icon: 'settings', action: { type: 'menu' } });\n // Plugin commands, grouped under each plugin's name; they run in the focused site tab.\n if (context.commands) {\n const { tab } = context.commands;\n // One heading per plugin: stable sort keeps each plugin's own order.\n const sorted = context.commands.items.slice(0, MAX_PLUGIN_COMMANDS).sort((a, b) => a.plugin.localeCompare(b.plugin));\n for (const command of sorted) {\n items.push({ id: `cmd:${command.id}`, group: command.plugin, label: command.title, keywords: `${command.plugin} plugin ${command.keywords}`, icon: 'bolt', action: { type: 'plugin-command', tab, command: command.id } });\n }\n }\n items.push(...site.items?.() ?? []);\n if (!text) return items;\n const completions = site.completions?.(query.replace(/^\\s+/, '')) ?? [];\n const scored = rankItems(items, text, item => item === search);\n // The literal search stays available as the last resort.\n return search ? [...completions, ...scored, search] : [...completions, ...scored];\n}\n\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Theme swatches (page, text, accent) and the "Theme for this pane" menu. */
|
|
2
|
-
.wb-dots { display: inline-flex; align-items: center; gap: 3px; flex: none; height: 18px; padding: 0 5px; border-radius: 6px; box-shadow: inset 0 0 0 1px rgb(127 127 127 / .28); }
|
|
2
|
+
.wb-dots { display: inline-flex; align-items: center; gap: 3px; flex: none; height: 18px; padding: 0 5px; border-radius: calc(6px * var(--bt-rs, 1)); box-shadow: inset 0 0 0 1px rgb(127 127 127 / .28); }
|
|
3
3
|
.wb-dots i { width: 7px; height: 7px; border-radius: 50%; }
|
|
4
4
|
.wb-pane-menu { width: 272px; }
|
|
5
5
|
.wb-pane-menu-head { display: flex; align-items: center; gap: 8px; padding: 7px 10px 6px; color: var(--bt-muted); font: 600 11px/1 var(--bt-ui); letter-spacing: .04em; text-transform: uppercase; }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The framework's version (kept in step with packages/waybetter/package.json by a test). */
|
|
2
|
-
export declare const FRAMEWORK_VERSION = "0.
|
|
2
|
+
export declare const FRAMEWORK_VERSION = "0.7.0";
|
|
3
3
|
/** Everything a report may say. */
|
|
4
4
|
export type ReportInfo = {
|
|
5
5
|
/** The app's name and version ("wayBetter for X", "1.3.2"). */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// nothing of that kind can ride along in a value either. The text is shown to the owner exactly as it would be shared and is
|
|
8
8
|
// never sent anywhere by the app (no request, and nothing is put in a URL).
|
|
9
9
|
/** The framework's version (kept in step with packages/waybetter/package.json by a test). */
|
|
10
|
-
export const FRAMEWORK_VERSION = '0.
|
|
10
|
+
export const FRAMEWORK_VERSION = '0.7.0';
|
|
11
11
|
const MAX_ITEMS = 60;
|
|
12
12
|
const ID = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/;
|
|
13
13
|
/** An id or a version as it is, or nothing: anything that is not made of id characters is left out, never trimmed into shape. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reportModel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/reportModel.ts"],"names":[],"mappings":"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","sourcesContent":["// \"Report a problem\": the diagnostic summary, as a pure model (unit-tested under node). It is a\n// short plain text in English (the people who read reports do) built from a fixed set of facts\n// about the app, never about the person: versions, the system, the language, the mode, the ids of\n// what is switched on, what paused itself, safe mode. It has no field for an account, a handle, an\n// address, a tab, a file path or anything of the site's, and every value must be made of the\n// characters an id or a version is made of, or it is left out (never trimmed into shape), so\n// nothing of that kind can ride along in a value either. The text is shown to the owner exactly as it would be shared and is\n// never sent anywhere by the app (no request, and nothing is put in a URL).\n\n/** The framework's version (kept in step with packages/waybetter/package.json by a test). */\nexport const FRAMEWORK_VERSION = '0.6.0';\n\n/** Everything a report may say. */\nexport type ReportInfo = {\n /** The app's name and version (\"wayBetter for X\", \"1.3.2\"). */\n product: string;\n appVersion: string;\n /** \"Windows 11 (x64)\", \"macOS\", \"Linux (x86_64)\". */\n system: string;\n /** \"WebView2 141.0.3537.71\", \"WebKit 605.1.15\". */\n webview: string;\n /** The catalog in use and how it was chosen (`site`, `system` or a language tag). */\n language: string;\n languageChoice: string;\n /** The mode in use (its id), when the app has modes. */\n mode?: string | null;\n /** The theme's id and the icon pack it uses, when the app has themes. */\n theme?: string;\n iconPack?: string;\n /** File names of the plugins that are switched on (null: could not be read). */\n plugins: readonly string[] | null;\n /** Lines the app adds: a fixed English label and ids (what paused itself, which areas are on). */\n details?: ReadonlyArray<{ label: string; values: readonly string[] }>;\n safeMode: boolean;\n};\n\nconst MAX_ITEMS = 60;\n\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/;\n\n/** An id or a version as it is, or nothing: anything that is not made of id characters is left out, never trimmed into shape. */\nexport function reportValue(value: unknown): string {\n const text = typeof value === 'number' ? String(value) : typeof value === 'string' ? value : '';\n return ID.test(text) ? text : '';\n}\n\n/** A plugin's file name: the name itself (never where the file is), or nothing. */\nexport function reportFileName(value: unknown): string {\n return typeof value === 'string' ? reportValue(value.split(/[\\\\/]/).pop()) : '';\n}\n\n/** A language tag (`tr`, `zh-Hant`) or one of the automatic choices; anything else is left out. */\nfunction languageValue(value: unknown): string {\n return typeof value === 'string' && (/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8}){0,3}$/.test(value) || ['site', 'system', 'fixed'].includes(value)) ? value : '';\n}\n\n/** What `systemFromUserAgent` and `webviewFromUserAgent` write, and nothing else. */\nconst SYSTEM = /^(Windows|macOS|Linux)( \\d+(\\.\\d+)?| 10 or 11)?( \\([A-Za-z0-9_]{1,12}\\))?$/;\nconst WEBVIEW = /^(WebView2|Chromium|WebKit) [0-9.]{1,24}$/;\n/** The app's name and its labels are its own constants: letters, digits and spaces. */\nconst NAME = /^[A-Za-z][A-Za-z0-9 ]{0,39}$/;\n\nfunction list(values: readonly unknown[] | null | undefined, clean: (value: unknown) => string): string {\n if (!values) return 'unknown';\n const kept = values.map(clean).filter(Boolean);\n const left = values.length - kept.length;\n const shown = kept.slice(0, MAX_ITEMS);\n const more = kept.length - shown.length + left;\n if (!shown.length) return more ? `${more} not shown` : 'none';\n return `${shown.join(', ')}${more ? `, and ${more} more` : ''}`;\n}\n\n/** The report's text: one fact per line. */\nexport function buildReport(info: ReportInfo): string {\n const lines = [\n `${NAME.test(info.product) ? info.product : 'App'} ${reportValue(info.appVersion) || 'unknown version'}`,\n `Framework: wayBetter ${FRAMEWORK_VERSION}`,\n `System: ${SYSTEM.test(info.system) ? info.system : 'unknown'}`,\n `Webview: ${WEBVIEW.test(info.webview) ? info.webview : 'unknown'}`,\n `Language: ${languageValue(info.language) || 'unknown'} (chosen: ${languageValue(info.languageChoice) || 'unknown'})`,\n ];\n if (info.mode !== undefined) lines.push(`Mode: ${info.mode === null ? 'none chosen' : reportValue(info.mode) || 'unknown'}`);\n if (info.theme !== undefined) lines.push(`Theme: ${reportValue(info.theme) || 'unknown'}`);\n if (info.iconPack !== undefined) lines.push(`Icon pack: ${info.iconPack === '' ? \"the site's own\" : reportValue(info.iconPack) || 'unknown'}`);\n lines.push(`Plugins on: ${list(info.plugins, reportFileName)}`);\n for (const detail of (info.details ?? []).slice(0, 12)) {\n if (NAME.test(detail.label)) lines.push(`${detail.label}: ${list(detail.values, reportValue)}`);\n }\n lines.push(`Safe mode: ${info.safeMode ? 'yes' : 'no'}`);\n return lines.join('\\n');\n}\n\n/**\n * The webview engine and its version from a user agent string. Chromium reduces the version in the\n * user agent (\"154.0.0.0\"); the full one comes from the engine's brand list when it gives one.\n */\nexport function webviewFromUserAgent(userAgent: string, brands: ReadonlyArray<{ brand?: string; version?: string }> = []): string {\n const full = brands.find(entry => /WebView2|Microsoft Edge/.test(entry.brand ?? '') && /^[\\d.]+$/.test(entry.version ?? ''));\n const edge = /\\bEdg\\/([\\d.]+)/.exec(userAgent);\n if (edge) return `WebView2 ${full?.version ?? edge[1]}`;\n const chrome = /\\bChrom(?:e|ium)\\/([\\d.]+)/.exec(userAgent);\n if (chrome) return `Chromium ${chrome[1]}`;\n const webkit = /\\bAppleWebKit\\/([\\d.]+)/.exec(userAgent);\n if (webkit) return `WebKit ${webkit[1]}`;\n return 'unknown';\n}\n\n/**\n * The operating system from a user agent string, refined by what the engine says when asked\n * (`platformVersion`: on Windows a major of 13 or more is Windows 11; `architecture`). Coarse on\n * purpose: a family and a version, nothing that names a machine.\n */\nexport function systemFromUserAgent(userAgent: string, hints: { platformVersion?: string; architecture?: string; bitness?: string } = {}): string {\n const arch = hints.architecture ? `${hints.architecture}${hints.bitness === '64' && hints.architecture === 'x86' ? '_64' : ''}` : '';\n if (/Windows NT/.test(userAgent)) {\n const major = Number.parseInt(hints.platformVersion ?? '', 10);\n const version = Number.isFinite(major) && major > 0 ? (major >= 13 ? '11' : '10') : /Windows NT 10\\.0/.test(userAgent) ? '10 or 11' : '';\n const bits = arch || (/Win64|x64|WOW64/.test(userAgent) ? 'x64' : /ARM64/i.test(userAgent) ? 'arm64' : '');\n return `Windows${version ? ` ${version}` : ''}${bits ? ` (${bits})` : ''}`;\n }\n if (/Macintosh|Mac OS X/.test(userAgent)) {\n const version = (hints.platformVersion ?? '').split('.').slice(0, 2).join('.');\n return `macOS${/^\\d+(\\.\\d+)?$/.test(version) && version !== '0' ? ` ${version}` : ''}${arch ? ` (${arch})` : ''}`;\n }\n if (/Linux|X11/.test(userAgent)) {\n const machine = /Linux (x86_64|aarch64|armv\\w+|i686)/.exec(userAgent)?.[1] ?? arch;\n return `Linux${machine ? ` (${machine})` : ''}`;\n }\n return 'unknown';\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reportModel.js","sourceRoot":"","sources":["../../../../../../shell/src/frame/reportModel.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,+FAA+F;AAC/F,kGAAkG;AAClG,mGAAmG;AACnG,6FAA6F;AAC7F,6FAA6F;AAC7F,6HAA6H;AAC7H,4EAA4E;AAE5E,6FAA6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AA0BzC,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,MAAM,EAAE,GAAG,oCAAoC,CAAC;AAEhD,iIAAiI;AACjI,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAChG,OAAO,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACnC,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAClF,CAAC;AAED,mGAAmG;AACnG,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,yCAAyC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1J,CAAC;AAED,qFAAqF;AACrF,MAAM,MAAM,GAAG,4EAA4E,CAAC;AAC5F,MAAM,OAAO,GAAG,2CAA2C,CAAC;AAC5D,uFAAuF;AACvF,MAAM,IAAI,GAAG,8BAA8B,CAAC;AAE5C,SAAS,IAAI,CAAC,MAA6C,EAAE,KAAiC;IAC5F,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;IAC/C,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9D,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAClE,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,MAAM,KAAK,GAAG;QACZ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,iBAAiB,EAAE;QACxG,wBAAwB,iBAAiB,EAAE;QAC3C,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE;QAC/D,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE;QACnE,aAAa,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,aAAa,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,SAAS,GAAG;KACtH,CAAC;IACF,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IAC7H,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IAC3F,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IAC/I,KAAK,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IAChE,KAAK,MAAM,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACvD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,SAA8D,EAAE;IACtH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7H,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,IAAI;QAAE,OAAO,YAAY,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,4BAA4B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5D,IAAI,MAAM;QAAE,OAAO,YAAY,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,IAAI,MAAM;QAAE,OAAO,UAAU,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,QAA+E,EAAE;IACtI,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACrI,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QACzI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3G,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC7E,CAAC;IACD,IAAI,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/E,OAAO,QAAQ,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpH,CAAC;IACD,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,qCAAqC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACnF,OAAO,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAClD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["// \"Report a problem\": the diagnostic summary, as a pure model (unit-tested under node). It is a\n// short plain text in English (the people who read reports do) built from a fixed set of facts\n// about the app, never about the person: versions, the system, the language, the mode, the ids of\n// what is switched on, what paused itself, safe mode. It has no field for an account, a handle, an\n// address, a tab, a file path or anything of the site's, and every value must be made of the\n// characters an id or a version is made of, or it is left out (never trimmed into shape), so\n// nothing of that kind can ride along in a value either. The text is shown to the owner exactly as it would be shared and is\n// never sent anywhere by the app (no request, and nothing is put in a URL).\n\n/** The framework's version (kept in step with packages/waybetter/package.json by a test). */\nexport const FRAMEWORK_VERSION = '0.7.0';\n\n/** Everything a report may say. */\nexport type ReportInfo = {\n /** The app's name and version (\"wayBetter for X\", \"1.3.2\"). */\n product: string;\n appVersion: string;\n /** \"Windows 11 (x64)\", \"macOS\", \"Linux (x86_64)\". */\n system: string;\n /** \"WebView2 141.0.3537.71\", \"WebKit 605.1.15\". */\n webview: string;\n /** The catalog in use and how it was chosen (`site`, `system` or a language tag). */\n language: string;\n languageChoice: string;\n /** The mode in use (its id), when the app has modes. */\n mode?: string | null;\n /** The theme's id and the icon pack it uses, when the app has themes. */\n theme?: string;\n iconPack?: string;\n /** File names of the plugins that are switched on (null: could not be read). */\n plugins: readonly string[] | null;\n /** Lines the app adds: a fixed English label and ids (what paused itself, which areas are on). */\n details?: ReadonlyArray<{ label: string; values: readonly string[] }>;\n safeMode: boolean;\n};\n\nconst MAX_ITEMS = 60;\n\nconst ID = /^[A-Za-z0-9][A-Za-z0-9._+-]{0,63}$/;\n\n/** An id or a version as it is, or nothing: anything that is not made of id characters is left out, never trimmed into shape. */\nexport function reportValue(value: unknown): string {\n const text = typeof value === 'number' ? String(value) : typeof value === 'string' ? value : '';\n return ID.test(text) ? text : '';\n}\n\n/** A plugin's file name: the name itself (never where the file is), or nothing. */\nexport function reportFileName(value: unknown): string {\n return typeof value === 'string' ? reportValue(value.split(/[\\\\/]/).pop()) : '';\n}\n\n/** A language tag (`tr`, `zh-Hant`) or one of the automatic choices; anything else is left out. */\nfunction languageValue(value: unknown): string {\n return typeof value === 'string' && (/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8}){0,3}$/.test(value) || ['site', 'system', 'fixed'].includes(value)) ? value : '';\n}\n\n/** What `systemFromUserAgent` and `webviewFromUserAgent` write, and nothing else. */\nconst SYSTEM = /^(Windows|macOS|Linux)( \\d+(\\.\\d+)?| 10 or 11)?( \\([A-Za-z0-9_]{1,12}\\))?$/;\nconst WEBVIEW = /^(WebView2|Chromium|WebKit) [0-9.]{1,24}$/;\n/** The app's name and its labels are its own constants: letters, digits and spaces. */\nconst NAME = /^[A-Za-z][A-Za-z0-9 ]{0,39}$/;\n\nfunction list(values: readonly unknown[] | null | undefined, clean: (value: unknown) => string): string {\n if (!values) return 'unknown';\n const kept = values.map(clean).filter(Boolean);\n const left = values.length - kept.length;\n const shown = kept.slice(0, MAX_ITEMS);\n const more = kept.length - shown.length + left;\n if (!shown.length) return more ? `${more} not shown` : 'none';\n return `${shown.join(', ')}${more ? `, and ${more} more` : ''}`;\n}\n\n/** The report's text: one fact per line. */\nexport function buildReport(info: ReportInfo): string {\n const lines = [\n `${NAME.test(info.product) ? info.product : 'App'} ${reportValue(info.appVersion) || 'unknown version'}`,\n `Framework: wayBetter ${FRAMEWORK_VERSION}`,\n `System: ${SYSTEM.test(info.system) ? info.system : 'unknown'}`,\n `Webview: ${WEBVIEW.test(info.webview) ? info.webview : 'unknown'}`,\n `Language: ${languageValue(info.language) || 'unknown'} (chosen: ${languageValue(info.languageChoice) || 'unknown'})`,\n ];\n if (info.mode !== undefined) lines.push(`Mode: ${info.mode === null ? 'none chosen' : reportValue(info.mode) || 'unknown'}`);\n if (info.theme !== undefined) lines.push(`Theme: ${reportValue(info.theme) || 'unknown'}`);\n if (info.iconPack !== undefined) lines.push(`Icon pack: ${info.iconPack === '' ? \"the site's own\" : reportValue(info.iconPack) || 'unknown'}`);\n lines.push(`Plugins on: ${list(info.plugins, reportFileName)}`);\n for (const detail of (info.details ?? []).slice(0, 12)) {\n if (NAME.test(detail.label)) lines.push(`${detail.label}: ${list(detail.values, reportValue)}`);\n }\n lines.push(`Safe mode: ${info.safeMode ? 'yes' : 'no'}`);\n return lines.join('\\n');\n}\n\n/**\n * The webview engine and its version from a user agent string. Chromium reduces the version in the\n * user agent (\"154.0.0.0\"); the full one comes from the engine's brand list when it gives one.\n */\nexport function webviewFromUserAgent(userAgent: string, brands: ReadonlyArray<{ brand?: string; version?: string }> = []): string {\n const full = brands.find(entry => /WebView2|Microsoft Edge/.test(entry.brand ?? '') && /^[\\d.]+$/.test(entry.version ?? ''));\n const edge = /\\bEdg\\/([\\d.]+)/.exec(userAgent);\n if (edge) return `WebView2 ${full?.version ?? edge[1]}`;\n const chrome = /\\bChrom(?:e|ium)\\/([\\d.]+)/.exec(userAgent);\n if (chrome) return `Chromium ${chrome[1]}`;\n const webkit = /\\bAppleWebKit\\/([\\d.]+)/.exec(userAgent);\n if (webkit) return `WebKit ${webkit[1]}`;\n return 'unknown';\n}\n\n/**\n * The operating system from a user agent string, refined by what the engine says when asked\n * (`platformVersion`: on Windows a major of 13 or more is Windows 11; `architecture`). Coarse on\n * purpose: a family and a version, nothing that names a machine.\n */\nexport function systemFromUserAgent(userAgent: string, hints: { platformVersion?: string; architecture?: string; bitness?: string } = {}): string {\n const arch = hints.architecture ? `${hints.architecture}${hints.bitness === '64' && hints.architecture === 'x86' ? '_64' : ''}` : '';\n if (/Windows NT/.test(userAgent)) {\n const major = Number.parseInt(hints.platformVersion ?? '', 10);\n const version = Number.isFinite(major) && major > 0 ? (major >= 13 ? '11' : '10') : /Windows NT 10\\.0/.test(userAgent) ? '10 or 11' : '';\n const bits = arch || (/Win64|x64|WOW64/.test(userAgent) ? 'x64' : /ARM64/i.test(userAgent) ? 'arm64' : '');\n return `Windows${version ? ` ${version}` : ''}${bits ? ` (${bits})` : ''}`;\n }\n if (/Macintosh|Mac OS X/.test(userAgent)) {\n const version = (hints.platformVersion ?? '').split('.').slice(0, 2).join('.');\n return `macOS${/^\\d+(\\.\\d+)?$/.test(version) && version !== '0' ? ` ${version}` : ''}${arch ? ` (${arch})` : ''}`;\n }\n if (/Linux|X11/.test(userAgent)) {\n const machine = /Linux (x86_64|aarch64|armv\\w+|i686)/.exec(userAgent)?.[1] ?? arch;\n return `Linux${machine ? ` (${machine})` : ''}`;\n }\n return 'unknown';\n}\n"]}
|