Skip to content

Commit

Permalink
fix: improvements and ipc fixes for loading window content using cust…
Browse files Browse the repository at this point in the history
…om protocol (#8670)

* fix: improvements and ipc fixes for loading window content using custom protocol

closes #5478

* Discard changes to tooling/cli/Cargo.lock

* clippy

* fix tests

* typo

* fix webviewurl deserialize

* resolve todo, fixes

* fmt

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
amrbashir and lucasfernog committed Jan 31, 2024
1 parent 00e1567 commit 58fe2e8
Show file tree
Hide file tree
Showing 43 changed files with 8,701 additions and 574 deletions.
5 changes: 5 additions & 0 deletions .changes/tauri-custom-protcol-for-window-url.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'patch:enhance'
---

Allow IPC calls when window origin is a defined custom protocol.
5 changes: 5 additions & 0 deletions .changes/tauri-utils-dist-dir-optional.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri-utils': 'patch:breaking'
---

Changed `dist_dir` and `dev_path` config options to be optional.
5 changes: 5 additions & 0 deletions .changes/tauri-utils-webivew-url-custom-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri-utils': 'patch:feat'
---

Add `WebviewUrl::CustomProtocol` enum variant.
4 changes: 2 additions & 2 deletions core/tauri-build/src/codegen/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ impl CodegenContext {
&config.build.dist_dir
};
match app_url {
AppUrl::Url(WebviewUrl::App(p)) => {
Some(AppUrl::Url(WebviewUrl::App(p))) => {
println!("cargo:rerun-if-changed={}", config_parent.join(p).display());
}
AppUrl::Files(files) => {
Some(AppUrl::Files(files)) => {
for path in files {
println!(
"cargo:rerun-if-changed={}",
Expand Down
55 changes: 26 additions & 29 deletions core/tauri-codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,36 +164,33 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
};

let assets = match app_url {
AppUrl::Url(url) => match url {
WebviewUrl::External(_) => Default::default(),
WebviewUrl::App(path) => {
if path.components().count() == 0 {
panic!(
"The `{}` configuration cannot be empty",
if dev { "devPath" } else { "distDir" }
)
}
let assets_path = config_parent.join(path);
if !assets_path.exists() {
panic!(
"The `{}` configuration is set to `{:?}` but this path doesn't exist",
if dev { "devPath" } else { "distDir" },
path
)
Some(url) => match url {
AppUrl::Url(url) => match url {
WebviewUrl::External(_) | WebviewUrl::CustomProtocol(_) => Default::default(),
WebviewUrl::App(path) => {
let assets_path = config_parent.join(path);
if !assets_path.exists() {
panic!(
"The `{}` configuration is set to `{:?}` but this path doesn't exist",
if dev { "devPath" } else { "distDir" },
path
)
}
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
}
EmbeddedAssets::new(assets_path, &options, map_core_assets(&options, target))?
}
_ => unimplemented!(),
},
AppUrl::Files(files) => EmbeddedAssets::new(
files
.iter()
.map(|p| config_parent.join(p))
.collect::<Vec<_>>(),
&options,
map_core_assets(&options, target),
)?,
_ => unimplemented!(),
},
AppUrl::Files(files) => EmbeddedAssets::new(
files
.iter()
.map(|p| config_parent.join(p))
.collect::<Vec<_>>(),
&options,
map_core_assets(&options, target),
)?,
_ => unimplemented!(),
None => Default::default(),
};

let out_dir = {
Expand Down Expand Up @@ -398,7 +395,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
Default::default()
};

let resolved_act = Resolved::resolve(acl, capabilities, target).expect("failed to resolve ACL");
let resolved_acl = Resolved::resolve(acl, capabilities, target).expect("failed to resolve ACL");

Ok(quote!({
#[allow(unused_mut, clippy::let_and_return)]
Expand All @@ -410,7 +407,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
#package_info,
#info_plist,
#pattern,
#resolved_act
#resolved_acl
);
#with_tray_icon_code
context
Expand Down
21 changes: 14 additions & 7 deletions core/tauri-config-schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@
"build": {
"description": "The build configuration.",
"default": {
"devPath": "http://localhost:8080/",
"distDir": "../dist",
"withGlobalTauri": false
},
"allOf": [
Expand Down Expand Up @@ -575,13 +573,18 @@
"description": "An URL to open on a Tauri webview window.",
"anyOf": [
{
"description": "An external URL.",
"description": "An external URL. Must use either the `http` or `https` schemes.",
"type": "string",
"format": "uri"
},
{
"description": "The path portion of an app URL. For instance, to load `tauri://localhost/users/john`, you can simply provide `users/john` in this configuration.",
"type": "string"
},
{
"description": "A custom protocol url, for example, `doom://index.html`",
"type": "string",
"format": "uri"
}
]
},
Expand Down Expand Up @@ -2408,19 +2411,23 @@
},
"devPath": {
"description": "The path to the application assets or URL to load in development.\n\nThis is usually an URL to a dev server, which serves your application assets with live reloading. Most modern JavaScript bundlers provides a way to start a dev server by default.\n\nSee [vite](https://vitejs.dev/guide/), [Webpack DevServer](https://webpack.js.org/configuration/dev-server/) and [sirv](https://github.com/lukeed/sirv) for examples on how to set up a dev server.",
"default": "http://localhost:8080/",
"allOf": [
"anyOf": [
{
"$ref": "#/definitions/AppUrl"
},
{
"type": "null"
}
]
},
"distDir": {
"description": "The path to the application assets or URL to load in production.\n\nWhen a path relative to the configuration file is provided, it is read recursively and all files are embedded in the application binary. Tauri then looks for an `index.html` file unless you provide a custom window URL.\n\nYou can also provide a list of paths to be embedded, which allows granular control over what files are added to the binary. In this case, all files are added to the root and you must reference it that way in your HTML files.\n\nWhen an URL is provided, the application won't have bundled assets and the application will load that URL by default.",
"default": "../dist",
"allOf": [
"anyOf": [
{
"$ref": "#/definitions/AppUrl"
},
{
"type": "null"
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion core/tauri-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@

### New Features

- [`acc36fe1`](https://www.github.com/tauri-apps/tauri/commit/acc36fe1176cc8aa9063bde932abeb94796c5c72)([#6158](https://www.github.com/tauri-apps/tauri/pull/6158)) Add option to configure `require_literal_leading_dot` on `fs` and `asset` protcol scopes.
- [`acc36fe1`](https://www.github.com/tauri-apps/tauri/commit/acc36fe1176cc8aa9063bde932abeb94796c5c72)([#6158](https://www.github.com/tauri-apps/tauri/pull/6158)) Add option to configure `require_literal_leading_dot` on `fs` and `asset` protocol scopes.
- [`35cd751a`](https://www.github.com/tauri-apps/tauri/commit/35cd751adc6fef1f792696fa0cfb471b0bf99374)([#5176](https://www.github.com/tauri-apps/tauri/pull/5176)) Added the `desktop_template` option on `tauri.conf.json > tauri > bundle > deb`.
- [`c4d6fb4b`](https://www.github.com/tauri-apps/tauri/commit/c4d6fb4b1ea8acf02707a9fe5dcab47c1c5bae7b)([#2353](https://www.github.com/tauri-apps/tauri/pull/2353)) Added the `maximizable`, `minimizable` and `closable` options to the window configuration.
- [`3cb7a3e6`](https://www.github.com/tauri-apps/tauri/commit/3cb7a3e642bb10ee90dc1d24daa48b8c8c15c9ce)([#6997](https://www.github.com/tauri-apps/tauri/pull/6997)) Add `MimeType::parse_with_fallback` and `MimeType::parse_from_uri_with_fallback`
Expand Down
10 changes: 5 additions & 5 deletions core/tauri-utils/src/acl/resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::{
};

/// A key for a scope, used to link a [`ResolvedCommand#structfield.scope`] to the store [`Resolved#structfield.scopes`].
pub type ScopeKey = usize;
pub type ScopeKey = u64;

/// Metadata for what referenced a [`ResolvedCommand`].
#[cfg(debug_assertions)]
Expand Down Expand Up @@ -206,7 +206,7 @@ impl Resolved {

let mut hasher = DefaultHasher::new();
allowed.scope.hash(&mut hasher);
let hash = hasher.finish() as usize;
let hash = hasher.finish();

allowed.resolved_scope_key.replace(hash);

Expand Down Expand Up @@ -297,15 +297,15 @@ struct ResolvedCommandTemp {
#[cfg(debug_assertions)]
pub referenced_by: Vec<ResolvedCommandReference>,
pub windows: HashSet<String>,
pub scope: Vec<usize>,
pub resolved_scope_key: Option<usize>,
pub scope: Vec<ScopeKey>,
pub resolved_scope_key: Option<ScopeKey>,
}

fn resolve_command(
commands: &mut BTreeMap<CommandKey, ResolvedCommandTemp>,
command: String,
capability: &Capability,
scope_id: Option<usize>,
scope_id: Option<ScopeKey>,
#[cfg(debug_assertions)] permission: &Permission,
) {
let contexts = match &capability.context {
Expand Down
94 changes: 45 additions & 49 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,50 @@ fn default_true() -> bool {
}

/// An URL to open on a Tauri webview window.
#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)]
#[derive(PartialEq, Eq, Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(untagged)]
#[non_exhaustive]
pub enum WebviewUrl {
/// An external URL.
/// An external URL. Must use either the `http` or `https` schemes.
External(Url),
/// The path portion of an app URL.
/// For instance, to load `tauri://localhost/users/john`,
/// you can simply provide `users/john` in this configuration.
App(PathBuf),
/// A custom protocol url, for example, `doom://index.html`
CustomProtocol(Url),
}

impl<'de> Deserialize<'de> for WebviewUrl {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum WebviewUrlDeserializer {
Url(Url),
Path(PathBuf),
}

match WebviewUrlDeserializer::deserialize(deserializer)? {
WebviewUrlDeserializer::Url(u) => {
if u.scheme() == "https" || u.scheme() == "http" {
Ok(Self::External(u))
} else {
Ok(Self::CustomProtocol(u))
}
}
WebviewUrlDeserializer::Path(p) => Ok(Self::App(p)),
}
}
}

impl fmt::Display for WebviewUrl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::External(url) => write!(f, "{url}"),
Self::External(url) | Self::CustomProtocol(url) => write!(f, "{url}"),
Self::App(path) => write!(f, "{}", path.display()),
}
}
Expand Down Expand Up @@ -1858,7 +1885,7 @@ pub enum HookCommand {
///
/// See more: <https://tauri.app/v1/api/config#buildconfig>
#[skip_serializing_none]
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)]
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, Default)]
#[cfg_attr(feature = "schema", derive(JsonSchema))]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct BuildConfig {
Expand All @@ -1871,8 +1898,8 @@ pub struct BuildConfig {
///
/// See [vite](https://vitejs.dev/guide/), [Webpack DevServer](https://webpack.js.org/configuration/dev-server/) and [sirv](https://github.com/lukeed/sirv)
/// for examples on how to set up a dev server.
#[serde(default = "default_dev_path", alias = "dev-path")]
pub dev_path: AppUrl,
#[serde(alias = "dev-path")]
pub dev_path: Option<AppUrl>,
/// The path to the application assets or URL to load in production.
///
/// When a path relative to the configuration file is provided,
Expand All @@ -1884,8 +1911,8 @@ pub struct BuildConfig {
///
/// When an URL is provided, the application won't have bundled assets
/// and the application will load that URL by default.
#[serde(default = "default_dist_dir", alias = "dist-dir")]
pub dist_dir: AppUrl,
#[serde(alias = "dist-dir")]
pub dist_dir: Option<AppUrl>,
/// A shell command to run before `tauri dev` kicks in.
///
/// The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.
Expand All @@ -1908,31 +1935,6 @@ pub struct BuildConfig {
pub with_global_tauri: bool,
}

impl Default for BuildConfig {
fn default() -> Self {
Self {
runner: None,
dev_path: default_dev_path(),
dist_dir: default_dist_dir(),
before_dev_command: None,
before_build_command: None,
before_bundle_command: None,
features: None,
with_global_tauri: false,
}
}
}

fn default_dev_path() -> AppUrl {
AppUrl::Url(WebviewUrl::External(
Url::parse("http://localhost:8080").unwrap(),
))
}

fn default_dist_dir() -> AppUrl {
AppUrl::Url(WebviewUrl::App("../dist".into()))
}

#[derive(Debug, PartialEq, Eq)]
struct PackageVersion(String);

Expand Down Expand Up @@ -2123,8 +2125,8 @@ pub struct PluginConfig(pub HashMap<String, JsonValue>);
fn default_build() -> BuildConfig {
BuildConfig {
runner: None,
dev_path: default_dev_path(),
dist_dir: default_dist_dir(),
dev_path: None,
dist_dir: None,
before_dev_command: None,
before_build_command: None,
before_bundle_command: None,
Expand Down Expand Up @@ -2159,6 +2161,10 @@ mod build {
let url = url_lit(url);
quote! { #prefix::External(#url) }
}
Self::CustomProtocol(url) => {
let url = url_lit(url);
quote! { #prefix::CustomProtocol(#url) }
}
})
}
}
Expand Down Expand Up @@ -2489,8 +2495,8 @@ mod build {

impl ToTokens for BuildConfig {
fn to_tokens(&self, tokens: &mut TokenStream) {
let dev_path = &self.dev_path;
let dist_dir = &self.dist_dir;
let dev_path = opt_lit(self.dev_path.as_ref());
let dist_dir = opt_lit(self.dist_dir.as_ref());
let with_global_tauri = self.with_global_tauri;
let runner = quote!(None);
let before_dev_command = quote!(None);
Expand Down Expand Up @@ -2758,8 +2764,6 @@ mod test {
let t_config = TauriConfig::default();
// get default build config
let b_config = BuildConfig::default();
// get default dev path
let d_path = default_dev_path();
// get default window
let d_windows: Vec<WindowConfig> = vec![];
// get default bundle
Expand Down Expand Up @@ -2806,10 +2810,8 @@ mod test {
// create a build config
let build = BuildConfig {
runner: None,
dev_path: AppUrl::Url(WebviewUrl::External(
Url::parse("http://localhost:8080").unwrap(),
)),
dist_dir: AppUrl::Url(WebviewUrl::App("../dist".into())),
dev_path: None,
dist_dir: None,
before_dev_command: None,
before_build_command: None,
before_bundle_command: None,
Expand All @@ -2821,12 +2823,6 @@ mod test {
assert_eq!(t_config, tauri);
assert_eq!(b_config, build);
assert_eq!(d_bundle, tauri.bundle);
assert_eq!(
d_path,
AppUrl::Url(WebviewUrl::External(
Url::parse("http://localhost:8080").unwrap()
))
);
assert_eq!(d_windows, tauri.windows);
}
}
Loading

0 comments on commit 58fe2e8

Please sign in to comment.