From 644eb2c12f111e6d8dd2babc2fbacacc0638ff1d Mon Sep 17 00:00:00 2001 From: rootiest Date: Mon, 3 Aug 2026 20:30:42 -0400 Subject: [PATCH] feat: add namespace support to ColorScheme to prevent css collisions --- src/color_scheme.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/color_scheme.rs b/src/color_scheme.rs index be112cb..1de6214 100644 --- a/src/color_scheme.rs +++ b/src/color_scheme.rs @@ -12,9 +12,19 @@ pub struct ColorScheme { impl ColorScheme { pub fn load(path: impl Into) -> Result { + Self::load_with_namespace(path, "") + } + + pub fn load_with_namespace(path: impl Into, namespace: &str) -> Result { let path = path.into(); - let content = std::fs::read_to_string(&path) + let mut content = std::fs::read_to_string(&path) .with_context(|| format!("reading {}", path.display()))?; + + if !namespace.is_empty() { + content = content.replace(".ColorScheme-", &format!(".{namespace}-ColorScheme-")); + content = content.replace("class=\"ColorScheme-", &format!("class=\"{namespace}-ColorScheme-")); + } + let colors = parse_colors(&content); Ok(Self { path, @@ -85,7 +95,7 @@ fn parse_colors(content: &str) -> Vec<(String, String)> { let Some(style) = style_block(content) else { return Vec::new(); }; - let re = Regex::new(r#"\.(ColorScheme-[a-zA-Z0-9]+)\s*\{\s*color:\s*(#[a-fA-F0-9]{3,6})"#) + let re = Regex::new(r#"\.([a-zA-Z0-9\-]*ColorScheme-[a-zA-Z0-9]+)\s*\{\s*color:\s*(#[a-fA-F0-9]{3,6})"#) .expect("static regex is valid"); re.captures_iter(style) .map(|c| (c[1].to_string(), c[2].to_string())) @@ -245,4 +255,22 @@ mod tests { std::fs::remove_dir_all(&dir).ok(); } + + #[test] + fn load_with_namespace_rewrites_classes() { + let dir = std::env::temp_dir().join(format!( + "icon-color-tool-test-namespace-{}", + std::process::id() + )); + std::fs::create_dir_all(&dir).unwrap(); + let file = dir.join("icon.svg"); + std::fs::write(&file, SINGLE_COLOR_SVG).unwrap(); + + let scheme = ColorScheme::load_with_namespace(&file, "Emblem").unwrap(); + assert!(scheme.content.contains(".Emblem-ColorScheme-Text")); + assert!(scheme.content.contains("class=\"Emblem-ColorScheme-Text\"")); + assert_eq!(scheme.colors[0].0, "Emblem-ColorScheme-Text"); + + std::fs::remove_dir_all(&dir).ok(); + } }