Skip to content

Commit

Permalink
Fix buggy selector transformation
Browse files Browse the repository at this point in the history
  • Loading branch information
askoufis committed Nov 19, 2024
1 parent 7047243 commit de95bcd
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
7 changes: 7 additions & 0 deletions .changeset/flat-humans-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@vanilla-extract/css': patch
---

Fixes a bug causing invalid selectors to be generated in some cases

When transforming selectors containing consective copies of the same classname, e.g: `&&`, if `&` was a substring of another local classname and that classname happened to end with the same character that `&` started with, the generated selector would be invalid.
55 changes: 55 additions & 0 deletions packages/css/src/transformCss.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,61 @@ describe('transformCss', () => {
}
`);
});

it('should handle consecutive references to the same classname that is a substring of another classname with the same start and end character', () => {
const classname1 = 'debugName_hash1';
const classname2 = 'debugName_hash1d';

expect(
transformCss({
composedClassLists: [],
localClassNames: [classname1, classname2],

cssObjs: [
{
type: 'local',
selector: classname1,
rule: {
selectors: {
// Bug reproduction
['&&']: {
background: 'black',
},
// Exhaustive tests for combinations of two adjacent classnames
[`${classname2}&`]: {
background: 'orange',
},
[`&${classname2}&`]: {
background: 'orange',
},
[`${classname2}${classname2}&`]: {
background: 'orange',
},
},
},
},
{
type: 'local',
selector: classname2,
rule: {},
},
],
}).join('\n'),
).toMatchInlineSnapshot(`
.debugName_hash1.debugName_hash1 {
background: black;
}
.debugName_hash1d.debugName_hash1 {
background: orange;
}
.debugName_hash1.debugName_hash1d.debugName_hash1 {
background: orange;
}
.debugName_hash1d.debugName_hash1d.debugName_hash1 {
background: orange;
}
`);
});
});

endFileScope();
14 changes: 9 additions & 5 deletions packages/css/src/transformCss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,15 @@ class Stylesheet {
const [endIndex, [firstMatch]] = results[i];
const startIndex = endIndex - firstMatch.length + 1;

if (startIndex >= lastReplaceIndex) {
// Class names can be substrings of other class names
// e.g. '_1g1ptzo1' and '_1g1ptzo10'
// If the startIndex >= lastReplaceIndex, then
// this is the case and this replace should be skipped
// Class names can be substrings of other class names
// e.g. '_1g1ptzo1' and '_1g1ptzo10'
// Additionally, concatenated classnames can be substrings of other classnames
// 'debugName_18fxj81' and 'debugName_18fxj81d'
// If this is the case then this replace should be skipped
const match =
startIndex >= lastReplaceIndex || endIndex >= lastReplaceIndex;

if (match) {
continue;
}

Expand Down

0 comments on commit de95bcd

Please sign in to comment.