Skip to content

Commit

Permalink
Merge branch 'add/css-modules-granular-options' of github.com:timneut…
Browse files Browse the repository at this point in the history
…kens/lightningcss into timneutkens-add/css-modules-granular-options
  • Loading branch information
devongovett committed May 15, 2024
2 parents 445def9 + 250edc7 commit 0c84b46
Show file tree
Hide file tree
Showing 12 changed files with 351 additions and 89 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ assert_cmd = "2.0"
assert_fs = "1.0"
predicates = "2.1"
serde_json = "1"
pretty_assertions = "1.4.0"

[[test]]
name = "cli_integration_tests"
Expand Down
9 changes: 9 additions & 0 deletions napi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,9 @@ enum CssModulesOption {
struct CssModulesConfig {
pattern: Option<String>,
dashed_idents: Option<bool>,
animation: Option<bool>,
grid: Option<bool>,
custom_idents: Option<bool>,
}

#[cfg(feature = "bundler")]
Expand Down Expand Up @@ -713,6 +716,9 @@ fn compile<'i>(
Default::default()
},
dashed_idents: c.dashed_idents.unwrap_or_default(),
animation: c.animation.unwrap_or_default(),
grid: c.grid.unwrap_or_default(),
custom_idents: c.custom_idents.unwrap_or_default(),
}),
}
} else {
Expand Down Expand Up @@ -840,6 +846,9 @@ fn compile_bundle<
Default::default()
},
dashed_idents: c.dashed_idents.unwrap_or_default(),
animation: c.animation.unwrap_or(true),
grid: c.grid.unwrap_or(true),
custom_idents: c.custom_idents.unwrap_or(true),
}),
}
} else {
Expand Down
23 changes: 22 additions & 1 deletion src/css_modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,34 @@ use std::hash::{Hash, Hasher};
use std::path::Path;

/// Configuration for CSS modules.
#[derive(Default, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct Config<'i> {
/// The name pattern to use when renaming class names and other identifiers.
/// Default is `[hash]_[local]`.
pub pattern: Pattern<'i>,
/// Whether to rename dashed identifiers, e.g. custom properties.
pub dashed_idents: bool,
/// Whether to scope animation names.
/// Default is `true`.
pub animation: bool,
/// Whether to scope grid names.
/// Default is `true`.
pub grid: bool,
/// Whether to scope custom identifiers
/// Default is `true`.
pub custom_idents: bool,
}

impl<'i> Default for Config<'i> {
fn default() -> Self {
Config {
pattern: Default::default(),
dashed_idents: Default::default(),
animation: true,
grid: true,
custom_idents: true,
}
}
}

