Skip to content

Commit

Permalink
fix: escape css ident
Browse files Browse the repository at this point in the history
  • Loading branch information
inottn committed Sep 2, 2024
1 parent f9820e4 commit c164c12
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 24 deletions.
9 changes: 8 additions & 1 deletion crates/rspack_plugin_css/src/dependency/local_ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use rspack_core::{
};
use rspack_util::ext::DynHash;

use crate::utils::escape_css;

#[derive(Debug, Clone)]
pub struct CssLocalIdentDependency {
id: DependencyId,
Expand Down Expand Up @@ -69,7 +71,12 @@ impl DependencyTemplate for CssLocalIdentDependency {
source: &mut TemplateReplaceSource,
_code_generatable_context: &mut TemplateContext,
) {
source.replace(self.start, self.end, &self.local_ident, None);
source.replace(
self.start,
self.end,
&escape_css(&self.local_ident, false),
None,
);
}

fn dependency_id(&self) -> Option<DependencyId> {
Expand Down
12 changes: 8 additions & 4 deletions crates/rspack_plugin_css/src/parser_and_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ use crate::{
static REGEX_IS_MODULES: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"\.module(s)?\.[^.]+$").expect("Invalid regex"));

static REGEX_IS_COMMENTS: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"/\*[\s\S]*?\*/").expect("Invalid regex"));

pub(crate) static CSS_MODULE_SOURCE_TYPE_LIST: &[SourceType; 1] = &[SourceType::Css];

pub(crate) static CSS_MODULE_EXPORTS_ONLY_SOURCE_TYPE_LIST: &[SourceType; 1] =
Expand Down Expand Up @@ -195,7 +198,7 @@ impl ParserAndGenerator for CssParserAndGenerator {
))),
css_module_lexer::Dependency::LocalClass { name, range, .. }
| css_module_lexer::Dependency::LocalId { name, range, .. } => {
let (prefix, name) = name.split_at(1); // split '#' or '.'
let (_prefix, name) = name.split_at(1); // split '#' or '.'
let local_ident = LocalIdentOptions::new(
resource_data,
self
Expand Down Expand Up @@ -223,9 +226,9 @@ impl ParserAndGenerator for CssParserAndGenerator {
);
}
dependencies.push(Box::new(CssLocalIdentDependency::new(
format!("{prefix}{local_ident}"),
local_ident,
convention_names,
range.start,
range.start + 1,
range.end,
)));
}
Expand Down Expand Up @@ -315,6 +318,7 @@ impl ParserAndGenerator for CssParserAndGenerator {
.as_ref()
.expect("should have local_ident_name for module_type css/auto or css/module");
let convention_names = export_locals_convention(prop, convention);
let value = REGEX_IS_COMMENTS.replace_all(value, "");
for name in convention_names.iter() {
update_css_exports(
exports,
Expand Down Expand Up @@ -434,7 +438,7 @@ impl ParserAndGenerator for CssParserAndGenerator {
escape_css(&v.ident, false)
)
} else {
format!("{}:{}/", escaped, &v.ident)
format!("{}:{}/", escaped, escape_css(&v.ident, false))
}
})
.collect::<Vec<_>>()
Expand Down
17 changes: 1 addition & 16 deletions crates/rspack_plugin_css/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,14 @@ impl LocalIdentNameRenderOptions<'_> {
.render(self.path_data, None)
.always_ok();
s = s.replace("[uniqueName]", self.unique_name);
s = escape_css_ident(&s);
s = s.replace(r"\[local\]", self.local); // [local] is escaped to \[local\]
s = s.replace("[local]", self.local);
s
}
}

static UNESCAPE_CSS_IDENT_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"([^a-zA-Z0-9_\u0081-\uffff-])").expect("invalid regex"));

pub fn escape_css_ident(s: &str) -> String {
UNESCAPE_CSS_IDENT_REGEX.replace_all(s, "\\$1").into_owned()
}

pub fn escape_css(s: &str, omit_optional_underscore: bool) -> Cow<str> {
let escaped = UNESCAPE_CSS_IDENT_REGEX.replace_all(s, |s: &Captures| format!("\\{}", &s[0]));
if !omit_optional_underscore
Expand All @@ -129,16 +124,6 @@ pub fn escape_css(s: &str, omit_optional_underscore: bool) -> Cow<str> {
escaped
}
}
// const escapeCss = (str, omitOptionalUnderscore) => {
// const escaped = `${str}`.replace(
// // cspell:word uffff
// /[^a-zA-Z0-9_\u0081-\uffff-]/g,
// s => `\\${s}`
// );
// return !omitOptionalUnderscore && /^(?!--)[0-9_-]/.test(escaped)
// ? `_${escaped}`
// : escaped;
// };

pub(crate) fn export_locals_convention(
key: &str,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

exports[`config config/builtin-lightningcss-loader/basic-include exported tests should transform css correct 1`] = `
"body {
& .-ca56f23580d7bbb484-used {
& ._-ca56f23580d7bbb484-used {
color: #00f;
}
}
head{--webpack--909:used:-ca56f23580d7bĒ484-ĀĂ/&_368;}"
head{--webpack--909:used:_-ca56f23580d7bē484-ĀĂ/&_368;}"
`;

exports[`config config/builtin-lightningcss-loader/minify exported tests css content minifyed 1`] = `
Expand Down Expand Up @@ -261,7 +261,7 @@ exports[`config config/css/export-selector exported tests should have correct cs
/* #endregion \\"./style.module.css?imported\\" */
head{--webpack--imported_js:foo:foo/bar:b a r/local:local/dashName:dashName/&\\\\.\\\\/style\\\\.module\\\\.css\\\\?imported;}"
head{--webpack--imported_js:foo:foo/bar:b\\\\ a\\\\ r/local:local/dashName:dashName/&\\\\.\\\\/style\\\\.module\\\\.css\\\\?imported;}"
`;
exports[`config config/css/rewrite-url exported tests should rewrite the css url() 1`] = `"5d8d67b36a3d70a5cea9.png"`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as styles from "./index.module.css";

it("should generate correct exports", () => {
expect(styles).toEqual(
nsObj({
a: '"aaa" 123',
b: "multiple lines bbb"
})
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
:export {
a: "aaa" 123;
b: multiple lines /**
comment1
comment2
comment3
*/ bbb/* comment4 */
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import("@rspack/core").Configuration} */
module.exports = {
experiments: {
css: true
}
};

0 comments on commit c164c12

Please sign in to comment.