Skip to content

Commit f3e7880

Browse files
Parse candidates in .svelte files with class:abc="condition" syntax (#13274)
* handle `.svelte` file In svelte there is a convention where you can use `<div class:px-4="condition" />` which means that we extract `class:px-4` as a utility where `class` is a variant. This is obviously incorrect, to solve this we can ignore the `class:` part before parsing the whole file. This is also what we do in v3. Ideally we have completely separate parsers for various programming languages (based on file type) and fallback to the generic one we have now. Implementing that, is a much bigger scope. * flatten match arms * add test to verify we can parse `class:px-4="condition"` * explicitly ingore everything but the svelte file * merge tests There is some funky stuff happening when running `cargo test` where it sees contents from another test. Maybe a bug in the tmpdir crate. I don't see this problem locally when running `cargo nextest run`, but when using the native `cargo test` command it fails. * update changelog * run prettier * Update oxide/crates/core/src/lib.rs Co-authored-by: Jordan Pittman <[email protected]> * fixup syntax errors --------- Co-authored-by: Jordan Pittman <[email protected]>
1 parent cdb0997 commit f3e7880

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
### Fixed
1515

1616
- Validate bare values ([#13245](https://github.com/tailwindlabs/tailwindcss/pull/13245))
17+
- Parse candidates in `.svelte` files with `class:abc="condition"` syntax ([#13274](https://github.com/tailwindlabs/tailwindcss/pull/13274))
1718

1819
### Changed
1920

oxide/crates/core/src/lib.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::parser::Extractor;
2+
use bstr::ByteSlice;
23
use cache::Cache;
34
use fxhash::FxHashSet;
45
use ignore::DirEntry;
@@ -399,6 +400,32 @@ pub fn scan_files(input: Vec<ChangedContent>, options: u8) -> Vec<String> {
399400
}
400401
}
401402

403+
fn read_changed_content(c: ChangedContent) -> Option<Vec<u8>> {
404+
if let Some(content) = c.content {
405+
return Some(content.into_bytes());
406+
}
407+
408+
let Some(file) = c.file else {
409+
return Default::default();
410+
};
411+
412+
let Ok(content) = std::fs::read(&file).map_err(|e| {
413+
event!(tracing::Level::ERROR, "Failed to read file: {:?}", e);
414+
e
415+
}) else {
416+
return Default::default();
417+
};
418+
419+
let Some(extension) = file.extension().map(|x| x.to_str()) else {
420+
return Some(content);
421+
};
422+
423+
match extension {
424+
Some("svelte") => Some(content.replace(" class:", " ")),
425+
_ => Some(content),
426+
}
427+
}
428+
402429
#[tracing::instrument(skip(changed_content))]
403430
fn read_all_files(changed_content: Vec<ChangedContent>) -> Vec<Vec<u8>> {
404431
event!(
@@ -409,17 +436,7 @@ fn read_all_files(changed_content: Vec<ChangedContent>) -> Vec<Vec<u8>> {
409436

410437
changed_content
411438
.into_par_iter()
412-
.map(|c| match (c.file, c.content) {
413-
(Some(file), None) => match std::fs::read(file) {
414-
Ok(content) => content,
415-
Err(e) => {
416-
event!(tracing::Level::ERROR, "Failed to read file: {:?}", e);
417-
Default::default()
418-
}
419-
},
420-
(None, Some(content)) => content.into_bytes(),
421-
_ => Default::default(),
422-
})
439+
.filter_map(read_changed_content)
423440
.collect()
424441
}
425442

@@ -433,11 +450,7 @@ fn read_all_files_sync(changed_content: Vec<ChangedContent>) -> Vec<Vec<u8>> {
433450

434451
changed_content
435452
.into_iter()
436-
.filter_map(|c| match (c.file, c.content) {
437-
(Some(file), None) => std::fs::read(file).ok(),
438-
(None, Some(content)) => Some(content.into_bytes()),
439-
_ => Default::default(),
440-
})
453+
.filter_map(read_changed_content)
441454
.collect()
442455
}
443456

oxide/crates/core/tests/auto_content.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,14 @@ mod auto_content {
297297
("foo.jpg", Some("xl:font-bold")),
298298
// A file that is ignored
299299
("foo.html", Some("lg:font-bold")),
300+
// A svelte file with `class:foo="bar"` syntax
301+
("index.svelte", Some("<div class:px-4='condition'></div>")),
300302
])
301303
.1;
302304

303-
assert_eq!(candidates, vec!["font-bold", "md:flex"]);
305+
assert_eq!(
306+
candidates,
307+
vec!["condition", "div", "font-bold", "md:flex", "px-4"]
308+
);
304309
}
305310
}

0 commit comments

Comments
 (0)