CSSOM
CSSOM copied to clipboard
Preserve multiple definitions of the same property in the same rule?
It's not uncommon for CSS authors to take advantage of the fact that a browser must ignore a CSS property in its entirety if a parse error or unsupported token is encountered in the value. For example:
body {
background-image: -moz-radial-gradient(center, #a8e936, #76a326);
background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 800, from(#a8e936), to(#76a326));
background-image: -webkit-radial-gradient(center, #a8e936, #76a326);
}
If parsed and reserialized using CSSOM only the last of the three background-image properties will survive. In the project I'm working on it would be very desirable to be able to reconstruct the whole thing. I'm not sure if this falls within the scope of CSSOM -- but would it be possible to achieve that behavior somehow?
Best regards, Papandreou
I fully understand your problem. I'm rewriting the parser in SAC-style. It will allow me to parse CSS into different object models, not just CSSOM. Like so:
body { background-image: -moz-radial-gradient(center, #a8e936, #76a326); background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 800, from(#a8e936), to(#76a326)); background-image: -webkit-radial-gradient(center, #a8e936, #76a326); }
into
{ "cssRules": [ { "selectorText": "body", "style": { "0": { name: "background-image", value: "-moz-radial-gradient(center, #a8e936, #76a326)" }, "1": { name: "background-image", value: "-webkit-gradient(radial, 50% 50%, 0, 50% 50%, 800, from(#a8e936), to(#76a326))" }, "2": { name: "background-image", value: "-webkit-radial-gradient(center, #a8e936, #76a326);" }, "length": 3, "background-image": [0, 1, 2] } } ] }
Stay tuned!
Awesome :). That'd be exactly what I need!
yes, i have the same problem. would be awesome to have this.
I don't think I'll fix it soon. If you want it ASAP you could override CSSStyleDeclaration.prototype.setProperty.
I ended up hacking the CSS parser to continue with a new rule (with an identical selector) if it sees a property redefinition. Seems like that preserves the semantics: https://github.com/One-com/assetgraph/compare/9609d665b8c8e645d8f3...ee00c998754b15c75952#diff-0 (only the changes to lib/3rdparty/CSSOM/lib/parse.js
are relevant, don't mind the other diffs).
Haven't looked into doing the opposite during serialization yet.
@papandreou
img {
border: none;
border: 1px solid red;
}
serializes to
img {
border: none;
}
img {
border: 1px solid red;
}
The downside is it changes amount of selectors.
@NV: Since I wrote the previous message I've patched the serialization code to do the inverse: https://github.com/One-com/assetgraph/blob/master/lib/3rdparty/CSSOM/lib/CSSStyleSheet.js#L77-L91
So your example now serializes to one rule with a single selector :)
Yes, it's still a hack, and in some corner cases it will collapse neighboring rules with the same selector that were separate originally, but the semantics are preserved and it seems to be adequate for my use case.
+1 for fixing this, using papandreou fork for now.
+1 vote
@quaelin: In the mean time you can npm install cssom-papandreou
to use my hack.
Thanks @papandreou, your fork is doing the trick. :)
Ive been using papandreou fork for some time as well, works great - love OS this way :)
i definitely need this too. do you have the SAC thing open-sourced anywhere?
No, I still haven’t released it.
i ended up just whipping up https://github.com/visionmedia/node-css since I don't (currently at least) need completely parsed selectors / values
+1 for merging in the pull request
This does not seem to have been merged yet. I tried using cssom-papandreou but that doesn't preserve multiple rules for same attribute.
I also need this. https://github.com/papandreou/CSSOM/tree/cssom-papandreou has fixed it, but it does not have the latest version of cssom. So I created another fork: https://github.com/intesso/CSSOM and created a pull request: https://github.com/NV/CSSOM/pull/53.
Is there any fix or suggested work around to this yet? Thx!
vote +1 , this is very important when i use flex. such as
display:-webkit-box; display:-webkit-flex; display:flex;
@superlc I recommend using postcss instead, unless it's important to work with the CSSOM api. Postcss doesn't have this limitation.