From 11c4257edd486cc3fc3db1c9a9c4b73552fae3e2 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Sat, 15 Feb 2025 21:41:27 +0900 Subject: [PATCH] Implement debug mode --- .changeset/few-items-yell.md | 7 + bindings/devup-ui-wasm/src/lib.rs | 10 + libs/css/src/lib.rs | 237 +++++++++++++++--- packages/vite-plugin/src/plugin.ts | 8 +- .../src/__tests__/plugin.test.ts | 2 + packages/webpack-plugin/src/plugin.ts | 5 + 6 files changed, 236 insertions(+), 33 deletions(-) create mode 100644 .changeset/few-items-yell.md diff --git a/.changeset/few-items-yell.md b/.changeset/few-items-yell.md new file mode 100644 index 00000000..b2dd914f --- /dev/null +++ b/.changeset/few-items-yell.md @@ -0,0 +1,7 @@ +--- +"@devup-ui/webpack-plugin": patch +"@devup-ui/wasm": patch +"@devup-ui/vite-plugin": patch +--- + +Implement debug mode diff --git a/bindings/devup-ui-wasm/src/lib.rs b/bindings/devup-ui-wasm/src/lib.rs index 55984384..b6317cbc 100644 --- a/bindings/devup-ui-wasm/src/lib.rs +++ b/bindings/devup-ui-wasm/src/lib.rs @@ -86,6 +86,16 @@ impl Output { } } +#[wasm_bindgen(js_name = "setDebug")] +pub fn set_debug(debug: bool) { + css::set_debug(debug); +} + +#[wasm_bindgen(js_name = "isDebug")] +pub fn is_debug() { + css::is_debug(); +} + #[wasm_bindgen(js_name = "importSheet")] pub fn import_sheet(sheet_object: JsValue) -> Result<(), JsValue> { *GLOBAL_STYLE_SHEET.lock().unwrap() = serde_wasm_bindgen::from_value(sheet_object) diff --git a/libs/css/src/lib.rs b/libs/css/src/lib.rs index a1c1577d..82fc8f3e 100644 --- a/libs/css/src/lib.rs +++ b/libs/css/src/lib.rs @@ -5,6 +5,7 @@ use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::fmt; use std::fmt::{Display, Formatter}; +use std::hash::{DefaultHasher, Hash, Hasher}; use std::sync::Mutex; static SELECTOR_ORDER_MAP: Lazy> = Lazy::new(|| { @@ -17,6 +18,17 @@ static SELECTOR_ORDER_MAP: Lazy> = Lazy::new(|| { map }); +static DEBUG: Lazy> = Lazy::new(|| Mutex::new(false)); + +pub fn set_debug(value: bool) { + let mut debug = DEBUG.lock().unwrap(); + *debug = value; +} + +pub fn is_debug() -> bool { + *DEBUG.lock().unwrap() +} + #[derive(Debug, PartialEq, Clone, Hash, Eq, Serialize, Deserialize)] pub enum StyleSelector { Media(String), @@ -327,41 +339,81 @@ pub fn sheet_to_classname( selector: Option<&str>, style_order: Option, ) -> String { - let key = format!( - "{}-{}-{}-{}-{}", - property.trim(), - level, - F_SPACE_RE.replace_all(value.unwrap_or(""), ",").trim(), - selector.unwrap_or("").trim(), - style_order.unwrap_or(255) - ); - let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); - map.get(&key).map(|v| format!("d{}", v)).unwrap_or_else(|| { - let len = map.len(); - map.insert(key, len as i32); - format!("d{}", map.len() - 1) - }) + if *DEBUG.lock().unwrap() { + let selector = selector.unwrap_or("").trim(); + format!( + "{}-{}-{}-{}-{}", + property.trim(), + level, + F_SPACE_RE.replace_all(value.unwrap_or(""), ",").trim(), + if selector.is_empty() { + "".to_string() + } else { + let mut hasher = DefaultHasher::new(); + selector.hash(&mut hasher); + hasher.finish().to_string() + }, + style_order.unwrap_or(255) + ) + } else { + let key = format!( + "{}-{}-{}-{}-{}", + property.trim(), + level, + F_SPACE_RE.replace_all(value.unwrap_or(""), ",").trim(), + selector.unwrap_or("").trim(), + style_order.unwrap_or(255) + ); + let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); + map.get(&key).map(|v| format!("d{}", v)).unwrap_or_else(|| { + let len = map.len(); + map.insert(key, len as i32); + format!("d{}", map.len() - 1) + }) + } } pub fn css_to_classname(css: &str) -> String { - let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); - map.get(css).map(|v| format!("d{}", v)).unwrap_or_else(|| { - let len = map.len(); - map.insert(css.to_string(), len as i32); - format!("d{}", map.len() - 1) - }) + if *DEBUG.lock().unwrap() { + let mut hasher = DefaultHasher::new(); + css.hash(&mut hasher); + format!("css-{}", hasher.finish()) + } else { + let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); + map.get(css).map(|v| format!("d{}", v)).unwrap_or_else(|| { + let len = map.len(); + map.insert(css.to_string(), len as i32); + format!("d{}", map.len() - 1) + }) + } } pub fn sheet_to_variable_name(property: &str, level: u8, selector: Option<&str>) -> String { - let key = format!("{}-{}-{}", property, level, selector.unwrap_or("")); - let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); - map.get(&key) - .map(|v| format!("--d{}", v)) - .unwrap_or_else(|| { - let len = map.len(); - map.insert(key, len as i32); - format!("--d{}", map.len() - 1) - }) + if *DEBUG.lock().unwrap() { + let selector = selector.unwrap_or("").trim(); + format!( + "--{}-{}-{}", + property, + level, + if selector.is_empty() { + "".to_string() + } else { + let mut hasher = DefaultHasher::new(); + selector.hash(&mut hasher); + hasher.finish().to_string() + } + ) + } else { + let key = format!("{}-{}-{}", property, level, selector.unwrap_or("").trim()); + let mut map = GLOBAL_CLASS_MAP.lock().unwrap(); + map.get(&key) + .map(|v| format!("--d{}", v)) + .unwrap_or_else(|| { + let len = map.len(); + map.insert(key, len as i32); + format!("--d{}", map.len() - 1) + }) + } } #[cfg(test)] @@ -369,10 +421,20 @@ mod tests { use super::*; use serial_test::serial; + #[test] + #[serial] + fn test_set_debug() { + set_debug(true); + assert!(is_debug()); + set_debug(false); + assert!(!is_debug()); + } + #[test] #[serial] fn test_sheet_to_variable_name() { reset_class_map(); + set_debug(false); assert_eq!(sheet_to_variable_name("background", 0, None), "--d0"); assert_eq!( sheet_to_variable_name("background", 0, Some("hover")), @@ -385,18 +447,44 @@ mod tests { ); } + #[test] + #[serial] + fn test_debug_sheet_to_variable_name() { + set_debug(true); + assert_eq!( + sheet_to_variable_name("background", 0, None), + "--background-0-" + ); + assert_eq!( + sheet_to_variable_name("background", 0, Some("hover".into())), + "--background-0-12448419602614487988" + ); + assert_eq!( + sheet_to_variable_name("background", 1, None), + "--background-1-" + ); + assert_eq!( + sheet_to_variable_name("background", 1, Some("hover".into())), + "--background-1-12448419602614487988" + ); + } + #[test] #[serial] fn test_sheet_to_classname() { + set_debug(false); reset_class_map(); - assert_eq!(sheet_to_classname("background", 0, None, None, None), "d0"); assert_eq!( - sheet_to_classname("background", 0, Some("hover"), None, None), + sheet_to_classname("background", 0, Some("red"), None, None), + "d0" + ); + assert_eq!( + sheet_to_classname("background", 0, Some("red"), Some("hover"), None), "d1" ); assert_eq!(sheet_to_classname("background", 1, None, None, None), "d2"); assert_eq!( - sheet_to_classname("background", 1, Some("hover"), None, None), + sheet_to_classname("background", 1, None, Some("hover"), None), "d3" ); @@ -438,6 +526,56 @@ mod tests { ); } + #[test] + #[serial] + fn test_debug_sheet_to_classname() { + set_debug(true); + assert_eq!( + sheet_to_classname("background", 0, None, None, None), + "background-0---255" + ); + assert_eq!( + sheet_to_classname("background", 0, Some("red"), Some("hover"), None), + "background-0-red-12448419602614487988-255" + ); + assert_eq!( + sheet_to_classname("background", 1, None, None, None), + "background-1---255" + ); + assert_eq!( + sheet_to_classname("background", 1, Some("red"), Some("hover"), None), + "background-1-red-12448419602614487988-255" + ); + } + + #[test] + #[serial] + fn test_css_to_classname() { + set_debug(false); + reset_class_map(); + assert_eq!(css_to_classname("background: red"), "d0"); + assert_eq!(css_to_classname("background: blue"), "d1"); + } + #[test] + #[serial] + fn test_debug_css_to_classname() { + set_debug(true); + assert_eq!( + css_to_classname("background: red"), + "css-10773204219957113694" + ); + assert_eq!( + css_to_classname("background: blue"), + "css-1226995032436176700" + ); + set_debug(true); + reset_class_map(); + assert_eq!( + css_to_classname("background: red"), + "css-10773204219957113694" + ); + } + #[test] fn test_convert_property() { assert_eq!( @@ -726,6 +864,41 @@ mod tests { ":root[data-theme=dark] .cls:hover" ); } + #[test] + fn test_get_selector_separator() { + assert!(matches!( + get_selector_separator("placeholder"), + SelectorSeparator::Double + )); + assert!(matches!( + get_selector_separator("before"), + SelectorSeparator::Double + )); + assert!(matches!( + get_selector_separator("after"), + SelectorSeparator::Double + )); + + assert!(matches!( + get_selector_separator("hover"), + SelectorSeparator::Single + )); + + assert!(matches!( + get_selector_separator(":hover"), + SelectorSeparator::None + )); + + assert!(matches!( + get_selector_separator("::placeholder"), + SelectorSeparator::None + )); + + assert!(matches!( + get_selector_separator("[aria-disabled='true']"), + SelectorSeparator::None + )); + } #[test] #[serial] diff --git a/packages/vite-plugin/src/plugin.ts b/packages/vite-plugin/src/plugin.ts index 6617db5b..35bd6864 100644 --- a/packages/vite-plugin/src/plugin.ts +++ b/packages/vite-plugin/src/plugin.ts @@ -7,6 +7,7 @@ import { getCss, getThemeInterface, registerTheme, + setDebug, } from '@devup-ui/wasm' import { type PluginOption } from 'vite' @@ -19,9 +20,12 @@ export interface DevupUIPluginOptions { devupPath: string interfacePath: string extractCss: boolean + debug: boolean } -function writeDataFiles(options: Omit) { +function writeDataFiles( + options: Omit, +) { registerTheme(JSON.parse(readFileSync(options.devupPath, 'utf-8'))?.['theme']) const interfaceCode = getThemeInterface( options.package, @@ -46,7 +50,9 @@ export function DevupUI({ devupPath = 'devup.json', interfacePath = '.df', extractCss = true, + debug = false, }: Partial = {}): PluginOption { + setDebug(debug) if (existsSync(devupPath)) { try { writeDataFiles({ diff --git a/packages/webpack-plugin/src/__tests__/plugin.test.ts b/packages/webpack-plugin/src/__tests__/plugin.test.ts index 5b3658ad..fe47ed96 100644 --- a/packages/webpack-plugin/src/__tests__/plugin.test.ts +++ b/packages/webpack-plugin/src/__tests__/plugin.test.ts @@ -33,6 +33,7 @@ describe('devupUIPlugin', () => { devupPath: 'devup.json', interfacePath: '.df', watch: false, + debug: false, }) }) @@ -52,6 +53,7 @@ describe('devupUIPlugin', () => { devupPath: 'new-devup-path', interfacePath: 'new-interface-path', watch: false, + debug: false, }) }) diff --git a/packages/webpack-plugin/src/plugin.ts b/packages/webpack-plugin/src/plugin.ts index fa1fe8d9..031008f3 100644 --- a/packages/webpack-plugin/src/plugin.ts +++ b/packages/webpack-plugin/src/plugin.ts @@ -13,6 +13,7 @@ import { importClassMap, importSheet, registerTheme, + setDebug, } from '@devup-ui/wasm' import { type Compiler } from 'webpack' @@ -22,6 +23,7 @@ export interface DevupUIWebpackPluginOptions { devupPath: string interfacePath: string watch: boolean + debug: boolean } export class DevupUIWebpackPlugin { @@ -33,6 +35,7 @@ export class DevupUIWebpackPlugin { interfacePath = '.df', cssFile = resolve(interfacePath, 'devup-ui.css'), watch = false, + debug = false, }: Partial = {}) { this.options = { package: libPackage, @@ -40,6 +43,7 @@ export class DevupUIWebpackPlugin { devupPath, interfacePath, watch, + debug, } } @@ -71,6 +75,7 @@ export class DevupUIWebpackPlugin { } apply(compiler: Compiler) { + setDebug(this.options.debug) // read devup.json const existsDevup = existsSync(this.options.devupPath)