host: plugins, custom CSS, feature flags, settings and open_panel are host commands
run_app now keeps and serves what every app's panel and page need, with the same caller checks
as the rest (commands::SHELL: shell_only first; testkit::assert_host_guards covers them):
- app.rs: PageState (the plugin store in app data `plugins`, the feature flags, ShellSettings)
managed by the host; commands plugins_list, plugin_set_enabled, plugins_open_folder,
custom_css_get/set, features_get/set, settings_get/set (moved from wayBetter for X). The app
reads the state through app::page(), gets a loaded document's scripts from app::page_scripts()
(flags, links, custom CSS, plugins) and writes through set_features/set_settings/set_custom_css
(a backup import). AppConfig takes the app's PluginHost (AppConfig::new(site, title, plugins))
and an optional home_url. SiteHooks::navigation_started and new_window_mode default to the
owner's link settings.
- settings.rs (pure, tested): ShellSettings { homeUrl, externalLinks, siteLinks, restoreTabs }
with its input form (missing fields take the defaults; `xLinks`, the name wayBetter for X used,
is read as siteLinks), links_script ({ site: mode }), feature validation and features_script.
- commands::SITE + open_panel: a tab on the site's origin asks the shell to open the app's panel
(site_tab_only first). testkit: assert_site_only(command, site) checks that every capability
granting a site command is a tab capability limited to the site's URLs; assert_host_commands and
assert_host_guards include the site commands.
- shell frame backupModel: a settings section that still says xLinks compares as siteLinks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
94ca44edad
commit
f6a50602d7
7 changed files with 529 additions and 36 deletions
|
|
@ -1,9 +1,10 @@
|
|||
//! 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 and
|
||||
//! [`TAB`] to tab webviews only; [`crate::testkit`] checks both. Every command re-checks its caller
|
||||
//! natively (`host::shell_only` / `host::tab_only`) before anything else.
|
||||
//! ([`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] = &[
|
||||
|
|
@ -20,14 +21,27 @@ pub const SHELL: &[&str] = &[
|
|||
"profiles_set",
|
||||
"i18n_get",
|
||||
"i18n_set",
|
||||
"plugins_list",
|
||||
"plugin_set_enabled",
|
||||
"plugins_open_folder",
|
||||
"custom_css_get",
|
||||
"custom_css_set",
|
||||
"features_get",
|
||||
"features_set",
|
||||
"settings_get",
|
||||
"settings_set",
|
||||
];
|
||||
|
||||
/// 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"];
|
||||
|
||||
/// 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)
|
||||
SHELL.contains(&command) || TAB.contains(&command) || SITE.contains(&command)
|
||||
}
|
||||
|
||||
/// The capability permission tauri-build generates for `command` (`tabs_sync` → `allow-tabs-sync`).
|
||||
|
|
@ -42,8 +56,8 @@ pub fn permission(command: &str) -> String {
|
|||
/// tauri_build::AppManifest::new().commands(waybetter_host::commands::manifest(&["draft_list"]))
|
||||
/// ```
|
||||
pub fn manifest(app: &[&'static str]) -> &'static [&'static str] {
|
||||
let mut all: Vec<&'static str> = Vec::with_capacity(app.len() + SHELL.len() + TAB.len());
|
||||
for command in app.iter().chain(SHELL).chain(TAB) {
|
||||
let mut all: Vec<&'static str> = Vec::with_capacity(app.len() + SHELL.len() + TAB.len() + SITE.len());
|
||||
for command in app.iter().chain(SHELL).chain(TAB).chain(SITE) {
|
||||
if !all.contains(command) {
|
||||
all.push(command);
|
||||
}
|
||||
|
|
@ -60,7 +74,7 @@ mod tests {
|
|||
let all = manifest(&["draft_list", "tabs_sync"]);
|
||||
assert_eq!(all[0], "draft_list");
|
||||
assert_eq!(all.iter().filter(|c| **c == "tabs_sync").count(), 1);
|
||||
for command in SHELL.iter().chain(TAB) {
|
||||
for command in SHELL.iter().chain(TAB).chain(SITE) {
|
||||
assert!(all.contains(command), "{command}");
|
||||
assert!(is_host(command));
|
||||
}
|
||||
|
|
@ -70,6 +84,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn shell_and_tab_commands_do_not_overlap() {
|
||||
assert!(!SHELL.iter().any(|command| TAB.contains(command)));
|
||||
assert!(!SHELL.iter().any(|command| TAB.contains(command) || SITE.contains(command)));
|
||||
assert!(!TAB.iter().any(|command| SITE.contains(command)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue