mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-21 02:26:31 +03:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
502f0f28b5 |
@@ -77,56 +77,31 @@ fn legacy_kebab(value: &str) -> Option<String> {
|
||||
}
|
||||
|
||||
fn normalized_kebab(value: &str) -> Option<String> {
|
||||
let lower = value.to_lowercase();
|
||||
// replace runs of / \ . with '-'
|
||||
let mut s = String::with_capacity(lower.len());
|
||||
let mut in_sep = false;
|
||||
for c in lower.chars() {
|
||||
if c == '/' || c == '\\' || c == '.' {
|
||||
if !in_sep {
|
||||
s.push('-');
|
||||
in_sep = true;
|
||||
}
|
||||
} else {
|
||||
in_sep = false;
|
||||
s.push(c);
|
||||
}
|
||||
}
|
||||
// replace runs of [^a-z0-9-] with '-'
|
||||
let mut t = String::with_capacity(s.len());
|
||||
let mut in_bad = false;
|
||||
for c in s.chars() {
|
||||
if c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-' {
|
||||
in_bad = false;
|
||||
t.push(c);
|
||||
} else if !in_bad {
|
||||
t.push('-');
|
||||
in_bad = true;
|
||||
}
|
||||
}
|
||||
// collapse -+
|
||||
let mut u = String::with_capacity(t.len());
|
||||
let mut in_dash = false;
|
||||
for c in t.chars() {
|
||||
if c == '-' {
|
||||
if !in_dash {
|
||||
u.push('-');
|
||||
in_dash = true;
|
||||
}
|
||||
} else {
|
||||
in_dash = false;
|
||||
u.push(c);
|
||||
}
|
||||
}
|
||||
// strip leading/trailing '-' (JS: /^-|-$/g -> one at each end; after collapse there is at most one)
|
||||
let u = u.strip_prefix('-').unwrap_or(&u).to_string();
|
||||
let u = u.strip_suffix('-').unwrap_or(&u).to_string();
|
||||
(!u.is_empty()).then_some(u)
|
||||
let normalized = value
|
||||
.to_lowercase()
|
||||
.split(|c: char| !c.is_ascii_lowercase() && !c.is_ascii_digit())
|
||||
.filter(|part| !part.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join("-");
|
||||
(!normalized.is_empty()).then_some(normalized)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{kebab, legacy_kebab, SLUG_MAX};
|
||||
use super::{kebab, legacy_kebab, normalized_kebab, SLUG_MAX};
|
||||
|
||||
#[test]
|
||||
fn normalization_preserves_ascii_runs_after_unicode_lowercasing() {
|
||||
for (input, expected) in [
|
||||
("", None),
|
||||
(" /\\.--_!?\n🦀 ", None),
|
||||
("--Button./\\ _Primary...99--", Some("button-primary-99")),
|
||||
("A🦀B café", Some("a-b-caf")),
|
||||
("İSTANBUL KELVIN", Some("i-stanbul-kelvin")),
|
||||
] {
|
||||
assert_eq!(normalized_kebab(input).as_deref(), expected, "{input:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn truncated_slugs_keep_distinct_full_inputs_distinct() {
|
||||
|
||||
@@ -495,7 +495,6 @@ re!(
|
||||
format!("border(?:Left|Right){WS}*[:=]{WS}*[\"'`]({D}+)px{WS}+solid")
|
||||
);
|
||||
re!(BORDER_ACCENT_TW_RE, format!("{B}border-[tb]-({D}+){B}"));
|
||||
re!(ANIMATE_SPIN_RE, format!("{B}animate-spin{B}"));
|
||||
re!(
|
||||
BORDER_ACCENT_CSS_RE,
|
||||
format!(
|
||||
@@ -868,12 +867,7 @@ pub static REGEX_MATCHERS: Lazy<Vec<Matcher>> = Lazy::new(|| {
|
||||
Matcher {
|
||||
id: "border-accent-on-rounded",
|
||||
find_all: |l| all(&BORDER_ACCENT_TW_RE, l),
|
||||
test: |m, line| {
|
||||
let scope = containing_markup_tag(line)(m.index);
|
||||
has_rounded(&scope)
|
||||
&& num(m.g(1)) >= 1.0
|
||||
&& !ANIMATE_SPIN_RE.is_match(&scope)
|
||||
},
|
||||
test: |m, line| has_rounded(line) && num(m.g(1)) >= 1.0,
|
||||
fmt: |m, _| m.whole().to_string(),
|
||||
},
|
||||
Matcher {
|
||||
@@ -1463,27 +1457,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn border_accent_skips_tailwind_spinner() {
|
||||
let g = |line: &str| run("border-accent-on-rounded", line);
|
||||
assert_eq!(
|
||||
g(r#"<div className="rounded-lg border-t-4 border-blue-500" />"#),
|
||||
vec!["border-t-4"]
|
||||
);
|
||||
assert_eq!(
|
||||
g(r#"<div className="rounded-full border-b-2" />"#),
|
||||
vec!["border-b-2"]
|
||||
);
|
||||
assert!(g(r#"<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-accent" />"#).is_empty());
|
||||
assert!(g(r#"<div className="sm:animate-spin rounded-full h-8 w-8 border-t-2" />"#).is_empty());
|
||||
assert!(g(r#"<div className="motion-safe:animate-spin rounded-full border-b-2" />"#).is_empty());
|
||||
assert_eq!(
|
||||
g(r#"<div className="animate-spin rounded-full h-12 w-12 border-b-2" /><div className="rounded-lg border-t-4" />"#),
|
||||
vec!["border-t-4"]
|
||||
);
|
||||
assert!(g(r#"<div className="animate-spin rounded-full h-12 w-12 border-b-2" /><div className="border-t-4" />"#).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dashes() {
|
||||
assert_eq!(count_em_dashes("a — b -- c ---d"), 2);
|
||||
|
||||
Reference in New Issue
Block a user