Skip to content

Commit

Permalink
[reactive-element] Add CSP compatibility for element styles (#2134)
Browse files Browse the repository at this point in the history
  • Loading branch information
justinfagnani committed Sep 9, 2021
1 parent d8ff590 commit 0470d86
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/flat-zoos-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@lit/reactive-element': patch
---

Allow assigning a nonce value to `window.litNonce` in order to apply the nonce to generated <style> tags for CSP compatibility.
5 changes: 5 additions & 0 deletions packages/reactive-element/src/css-tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ export const adoptStyles = (
} else {
styles.forEach((s) => {
const style = document.createElement('style');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const nonce = (window as any)['litNonce'];
if (nonce !== undefined) {
style.setAttribute('nonce', nonce);
}
style.textContent = (s as CSSResult).cssText;
renderRoot.appendChild(style);
});
Expand Down
22 changes: 21 additions & 1 deletion packages/reactive-element/src/reactive-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,27 @@ export abstract class ReactiveElement

/**
* Array of styles to apply to the element. The styles should be defined
* using the [[`css`]] tag function or via constructible stylesheets.
* using the [[`css`]] tag function, via constructible stylesheets, or
* imported from native CSS module scripts.
*
* Note on Content Security Policy:
*
* Element styles are implemented with `<style>` tags when the browser doesn't
* support adopted StyleSheets. To use such `<style>` tags with the style-src
* CSP directive, the style-src value must either include 'unsafe-inline' or
* 'nonce-<base64-value>' with <base64-value> replaced be a server-generated
* nonce.
*
* To provide a nonce to use on generated <style> elements, set
* `window.litNonce` to a server-generated nonce in your page's HTML, before
* loading application code:
*
* ```html
* <script>
* // Generated and unique per request:
* window.litNonce = 'a1b2c3d4';
* </script>
* ```
* @nocollapse
* @category styles
*/
Expand Down
43 changes: 43 additions & 0 deletions packages/reactive-element/src/test/reactive-element-csp_test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="style-src 'nonce-abc123';"
/>
<script>
window.litNonce = 'abc123';
</script>
<link rel="stylesheet" href="../../node_modules/mocha/mocha.css" />
</head>

<body>
<script type="module">
// node resolution doesn't seem to be working here.
import {
mocha,
sessionFinished,
sessionFailed,
} from '../../../tests/node_modules/@web/test-runner-mocha/dist/standalone.js';
// import { mocha, sessionFinished, sessionFailed } from '@web/test-runner-mocha';

(async () => {
try {
// setup mocha
mocha.setup({ui: 'tdd'});

await import('./reactive-element_styling_test.js');

// run the tests, and notify the test runner after finishing
mocha.run(() => {
sessionFinished();
});
} catch (error) {
console.error(error);
// notify the test runner about errors
sessionFailed(error);
}
})();
</script>
<div id="mocha"></div>
</body>
</html>

0 comments on commit 0470d86

Please sign in to comment.