diff --git a/CHANGELOG.md b/CHANGELOG.md index ba47afa1cabd..11e2e77a0174 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ensure strings in Pug and Slim templates are handled correctly ([#17000](https://github.com/tailwindlabs/tailwindcss/pull/17000)) - Ensure `}` and `{` are valid boundary characters when extracting candidates ([#17001](https://github.com/tailwindlabs/tailwindcss/pull/17001)) - Add `razor`/`cshtml` pre processing ([#17027](https://github.com/tailwindlabs/tailwindcss/pull/17027)) +- Ensure extracting candidates from JS embedded in a PHP string works as expected ([#17031](https://github.com/tailwindlabs/tailwindcss/pull/17031)) ## [4.0.11] - 2025-03-06 diff --git a/crates/oxide/src/extractor/boundary.rs b/crates/oxide/src/extractor/boundary.rs index 3d13d895c12e..4e0f22089505 100644 --- a/crates/oxide/src/extractor/boundary.rs +++ b/crates/oxide/src/extractor/boundary.rs @@ -97,6 +97,18 @@ enum Class { // ^ // ``` #[bytes(b'=')] + // Escaped character when embedding one language in another via strings, e.g.: + // + // ``` + // $attributes->merge([ + // 'x-init' => '$el.classList.add(\'-translate-x-full\'); $el.classList.add(\'transition-transform\')', + // ^ ^ + // ]); + // ``` + // + // In this case there is some JavaScript embedded in an string in PHP and some of the quotes + // need to be escaped. + #[bytes(b'\\')] After, #[fallback] diff --git a/crates/oxide/src/extractor/mod.rs b/crates/oxide/src/extractor/mod.rs index baf98383188e..e6e88b8f1322 100644 --- a/crates/oxide/src/extractor/mod.rs +++ b/crates/oxide/src/extractor/mod.rs @@ -888,6 +888,39 @@ mod tests { ); } + #[test] + fn test_js_embedded_in_php_syntax() { + // Escaped single quotes + let input = r#" + @php + if ($sidebarIsStashable) { + $attributes = $attributes->merge([ + 'x-init' => '$el.classList.add(\'-translate-x-full\'); $el.classList.add(\'transition-transform\')', + ]); + } + @endphp + "#; + assert_extract_candidates_contains( + input, + vec!["-translate-x-full", "transition-transform"], + ); + + // Double quotes + let input = r#" + @php + if ($sidebarIsStashable) { + $attributes = $attributes->merge([ + 'x-init' => "\$el.classList.add('-translate-x-full'); \$el.classList.add('transition-transform')", + ]); + } + @endphp + "#; + assert_extract_candidates_contains( + input, + vec!["-translate-x-full", "transition-transform"], + ); + } + // https://github.com/tailwindlabs/tailwindcss/issues/16978 #[test] fn test_classes_containing_number_followed_by_dash_or_underscore() {