/// A CSS modules class name pattern.
Expand Down
133 changes: 133 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ mod tests {
use crate::vendor_prefix::VendorPrefix;
use cssparser::SourceLocation;
use indoc::indoc;
use pretty_assertions::assert_eq;
use std::collections::HashMap;

fn test(source: &str, expected: &str) {
Expand Down Expand Up @@ -23053,6 +23054,98 @@ mod tests {
Default::default(),
);

css_modules_test(
r#"
.foo {
color: red;
}

#id {
animation: 2s test;
}

@keyframes test {
from { color: red }
to { color: yellow }
}
"#,
indoc! {r#"
.EgL3uq_foo {
color: red;
}

#EgL3uq_id {
animation: 2s test;
}

@keyframes test {
from {
color: red;
}

to {
color: #ff0;
}
}
"#},
map! {
"foo" => "EgL3uq_foo",
"id" => "EgL3uq_id",
"test" => "EgL3uq_test" referenced: true
},
HashMap::new(),
crate::css_modules::Config {
animation: false,
// custom_idents: false,
..Default::default()
},
);

css_modules_test(
r#"
@counter-style circles {
symbols: Ⓐ Ⓑ Ⓒ;
}

ul {
list-style: circles;
}

ol {
list-style-type: none;
}

li {
list-style-type: disc;
}
"#,
indoc! {r#"
@counter-style circles {
symbols: Ⓐ Ⓑ Ⓒ;
}

ul {
list-style: circles;
}

ol {
list-style-type: none;
}

li {
list-style-type: disc;
}
"#},
map! {
"circles" => "EgL3uq_circles" referenced: true
},
HashMap::new(),
crate::css_modules::Config {
custom_idents: false,
..Default::default()
},
);

#[cfg(feature = "grid")]
css_modules_test(
r#"
Expand Down Expand Up @@ -23135,6 +23228,46 @@ mod tests {
Default::default(),
);

#[cfg(feature = "grid")]
css_modules_test(
r#"
.grid {
grid-template-areas: "foo";
}

.foo {
grid-area: foo;
}

.bar {
grid-column-start: foo-start;
}
"#,
indoc! {r#"
.EgL3uq_grid {
grid-template-areas: "foo";
}

.EgL3uq_foo {
grid-area: foo;
}

.EgL3uq_bar {
grid-column-start: foo-start;
}
"#},
map! {
"foo" => "EgL3uq_foo",
"grid" => "EgL3uq_grid",
"bar" => "EgL3uq_bar"
},
HashMap::new(),
crate::css_modules::Config {
grid: false,
..Default::default()
},
);

css_modules_test(
r#"
test {
Expand Down
91 changes: 52 additions & 39 deletions src/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,56 +267,69 @@ impl<'a, 'b, 'c, W: std::fmt::Write + Sized> Printer<'a, 'b, 'c, W> {
/// Writes a CSS identifier to the underlying destination, escaping it
/// as appropriate. If the `css_modules` option was enabled, then a hash
/// is added, and the mapping is added to the CSS module.
pub fn write_ident(&mut self, ident: &str) -> Result<(), PrinterError> {
if let Some(css_module) = &mut self.css_module {
let dest = &mut self.dest;
let mut first = true;
css_module.config.pattern.write(
&css_module.hashes[self.loc.source_index as usize],
&css_module.sources[self.loc.source_index as usize],
ident,
|s| {
self.col += s.len() as u32;
if first {
first = false;
serialize_identifier(s, dest)
} else {
serialize_name(s, dest)
}
},
)?;

css_module.add_local(&ident, &ident, self.loc.source_index);
} else {
serialize_identifier(ident, self)?;
}

Ok(())
}

pub(crate) fn write_dashed_ident(&mut self, ident: &str, is_declaration: bool) -> Result<(), PrinterError> {
self.write_str("--")?;

match &mut self.css_module {
Some(css_module) if css_module.config.dashed_idents => {
pub fn write_ident(&mut self, ident: &str, handle_css_module: bool) -> Result<(), PrinterError> {
if handle_css_module {
if let Some(css_module) = &mut self.css_module {
let dest = &mut self.dest;
let mut first = true;
css_module.config.pattern.write(
&css_module.hashes[self.loc.source_index as usize],
&css_module.sources[self.loc.source_index as usize],
&ident[2..],
ident,
|s| {
self.col += s.len() as u32;
serialize_name(s, dest)
if first {
first = false;
serialize_identifier(s, dest)
} else {
serialize_name(s, dest)
}
},
)?;

if is_declaration {
css_module.add_dashed(ident, self.loc.source_index);
}
css_module.add_local(&ident, &ident, self.loc.source_index);
} else {
serialize_identifier(ident, self)?
}
_ => {
serialize_name(&ident[2..], self)?;
} else {
serialize_identifier(ident, self)?
}

Ok(())
}

pub(crate) fn write_dashed_ident(
&mut self,
ident: &str,
is_declaration: bool,
handle_css_module: bool,
) -> Result<(), PrinterError> {
self.write_str("--")?;

if handle_css_module {
match &mut self.css_module {
Some(css_module) if css_module.config.dashed_idents => {
let dest = &mut self.dest;
css_module.config.pattern.write(
&css_module.hashes[self.loc.source_index as usize],
&css_module.sources[self.loc.source_index as usize],
&ident[2..],
|s| {
self.col += s.len() as u32;
serialize_name(s, dest)
},
)?;

if is_declaration {
css_module.add_dashed(ident, self.loc.source_index);
}
}
_ => {
serialize_name(&ident[2..], self)?;
}
}
} else {
serialize_name(&ident[2..], self)?;
}

Ok(())
Expand Down
Loading

0 comments on commit 0c84b46

Please sign in to comment.