Open lucacasonato opened 2 years ago
Yes, this seems like a lack purely due to apathy, not due to any actual problems, since authors can trivially serialize an entire sheet anyway, as demonstrated. I think this would be completely fine to add.
I couldn't find any discussions about this in the past with a quick search thru my archives, but that doesn't guarantee there wasn't any. Is anyone aware of us discussing this in the past?
Hello, I'm currently taking this issue after some guidance from @tabatkins (thanks a lot for your guidance btw).
I wanted to know whether the stringifier should be the toString method of CSSStyleSheet like this issue suggests or if it should be exposed as a string property just like in CSSRule. Would love some opinions on this.
For consistency, we probably should expose it as cssText
, but we can make it better by making it a stringifier attribute.
CSSStyleRule
doesn't have a stringifier, so I would keep CSSStyleSheet
consistent.
Or we add a stringifier to both?
I would be open to changing both, but what are the chances that there's something out there that relies on the current stringified behavior of CSSStyleRule?
Also is there a difference spec-wise other than adding stringifier to the attribute to make something a stringifier?
Nope, that keyword is all you need.
(If you don't have an attribute already containing the text you have to write the definition slightly different to have an independent stringifier, but it's literally just a few words difference in invocation.)
And yeah, adding a stringifier to both would be ideal (but it increases the testing cost slightly). Relying on the current stringification seems not too likely. (In theory someone could be using it for dirty type-testing since it currently stringifies to "[Object CSSRule]"
, but doing that generically requires you to specifically use Object.prototype.toString.call()
precisely because a lot of objects have stringifiers, so it's likely such uses are relying on that and won't be affected.)
It should also be consistent with other interfaces like CSSStyleDeclaration
. And given that most things don't have stringifiers, I wouldn't add them here.
On the other side however, it seems like MediaList
interface has a stringifier, though it seems like it's the only one in cssom and I can't seem to track the reasoning behind that.
We can choose add a stringifier to CSSStyleDeclaration
as well but if we do want to move in the path of least resistance, just forgoing stringifiers is best. Can anyone provide context on the state of stringifiers as a whole in w3c spec, like how common are they currently and any specs that heavily uses stringifiers as major features?
Here's a use case for this:
In the second snippet there, the #shared-stylesheet
could have a CSS OM and no textContent
, so to-stringing it would be handy.
But iterating the rules is also not that difficult.
Use case: Visual Regression (screenshot) testing
There is a problem with visual regression tests where they aren't cross-browser or cross-platform compatible due to subtle differences in rendering, especially fonts. So taking a screenshot of the app in a specific state, and then comparing the pixels against a previous known-good screenshot will fail just because the screenshot was done on a different OS or slightly different browser version.
If you could serialize the entire DOM and CSSOM and get hashes of each, then store those hashes next to the screenshot, you'd be able to inform a CI tool to update the snapshots when it re-runs if the hashes do not match. Allowing you to locally update the hashes when you want a new known good, without having to commit a screenshot from your machine that will only work for your machine. Then when the CI runs, it validates the screenshots, or replaces them if the hashes don't match.
This would work best if you could serialize just the part of the DOM and CSSOM that applies to a specific selector, like [data-test="myWidget"]
. So the screenshot does not need to be of the entire page, but just the part related to that specific test.
Ran into a super weird issue today when using the cssText
approach shown in the original description. Apparently it can produce invalid CSS when using custom properties (https://issues.chromium.org/issues/40804066). Obviously this bug should be fixed, but a ..toString()
function could help avoid the problem altogether
Edit: Actually .toString()
would have the same issue since that's how it's specced to be serialized. I think the spec should probably be fixed if we're wanting to serialize entire stylesheets?
CSSOM allows programmatic construction and modification of
CSSStyleSheet
s. These created sheets can be attached to a HTML document on the client so users can directly use them. It is however not currently trivial to "export" programmatic style sheets back into a text representation.This is unfortunate, because the CSSOM API would be great for the generation of style sheets server side, if the server side runtime were to support the API. This is something that we would like to do in Deno (https://github.com/denoland/deno/issues/13898). In Deno, there is no DOM, so the style sheet could never directly be used. Instead you would build a style sheet with the CSSOM API, and then export it to a string and send it to a client.
It is possible to turn a
CSSStyleSheet
into a string my manually concatenating the string representations of each rule. This is what thestringify-css-stylesheet
npm package does for example. A simplified example:It would be awesome if
CSSStyleSheet.prototype.toString()
would exist to do this natively, without requiring any helper code.