Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move CSS in a separate file to be CSP-compliant #6048

Merged
merged 3 commits into from Feb 8, 2019

Conversation

simonbrunel
Copy link
Member

@simonbrunel simonbrunel commented Feb 6, 2019

In order to be compatible with any CSP, we need to prevent the automatic creation of the DOM 'style' element and offer our CSS as a separate file that can be manually loaded (Chart.js or Chart.min.js). Users can now opt-out the style injection using Chart.platform.disableCSSInjection = true (note that the style sheet is now injected on the first chart creation).

To prevent duplicating and maintaining the same CSS code at different places, move all these rules in platform.dom.css and write a minimal rollup plugin to inject that style as string in platform.dom.js. Additionally, this plugin extract the imported style in ./dist/Chart.js and ./dist/Chart.min.js.

@jelhan @SebastianNiemann can you guys review and test that PR, then confirm it fixes CSP issues?

Closes #5952
Closes #6015
Fixes #5208
Fixes #5295

In order to be compatible with any CSP, we need to prevent the automatic creation of the DOM 'style' element and offer our CSS as a separate file that can be manually loaded (`Chart.js` or `Chart.min.js`). Users can now opt-out the style injection using `Chart.platform.useExternalStylesheet = true` (note that the style sheet is now injected on the first chart creation).

To prevent duplicating and maintaining the same CSS code at different places, move all these rules in `platform.dom.css` and write a minimal rollup plugin to inject that style as string in `platform.dom.js`. Additionally, this plugin extract the imported style in `./dist/Chart.js` and `./dist/Chart.min.js`.
@sebiniemann
Copy link
Contributor

sebiniemann commented Feb 6, 2019

@simonbrunel

I just build the new Chart.js bundle and added it to my test page. Everything seems to work fine (CSP was set via the <meta http-equiv="Content-Security-Policy"): https://sebastianniemann.github.io/Chart.js-CSP-demo/

Given that I am still neither familiar with the Chart.js coding style (I am used to very strict linting rules doing this job 😅 ) nor which ECMAScript/browser versions should be supported, my review was mostly focused on whether the PR fixes the CSP as well as looking for any obvious oversight.

etimberg
etimberg previously approved these changes Feb 6, 2019
Copy link
Member

@etimberg etimberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks OK to me

sebiniemann
sebiniemann previously approved these changes Feb 6, 2019
benmccann
benmccann previously approved these changes Feb 7, 2019
Copy link
Contributor

@benmccann benmccann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great!

docs/getting-started/integration.md Outdated Show resolved Hide resolved
docs/getting-started/integration.md Show resolved Hide resolved
samples/advanced/content-security-policy.html Show resolved Hide resolved
samples/samples.js Outdated Show resolved Hide resolved
samples/advanced/content-security-policy.html Show resolved Hide resolved
src/platforms/platform.dom.css Outdated Show resolved Hide resolved
@simonbrunel
Copy link
Member Author

Thanks @SebastianNiemann

I am used to very strict linting rules doing this job

Similar rules are setup for that project and automatically checked by our CI

... mostly focused on whether the PR fixes the CSP as well as looking for any obvious oversight.

Exactly what I was expecting, thanks ;)

@simonbrunel
Copy link
Member Author

As explained in this comment, I'm not completely happy with the option name: useExternalStylesheet.

What about: disableStylesheetInjection (similar to the initial proposal)? (or shorter disableCSSInjection)

Or if we don't want a negative option, enable(Stylesheet|CSS)Injection (default true)

Better suggestions?

@kurkle
Copy link
Member

kurkle commented Feb 7, 2019

How about just injectCSS (default true)?

@sebiniemann
Copy link
Contributor

sebiniemann commented Feb 7, 2019

Something like injectCSS or disableCSSInjection sound good to me. Being used to activate flags (= true) and given that I usually only want to set this option to disable the injection, I would favour disableCSSInjection. However, both ways seem clear to me.

Similar rules are setup for that project and automatically checked by our CI

I didn't meant to depreciate the linter process in any means 😃 , just wanted to explain myself, as I always have to work with a very nitpicking and merciless linter at our company on a daily basis. Therefore, I usually do not to review any non-company code regarding its coding style, to avoid to be too nitpicking myself 😉

@benmccann
Copy link
Contributor

