Skip to content

Commit

Permalink
fix: Escape backtick and backslash in CSS (#536)
Browse files Browse the repository at this point in the history
## Details

Escape backtick and backslash in CSS source. In any CSS file, today usage of:
* backtick makes the compiler produce an invalid javascript
* backslash escape the next character

Fix #530 

## Does this PR introduce a breaking change?

* [ ] Yes
* [X] No
  • Loading branch information
pmdartus authored and diervo committed Jul 26, 2018
1 parent 3bbf59e commit 237d88b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
36 changes: 36 additions & 0 deletions packages/lwc-compiler/src/transformers/__tests__/transform.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,40 @@ describe('CSS transform', () => {

expect(pretify(code)).toBe(pretify(expected));
});

it('should escape grave accents', async () => {
const actual = `/* Comment with grave accents \`#\` */`;
const expected = `
function style(token) {
return \`/* Comment with grave accents \\\`#\\\` */\`;
}
export default style;
`;

const { code } = await transform(actual, 'foo.css', {
namespace: 'x',
name: 'foo',
});

expect(pretify(code)).toBe(pretify(expected));
});

it('should escape backslash', async () => {
const actual = '.foo { content: "\\\\"; }';
const expected = `
function style(token) {
return \`.foo[\${token}] { content: "\\\\\\\\"; }\`;
}
export default style;
`;

const { code } = await transform(actual, 'foo.css', {
namespace: 'x',
name: 'foo',
});

expect(pretify(code)).toBe(pretify(expected));
});
});
15 changes: 14 additions & 1 deletion packages/lwc-compiler/src/transformers/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ export default style;
/** The javascript identifier used when custom properties get resolved from a module. */
const CUSTOM_PROPERTIES_IDENTIFIER = 'customProperties';

/**
* Escape CSS string to injected in a javascript string literal. This method escapes:
* - grave accent to avoid conflict with the template string
* - back slash to avoid unexpected string escape in the generated CSS
*/
function escapeString(src: string): string {
return src.replace(/[`\\]/g, (char: string) => {
return '\\' + char;
});
}

/**
* Transform the var() function to a javascript call expression with the name and fallback value.
*/
Expand Down Expand Up @@ -75,9 +86,11 @@ export default async function transformStyle(
);
}

const escapedSource = escapeString(src);

let res;
try {
res = await postcss(plugins).process(src, {
res = await postcss(plugins).process(escapedSource, {
from: filename,
});
} catch (e) {
Expand Down

0 comments on commit 237d88b

Please sign in to comment.