186 lines
8.4 KiB
Rust
186 lines
8.4 KiB
Rust
//! The Tauri commands [`crate::app::run_app`] registers for every app, and who may call them.
|
|
//!
|
|
//! An app's `build.rs` lists its own commands plus these in the app-command manifest
|
|
//! ([`manifest`]), and its capability files grant [`SHELL`] to the local `shell` webview only,
|
|
//! [`TAB`] to tab webviews only and [`SITE`] to tab webviews on the site's origin only;
|
|
//! [`crate::testkit`] checks them. Every command re-checks its caller natively
|
|
//! (`host::shell_only` / `host::tab_only` / `host::site_tab_only`) before anything else.
|
|
|
|
/// Shell-only: the local `shell` webview (debug builds also accept the dev server).
|
|
pub const SHELL: &[&str] = &[
|
|
"tabs_sync",
|
|
"tab_navigate",
|
|
"tab_action",
|
|
"tab_zoom",
|
|
"tab_find",
|
|
"safe_mode_get",
|
|
"safe_mode_set",
|
|
"diag_get",
|
|
"diag_log",
|
|
"open_external_url",
|
|
"shell_focus",
|
|
"shell_ready",
|
|
"tab_still_ready",
|
|
"shell_raise",
|
|
"window_system_menu",
|
|
"profiles_get",
|
|
"profiles_set",
|
|
"i18n_get",
|
|
"i18n_set",
|
|
"plugins_list",
|
|
"plugin_set_enabled",
|
|
"plugins_open_folder",
|
|
"custom_css_get",
|
|
"custom_css_set",
|
|
"features_get",
|
|
"features_set",
|
|
"mode_get",
|
|
"mode_set",
|
|
"settings_get",
|
|
"settings_set",
|
|
"tab_run_command",
|
|
];
|
|
|
|
/// Tab-only: any tab webview, speaking only about itself.
|
|
pub const TAB: &[&str] = &["tab_shortcut", "tab_link_drag"];
|
|
|
|
/// Site-tab-only: a tab webview that is on the site's origin right now (the page runtime asks
|
|
/// the shell to open the app's panel). Grant these in a capability limited to the site's URLs.
|
|
pub const SITE: &[&str] = &["open_panel"];
|
|
|
|
/// Shell-only, optional: the store's commands (install links, dropped files, the signed Store and
|
|
/// the install screen), served when the app sets `AppConfig::store`. An app that uses the store
|
|
/// grants these to the shell (`testkit::Capabilities::assert_shell_only_group`).
|
|
pub const STORE: &[&str] = &[
|
|
"install_pending",
|
|
"install_stage_link",
|
|
"install_stage_file",
|
|
"install_stage_opened",
|
|
"install_cancel",
|
|
"install_commit",
|
|
"plugin_remove",
|
|
"install_records",
|
|
"install_forget",
|
|
"store_catalog",
|
|
"store_stage",
|
|
"strings_list",
|
|
"strings_read",
|
|
"strings_set",
|
|
"strings_remove",
|
|
"strings_apply",
|
|
];
|
|
|
|
/// Shell-only, optional: the media panel's commands (gallery folders, previews, the clipboard
|
|
/// history), served when the app sets `AppConfig::media`. An app that uses them grants these to the
|
|
/// shell (`testkit::Capabilities::assert_shell_only_group`).
|
|
pub const MEDIA: &[&str] = &[
|
|
"media_get",
|
|
"media_set",
|
|
"gallery_add_folder",
|
|
"gallery_list",
|
|
"gallery_thumb",
|
|
"clip_list",
|
|
"clip_thumb",
|
|
"clip_remove",
|
|
];
|
|
|
|
/// Shell-only, optional: Google Fonts (what is installed, install, remove, the faces of a family and
|
|
/// a preview), served when the app sets `AppConfig::fonts`; needs the `net` feature.
|
|
pub const GFONTS: &[&str] = &["gfonts_installed", "gfonts_install", "gfonts_remove", "gfonts_faces", "gfonts_preview"];
|
|
|
|
/// Shell-only, optional: native updates (status, check now, apply, the shell reached a working
|
|
/// state), served when the app sets `AppConfig::updates`; needs the `net` feature.
|
|
pub const UPDATE: &[&str] = &["update_status", "update_check", "apply_update", "app_ready"];
|
|
|
|
/// Shell-only, optional: saved workspaces (named tab, pane and deck layouts). State-free: served
|
|
/// for every app; an app that uses them grants them to the shell.
|
|
pub const WORKSPACES: &[&str] = &["workspaces_get", "workspaces_set"];
|
|
|
|
/// Shell-only, optional: encrypted folder sync of the settings backup, served when the app sets
|
|
/// `AppConfig::sync`.
|
|
pub const SYNC: &[&str] = &[
|
|
"sync_status",
|
|
"sync_choose_folder",
|
|
"sync_unlock",
|
|
"sync_lock",
|
|
"sync_disable",
|
|
"sync_configure",
|
|
"sync_push",
|
|
"sync_check",
|
|
"sync_open",
|
|
"sync_mark_pulled",
|
|
];
|
|
|
|
/// Shell-only, optional: developer mode (live reload of plugins, custom CSS and one theme file),
|
|
/// served when the app sets `AppConfig::dev`.
|
|
pub const DEV: &[&str] = &["dev_get", "dev_set", "dev_pick_theme", "dev_clear_theme", "dev_reload_plugin", "dev_report_error"];
|
|
|
|
/// Shell-only, optional: the settings backup (collect, export to a file, open a file for the preview,
|
|
/// apply chosen sections). State-free: served for every app; what a backup carries is the app's
|
|
/// (`SiteHooks::backup_sections`, `backup_drafts`, `backup_apply`).
|
|
pub const BACKUP: &[&str] = &["backup_collect", "backup_export_file", "backup_open_file", "backup_apply"];
|
|
|
|
/// Shell-only, optional: site themes (the owner's theme, account and pane themes, the Theme
|
|
/// Builder's live preview), served when the app sets `AppConfig::themes`. An app that uses them
|
|
/// grants these to the shell (`testkit::Capabilities::assert_shell_only_group`).
|
|
pub const THEME: &[&str] = &["theme_get", "theme_set", "theme_preview", "theme_scopes_get", "theme_scopes_set"];
|
|
|
|
/// Shell-only, optional: the keyword alert settings (`alerts_get`, `alerts_set`), served when the app
|
|
/// sets `AppConfig::alerts`. An app that uses them grants these to the shell
|
|
/// (`testkit::Capabilities::assert_shell_only_group`).
|
|
pub const ALERTS: &[&str] = &["alerts_get", "alerts_set"];
|
|
|
|
/// Shell-only, optional: the drafts vault (list, save with a revision check, revisions, archive and
|
|
/// restore, observations, one consistent export), served when the app sets `AppConfig::vault`. An app
|
|
/// that uses them grants these to the shell (`testkit::Capabilities::assert_shell_only_group`).
|
|
pub const VAULT: &[&str] = &["draft_list", "draft_save", "draft_revisions", "draft_status", "observation_list", "data_export"];
|
|
|
|
/// Whether `command` is one of the host's (dispatched to the host, never to the app's handler).
|
|
pub fn is_host(command: &str) -> bool {
|
|
SHELL.contains(&command) || TAB.contains(&command) || SITE.contains(&command) || STORE.contains(&command) || MEDIA.contains(&command) || GFONTS.contains(&command) || UPDATE.contains(&command) || WORKSPACES.contains(&command) || SYNC.contains(&command) || DEV.contains(&command) || BACKUP.contains(&command) || THEME.contains(&command) || ALERTS.contains(&command) || VAULT.contains(&command)
|
|
}
|
|
|
|
/// The capability permission tauri-build generates for `command` (`tabs_sync` → `allow-tabs-sync`).
|
|
pub fn permission(command: &str) -> String {
|
|
format!("allow-{}", command.replace('_', "-"))
|
|
}
|
|
|
|
/// The app-command manifest for `build.rs`: the app's own commands followed by the host's (each
|
|
/// once). Leaked on purpose: tauri-build wants `&'static` and a build script runs once.
|
|
///
|
|
/// ```ignore
|
|
/// tauri_build::AppManifest::new().commands(waybetter_host::commands::manifest(&["capture_draft"]))
|
|
/// ```
|
|
pub fn manifest(app: &[&'static str]) -> &'static [&'static str] {
|
|
let mut all: Vec<&'static str> = Vec::with_capacity(app.len() + SHELL.len() + TAB.len() + SITE.len() + STORE.len() + MEDIA.len() + GFONTS.len() + UPDATE.len() + WORKSPACES.len() + SYNC.len() + DEV.len() + BACKUP.len() + THEME.len() + ALERTS.len() + VAULT.len());
|
|
for command in app.iter().chain(SHELL).chain(TAB).chain(SITE).chain(STORE).chain(MEDIA).chain(GFONTS).chain(UPDATE).chain(WORKSPACES).chain(SYNC).chain(DEV).chain(BACKUP).chain(THEME).chain(ALERTS).chain(VAULT) {
|
|
if !all.contains(command) {
|
|
all.push(command);
|
|
}
|
|
}
|
|
Box::leak(all.into_boxed_slice())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn manifest_adds_the_host_commands_once() {
|
|
let all = manifest(&["capture_draft", "tabs_sync"]);
|
|
assert_eq!(all[0], "capture_draft");
|
|
assert_eq!(all.iter().filter(|c| **c == "tabs_sync").count(), 1);
|
|
for command in SHELL.iter().chain(TAB).chain(SITE).chain(STORE).chain(MEDIA).chain(GFONTS).chain(UPDATE).chain(WORKSPACES).chain(SYNC).chain(DEV).chain(BACKUP).chain(THEME).chain(ALERTS).chain(VAULT) {
|
|
assert!(all.contains(command), "{command}");
|
|
assert!(is_host(command));
|
|
}
|
|
assert!(!is_host("capture_draft"));
|
|
assert_eq!(permission("tab_link_drag"), "allow-tab-link-drag");
|
|
}
|
|
|
|
#[test]
|
|
fn shell_and_tab_commands_do_not_overlap() {
|
|
assert!(!SHELL.iter().any(|command| TAB.contains(command) || SITE.contains(command) || STORE.contains(command) || MEDIA.contains(command) || GFONTS.contains(command) || UPDATE.contains(command) || WORKSPACES.contains(command) || SYNC.contains(command) || DEV.contains(command) || BACKUP.contains(command) || THEME.contains(command) || ALERTS.contains(command)));
|
|
assert!(!TAB.iter().any(|command| SITE.contains(command)));
|
|
}
|
|
}
|