I agree with the renaming. My vote would be for disableCSSInjection since CSS is shorter than Stylesheet. I would name the variable internally as var injectCSS = !platform.disableCSSInjection to avoid the negative in the code, but I think for user options it makes sense to set an option to true when using it, so like disable in the name

@simonbrunel
Copy link
Member Author

I also prefer disableCSSInjection since I think a falsy value is a better default.

@kurkle
Copy link
Member

kurkle commented Feb 7, 2019

I don't personally like having enable/disable in a boolean property name, because the value brings that part. But lets ignore that :)

@benmccann
Copy link
Contributor

Also a good point. I would be fine with injectCSS as well

@sebiniemann
Copy link
Contributor

sebiniemann commented Feb 7, 2019

I would say it the other way around. Because disable/enable/is/has/use is making it very clear that a variable holds a boolean value, it adds to the readability. Being able to guess/know a variable's type correctly just by reading its name seems to be a good thing to me.

@simonbrunel
Copy link
Member Author

I would be fine with injectCSS if it was a property of an options/config object but as part of the platform interface, it sounds too much like a method with immediate impact. I would also prefer false as default and I'm not sure what would be the negative/opposite of injectCSS?

What about preventCSSInjection? @kurkle is it better than disableCSSInjection?

@benmccann
Copy link
Contributor

Maybe let's stick with disableCSSInjection then. I like it more than preventCSSInjection

@kurkle
Copy link
Member

kurkle commented Feb 7, 2019

To me, disableCSSInjection is better than preventCSSInjection. Prevent does not sound absolute.

Copy link
Member

@kurkle kurkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one question remains, but it does not affect my approval.

src/platforms/platform.dom.js Show resolved Hide resolved
@simonbrunel simonbrunel merged commit 96f7344 into chartjs:master Feb 8, 2019
@simonbrunel simonbrunel deleted the feat/external-css branch February 8, 2019 17:17
simonbrunel added a commit that referenced this pull request Feb 8, 2019
In order to be compatible with any CSP, we need to prevent the automatic creation of the DOM 'style' element and offer our CSS as a separate file that can be manually loaded (`Chart.js` or `Chart.min.js`). Users can now opt-out the style injection using `Chart.platform.disableCSSInjection = true` (note that the style sheet is now injected on the first chart creation).

To prevent duplicating and maintaining the same CSS code at different places, move all these rules in `platform.dom.css` and write a minimal rollup plugin to inject that style as string in `platform.dom.js`. Additionally, this plugin extract the imported style in `./dist/Chart.js` and `./dist/Chart.min.js`.
janelledement pushed a commit to janelledement/Chart.js that referenced this pull request Feb 10, 2019
In order to be compatible with any CSP, we need to prevent the automatic creation of the DOM 'style' element and offer our CSS as a separate file that can be manually loaded (`Chart.js` or `Chart.min.js`). Users can now opt-out the style injection using `Chart.platform.disableCSSInjection = true` (note that the style sheet is now injected on the first chart creation).

To prevent duplicating and maintaining the same CSS code at different places, move all these rules in `platform.dom.css` and write a minimal rollup plugin to inject that style as string in `platform.dom.js`. Additionally, this plugin extract the imported style in `./dist/Chart.js` and `./dist/Chart.min.js`.
@jelhan
Copy link

jelhan commented Feb 12, 2019

@simonbrunel Sorry for not replying earlier. I was in vacation for last weeks. This is awesome work. Thanks a lot!

@timseverien
Copy link

Looking good! When can we expect this to be released?

@simonbrunel
Copy link
Member Author

@timseverien I would expect it soon (no date planned) but we still need to figure out a few things around the new date adapters before releasing it.

@simonbrunel simonbrunel mentioned this pull request Apr 2, 2019
3 tasks
exwm pushed a commit to exwm/Chart.js that referenced this pull request Apr 30, 2021
In order to be compatible with any CSP, we need to prevent the automatic creation of the DOM 'style' element and offer our CSS as a separate file that can be manually loaded (`Chart.js` or `Chart.min.js`). Users can now opt-out the style injection using `Chart.platform.disableCSSInjection = true` (note that the style sheet is now injected on the first chart creation).

To prevent duplicating and maintaining the same CSS code at different places, move all these rules in `platform.dom.css` and write a minimal rollup plugin to inject that style as string in `platform.dom.js`. Additionally, this plugin extract the imported style in `./dist/Chart.js` and `./dist/Chart.min.js`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants