diff --git a/Cargo.lock b/Cargo.lock index ca38ef9..05c1f0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3016,9 +3016,9 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "normpath" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c178369371fd7db523726931e50d430b560e3059665abc537ba3277e9274c9c4" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" dependencies = [ "windows-sys 0.61.0", ] diff --git a/wgui/src/assets.rs b/wgui/src/assets.rs index 8dc80d2..dd2e822 100644 --- a/wgui/src/assets.rs +++ b/wgui/src/assets.rs @@ -1,3 +1,22 @@ +use std::path::{Path, PathBuf}; + pub trait AssetProvider { fn load_from_path(&mut self, path: &str) -> anyhow::Result>; } + +// replace "./foo/bar/../file.txt" with "./foo/file.txt" +pub fn normalize_path(path: &Path) -> PathBuf { + let mut stack = Vec::new(); + for component in path.components() { + match component { + std::path::Component::ParentDir => { + stack.pop(); + } + std::path::Component::Normal(name) => { + stack.push(name); + } + _ => {} + } + } + stack.iter().collect() +} diff --git a/wgui/src/parser/mod.rs b/wgui/src/parser/mod.rs index 88c1b48..0da414f 100644 --- a/wgui/src/parser/mod.rs +++ b/wgui/src/parser/mod.rs @@ -8,7 +8,7 @@ mod widget_rectangle; mod widget_sprite; use crate::{ - assets::AssetProvider, + assets::{self, AssetProvider}, components::{Component, ComponentWeak}, drawing::{self}, event::EventListenerCollection, @@ -478,6 +478,7 @@ fn parse_tag_include<'a, U1, U2>( "src" => { let mut new_path = file.path.parent().unwrap_or_else(|| Path::new("/")).to_path_buf(); new_path.push(value); + let new_path = assets::normalize_path(&new_path); let (new_file, node_layout) = get_doc_from_path(ctx, &new_path)?; parse_document_root(&new_file, ctx, parent_id, node_layout)?;