Open kimtaa opened 11 months ago
Interesting this is happening and I haven't noticed even though I use these in Chrome extensions (which doesn't allow unsafe-inline
). In your example, the component still works and I don't know why they use inline CSS for certain things instead of constructed stylesheet like the others.
The component works despite the error - might it be because it is rendered a second time? But without text direction style since it is not set?
According to the documentation for styleMap: On subsequent renders, any previously set style properties that are undefined or null are removed (set to null).
.
I don't know why they use inline CSS for certain things instead of constructed stylesheet like the others.
The component works despite the error
Because all the style does is set the direction, which needs to be dynamic.
I see the need for dynamic styles - how does one add styles dynamically without using the style attribute?
One could use the classMap() utility to solve this particular problem, but it's not a general, dynamic, solution.
textfield/internal/_shared.scss:
.direction-ltr {
direction: ltr;
}
.direction-rtl {
direction: rtl;
}
textfield/internal/text-field.ts:
const classes = {
'direction-rtl': this.textDirection === "rtl",
'direction-ltr': this.textDirection === "ltr"
};
And then add the classes to the elements with ${classMap(classes)}
That may work for text field, but there are other components that need to bind the style
attribute for things that cannot be pre-calculated, like slider.
Yes - it would be much better to find a general solution on how to dynamically set styles, while still playing nice with strict CSPs.
What about using css variables, and updating them through update()?
For example, the linear progress indicator:
Add static style with variable: internal/_linear_progress.scss (omitted indeterminate/buffer/max for brevity):
.primary-bar {
transform: scaleX(var(--_progress_value));
}
Remove the use of styleMap, and add updating of progress: progress/internal/linear-progress.ts:
override update(changedProperties: PropertyValueMap<any>) {
super.update(changedProperties);
if (changedProperties.has('value')) {
this.style.setProperty('--_progress_value', this.value.toString());
}
}
this.style.setProperty('--_progress_value', this.value.toString());
Now I don't know much about CSPs, but if you can do that why not just do element.style.transform =
scaleX(${this.value})`?
Now I don't know much about CSPs, but if you can do that why not just do
element.style.transform =
scaleX(${this.value})`?
I don't know much about CSPs either, but that seems to work as well :)
I assume there are cases when a css variable makes more sense, and other cases when setting the style directly is the cleaner option.
In any case - are these two ways to set dynamic styles sound? And not working around the security the CSP is trying to apply?
I don't know enough about CSP, do any of the Lit folks have advice for this? CC @rictic
Could we use adoptedStyleSheets to solve the problem?
Yeah, looks like fundamental issue with how we implemented styleMap. Filed in Lit core as https://github.com/lit/lit/issues/4719
If you don't need the ability to dynamically remove style properties from a style map, I think there's a a work around that could work: https://lit.dev/playground/#gist=0985f5699785c208bcc837e14e89664a
What is affected?
Component
Description
When using a strict CSP (i.e with a nonce or without 'unsafe-inline'), I would except no errors to be thrown in the console. However, some components are including styles in a way that is incompatible with a strict CSP.
In the console I get the following error:
The source seems to be adding a style attribute directly to an element. For example, main/textfield/internal/text-field.ts adds
style=${styleMap(style)}
to the textarea- and input-elements.Reproduction
An error is thrown in the console about chrome refusing to apply an inline style because it violates the CSP. I've added a simple example in the lit.dev playground: https://lit.dev/playground/#project=W3sibmFtZSI6Im1hdGVyaWFsLWltcG9ydHMuanMiLCJjb250ZW50IjoiaW1wb3J0IFwiQG1hdGVyaWFsL3dlYi90ZXh0ZmllbGQvb3V0bGluZWQtdGV4dC1maWVsZC5qc1wiOyJ9LHsibmFtZSI6ImluZGV4Lmh0bWwiLCJjb250ZW50IjoiPCFET0NUWVBFIGh0bWw-XG5cbjxoZWFkPlxuICA8bWV0YSBodHRwLWVxdWl2PVwiQ29udGVudC1TZWN1cml0eS1Qb2xpY3lcIiBjb250ZW50PVwic3R5bGUtc3JjICdzZWxmJ1wiPlxuPC9oZWFkPlxuXG48c2NyaXB0IHR5cGU9XCJtb2R1bGVcIiBzcmM9XCIuL21hdGVyaWFsLWltcG9ydHMuanNcIj48L3NjcmlwdD5cblxuPG1kLW91dGxpbmVkLXRleHQtZmllbGQgbGFiZWw9XCJTb21lIGxhYmVsXCI-PC9tZC1vdXRsaW5lZC10ZXh0LWZpZWxkPlxuIn0seyJuYW1lIjoicGFja2FnZS5qc29uIiwiY29udGVudCI6IntcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwibGl0XCI6IFwiXjIuMC4wXCIsXG4gICAgXCJAbGl0L3JlYWN0aXZlLWVsZW1lbnRcIjogXCJeMS4wLjBcIixcbiAgICBcImxpdC1lbGVtZW50XCI6IFwiXjMuMC4wXCIsXG4gICAgXCJsaXQtaHRtbFwiOiBcIl4yLjAuMFwiXG4gIH1cbn0iLCJoaWRkZW4iOnRydWV9XQ
I have only tested the text-field component, but other components that also add styles directly to elements are: linear-progress, slider and menu. I would guess the issue also affects those components as well.
Workaround
I have not found a workaround
Is this a regression?
No or unsure. This never worked, or I haven't tried before.
Affected versions
@material/web@1.0.1
Browser/OS/Node environment
Browser: Google Chrome 118.0.5993.88 OS: MacOS 13.5.2 Node: v20.8.0