reworkcss / css Goto Github PK
View Code? Open in Web Editor NEWCSS parser / stringifier for Node.js
License: MIT License
CSS parser / stringifier for Node.js
License: MIT License
It would be much appreciated. Thanks!
I'm having issues with the @font-face rule. I took the code straight from the 'The New Bulletproof @font-face Syntax'
Attempting to run the following rule through the parser and I am getting 'Uncaught TypeError: undefined is not a function' inside of Base.visit.
@font-face {
font-family: 'MyFontFamily';
src: url('myfont-webfont.eot?#iefix') format('embedded-opentype'),
url('myfont-webfont.woff') format('woff'),
url('myfont-webfont.ttf') format('truetype'),
url('myfont-webfont.svg#svgFontName') format('svg');
}
Any information would be very helpful.
Hi there!
Your module is great, but it's missing one thing. I'd like to parse a CSS file and count the parsing errors if there are some. This is currently not possible.
The option could be named listErrors
. So there are 3 modes:
It looks like there's a place for this option, have a look at this function:
https://github.com/reworkcss/css/blob/master/lib/parse/index.js#L59-L71
The errors would be a new field in the JSON output:
{
"type": "stylesheet",
"stylesheet": {
"rules": [...],
"parsingErrors": [
{
"message": "mystyles.css:300:12:missing '}'",
"reason": "missing '}'",
"filename": "mystyles.css",
"line": 300,
"column": 12,
"source": "..."
}
]
}
}
If you agree with the idea, i can create a pull-request.
Hello, it seems I encountered a valid case which makes the parser to fail.
Here it is: -shadowcsshost-no-combinator.foo .bar {;background: blue;}
Parsing this raises the following error:
Error: undefined:1:40: missing '}' (line 1)
I'll try to come up with a PR, but someone knowing the module would be faster.
Cheers
It looks like this commit removed it.
The parser should accept at-rules for margin boxes inside @page
's body:
@page {
color:red;
@bottom-left {
color:green;
}
}
See: http://www.w3.org/TR/css3-page/#margin-at-rules
Actually, it just returns an error: Error: @page missing '}'
(Moved from https://github.com/reworkcss/css-parse/issues/80)
or css.js since this can be used in the browser too
Would it be possible to get a Browserify build packaged?
css-parse
and css-stringify
is locked in package.json
in specify version. So Rework from npm still use old versions and has parsing issues.
Is there a library available to do this similar to jQuery/querySelect
?
I'm currently using cheerio and this library and need a way to check for styles. I'd rather not use jsdom.
Looping through the objects and selector
Arrays is only good for exact string matches.
Given the following CSS file and source map:
/* test/fixtures/concatenated.css */
.one {
border: 1;
}
.two {
margin: 2px;
}
/*# sourceMappingURL=concatenated.css.map */
{"version":3,"file":"concatenated.css","mappings":"AAAA;EACI;;;ACDJ;EACI","sources":["test/fixtures/1.css","test/fixtures/2.css"],"sourcesContent":[".one {\n border: 1;\n}\n",".two {\n margin: 2px;\n}"],"names":[]}
When I run my CSS file through Rework:
var rework = require('rework');
var y = require('fs').readFileSync('test/fixtures/concatenated.css');
var x = rework(y.toString(), { source: 'test/fixtures/concatenated.css' })
.toString({ sourcemap: true, sourcemapAsObject: true });
console.log(x);
Results in the following source map:
{
version: 3,
sources: [
'test/fixtures/test/fixtures/1.css',
'test/fixtures/test/fixtures/2.css',
'test/fixtures/concatenated.css'
],
names: [
],
mappings: 'AAAA;EACI;;;ACDJ;EACI;;;ACMJ',
sourcesContent: [
'.one {\n border: 1;\n}\n',
'.two {\n margin: 2px;\n}',
'.one {\n border: 1;\n}\n\n.two {\n margin: 2px;\n}\n/*# sourceMappingURL=concatenated.css.map */\n'
]
}
It looks like Rework has correctly identified that the input data has a corresponding source map. However, I don't think concatenated.css
should be added as a source, nor to sourcesContent
. In this example, shouldn't the source map just look like the original?
{
version: 3,
sources: [
'test/fixtures/test/fixtures/1.css',
'test/fixtures/test/fixtures/2.css'
],
names: [
],
mappings: 'AAAA;EACI;;;ACDJ;EACI;;;ACMJ',
sourcesContent: [
'.one {\n border: 1;\n}\n',
'.two {\n margin: 2px;\n}'
]
}
Hi there, thanks for a great tool, using it for penthouse since a few versions back.
Not sure where this fits, whether this is something that can/should be fixed or not, as issue only happens inside phantomjs. Any input on how to resolve it, even if fix is outside of this repo much appreciated. Basically I came across this invalid css which does *not* generate any
parsingError, but does throw off the parser so as to make it fail to detect any following rules (after the
.breakingDeclaration), which causes
penthouse` to lose part of critical css in this scenario.
I'm on version 2.0.0
of css
(couldn't get more recent version to work in phantom, worth it's own issue..).
Call css.parse()
on the following css* inside a phantomjs script (I've tried both 1.9.8
and 2.0.0
- same result):
.breakingDeclaration{filter:unquote("()")}html{}
To clarify, this call is made inside the top level body of a phantomjs
script, not inside any page.evaluate js injected to headless browser. The actual line is here.
rules
in stylesheet (.breakingDeclaration and html)-or-
parsingError
for the .breakingDeclaration
declarationonly the .breakingDeclaration
rule (and any preceeding ones) is kept. html
(and any following) rules are lost.
I guess it's the double nested set of ()
inside the declaration that throws of a regex somewhere? Note too that I spotted that even though the rules are lost in the AST rules array, calling stringify
with the same array somehow adds the missing rules back again. Doesn't help me though.
*The actual declaration was filter:unquote("progid:DXImageTransform.Microsoft.gradient(enabled = false)")
- some left behind directive, dunno what language.
The current one is outdated and doesn’t fit with css-parse’s syntax.
Hi, guys.
I found that 'css' could be used in browser on https://github.com/reworkcss/css, but I notice that it totally rely on nodejs.
So how could I use it on browser please?
Hi,
I'm thinking about implementing a rework plugin for conditionals, similar to this from SASS:
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
Obviously I would need to parse some more @-Rules.
Looking at the code, it is not possible to extend the parsed rules.
It would be nice if there were an interface for that.
I work on a product that must parse CSS from <style>
tags of emails, and today we got a very weird email which contained the string below. Which makes css.parse
hang forever.
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
//*-
I think the regex engine goes bersek since the comment RE got a lot of *
operators.
Problems parsing braces inside a comment inside a value.
.ui-corner-all {
-webkit-border-radius: .3125em /*{global-radii-blocks}*/;
border-radius: .3125em /*{global-radii-blocks}*/;
}
Produces this error
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: property missing ':' near line 3:56
(Moved from https://github.com/reworkcss/css-parse/issues/91)
I hate to open an unclear/ambiguous issue, but I've been unable to track down what's actually going wrong here.
With the following CSS, simply running css.parse()
is blowing up:
Error: undefined:1:249: property missing ':'
It seems to only be occurring when there are multiple rules on one line (i.e. minified) that contain the string "charset", only when the SVG is URL encoded. I've stripped it down as much as I can to get it to a readable size (original file: http://www.shopify.com/assets2/application-bf82c00b0b5b610626f416a6ccc3d6aa.css).
Any thoughts on what might be going on here? I'll try to take a closer look in the next few days but figured I'd open the issue in the meantime. Thanks!
.thing1{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg%3E%3Cg%3E%3Crect%20transform=%22matrix(0.7071%20-0.7071%200.7071%200.7071%20-9.5016%2021.7357)%22/%3E%3C/g%3E%3C/svg%3E");}.thing2{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg%3E%3C/svg%3E");}
Feature Request:
I want to process a CSS file with rework which already has a source map. These source map is served by a server (e.g. /*# sourceMappingURL=http://some.server:8082/dist/style.css.map */
). But rework throws an ENOENT error, because it tries to read the file via fs.readFileSync
(see https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js#L106). It would be great if a source map referenced via http://
could be read via https://github.com/mikeal/request or something else.
Further information:
I often use a different local server for source maps than for my real app. This is a pattern which can be easily accomplished via https://github.com/gruntjs/grunt-contrib-less and is a feature I already requested for gruntjs/grunt-contrib-uglify#238 and gruntjs/grunt-contrib-concat#92, too. (Not that this is related to CSS, but should show that it isn't uncommon for source maps in general.)
(Moved from https://github.com/reworkcss/css-stringify/issues/17)
Parsing:
@page :left {
color:red;
}
results in Error: @page missing '}'
NB: it should also work for :right
, :first
and :blank
but also for :blank:first
See: http://www.w3.org/TR/css3-page/#page-selectors
Also,
it would be great if the parser was lazy enough to accept the named page syntax princexml uses:
@page big_table {
size: A4 landscape;
}
and also:
@page big_table, big_table2:first {
size: A4 landscape;
}
which all are valid syntax: see http://www.w3.org/TR/css3-page/#syntax-page-selector
(Moved from https://github.com/reworkcss/css-parse/issues/79)
Just wondering. I was looking around at the packages that depend on css
, but nothing was standing out as a linter.
Also curious if anyone has any thoughts on creating a pluggable linter similar to ESLint with this.
test/*/cases
into test/cases
.test/parse/css-parse.js
and test/stringify/css-stringify.js
into test/cases.js
. The stringify tests uses css.parse
to get ASTs anyways. By joining the cases we know that everything that parses also can be stringified.test/parse/css-parse.js
and test/stringify/css-stringify.js
into test/parse.js
and test/stringify.js
.What do you think?
.test{
+display: inline-block;
}
It will be parse error.
I'm currently using this in the browser with webpack. However when compiling the assets I get the warning that the the module fs
cannot be found. Used in lib/stringify/source-map-support.js
. This is an irrelevant error for me as I'm not using the source maps.
It would be great if there was a browser compatible version available that simply left out the source map support.
I'm using this library in the browser by bundling it with browserify. Everything works fine except when I want to generate source maps. I'll get an error because fs.readFileSync
isn't defined. The code path that uses readFile doesn't seem necessary to generate source maps and seems to only be used to apply any original source maps (I'm a bit unclear on that use case):
exports.applySourceMaps = function() {
Object.keys(this.files).forEach(function(file) {
var content = this.files[file];
this.map.setSourceContent(file, content);
var originalMap = sourceMapResolve.resolveSync(
content, file, fs.readFileSync);
if (originalMap) {
var map = new SourceMapConsumer(originalMap.map);
var relativeTo = originalMap.sourcesRelativeTo;
this.map.applySourceMap(map, file, urix(path.dirname(relativeTo)));
}
}, this);
};
Right now I'm commenting that part out, but it would be nice to have it work out of the box. If there's any way to put the readFile
part behind a conditional, that would be great.
Feature request for adding css attribute parsing.
example
`style="border-width: 1px"
a { color: blue; *zoom: 1 }
...gets you undefined
for declarations (wasn't even an array :().
For example: what are the values of rule
that can be expected; how are @rules
represented.
Parsing this
@keyframes kf {
0% { opacity: 0 }
25% { opacity: 0 } /* keep 0 to 25% of the timing to simulates a delay */
100% { opacity: 1 }
}
Give that stringified
@keyframes kf {
0% {
opacity: 0;
}
25% {
opacity: 0;
}
/* keep 0 to 25% of the timing to simulates a delay */
100% {
opacity: 1;
}
}
This is weird.
What is the reason we just don't keep the code as is like postcss does ? Is there any ?
Unfortunately my app has to be able to parse a stylesheet that has almost a hundred lines that look like this:
@media only screen and (max-width:480px){td[id=cellBody]{padding:10px}
That repeats a couple of hundred times. Totals about 20,000 lines of this. Yes very badly formed. If you look closely you can see that each additional css declaration to be nested in the one above it because it opens 2 brackets and only closes 1 of them.
Handing this to css.parse()
causes node.js to run out of call stack space (on my computer the max size is 10483) and emit a
RangeError: Maximum call stack size exceeded
I'm working around this in my app, but I'm bringing this to your attention as you may want to detect and handle this edge case in this library.
Can this parser parse custom rule like $var: 'abc'
or mixin(a1, a2) { // body }
? If yeap, how I can do this?
@-moz-document url-prefix(){}
is getting ignored when the file gets parsed.
for css-parse and css-stringify for browser use
Perhaps the option should be removed. KISS. Why would you turn it off?
to aid in documentation generation
(Moved from https://github.com/reworkcss/css-parse/issues/31)
I think we should move these two modules into this one.
Thoughts?
Need filename and source from the parser
(Moved from https://github.com/reworkcss/css-stringify/issues/18)
It would be great to get 2.0.0 out by 13th June. Then Rework can be updated and a series of upstream projects (inc. some internal to Twitter) can move forward. I think we should feature-freeze within the next few days, and decide on the chores we want to get in before the release.
Our CSS files have multi-line copyright headers at the top like the following:
/* ***************************************************************** */
/* Copyright 1970, 2038 */
/* ***************************************************************** */
After applying a parse()
+ stringify()
combo like the gulp-flip
plugin does, the headers are all interleaved by double newlines. This can be easily reproduced with this simple test case:
var css = require('css');
var obj = css.parse('/* */\n/* */\n/* */', {});
console.log(css.stringify(obj, {}));
Which prints:
/* */
/* */
/* */
this issue mostly for discussion, but as long as we share ASTs we can have better interoperability. I totally get the need for node-level utilities to inject declarations etc, but I think we could have a suite of tools (or nodes "classes") on top of the vanilla AST
the most "elegant" thing to do would just be piping streams of things that manipulate the CSS, but since that's slow and causes needless re-parsing it would be great if we could either a) make this parser facilitate autoprefixer's needs b) spec the AST to maintain compatibility
@ai said:
I think we should:
Try to parse custom at-rules. By spec, unknown at-rule can contain any content. By all current at-rules (and custom at-rules from frameworks) contains only rules or declarations. The best solution is:
But it is ideal way (in PostCSS I had no time to realize it in PostCSS) :).
I had a lot of issues from new at-rules or special JS libraries. Also, it is easy to configure some Rework plugins by custom at-rules. Like:
@sprites {
padding: 10px
}
Saves all outside spaces. Of cource, we should do it by special option.
This is important for text editor and keep style from uncompressing (some users use Autoprefixer after Sass with :compressed
output, some users use win text editors).
Integration tests, to understand that we parse most of production CSS. For example, previous version of Rework had issue with parse even Bootstrap. I test GitHub, Twitter, Bootstrap (a lot of hacks for old IE) and Habrahabr (Russian IT Reddit with very bad CSS files as example, how developers can write :) ).
Bad written CSS is importnat for me, because a lot of Rails project use some 3th part CSS from libraries and had problem with Autoprefixer, because they can’t fix libraries (like Bootstrap).
Saves comments inside values. There is some difficult situation with comments inside declaration’s values and at-rule parameters. We should clean values from comments for Rework plugin developers, but we need to keap origin raw dat with comments to stringify (PostCSS has special hack with raw properties).
But this PostCSS feature is only for integration test. I just check, that PostCSS’s parse/stringify doesn’t change any bite of production styles.
And I will be glad to remove postcss/parse.coffee
and use PostCSS only as object high-level API under the css-parse
AST.
BTW, I didn’t think that fragmentation is really bad. In real world we support diversity for languages (there is Red List for language) and biologically species (IUCN Red List). Diversity is important to evolution (hieroglyphs is very unusable but we hasn’t “cool” tattoo or Matrix digital rain if China moved to phonetic alphabet). But it is only philosophical note, I think most of Autoprefixer users will be glad to come back to Rework with PostCSS features :).
(Moved from https://github.com/reworkcss/css-parse/issues/68)
I think we should probably cut a new release soon. I don't think any of the changes are breaking changes, so we can just increment minor version.
Changes/Todo:
If the value of the selector [attribute = "value"] contains of a comma after the quote, it will be parsed as two selectors.
p[qwe="a",b"] { color: red }
http://iamdustan.com/reworkcss_ast_explorer/#/VhSUamTu5w/3
In lib/stringify/identity.js, I see Compiler.prototype.__proto__ = Base.prototype;
It could cause problems later since __proto__
is not standard.
I recommend using Compiler.prototype = new Base();
Hi there!
I got a parsing error on the following css:
.icon-article-liste{font-size:1.18em;margin-right: .425em}@-webkit-keyframes
rotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes
rotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}
The error says: @Keyframes missing name
The problem comes from the line-break after @-webkit-keyframes
which does not match the regexp looking for the name.
Thank you
There's also @viewport
(and -ms
, -webkit
, -o
prefixed versions) and probably some others that I've forgotten or don't know about. People building preprocessors might also want to use custom @-rules.
(Moved from https://github.com/reworkcss/css-stringify/issues/9)
I'm using this library to prettify and generate source maps for big CSS files. This lib will give you the toJSON()
of a SourceMapGenerator
object when you specify that you want source maps. I'm actually using the source map immediately afterwards in memory, so this serializing and loading is unnecessary and takes a significant chunk of time for files with a lot of mappings.
Could this library skip the toJSON()
call if you specify an option?
Say I have css code:
@font-face {
font-family: "my-style";
src: url(../font/a.eof),
url(http://www.sogou.com/a.eof);
}
then after compress, it output:
@font-face{font-family:"my-style";src:url((../font/a.eof),
url(http://www.sogou.com/a.eof);}
there has:
"\r\n " before url
var parse = require('css').parse
var parsed = parse('a:after { content: "\2193" }')
console.dir( parsed.stylesheet.rules[0])
results in
{ type: 'rule',
selectors: [ 'a:after' ],
declarations:
[ { type: 'declaration',
property: 'content',
value: '\'\u001193\'',
position: [Object] } ],
position:
{ start: { line: 1, column: 1 },
end: { line: 1, column: 27 },
source: undefined } }
\u001193
is not valid for the content property in CSS. This may be a function of how JSON.stringify handles "\2193"
, but nevertheless it results in JSON that cannot be applied as CSS.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.