Comparing version 0.0.11 to 0.0.12
17
index.js
@@ -9,3 +9,4 @@ #!/usr/bin/env node | ||
argv = require('optimist').argv, | ||
cli = require('./lib/CLI.js'); | ||
cli = require('./lib/CLI.js'), | ||
requireUncached = require('./lib/helpers/RequireUncached.js'); | ||
@@ -17,3 +18,3 @@ module.exports = absurd = function(path) { | ||
var _path = PathFormatter(path), | ||
_absurd = {}; | ||
_absurd = {api: API}; | ||
@@ -24,7 +25,9 @@ // --------------------------------------------------- compile | ||
_path(API); | ||
} else { | ||
try { | ||
require(_path.source)(API); | ||
} catch(err) { | ||
console.log("Error: I can't find '" + _path.source + "'."); | ||
} else { | ||
if(_path !== false) { | ||
try { | ||
requireUncached(_path.source)(API); | ||
} catch(err) { | ||
console.log("Error: I can't find '" + _path.source + "'."); | ||
} | ||
} | ||
@@ -31,0 +34,0 @@ } |
@@ -6,3 +6,4 @@ var fs = require('fs'); | ||
var _api = {}, | ||
_rules = []; | ||
_rules = [], | ||
_storage = {}; | ||
@@ -12,4 +13,8 @@ _api.getRules = function() { | ||
} | ||
_api.getStorage = function() { | ||
return _storage; | ||
} | ||
_api.flush = function() { | ||
_rules = []; | ||
_storage = []; | ||
} | ||
@@ -16,0 +21,0 @@ |
@@ -5,3 +5,8 @@ module.exports = function(API) { | ||
if(typeof props[prop] === 'object') { | ||
addRule(selector + " " + prop, props[prop]); | ||
// check for pseudo classes | ||
if(prop.charAt(0) === ":") { | ||
addRule(selector + prop, props[prop]); | ||
} else { | ||
addRule(selector + " " + prop, props[prop]); | ||
} | ||
props[prop] = false; | ||
@@ -12,2 +17,3 @@ } | ||
var addRule = function(selector, props) { | ||
// if the selector is already there | ||
if(typeof API.getRules()[selector] == 'object') { | ||
@@ -18,2 +24,3 @@ var current = API.getRules()[selector]; | ||
} | ||
// no, the selector is still not added | ||
} else { | ||
@@ -26,3 +33,9 @@ API.getRules()[selector] = props; | ||
for(var selector in rules) { | ||
addRule(selector, rules[selector]); | ||
if(typeof rules[selector].length !== 'undefined') { | ||
for(var i=0; r=rules[selector][i]; i++) { | ||
addRule(selector, r); | ||
} | ||
} else { | ||
addRule(selector, rules[selector]); | ||
} | ||
} | ||
@@ -29,0 +42,0 @@ return API; |
@@ -0,1 +1,2 @@ | ||
var requireUncached = require('../helpers/RequireUncached.js'); | ||
module.exports = function(API) { | ||
@@ -5,3 +6,3 @@ return function(path) { | ||
try { | ||
require(path)(API) | ||
requireUncached(path)(API) | ||
} catch(err) { | ||
@@ -13,3 +14,3 @@ console.log("Error: I can't find '" + path + "'."); | ||
try { | ||
require(p)(API); | ||
requireUncached(p)(API); | ||
} catch(err) { | ||
@@ -16,0 +17,0 @@ console.log("Error: I can't find '" + p + "'."); |
@@ -1,15 +0,90 @@ | ||
module.exports = function(argv, absurd) { | ||
var colors = require('colors'); | ||
var compile = function(absurd, source, output) { | ||
// if there is output provided | ||
if(output) { | ||
absurd(process.cwd() + "/" + source).compileFile(output, function(err, css) { | ||
if(err) throw err; | ||
console.log(("> save: " + output).green); | ||
}); | ||
} else { | ||
absurd(process.cwd() + "/" + source).compile(function(err, css) { | ||
if(err) throw err; | ||
console.log(("> css: " + css).green); | ||
}); | ||
} | ||
} | ||
module.exports = function(argv, absurd) { | ||
// if there is source provided | ||
if(argv.s) { | ||
if(argv.o) { | ||
absurd(process.cwd() + "/" + argv.s).compileFile(argv.o, function(err, css) { | ||
if(err) throw err; | ||
console.log(argv.o + " created successful."); | ||
}); | ||
} else { | ||
absurd(process.cwd() + "/" + argv.s).compile(function(err, css) { | ||
if(err) throw err; | ||
console.log(css); | ||
}); | ||
compile(absurd, argv.s, argv.o); | ||
// if there is watcher provided | ||
if(argv.w) { | ||
// var watchr = require('watchr'); | ||
// var paths = argv.w.split(","); | ||
// watchr.watch({ | ||
// paths: paths, | ||
// listeners: { | ||
// log: function(logLevel){ | ||
// // console.log('a log message occured:', arguments); | ||
// }, | ||
// error: function(err){ | ||
// console.log('> an error occured:'.red, err); | ||
// }, | ||
// watching: function(err, watcherInstance, isWatching){ | ||
// if (err) { | ||
// console.log(("> watching the path " + watcherInstance.path + " failed with error").red, err); | ||
// } else { | ||
// // console.log("watching the path " + watcherInstance.path + " completed"); | ||
// } | ||
// }, | ||
// change: function(changeType,filePath,fileCurrentStat,filePreviousStat){ | ||
// console.log(("> " + arguments[0] + ": " + arguments[1]).yellow); | ||
// compile(absurd, argv.s, argv.o); | ||
// } | ||
// }, | ||
// next: function(err, watchers) { | ||
// if (err) { | ||
// return console.log("watching everything failed with error", err); | ||
// } else { | ||
// for(var i=0; w=watchers[i]; i++) { | ||
// console.log(("> watching " + w.config.path).magenta); | ||
// } | ||
// } | ||
// // Close watchers after 60 seconds | ||
// // setTimeout(function(){ | ||
// // var i; | ||
// // console.log('Stop watching our paths'); | ||
// // for ( i=0; i<watchers.length; i++ ) { | ||
// // watchers[i].close(); | ||
// // } | ||
// // },60*1000); | ||
// } | ||
// }); | ||
var watch = require('watch') | ||
watch.createMonitor(argv.w, { | ||
ignoreDotFiles: true | ||
}, function (monitor) { | ||
monitor.files['/home/mikeal/.zshrc'] // Stat object for my zshrc. | ||
monitor.on("created", function (f, stat) { | ||
console.log(("> new file created: " + f).yellow); | ||
compile(absurd, argv.s, argv.o); | ||
}); | ||
monitor.on("changed", function (f, curr, prev) { | ||
console.log(("> file changed: " + f).yellow); | ||
compile(absurd, argv.s, argv.o); | ||
}); | ||
monitor.on("removed", function (f, stat) { | ||
console.log(("> file deleted: " + f).yellow); | ||
compile(absurd, argv.s, argv.o); | ||
}); | ||
}) | ||
console.log(("> watching " + argv.w).magenta); | ||
} | ||
} | ||
} |
module.exports = function(path) { | ||
var _path = {}; | ||
if(!path) { | ||
return {err: "Wrong or missing path parameters."}; | ||
return false; | ||
} else if(typeof path == "string") { | ||
@@ -6,0 +6,0 @@ _path = {source: path}; |
{ | ||
"name": "absurd", | ||
"version": "0.0.11", | ||
"version": "0.0.12", | ||
"homepage": "https://github.com/krasimir/absurd", | ||
@@ -10,3 +10,5 @@ "description": "CSS preprocessor", | ||
"dependencies": { | ||
"optimist": "0.6.0" | ||
"optimist": "0.6.0", | ||
"colors": "0.6.2", | ||
"watch": "0.8.0" | ||
}, | ||
@@ -13,0 +15,0 @@ "keywords": [ |
234
README.md
@@ -1,4 +0,236 @@ | ||
absurd | ||
absurd.js | ||
====== | ||
Writing your CSS in JavaScript. That's it! | ||
## Installation | ||
npm install -g absurd | ||
## Usage | ||
Absurd is really simple. It just gets instructions and base on them produces css. So, it's just a matter of personal choice where to use it. You may want to integrate the module directly into your application. If that's not ok for you then you are able to compile the css by using the command line. | ||
### Inline styles | ||
var Absurd = require("absurd"); | ||
Absurd(function(api) { | ||
// use the Absurd's api here | ||
}).compile(function(err, css) { | ||
// do something with the css | ||
}); | ||
Or you may get the API separately. | ||
var absurd = Absurd(); | ||
var api = absurd.api; | ||
api.add({ ... }).import("..."); | ||
absurd.compile(function(err, css) { | ||
// do something with the css | ||
}); | ||
### Puting the styles in an external file | ||
Just create a *.js* file like for example */css/styles.js*. The file should contain the usual nodejs module code. | ||
module.exports = function(api) { | ||
// use the Absurd's api here | ||
} | ||
After that, in your nodejs application */app.js* | ||
Absurd("./css/styles.js").compile(function(err, css) { | ||
// ... | ||
}); | ||
### Compiling to file | ||
var output = "./css/styles.css"; | ||
Absurd("./css/styles.js").compileFile(output, function(err, css) { | ||
// ... | ||
}); | ||
### Using through command line interface | ||
// outputs the css in the console | ||
absurd -s [source file] | ||
// outputs the css to a file | ||
absurd -s [source file] -o [output file] | ||
## Syntax | ||
In the context of JavaScript the closest thing to pure CSS syntax is JSON format. So, every valid JSON is actually valid Absurd syntax. As you can see above, there are two ways to send styles to the module. In both cases you have an access to the Absurd's API. For example: | ||
Absurd(function(api) { | ||
api.add({}); | ||
}); | ||
or in an external js file | ||
module.exports = function(api) { | ||
api.add({}); | ||
} | ||
The *add* method accepts valid JSON. This could be something like | ||
{ | ||
body: { | ||
'margin-top': '20px', | ||
'padding': 0, | ||
'font-weight': 'bold', | ||
section: { | ||
'padding-top': '20px' | ||
} | ||
} | ||
} | ||
Every object defines a selector. Every property of that object could be a property and its value or another object. For example the JSON above is compiled to: | ||
body { | ||
margin-top: 20px; | ||
padding: 0; | ||
font-weight: bold; | ||
} | ||
body section { | ||
padding-top: 20px; | ||
} | ||
You may send even an array of style like that | ||
{ | ||
'.header nav': [ | ||
{ 'font-size': '10px' }, | ||
{ 'font-size': '20px' } | ||
] | ||
} | ||
And that's compiled to | ||
.header nav { | ||
font-size: 20px; | ||
} | ||
### Pseudo classes | ||
It's similar like the example above: | ||
a: { | ||
'text-decoration': 'none', | ||
'color': '#000', | ||
':hover': { | ||
'text-decoration': 'underline', | ||
'color': '#999' | ||
}, | ||
':before': { | ||
content: '"> "' | ||
} | ||
} | ||
Is compiled to: | ||
a { | ||
text-decoration: none; | ||
color: #000; | ||
} | ||
a:hover { | ||
text-decoration: underline; | ||
color: #999; | ||
} | ||
a:before { | ||
content: "> "; | ||
} | ||
### Importing | ||
Of course you can't put everything in a single file. That's why there is *.import* method: | ||
/css/index.js | ||
module.exports = function(api) { | ||
api.import(__dirname + '/config/colors.js'); | ||
api.import(__dirname + '/config/sizes.js'); | ||
api.import([ | ||
__dirname + '/layout/grid.js', | ||
__dirname + '/forms/login-form.js', | ||
__dirname + '/forms/feedback-form.js' | ||
]); | ||
} | ||
### Using variables | ||
There is no need to use something special. Because that's pure javascript you may write: | ||
var brandColor = "#00F"; | ||
Absurd(function(api) { | ||
api.add({ | ||
'.header nav': { | ||
color: brandColor | ||
} | ||
}) | ||
}) | ||
However, if you want to share variables between the files you may use the API's method *storage*. Let's say that you have two files */css/A.js* and */css/B.js* and you want to share values between them. | ||
// A.js | ||
module.exports = function(api) { | ||
api.storage("brandColor", "#00F"); | ||
} | ||
// B.js | ||
module.exports = function(api) { | ||
api.add({ | ||
body: { | ||
color: api.storage("brandColor") | ||
} | ||
}) | ||
} | ||
### Mixins | ||
In the context of Absurd mixins are actually normal javascript functions. The ability to put things inside the Absurd's storage gives you also the power to share mixins between the files. For example: | ||
// A.js | ||
module.exports = function(api) { | ||
api.storage("button", function(color, thickness) { | ||
return { | ||
color: color, | ||
display: "inline-block", | ||
padding: "10px 20px", | ||
border: "solid " + thickness + "px " + color, | ||
'font-size': "10px" | ||
} | ||
}); | ||
} | ||
// B.js | ||
module.exports = function(api) { | ||
api.add({ | ||
'.header-button': [ | ||
api.storage("button")("#AAA", 10), | ||
{ | ||
color: '#F00', | ||
'font-size': '13px' | ||
} | ||
] | ||
}); | ||
} | ||
What you do is to send array of two objects to the selector '.header-button'. The above code is compiled to: | ||
.header-button { | ||
color: #F00; | ||
display: inline-block; | ||
padding: 10px 20px; | ||
border: solid 10px #AAA; | ||
font-size: 13px; | ||
} | ||
Notice that the second object overwrites few styles passed via the mixin. | ||
## Testing | ||
The tests are placed in */tests* directory. Install [jasmine-node](https://github.com/mhevery/jasmine-node) and run | ||
jasmine ./tests |
@@ -30,13 +30,19 @@ describe("Absurd acting in code:", function() { | ||
absurd = Absurd(); | ||
path = absurd.getPath(); | ||
expect(path.source).not.toBeDefined(); | ||
expect(path.err).toBeDefined(); | ||
done(); | ||
}); | ||
it("should work with no path passed", function(done) { | ||
absurd = Absurd(); | ||
absurd.api.add({a: {color: "#123"}}); | ||
absurd.compile(function(err, css) { | ||
expect(err).toBe(null); | ||
expect(css).toBeDefined(); | ||
expect(css).toContain("color: #123;"); | ||
done(); | ||
}) | ||
}); | ||
it("should compile an inline function", function(done) { | ||
Absurd(function(A) { | ||
A.add({ | ||
Absurd(function(api) { | ||
api.add({ | ||
'.absurd-title': { | ||
@@ -64,3 +70,19 @@ 'border-radius': '10px' | ||
it("should compile styles passed in array", function(done) { | ||
Absurd(function(api) { | ||
api.add({ | ||
'.header nav': [ | ||
{ 'font-size': '10px' }, | ||
{ 'font-size': '20px' } | ||
] | ||
}) | ||
}).compile(function(err, css) { | ||
expect(err).toBe(null); | ||
expect(css).toBeDefined(); | ||
expect(css).toContain(".header nav {\n font-size: 20px;"); | ||
done(); | ||
}) | ||
}); | ||
}); |
@@ -9,3 +9,3 @@ module.exports = function(A) { | ||
'.header': { | ||
margin: '10px 0 20px 0' | ||
margin: '10px 0 20px 10px' | ||
} | ||
@@ -12,0 +12,0 @@ |
@@ -6,3 +6,9 @@ module.exports = function(A) { | ||
'padding': 0, | ||
'font-weight': 'bold' | ||
'font-weight': 'bold', | ||
section: { | ||
'padding-top': '42px' | ||
}, | ||
p: { | ||
'line-height': '30px' | ||
} | ||
} | ||
@@ -12,5 +18,6 @@ }); | ||
'header .logo': { | ||
'font-size': '30px' | ||
'font-size': '18px' | ||
} | ||
}); | ||
A.import(__dirname + "/config/others.js"); | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
21809
29
579
236
6
3
+ Addedcolors@0.6.2
+ Addedwatch@0.8.0
+ Addedcolors@0.6.2(transitive)
+ Addedwatch@0.8.0(transitive)